From 56a360e300257ee6e7355244bbfbd545ff59f6a5 Mon Sep 17 00:00:00 2001 From: chinglee-iot <61685396+chinglee-iot@users.noreply.github.com> Date: Fri, 21 Jul 2023 13:32:00 +0800 Subject: [PATCH] Merge main to SMP branch (#86) * Fix array-bounds compiler warning on gcc11+ in list.h (#580) listGET_OWNER_OF_NEXT_ENTRY computes `( pxConstList )->pxIndex->pxNext` after verifying that `( pxConstList )->pxIndex` points to `xListEnd`, which due to being a MiniListItem_t, can be shorter than a ListItem_t. Thus, `( pxConstList )->pxIndex` is a `ListItem_t *` that extends past the end of the `List_t` whose `xListEnd` it points to. This is fixed by accessing `pxNext` through a `MiniListItem_t` instead. * move the prototype for vApplicationIdleHook to task.h. (#600) Co-authored-by: pluess Co-authored-by: Gaurav-Aggarwal-AWS <33462878+aggarg@users.noreply.github.com> * Update equal priority task preemption (#603) * vTaskResume and vTaskPrioritySet don't preempt equal priority task * Update vTaskResumeAll not to preempt task with equal priority * Fix in xTaskResumeFromISR * Update FreeRTOS/FreeRTOS build checks (#613) This is needed to be compatible with the refactoring done in this PR - https://github.com/FreeRTOS/FreeRTOS/pull/889 Signed-off-by: Gaurav Aggarwal Signed-off-by: Gaurav Aggarwal * Add ulTaskGetRunTimeCounter and ulTaskGetRunTimePercent (#611) Allow ulTaskGetIdleRunTimeCounter and ulTaskGetIdleRunTimePercent to be used whenever configGENERATE_RUN_TIME_STATS is enabled, as this is the only requirement for these functions to work. * Fix some CMake documentation typos (#616) The quick start instructions for CMake mention the "master" git branch which has been replaced by "main" in the current repo. The main CMakeLists.txt documents how to integrate a custom port. Fix a typo in the suggested CMake code. * Added support of 64bit events. (#597) * Added support of 64bit even Signed-off-by: Cervenka Dusan * Added missing brackets Signed-off-by: Cervenka Dusan * Made proper name for tick macro. Signed-off-by: Cervenka Dusan * Improved macro evaluation Signed-off-by: Cervenka Dusan * Fixed missed port files + documentation Signed-off-by: Cervenka Dusan * Changes made on PR Signed-off-by: Cervenka Dusan * Fix macro definition. Signed-off-by: Cervenka Dusan * Formatted code with uncrustify Signed-off-by: Cervenka Dusan --------- Signed-off-by: Cervenka Dusan * Introduce portMEMORY_BARRIER for Microblaze port. (#621) The introduction of `portMEMORY_BARRIER` will ensure the places in the kernel use a barrier will work. For example, `xTaskResumeAll` has a memory barrier to ensure its correctness when compiled with optimization enabled. Without the barrier `xTaskResumeAll` can fail (e.g. start reading and writing to address 0 and/or infinite looping) when `xPendingReadyList` contains more than one task to restore. In `xTaskResumeAll` the compiler chooses to cache the `pxTCB` the first time through the loop for use in every subsequent loop. This is incorrect as the removal of `pxTCB->xEventListItem` will actually change the value of `pxTCB` if it was read again at the top of the loop. The barrier forces the compiler to read `pxTCB` again at the top of the loop. The compiler is operating correctly. The removal `pxTCB->xEventListItem` executes on a `List_t *` and `ListItem_t *`. This means that the compiler can assume that any `MiniListItem_t` values are unchanged by the loop (i.e. "strict-aliasing"). This allows the compiler to cache `pxTCB` as it is obtained via a `MiniListItem_t`. This is incorrect in this case because it is possible for a `ListItem_t *` to actually alias a `MiniListItem_t`. This is technically a "violation of aliasing rules" so we use the the barrier to disable the strict-aliasing optimization in this loop. * Do not call exit() on MSVC Port when calling vPortEndScheduler (#624) * make port exitable * correctly set xPortRunning to False * add suggestions from Review Co-authored-by: Gaurav-Aggarwal-AWS <33462878+aggarg@users.noreply.github.com> * add suggestions from Review Co-authored-by: Gaurav-Aggarwal-AWS <33462878+aggarg@users.noreply.github.com> --------- Co-authored-by: Gaurav-Aggarwal-AWS <33462878+aggarg@users.noreply.github.com> * Update PR template to include checkbox for Unit Test related changes (#627) * Fix build failure introduced in PR #597 (#629) The PR #597 introduced a new config option configTICK_TYPE_WIDTH_IN_BITS which can be defined to one of the following: * TICK_TYPE_WIDTH_16_BITS - Tick type is 16 bit wide. * TICK_TYPE_WIDTH_32_BITS - Tick type is 32 bit wide. * TICK_TYPE_WIDTH_64_BITS - Tick type is 64 bit wide. Earlier we supported 16 and 32 bit width for tick type which was controlled using the config option configUSE_16_BIT_TICKS. The PR tried to maintain backward compatibility by honoring configUSE_16_BIT_TICKS. The backward compatibility did not work as expected though, as the macro configTICK_TYPE_WIDTH_IN_BITS was used before it was defined. This PR addresses it by ensuring that the macro configTICK_TYPE_WIDTH_IN_BITS is defined before it is used. Testing 1. configUSE_16_BIT_TICKS is defined to 0. Source (function xTaskIncrementTick in tasks.c): ``` const TickType_t xConstTickCount = xTickCount + ( TickType_t ) 1; ``` Assembly: ``` 109e: 4b50 ldr r3, [pc, #320] ; (11e0 ) 10a0: f8d3 4134 ldr.w r4, [r3, #308] ; 0x134 10a4: 3401 adds r4, #1 10a6: f8c3 4134 str.w r4, [r3, #308] ; 0x134 ``` It is clear from assembly that the tick type is 32 bit. 2. configUSE_16_BIT_TICKS is defined to 1. Source (function xTaskIncrementTick in tasks.c): ``` const TickType_t xConstTickCount = xTickCount + ( TickType_t ) 1; ``` Assembly: ``` 10e2: 4b53 ldr r3, [pc, #332] ; (1230 ) 10e4: f8b3 4134 ldrh.w r4, [r3, #308] ; 0x134 10e8: b2a4 uxth r4, r4 10ea: 3401 adds r4, #1 10ec: b2a4 uxth r4, r4 10ee: f8a3 4134 strh.w r4, [r3, #308] ; 0x134 ``` It is clear from assembly that the tick type is 16 bit. 3. configTICK_TYPE_WIDTH_IN_BITS is defined to TICK_TYPE_WIDTH_16_BITS. Source (function xTaskIncrementTick in tasks.c): ``` const TickType_t xConstTickCount = xTickCount + ( TickType_t ) 1; ``` Assembly: ``` 10e2: 4b53 ldr r3, [pc, #332] ; (1230 ) 10e4: f8b3 4134 ldrh.w r4, [r3, #308] ; 0x134 10e8: b2a4 uxth r4, r4 10ea: 3401 adds r4, #1 10ec: b2a4 uxth r4, r4 10ee: f8a3 4134 strh.w r4, [r3, #308] ; 0x134 ``` It is clear from assembly that the tick type is 16 bit. 4. configTICK_TYPE_WIDTH_IN_BITS is defined to TICK_TYPE_WIDTH_32_BITS. Source (function xTaskIncrementTick in tasks.c): ``` const TickType_t xConstTickCount = xTickCount + ( TickType_t ) 1; ``` Assembly: ``` 109e: 4b50 ldr r3, [pc, #320] ; (11e0 ) 10a0: f8d3 4134 ldr.w r4, [r3, #308] ; 0x134 10a4: 3401 adds r4, #1 10a6: f8c3 4134 str.w r4, [r3, #308] ; 0x134 ``` It is clear from assembly that the tick type is 32 bit. 5. configTICK_TYPE_WIDTH_IN_BITS is defined to TICK_TYPE_WIDTH_64_BITS. ``` #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. ``` The testing was done for GCC/ARM_CM3 port which does not support 64 bit tick type. 6. Neither configUSE_16_BIT_TICKS nor configTICK_TYPE_WIDTH_IN_BITS defined. ``` #error Missing definition: One of configUSE_16_BIT_TICKS and configTICK_TYPE_WIDTH_IN_BITS must be defined in FreeRTOSConfig.h. See the Configuration section of the FreeRTOS API documentation for details. ``` 7. Both configUSE_16_BIT_TICKS and configTICK_TYPE_WIDTH_IN_BITS defined. ``` #error Only one of configUSE_16_BIT_TICKS and configTICK_TYPE_WIDTH_IN_BITS must be defined in FreeRTOSConfig.h. See the Configuration section of the FreeRTOS API documentation for details. ``` Related issue - https://github.com/FreeRTOS/FreeRTOS-Kernel/issues/628 Signed-off-by: Gaurav Aggarwal * Feature/fixing clang gnu compiler warnings (#620) * Adding in ability to support a library for freertos_config and a custom freertos_kernel_port (#558) * Using single name definition for libraries everywhere. (#558) * Supporting backwards compatibility with FREERTOS_CONFIG_FILE_DIRECTORY (#571) * Removing compiler warnings for GNU and Clang. (#571) * Added in documentation on how to consume from a main project. Added default PORT selection for native POSIX and MINGW platforms. * Only adding freertos_config if it exists. Removing auto generation of it from a FREERTOS_CONFIG_FILE_DIRECTORY. * Fixing clang and gnu compiler warnings. * Adding in project information and how to compile for GNU/clang * Fixing compiler issue with unused variable - no need to declare variable. * Adding in compile warnings for linux builds that kernel is okay with using. * Fixing more extra-semi-stmt clang warnings. * Moving definition of hooks into header files if features are enabled. * Fixing formatting with uncrustify. * Fixing merge conflicts with main merge. * Fixing compiler errors due to merge issues and formatting. * Fixing Line feeds. * Adding 'portNORETURN' into portmacros.h. Other Updates based on PR request * Further clean-up of clang and clang-tidy issues. * Removing compiler specific pragmas from common c files. * Fixing missing lexicon entry and uncrustify formatting changes. * Resolving merge issue multiple defnitions of proto for prvIdleTask * Fixing formatting issues that are not covered by uncrustify. Use clang-tidy instead if you want this level of control. * More uncrustify formatting issues. * Fixing extra bracket in #if statement. --------- Co-authored-by: Gaurav-Aggarwal-AWS <33462878+aggarg@users.noreply.github.com> * POSIX port fixes (#626) * Fix types in POSIX port Use TaskFunction_t and StackType_t as other ports do. * Fix portTICK_RATE_MICROSECONDS in POSIX port --------- Co-authored-by: Jacques GUILLOU Co-authored-by: Gaurav-Aggarwal-AWS <33462878+aggarg@users.noreply.github.com> * Cortex-M35P: Add Cortex-M35P port (#631) * Cortex-M35P: Add Cortex-M35P port The Cortex-M35P support added to kernel. The port hasn't been validated yet with TF-M. Hence TF-M support is not included in this port. Signed-off-by: Devaraj Ranganna * Add portNORETURN to the newly added portmacro.h Signed-off-by: Gaurav Aggarwal --------- Signed-off-by: Devaraj Ranganna Signed-off-by: Gaurav Aggarwal Co-authored-by: Gaurav-Aggarwal-AWS <33462878+aggarg@users.noreply.github.com> Co-authored-by: Gaurav Aggarwal Co-authored-by: kar-rahul-aws <118818625+kar-rahul-aws@users.noreply.github.com> * Introduced Github Status Badge for Unit Tests (#634) * Introduced Github Status Badge for Unit Tests * Github status badge to point to latest run * Github status badge UT points to latest results * Fixed URL for Github Status badge --------- Co-authored-by: kar-rahul-aws <118818625+kar-rahul-aws@users.noreply.github.com> * Remove C99 requirement from CMake file (#633) * Remove C99 requirement from CMake file The kernel source is C89 compliant and does not need C99. Signed-off-by: Gaurav Aggarwal * Explicitly set C89 requirement for kernel Signed-off-by: Gaurav Aggarwal --------- Signed-off-by: Gaurav Aggarwal * Add Thread Local Storage (TLS) support using Picolibc functions (#343) * Pass top of stack to configINIT_TLS_BLOCK Picolibc wants to allocate the per-task TLS block within the stack segment, so it will need to modify the top of stack value. Pass the pxTopOfStack variable to make this explicit. Signed-off-by: Keith Packard * Move newlib-specific definitions to separate file This reduces the clutter in FreeRTOS.h caused by having newlib-specific macros present there. Signed-off-by: Keith Packard * Make TLS code depend only on configUSE_C_RUNTIME_TLS_SUPPORT Remove reference to configUSE_NEWLIB_REENTRANT as that only works when using newlib. configUSE_C_RUNTIME_TLS_SUPPORT is always set when configUSE_NEWLIB_REENTRANT is set, so using both was redundant in that case. Signed-off-by: Keith Packard * portable-ARC: Adapt ARC support to use generalized TLS support With generalized thread local storage (TLS) support present in the core, the two ARC ports need to have the changes to the TCB mirrored to them. Signed-off-by: Keith Packard * Add Thread Local Storage (TLS) support using Picolibc functions This patch provides definitions of the general TLS support macros in terms of the Picolibc TLS support functions. Picolibc is normally configured to use TLS internally for all variables that are intended to be task-local, so these changes are necessary for picolibc to work correctly with FreeRTOS. The picolibc helper functions rely on elements within the linker script to arrange the TLS data in memory and define some symbols. Applications wanting to use this mechanism will need changes in their linker script when migrating to picolibc. Signed-off-by: Keith Packard --------- Signed-off-by: Keith Packard Co-authored-by: Keith Packard Co-authored-by: Gaurav-Aggarwal-AWS <33462878+aggarg@users.noreply.github.com> * Interrupt priority assert improvements for CM3/4/7 (#602) * Interrupt priority assert improvements for CM3/4/7 In the ARM_CM3, ARM_CM4, and ARM_CM7 ports, change the assertion that `configMAX_SYSCALL_INTERRUPT_PRIORITY` is nonzero to account for the number of priority bits implemented by the hardware. Change these ports to also use the lowest priority for PendSV and SysTick, ignoring `configKERNEL_INTERRUPT_PRIORITY`. * Remove not needed configKERNEL_INTERRUPT_PRIORITY define Signed-off-by: Gaurav Aggarwal --------- Signed-off-by: Gaurav Aggarwal Co-authored-by: Gaurav-Aggarwal-AWS <33462878+aggarg@users.noreply.github.com> Co-authored-by: Gaurav Aggarwal * Introduced code coverage status badge (#635) * Introduced code coverage status badge * Trying to fix the URL checker issue * Fix URL check Signed-off-by: Gaurav Aggarwal --------- Signed-off-by: Gaurav Aggarwal Co-authored-by: Gaurav Aggarwal Co-authored-by: Gaurav-Aggarwal-AWS <33462878+aggarg@users.noreply.github.com> * added portPOINTER_SIZE_TYPE and SIZE_MAX definition to PIC24/dsPIC port (#636) * added portPOINTER_SIZE_TYPE definition to PIC24/dsPIC port * Added SIZE_MAX definition to PIC24/dsPIC33 * Fix TLS and stack alignment when using picolibc (#637) Both the TLS block and stack must be correctly aligned when using picolibc. The architecture stack alignment is represented by the portBYTE_ALIGNMENT_MASK and the TLS block alignment is provided by the Picolibc _tls_align() inline function for Picolibc version 1.8 and above. For older versions of Picolibc, we'll assume that the TLS block requires the same alignment as the stack. For downward growing stacks, this requires aligning the start of the TLS block to the maximum of the stack alignment and the TLS alignment. With this, both the TLS block and stack will now be correctly aligned. For upward growing stacks, the two areas must be aligned independently; the TLS block is aligned from the start of the stack, then the tls space is allocated, and then the stack is aligned above that. It's probably useful to know here that the linker ensures that variables within the TLS block are assigned offsets that match their alignment requirements. If the TLS block itself is correctly aligned, then everything within will also be. I have only tested the downward growing stack branch of this patch. Signed-off-by: Keith Packard Co-authored-by: Keith Packard Co-authored-by: Gaurav-Aggarwal-AWS <33462878+aggarg@users.noreply.github.com> * Enable building the GCC Cortex-R5 port without an FPU (#586) * Ensure configUSE_TASK_FPU_SUPPORT option is set correctly If one does enable the FPU of the Cortex-R5 processor, then the GCC compiler will define the macro __ARM_FP. This can be used to ensure, that the configUSE_TASK_FPU_SUPPORT is set accordingly. * Enable the implementation of vPortTaskUsesFPU only if configUSE_TASK_FPU_SUPPORT is set to 1 * Remove error case in pxPortInitialiseStack The case of configUSE_TASK_FPU_SUPPORT is 0 is now handled * Enable access to FPU registers only if FPU is enabled * Make minor formating changes * Format ARM Cortex-R5 port * Address review comments from @ChristosZosi * Minor code review suggestions Signed-off-by: Gaurav Aggarwal --------- Signed-off-by: Gaurav Aggarwal Co-authored-by: Christos Zosimidis Co-authored-by: Gaurav-Aggarwal-AWS <33462878+aggarg@users.noreply.github.com> Co-authored-by: Gaurav Aggarwal * Fix freertos_kernel cmake property, Posix Port (#640) * Fix freertos_kernel cmake property, Posix Port * Moves the `set_property()` call below the target definition in top level CMakeLists file * Corrects billion value from `ULL` suffix (not C90 compliant) to `UL` suffix with cast to uint64_t * Add blank line to CMakeLists.txt * Add missing FreeRTOS+ defines * Run kernel demos and unit tests for PR changes (#645) * Run kernel demos and unit tests for PR changes Kernel demos check builds multiple demos from FreeRTOS/FreeRTOS and unit tests check runs unit tests in FreeRTOS/FreeRTOS. Both of these checks currently use main branch of FreeRTOS-Kernel. This commits updates these checks to use the changes in the PR. Signed-off-by: Gaurav Aggarwal * Do not specify PR SHA explicitly as that is default Signed-off-by: Gaurav Aggarwal * Remove explicit PR SHA from kernel checks Signed-off-by: Gaurav Aggarwal --------- Signed-off-by: Gaurav Aggarwal * Add functions to get the buffers of statically created objects (#641) Added various ...GetStaticBuffer() functions to get the buffers of statically created objects. --------- Co-authored-by: Paul Bartell Co-authored-by: Nikhil Kamath <110539926+amazonKamath@users.noreply.github.com> Co-authored-by: Gaurav Aggarwal * Cortex-M Assert when NVIC implements 8 PRIO bits (#639) * Cortex-M Assert when NVIC implements 8 PRIO bits * Fix CM3 ports * Fix ARM_CM3_MPU * Fix ARM CM3 * Fix ARM_CM4_MPU * Fix ARM_CM4 * Fix GCC ARM_CM7 * Fix IAR ARM ports * Uncrustify changes * Fix MikroC_ARM_CM4F port * Fix MikroC_ARM_CM4F port-(2) * Fix RVDS ARM ports * Revert changes for Tasking/ARM_CM4F port * Revert changes for Tasking/ARM_CM4F port-(2) * Update port.c Fix GCC/ARM_CM4F port * Update port.c * update GCC\ARM_CM4F port * update port.c * Assert to check configMAX_SYSCALL_INTERRUPT_PRIORITY is set to higher priority * Fix merge error: remove duplicate code * Fix typos --------- Co-authored-by: Gaurav-Aggarwal-AWS <33462878+aggarg@users.noreply.github.com> Co-authored-by: Ubuntu * Remove C90 requirement from CMakeLists (#649) This is needed as it is breaking projects - https://forums.freertos.org/t/freertos-gcc-cmake/16984 We will re-evaluate and accordingly add this later. Signed-off-by: Gaurav Aggarwal * Only add alignment padding when needed (#650) Heap 4 and Heap 5 add some padding to ensure that the allocated blocks are always aligned to portBYTE_ALIGNMENT bytes. The code until now was adding padding always even if the resulting block was already aligned. This commits updates the code to only add padding if the resulting block is not aligned. Signed-off-by: Gaurav Aggarwal * add a missing comma (#651) * fix conversion warning (#658) FreeRTOS-Kernel/portable/GCC/ARM_CM4F/port.c:399:41: error: conversion from 'uint32_t' {aka 'long unsigned int'} to 'uint8_t' {aka 'unsigned char'} may change value [-Werror=conversion] Signed-off-by: Vo Trung Chi * ARMv7M: Adjust implemented priority bit assertions (#665) Adjust assertions related to the CMSIS __NVIC_PRIO_BITS and FreeRTOS configPRIO_BITS configuration macros such that these macros specify the minimum number of implemented priority bits supported by a config build rather than the exact number of implemented priority bits. Related to Qemu issue #1122 * Format portmacro.h in arm CM0 ports * portable/ARM_CM0: Add xPortIsInsideInterrupt Add missing xPortIsInsideInterrupt function to Cortex-M0 port. * tree-wide: Unify formatting of __cplusplus ifdefs * Paranthesize expression-like macro (#668) * Updated tasks.c checks for scheduler suspension (#670) This commit updates the checks for the variable uxSchedulerSuspended in tasks.c module to use a uniform format. Signed-off-by: Sudeep Mohanty * Fix cast alignment warning (#669) * Fix cast alignment warning Without this change, the code produces the following warning when compiled with `-Wcast-align` flag: ``` cast increases required alignment of target type ``` Signed-off-by: Gaurav Aggarwal * Align StackSize and StackAddress for macOS (#674) * Armv8-M (except Cortex-M23) interrupt priority checking (#673) * Armv8-M: Formatting changes Signed-off-by: Devaraj Ranganna * Armv8-M: Add support for interrupt priority check FreeRTOS provides `FromISR` system calls which can be called directly from interrupt service routines. It is crucial that the priority of these ISRs is set to same or lower value (numerically higher) than that of `configMAX_SYSCALL_INTERRUPT_PRIORITY`. For more information refer to https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. Add a check to trigger an assert when an ISR with priority higher (numerically lower) than `configMAX_SYSCALL_INTERRUPT_PRIORITY` calls `FromISR` system calls if `configASSERT` macro is defined. In addition, add a config option `configQEMU_DISABLE_INTERRUPT_PRIO_BITS_CHECK` to disable interrupt priority check while running on QEMU. Based on the discussion https://gitlab.com/qemu-project/qemu/-/issues/1122, The interrupt priority bits in QEMU do not match the real hardware. Therefore the assert that checks the number of implemented bits and __NVIC_PRIO_BITS will always fail. The config option `configQEMU_DISABLE_INTERRUPT_PRIO_BITS_CHECK` should be defined in the `FreeRTOSConfig.h` for QEMU targets. Signed-off-by: Devaraj Ranganna * Use SHPR2 for calculating interrupt priority bits This removes the dependency on the secure software to mark the interrupt as non-secure. Signed-off-by: Gaurav Aggarwal --------- Signed-off-by: Devaraj Ranganna Signed-off-by: Gaurav Aggarwal Co-authored-by: Gaurav Aggarwal Co-authored-by: Gaurav-Aggarwal-AWS <33462878+aggarg@users.noreply.github.com> * Use the extended movx instruction instead of mov (#676) The following is from the MSP430X instruction set - ``` MOVX.W Move source word to destination word. The source operand is copied to the destination. The source operand is not affected. Both operands may be located in the full address space. ``` The movx instruction allows both the operands to be located in the full address space and therefore, works with large data model as well. Signed-off-by: Gaurav Aggarwal * Fix eTaskGetState for pending ready tasks (#679) This commit fixes eTaskGetState so that eReady is returned for pending ready tasks. Co-authored-by: Darian Leung * Generates SBOM after source files are updated with release tag (#680) * update source file with release version info before SBOM generation * delete tag branch during cleanup * Add back croutines by reverting PR#590 (#685) * Add croutines to the code base * Add croutine changes to cmake, lexicon and readme * Add croutine file to portable cmake file * Add back more references from PR 591 * Remove __NVIC_PRIO_BITS and configPRIO_BITS check in port (#683) * Remove __NVIC_PRIO_BITS and configPRIO_BITS check in CM3, CM4 and ARMv8. * Add hardware not implemented bits check. These bits should be zero. --------- Co-authored-by: Gaurav-Aggarwal-AWS <33462878+aggarg@users.noreply.github.com> * Use UBaseType_t as interrupt mask (#689) * Use UBaseType_t as interrupt mask * Update GCC posix port to use UBaseType_t as interrupt mask * Fix clang warning in croutine and stream buffer (#686) * Fix document warning in croutine * Fix cast-qual warning in stream buffer * Use portTASK_FUNCTION_PROTO to replace portNORETURN (#688) * Use portTASK_FUNCTION_PROTO to replace portNORETURN * Fix typo in check comment of configMAX_SYSCALL_INTERRUPT_PRIORITY (#690) * Add constant type for portMAX_DELAY in port (#691) Co-authored-by: Gaurav-Aggarwal-AWS <33462878+aggarg@users.noreply.github.com> * Update static stream buffer size check (#693) * Use volatile size instead of sizeof directly to prevent always true/false warning * Fix typos in comments for the AT91SAM7S port (#695) Co-authored-by: RichardBarry <3073890+RichardBarry@users.noreply.github.com> * Fix #697: Missing portPOINTER_SIZE_TYPE definition for ATmega port (#698) * Remove empty expression statement compiler warning (#692) * Add do while( 0 ) loop for empty expression statement compiler warning * Update uxTaskGetSystemState for tasks in pending ready list (#702) * Update uxTaskGetSystemState to sync with eTaskGetState * Update in vTaskGetInfo for tasks in pending ready list should be in ready state. * Fix circular dependency in CMake project (#700) * Fix circular dependency in cmake project Fix for https://github.com/FreeRTOS/FreeRTOS-Kernel/issues/687 In order for custom ports to also break the cycle, they must link against freertos_kernel_include instead of freertos_kernel. * Simplify include path * Memory Protection Unit (MPU) Enhancements (#705) Memory Protection Unit (MPU) Enhancements This commit introduces a new MPU wrapper that places additional restrictions on unprivileged tasks. The following is the list of changes introduced with the new MPU wrapper: 1. Opaque and indirectly verifiable integers for kernel object handles: All the kernel object handles (for example, queue handles) are now opaque integers. Previously object handles were raw pointers. 2. Saving the task context in Task Control Block (TCB): When a task is swapped out by the scheduler, the task's context is now saved in its TCB. Previously the task's context was saved on its stack. 3. Execute system calls on a separate privileged only stack: FreeRTOS system calls, which execute with elevated privilege, now use a separate privileged only stack. Previously system calls used the calling task's stack. The application writer can control the size of the system call stack using new configSYSTEM_CALL_STACK_SIZE config macro. 4. Memory bounds checks: FreeRTOS system calls which accept a pointer and de-reference it, now verify that the calling task has required permissions to access the memory location referenced by the pointer. 5. System call restrictions: The following system calls are no longer available to unprivileged tasks: - vQueueDelete - xQueueCreateMutex - xQueueCreateMutexStatic - xQueueCreateCountingSemaphore - xQueueCreateCountingSemaphoreStatic - xQueueGenericCreate - xQueueGenericCreateStatic - xQueueCreateSet - xQueueRemoveFromSet - xQueueGenericReset - xTaskCreate - xTaskCreateStatic - vTaskDelete - vTaskPrioritySet - vTaskSuspendAll - xTaskResumeAll - xTaskGetHandle - xTaskCallApplicationTaskHook - vTaskList - vTaskGetRunTimeStats - xTaskCatchUpTicks - xEventGroupCreate - xEventGroupCreateStatic - vEventGroupDelete - xStreamBufferGenericCreate - xStreamBufferGenericCreateStatic - vStreamBufferDelete - xStreamBufferReset Also, an unprivileged task can no longer use vTaskSuspend to suspend any task other than itself. We thank the following people for their inputs in these enhancements: - David Reiss of Meta Platforms, Inc. - Lan Luo, Xinhui Shao, Yumeng Wei, Zixia Liu, Huaiyu Yan and Zhen Ling of School of Computer Science and Engineering, Southeast University, China. - Xinwen Fu of Department of Computer Science, University of Massachusetts Lowell, USA. - Yuequi Chen, Zicheng Wang, Minghao Lin of University of Colorado Boulder, USA. * Update History for Version 10.6.0 (#706) Signed-off-by: kar-rahul-aws * Fixed compile options polluting project (#694) * Fixed compile options polluting project Moved add_library higher * Apply suggestions from code review Co-authored-by: Paul Bartell * fixed cmakelists keeping in mind the suggestions --------- Co-authored-by: Paul Bartell Co-authored-by: Gaurav-Aggarwal-AWS <33462878+aggarg@users.noreply.github.com> Co-authored-by: Aniruddha Kanhere <60444055+AniruddhaKanhere@users.noreply.github.com> * Fix the comments in the CM3 and CM4 MPU Ports about the MPU Region numbers being loaded (#707) Co-authored-by: Soren Ptak Co-authored-by: Gaurav-Aggarwal-AWS <33462878+aggarg@users.noreply.github.com> * Update xSemaphoreGetStaticBuffer prototype in comment (#704) Co-authored-by: Gaurav-Aggarwal-AWS <33462878+aggarg@users.noreply.github.com> * Correct the misspelled name (#708) Signed-off-by: Gaurav Aggarwal --------- Signed-off-by: Gaurav Aggarwal Signed-off-by: Cervenka Dusan Signed-off-by: Devaraj Ranganna Signed-off-by: Keith Packard Signed-off-by: Vo Trung Chi Signed-off-by: Sudeep Mohanty Signed-off-by: kar-rahul-aws Co-authored-by: Archit Gupta <71798289+archigup@users.noreply.github.com> Co-authored-by: tcpluess Co-authored-by: pluess Co-authored-by: Gaurav-Aggarwal-AWS <33462878+aggarg@users.noreply.github.com> Co-authored-by: Chris Copeland Co-authored-by: David J. Fiddes <35607151+davefiddes@users.noreply.github.com> Co-authored-by: Dusan Cervenka Co-authored-by: bbain <16752579+bbain@users.noreply.github.com> Co-authored-by: Ju1He1 <93189163+Ju1He1@users.noreply.github.com> Co-authored-by: Aniruddha Kanhere <60444055+AniruddhaKanhere@users.noreply.github.com> Co-authored-by: phelter Co-authored-by: jacky309 Co-authored-by: Jacques GUILLOU Co-authored-by: Devaraj Ranganna Co-authored-by: Gaurav Aggarwal Co-authored-by: kar-rahul-aws <118818625+kar-rahul-aws@users.noreply.github.com> Co-authored-by: Nikhil Kamath <110539926+amazonKamath@users.noreply.github.com> Co-authored-by: Keith Packard Co-authored-by: Keith Packard Co-authored-by: Joseph Julicher Co-authored-by: Paul Bartell Co-authored-by: Christos Zosimidis Co-authored-by: Kody Stribrny <89810515+kstribrnAmzn@users.noreply.github.com> Co-authored-by: Holden Co-authored-by: Darian <32921628+Dazza0@users.noreply.github.com> Co-authored-by: Ubuntu Co-authored-by: Nicolas Co-authored-by: Vo Trung Chi Co-authored-by: Sudeep Mohanty <91244425+sudeep-mohanty@users.noreply.github.com> Co-authored-by: Monika Singh <108652024+moninom1@users.noreply.github.com> Co-authored-by: Darian Leung Co-authored-by: Tony Josi Co-authored-by: Evgeny Ermakov <22344340+unspecd@users.noreply.github.com> Co-authored-by: RichardBarry <3073890+RichardBarry@users.noreply.github.com> Co-authored-by: Joris Putcuyps Co-authored-by: Patrick Cook <114708437+cookpate@users.noreply.github.com> Co-authored-by: Mr. Jake Co-authored-by: Paul Bartell Co-authored-by: Soren Ptak Co-authored-by: Soren Ptak --- .github/lexicon.txt | 27 +- .github/workflows/auto-release.yml | 24 +- CMakeLists.txt | 19 +- History.txt | 111 + README.md | 3 +- croutine.c | 363 ++ event_groups.c | 6 +- include/CMakeLists.txt | 15 + include/FreeRTOS.h | 20 +- include/croutine.h | 755 +++ include/mpu_prototypes.h | 241 +- include/mpu_wrappers.h | 232 +- include/portable.h | 24 +- include/queue.h | 24 +- include/semphr.h | 7 +- include/stack_macros.h | 12 +- include/task.h | 18 +- portable/ARMv8M/copy_files.py | 12 + portable/ARMv8M/non_secure/port.c | 759 ++- .../GCC/ARM_CM23/mpu_wrappers_v2_asm.c | 2419 ++++++++++ .../portable/GCC/ARM_CM23/portasm.c | 558 ++- .../portable/GCC/ARM_CM23/portmacro.h | 1 - .../GCC/ARM_CM23_NTZ/mpu_wrappers_v2_asm.c | 2419 ++++++++++ .../portable/GCC/ARM_CM23_NTZ/portasm.c | 481 +- .../portable/GCC/ARM_CM23_NTZ/portmacro.h | 1 - .../GCC/ARM_CM33/mpu_wrappers_v2_asm.c | 2349 ++++++++++ .../portable/GCC/ARM_CM33/portasm.c | 528 ++- .../portable/GCC/ARM_CM33/portmacro.h | 1 - .../GCC/ARM_CM33_NTZ/mpu_wrappers_v2_asm.c | 2349 ++++++++++ .../portable/GCC/ARM_CM33_NTZ/portasm.c | 412 +- .../portable/GCC/ARM_CM33_NTZ/portmacro.h | 1 - .../portable/GCC/ARM_CM35P/portmacro.h | 1 - .../portable/GCC/ARM_CM55/portmacro.h | 1 - .../portable/GCC/ARM_CM85/portmacro.h | 1 - .../IAR/ARM_CM23/mpu_wrappers_v2_asm.S | 1623 +++++++ .../portable/IAR/ARM_CM23/portasm.s | 425 +- .../IAR/ARM_CM23_NTZ/mpu_wrappers_v2_asm.S | 1623 +++++++ .../portable/IAR/ARM_CM23_NTZ/portasm.s | 374 +- .../IAR/ARM_CM33/mpu_wrappers_v2_asm.S | 1552 +++++++ .../portable/IAR/ARM_CM33/portasm.s | 359 +- .../IAR/ARM_CM33_NTZ/mpu_wrappers_v2_asm.S | 1552 +++++++ .../portable/IAR/ARM_CM33_NTZ/portasm.s | 302 +- portable/ARMv8M/non_secure/portmacrocommon.h | 146 +- portable/CCS/ARM_CM3/port.c | 26 +- portable/CCS/ARM_CM4F/port.c | 26 +- portable/CMakeLists.txt | 2 +- portable/Common/mpu_wrappers.c | 4 +- portable/Common/mpu_wrappers_v2.c | 4121 +++++++++++++++++ portable/GCC/ARM7_AT91SAM7S/port.c | 2 +- portable/GCC/ARM_CM0/portmacro.h | 1 - .../ARM_CM23/non_secure/mpu_wrappers_v2_asm.c | 2419 ++++++++++ portable/GCC/ARM_CM23/non_secure/port.c | 759 ++- portable/GCC/ARM_CM23/non_secure/portasm.c | 558 ++- portable/GCC/ARM_CM23/non_secure/portmacro.h | 1 - .../GCC/ARM_CM23/non_secure/portmacrocommon.h | 146 +- .../non_secure/mpu_wrappers_v2_asm.c | 2419 ++++++++++ portable/GCC/ARM_CM23_NTZ/non_secure/port.c | 759 ++- .../GCC/ARM_CM23_NTZ/non_secure/portasm.c | 481 +- .../GCC/ARM_CM23_NTZ/non_secure/portmacro.h | 1 - .../ARM_CM23_NTZ/non_secure/portmacrocommon.h | 146 +- portable/GCC/ARM_CM3/port.c | 26 +- portable/GCC/ARM_CM3/portmacro.h | 1 - .../ARM_CM33/non_secure/mpu_wrappers_v2_asm.c | 2349 ++++++++++ portable/GCC/ARM_CM33/non_secure/port.c | 759 ++- portable/GCC/ARM_CM33/non_secure/portasm.c | 528 ++- portable/GCC/ARM_CM33/non_secure/portmacro.h | 1 - .../GCC/ARM_CM33/non_secure/portmacrocommon.h | 146 +- .../non_secure/mpu_wrappers_v2_asm.c | 2349 ++++++++++ portable/GCC/ARM_CM33_NTZ/non_secure/port.c | 759 ++- .../GCC/ARM_CM33_NTZ/non_secure/portasm.c | 412 +- .../GCC/ARM_CM33_NTZ/non_secure/portmacro.h | 1 - .../ARM_CM33_NTZ/non_secure/portmacrocommon.h | 146 +- .../non_secure/mpu_wrappers_v2_asm.c | 2349 ++++++++++ portable/GCC/ARM_CM35P/non_secure/port.c | 759 ++- portable/GCC/ARM_CM35P/non_secure/portasm.c | 528 ++- portable/GCC/ARM_CM35P/non_secure/portmacro.h | 1 - .../ARM_CM35P/non_secure/portmacrocommon.h | 146 +- .../non_secure/mpu_wrappers_v2_asm.c | 2349 ++++++++++ portable/GCC/ARM_CM35P_NTZ/non_secure/port.c | 759 ++- .../GCC/ARM_CM35P_NTZ/non_secure/portasm.c | 412 +- .../GCC/ARM_CM35P_NTZ/non_secure/portmacro.h | 1 - .../non_secure/portmacrocommon.h | 146 +- .../GCC/ARM_CM3_MPU/mpu_wrappers_v2_asm.c | 2349 ++++++++++ portable/GCC/ARM_CM3_MPU/port.c | 694 ++- portable/GCC/ARM_CM3_MPU/portmacro.h | 57 +- portable/GCC/ARM_CM4F/port.c | 26 +- portable/GCC/ARM_CM4F/portmacro.h | 1 - .../GCC/ARM_CM4_MPU/mpu_wrappers_v2_asm.c | 2349 ++++++++++ portable/GCC/ARM_CM4_MPU/port.c | 820 +++- portable/GCC/ARM_CM4_MPU/portmacro.h | 56 +- .../ARM_CM55/non_secure/mpu_wrappers_v2_asm.c | 2349 ++++++++++ portable/GCC/ARM_CM55/non_secure/port.c | 759 ++- portable/GCC/ARM_CM55/non_secure/portasm.c | 528 ++- portable/GCC/ARM_CM55/non_secure/portmacro.h | 1 - .../GCC/ARM_CM55/non_secure/portmacrocommon.h | 146 +- .../non_secure/mpu_wrappers_v2_asm.c | 2349 ++++++++++ portable/GCC/ARM_CM55_NTZ/non_secure/port.c | 759 ++- .../GCC/ARM_CM55_NTZ/non_secure/portasm.c | 412 +- .../GCC/ARM_CM55_NTZ/non_secure/portmacro.h | 1 - .../ARM_CM55_NTZ/non_secure/portmacrocommon.h | 146 +- portable/GCC/ARM_CM7/r0p1/port.c | 26 +- portable/GCC/ARM_CM7/r0p1/portmacro.h | 1 - .../ARM_CM85/non_secure/mpu_wrappers_v2_asm.c | 2349 ++++++++++ portable/GCC/ARM_CM85/non_secure/port.c | 759 ++- portable/GCC/ARM_CM85/non_secure/portasm.c | 528 ++- portable/GCC/ARM_CM85/non_secure/portmacro.h | 1 - .../GCC/ARM_CM85/non_secure/portmacrocommon.h | 146 +- .../non_secure/mpu_wrappers_v2_asm.c | 2349 ++++++++++ portable/GCC/ARM_CM85_NTZ/non_secure/port.c | 759 ++- .../GCC/ARM_CM85_NTZ/non_secure/portasm.c | 412 +- .../GCC/ARM_CM85_NTZ/non_secure/portmacro.h | 1 - .../ARM_CM85_NTZ/non_secure/portmacrocommon.h | 146 +- portable/GCC/AVR32_UC3/portmacro.h | 2 +- portable/GCC/CORTUS_APS3/portmacro.h | 2 +- portable/GCC/ColdFire_V2/portmacro.h | 2 +- portable/GCC/H8S2329/portmacro.h | 2 +- portable/GCC/HCS12/portmacro.h | 2 +- portable/GCC/MSP430F449/portmacro.h | 2 +- portable/GCC/PPC405_Xilinx/portmacro.h | 2 +- portable/GCC/PPC440_Xilinx/portmacro.h | 2 +- portable/GCC/RL78/portmacro.h | 2 +- portable/GCC/STR75x/portmacro.h | 2 +- portable/IAR/78K0R/portmacro.h | 2 +- .../ARM_CM23/non_secure/mpu_wrappers_v2_asm.S | 1623 +++++++ portable/IAR/ARM_CM23/non_secure/port.c | 759 ++- portable/IAR/ARM_CM23/non_secure/portasm.s | 425 +- .../IAR/ARM_CM23/non_secure/portmacrocommon.h | 146 +- .../non_secure/mpu_wrappers_v2_asm.S | 1623 +++++++ portable/IAR/ARM_CM23_NTZ/non_secure/port.c | 759 ++- .../IAR/ARM_CM23_NTZ/non_secure/portasm.s | 374 +- .../ARM_CM23_NTZ/non_secure/portmacrocommon.h | 146 +- portable/IAR/ARM_CM3/port.c | 26 +- .../ARM_CM33/non_secure/mpu_wrappers_v2_asm.S | 1552 +++++++ portable/IAR/ARM_CM33/non_secure/port.c | 759 ++- portable/IAR/ARM_CM33/non_secure/portasm.s | 359 +- .../IAR/ARM_CM33/non_secure/portmacrocommon.h | 146 +- .../non_secure/mpu_wrappers_v2_asm.S | 1552 +++++++ portable/IAR/ARM_CM33_NTZ/non_secure/port.c | 759 ++- .../IAR/ARM_CM33_NTZ/non_secure/portasm.s | 302 +- .../ARM_CM33_NTZ/non_secure/portmacrocommon.h | 146 +- .../non_secure/mpu_wrappers_v2_asm.S | 1552 +++++++ portable/IAR/ARM_CM35P/non_secure/port.c | 759 ++- portable/IAR/ARM_CM35P/non_secure/portasm.s | 359 +- .../ARM_CM35P/non_secure/portmacrocommon.h | 146 +- .../non_secure/mpu_wrappers_v2_asm.S | 1552 +++++++ portable/IAR/ARM_CM35P_NTZ/non_secure/port.c | 759 ++- .../IAR/ARM_CM35P_NTZ/non_secure/portasm.s | 302 +- .../non_secure/portmacrocommon.h | 146 +- portable/IAR/ARM_CM4F/port.c | 26 +- .../IAR/ARM_CM4F_MPU/mpu_wrappers_v2_asm.S | 1556 +++++++ portable/IAR/ARM_CM4F_MPU/port.c | 545 ++- portable/IAR/ARM_CM4F_MPU/portasm.s | 281 +- portable/IAR/ARM_CM4F_MPU/portmacro.h | 55 +- .../ARM_CM55/non_secure/mpu_wrappers_v2_asm.S | 1552 +++++++ portable/IAR/ARM_CM55/non_secure/port.c | 759 ++- portable/IAR/ARM_CM55/non_secure/portasm.s | 359 +- .../IAR/ARM_CM55/non_secure/portmacrocommon.h | 146 +- .../non_secure/mpu_wrappers_v2_asm.S | 1552 +++++++ portable/IAR/ARM_CM55_NTZ/non_secure/port.c | 759 ++- .../IAR/ARM_CM55_NTZ/non_secure/portasm.s | 302 +- .../ARM_CM55_NTZ/non_secure/portmacrocommon.h | 146 +- portable/IAR/ARM_CM7/r0p1/port.c | 26 +- .../ARM_CM85/non_secure/mpu_wrappers_v2_asm.S | 1552 +++++++ portable/IAR/ARM_CM85/non_secure/port.c | 759 ++- portable/IAR/ARM_CM85/non_secure/portasm.s | 359 +- .../IAR/ARM_CM85/non_secure/portmacrocommon.h | 146 +- .../non_secure/mpu_wrappers_v2_asm.S | 1552 +++++++ portable/IAR/ARM_CM85_NTZ/non_secure/port.c | 759 ++- .../IAR/ARM_CM85_NTZ/non_secure/portasm.s | 302 +- .../ARM_CM85_NTZ/non_secure/portmacrocommon.h | 146 +- portable/IAR/ATMega323/portmacro.h | 2 +- portable/IAR/AVR32_UC3/portmacro.h | 2 +- portable/IAR/AVR_AVRDx/portmacro.h | 2 +- portable/IAR/AVR_Mega0/portmacro.h | 2 +- portable/IAR/AtmelSAM7S64/port.c | 2 +- portable/IAR/AtmelSAM7S64/portmacro.h | 2 +- portable/IAR/AtmelSAM9XE/portmacro.h | 2 +- portable/IAR/LPC2000/portmacro.h | 2 +- portable/IAR/MSP430/portmacro.h | 2 +- portable/IAR/MSP430X/portmacro.h | 2 +- portable/IAR/RL78/portmacro.h | 2 +- portable/MikroC/ARM_CM4F/port.c | 26 +- portable/RVDS/ARM_CM3/port.c | 26 +- portable/RVDS/ARM_CM4F/port.c | 26 +- .../RVDS/ARM_CM4_MPU/mpu_wrappers_v2_asm.c | 1993 ++++++++ portable/RVDS/ARM_CM4_MPU/port.c | 782 +++- portable/RVDS/ARM_CM4_MPU/portmacro.h | 55 +- portable/RVDS/ARM_CM7/r0p1/port.c | 26 +- portable/ThirdParty/GCC/ATmega/portmacro.h | 2 + portable/ThirdParty/GCC/Posix/port.c | 8 +- portable/ThirdParty/GCC/Posix/portmacro.h | 8 +- .../ThirdParty/GCC/RP2040/include/portmacro.h | 5 +- portable/ThirdParty/GCC/RP2040/library.cmake | 1 + .../GCC/Xtensa_ESP32/include/portmacro.h | 2 - .../ThirdParty/xClang/XCOREAI/portmacro.h | 4 +- portable/WizC/PIC18/portmacro.h | 2 +- queue.c | 321 +- stream_buffer.c | 40 +- tasks.c | 120 +- timers.c | 4 +- 200 files changed, 96733 insertions(+), 7659 deletions(-) create mode 100644 croutine.c create mode 100644 include/CMakeLists.txt create mode 100644 include/croutine.h create mode 100644 portable/ARMv8M/non_secure/portable/GCC/ARM_CM23/mpu_wrappers_v2_asm.c create mode 100644 portable/ARMv8M/non_secure/portable/GCC/ARM_CM23_NTZ/mpu_wrappers_v2_asm.c create mode 100644 portable/ARMv8M/non_secure/portable/GCC/ARM_CM33/mpu_wrappers_v2_asm.c create mode 100644 portable/ARMv8M/non_secure/portable/GCC/ARM_CM33_NTZ/mpu_wrappers_v2_asm.c create mode 100644 portable/ARMv8M/non_secure/portable/IAR/ARM_CM23/mpu_wrappers_v2_asm.S create mode 100644 portable/ARMv8M/non_secure/portable/IAR/ARM_CM23_NTZ/mpu_wrappers_v2_asm.S create mode 100644 portable/ARMv8M/non_secure/portable/IAR/ARM_CM33/mpu_wrappers_v2_asm.S create mode 100644 portable/ARMv8M/non_secure/portable/IAR/ARM_CM33_NTZ/mpu_wrappers_v2_asm.S create mode 100644 portable/Common/mpu_wrappers_v2.c create mode 100644 portable/GCC/ARM_CM23/non_secure/mpu_wrappers_v2_asm.c create mode 100644 portable/GCC/ARM_CM23_NTZ/non_secure/mpu_wrappers_v2_asm.c mode change 100755 => 100644 portable/GCC/ARM_CM3/port.c create mode 100644 portable/GCC/ARM_CM33/non_secure/mpu_wrappers_v2_asm.c create mode 100644 portable/GCC/ARM_CM33_NTZ/non_secure/mpu_wrappers_v2_asm.c create mode 100644 portable/GCC/ARM_CM35P/non_secure/mpu_wrappers_v2_asm.c create mode 100644 portable/GCC/ARM_CM35P_NTZ/non_secure/mpu_wrappers_v2_asm.c create mode 100644 portable/GCC/ARM_CM3_MPU/mpu_wrappers_v2_asm.c mode change 100755 => 100644 portable/GCC/ARM_CM3_MPU/port.c mode change 100755 => 100644 portable/GCC/ARM_CM4F/port.c create mode 100644 portable/GCC/ARM_CM4_MPU/mpu_wrappers_v2_asm.c mode change 100755 => 100644 portable/GCC/ARM_CM4_MPU/port.c create mode 100644 portable/GCC/ARM_CM55/non_secure/mpu_wrappers_v2_asm.c create mode 100644 portable/GCC/ARM_CM55_NTZ/non_secure/mpu_wrappers_v2_asm.c create mode 100644 portable/GCC/ARM_CM85/non_secure/mpu_wrappers_v2_asm.c create mode 100644 portable/GCC/ARM_CM85_NTZ/non_secure/mpu_wrappers_v2_asm.c create mode 100644 portable/IAR/ARM_CM23/non_secure/mpu_wrappers_v2_asm.S create mode 100644 portable/IAR/ARM_CM23_NTZ/non_secure/mpu_wrappers_v2_asm.S create mode 100644 portable/IAR/ARM_CM33/non_secure/mpu_wrappers_v2_asm.S create mode 100644 portable/IAR/ARM_CM33_NTZ/non_secure/mpu_wrappers_v2_asm.S create mode 100644 portable/IAR/ARM_CM35P/non_secure/mpu_wrappers_v2_asm.S create mode 100644 portable/IAR/ARM_CM35P_NTZ/non_secure/mpu_wrappers_v2_asm.S create mode 100644 portable/IAR/ARM_CM4F_MPU/mpu_wrappers_v2_asm.S create mode 100644 portable/IAR/ARM_CM55/non_secure/mpu_wrappers_v2_asm.S create mode 100644 portable/IAR/ARM_CM55_NTZ/non_secure/mpu_wrappers_v2_asm.S create mode 100644 portable/IAR/ARM_CM85/non_secure/mpu_wrappers_v2_asm.S create mode 100644 portable/IAR/ARM_CM85_NTZ/non_secure/mpu_wrappers_v2_asm.S create mode 100644 portable/RVDS/ARM_CM4_MPU/mpu_wrappers_v2_asm.c diff --git a/.github/lexicon.txt b/.github/lexicon.txt index 90452c54c56..853c73f220e 100644 --- a/.github/lexicon.txt +++ b/.github/lexicon.txt @@ -1,3 +1,4 @@ + GNU nano 5.9 .github/lexicon.txt Modified aa aaaa aarch @@ -317,6 +318,7 @@ coproc coprocessor coprocessors coreid +coroutinehandle coverity covfs cp @@ -344,10 +346,16 @@ cpu cr crc crcb +crcoroutine +crdelay creadonlyarray creadwritearray createevent +crend crgint +croutine +crqueue +crstart crt crtv crxedchar @@ -1526,18 +1534,21 @@ prvcheckforrunstatechange prvcheckinterfaces prvchecktaskswaitingtermination prvcopydatatoqueue +prvcoroutineflashtask +prvcoroutineflashworktask prvdeletetcb prvexitfunction prvgettimens prvheapinit prvidletask +prvinitialisecoroutinelists prvinitialisemutex prvinitialisenewstreambuffer prvinitialisenewtimer prvinsertblockintofreelist prvlockqueue -prvnotifyqueuesetcontainer prvminimalidletask +prvnotifyqueuesetcontainer prvportmalloc prvportresetpic prvprocesssimulatedinterrupts @@ -1647,11 +1658,15 @@ pxblocktoinsert pxcallbackfunction pxcode pxcontainer +pxcoroutinecode +pxcoroutinewoken pxcrcb pxcreatedtask +pxcurrentcoroutine pxcurrenttcb pxcurrenttcbconst pxcurrenttimerlist +pxdelayedcoroutinelist pxdelayedtasklist pxend pxendofstack @@ -1686,6 +1701,7 @@ pxnextfreeblock pxnexttcb pxoriginalsp pxoriginaltos +pxoverflowdelayedcoroutinelist pxoverflowdelayedtasklist pxowner pxportinitialisestack @@ -1695,6 +1711,7 @@ pxqueue pxqueuebuffer pxqueuesetcontainer pxramstack +pxreadycoroutinelists pxreadytaskslists pxreceivecompletedcallback pxregions @@ -2444,6 +2461,7 @@ uxprevschedulersuspended uxpriority uxprioritytouse uxqueue +uxqueuegetqueueitemsize uxqueuelength uxqueuemessageswaiting uxqueuespacesavailable @@ -2474,6 +2492,7 @@ uxtopreadypriority uxtopusedpriority uxvariabletoincrement uxwantedbytes +vacoroutine vadifferenttask vafunction val @@ -2504,6 +2523,7 @@ vbr vbufferisr vcallbackfunction vclearinterruptmask +vcoroutineschedule vddcore vec vectactive @@ -2513,6 +2533,7 @@ ver veventgroupclearbitscallback veventgroupdelete veventgroupsetbitscallback +vflashcoroutine vfp vfunction vic @@ -2575,12 +2596,14 @@ vqueuedelete vqueueunregisterqueue vr vraiseprivilege +vreceivingcoroutine vreg vresetprivilege vrestorecontextoffirsttask vrpm vsemaphorecreatebinary vsemaphoredelete +vsendingcoroutine vsetbacklightstate vsoftwareinterruptentry vstartfirsttask @@ -2734,6 +2757,7 @@ xdd xdddd xdeadbeef xdelay +xdelayedcoroutinelist xdelayedtasklist xdelaytime xe @@ -2888,6 +2912,7 @@ xpar xparameters xpendedcounts xpendedticks +xpendingreadycoroutinelist xpendingreadylist xperiod xportgetcoreid diff --git a/.github/workflows/auto-release.yml b/.github/workflows/auto-release.yml index 3bf820a6f9c..426d8f0c01a 100644 --- a/.github/workflows/auto-release.yml +++ b/.github/workflows/auto-release.yml @@ -25,7 +25,6 @@ jobs: - name: Tool Setup uses: actions/setup-python@v2 with: - python-version: 3.7.10 architecture: x64 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -51,7 +50,18 @@ jobs: - name: create a new branch that references commit id working-directory: ./local_kernel - run: git checkout -b ${{ github.event.inputs.version_number }} ${{ github.event.inputs.commit_id }} + run: | + git checkout -b ${{ github.event.inputs.version_number }} ${{ github.event.inputs.commit_id }} + echo "COMMIT_SHA_1=$(git rev-parse HEAD)" >> $GITHUB_ENV + + - name: Update source files with version info + run: | + # Install deps and run + pip install -r ./tools/.github/scripts/release-requirements.txt + ./tools/.github/scripts/update_src_version.py FreeRTOS --kernel-repo-path=local_kernel --kernel-commit=${{ env.COMMIT_SHA_1 }} --new-kernel-version=${{ github.event.inputs.version_number }} --new-kernel-main-br-version=${{ github.event.inputs.main_br_version }} + exit $? + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Generate SBOM uses: FreeRTOS/CI-CD-Github-Actions/sbom-generator@main @@ -65,13 +75,19 @@ jobs: git add . git commit -m 'Update SBOM' git push -u origin ${{ github.event.inputs.version_number }} - echo "COMMIT_SHA=$(git rev-parse HEAD)" >> $GITHUB_ENV + echo "COMMIT_SHA_2=$(git rev-parse HEAD)" >> $GITHUB_ENV - name: Release run: | # Install deps and run pip install -r ./tools/.github/scripts/release-requirements.txt - ./tools/.github/scripts/release.py FreeRTOS --kernel-repo-path=local_kernel --kernel-commit=${{ env.COMMIT_SHA }} --new-kernel-version=${{ github.event.inputs.version_number }} --new-kernel-main-br-version=${{ github.event.inputs.main_br_version }} + ./tools/.github/scripts/release.py FreeRTOS --kernel-repo-path=local_kernel --kernel-commit=${{ env.COMMIT_SHA_2 }} --new-kernel-version=${{ github.event.inputs.version_number }} --new-kernel-main-br-version=${{ github.event.inputs.main_br_version }} exit $? env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Cleanup + working-directory: ./local_kernel + run: | + # Delete the branch created for Tag by SBOM generator + git push -u origin --delete ${{ github.event.inputs.version_number }} diff --git a/CMakeLists.txt b/CMakeLists.txt index d45de64b1b5..c57d464028d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -225,9 +225,12 @@ elseif((FREERTOS_PORT STREQUAL "A_CUSTOM_PORT") AND (NOT TARGET freertos_kernel_ " .)\n" " target_link_libraries(freertos_kernel_port\n" " PRIVATE\n" - " freertos_kernel)") + " freertos_kernel_include)") endif() + +add_library(freertos_kernel STATIC) + ######################################################################## # Overall Compile Options # Note the compile option strategy is to error on everything and then @@ -248,7 +251,7 @@ endif() # MSVC | MSVC # Note only for MinGW? # Renesas | ?TBD? -add_compile_options( +target_compile_options(freertos_kernel PRIVATE ### Gnu/Clang C Options $<$:-fdiagnostics-color=always> $<$:-fcolor-diagnostics> @@ -264,9 +267,11 @@ add_compile_options( ######################################################################## +add_subdirectory(include) add_subdirectory(portable) -add_library(freertos_kernel STATIC +target_sources(freertos_kernel PRIVATE + croutine.c event_groups.c list.c queue.c @@ -278,17 +283,11 @@ add_library(freertos_kernel STATIC $>,${FREERTOS_HEAP},portable/MemMang/heap_${FREERTOS_HEAP}.c> ) -target_include_directories(freertos_kernel - PUBLIC - include - # Note: DEPRECATED but still supported, may be removed in a future release. - $<$>:${FREERTOS_CONFIG_FILE_DIRECTORY}> -) target_link_libraries(freertos_kernel PUBLIC - $<$:freertos_config> freertos_kernel_port + freertos_kernel_include ) ######################################################################## diff --git a/History.txt b/History.txt index 94b74e80363..98f9822d454 100644 --- a/History.txt +++ b/History.txt @@ -1,5 +1,116 @@ Documentation and download available at https://www.FreeRTOS.org/ +Changes between FreeRTOS V10.5.1 and FreeRTOS 10.6.0 released July 13, 2023 + + + Add a new MPU wrapper that places additional restrictions on unprivileged + tasks. The following is the list of changes introduced with the new MPU + wrapper: + + 1. Opaque and indirectly verifiable integers for kernel object handles: + All the kernel object handles (for example, queue handles) are now + opaque integers. Previously object handles were raw pointers. + 2. Save the task context in Task Control Block (TCB): When a task is + swapped out by the scheduler, the task's context is now saved in its + TCB. Previously the task's context was saved on its stack. + 3. Execute system calls on a separate privileged only stack: FreeRTOS + system calls, which execute with elevated privilege, now use a + separate privileged only stack. Previously system calls used the + calling task's stack. The application writer can control the size of + the system call stack using new configSYSTEM_CALL_STACK_SIZE config + macro. + 4. Memory bounds checks: FreeRTOS system calls which accept a pointer + and de-reference it, now verify that the calling task has required + permissions to access the memory location referenced by the pointer. + 5. System calls restrictions: The following system calls are no longer + available to unprivileged tasks: + - vQueueDelete + - xQueueCreateMutex + - xQueueCreateMutexStatic + - xQueueCreateCountingSemaphore + - xQueueCreateCountingSemaphoreStatic + - xQueueGenericCreate + - xQueueGenericCreateStatic + - xQueueCreateSet + - xQueueRemoveFromSet + - xQueueGenericReset + - xTaskCreate + - xTaskCreateStatic + - vTaskDelete + - vTaskPrioritySet + - vTaskSuspendAll + - xTaskResumeAll + - xTaskGetHandle + - xTaskCallApplicationTaskHook + - vTaskList + - vTaskGetRunTimeStats + - xTaskCatchUpTicks + - xEventGroupCreate + - xEventGroupCreateStatic + - vEventGroupDelete + - xStreamBufferGenericCreate + - xStreamBufferGenericCreateStatic + - vStreamBufferDelete + - xStreamBufferReset + Also, an unprivileged task can no longer use vTaskSuspend to suspend + any task other than itself. + + We thank the following people for their inputs in these enhancements: + - David Reiss of Meta Platforms, Inc. + - Lan Luo, Xinhui Shao, Yumeng Wei, Zixia Liu, Huaiyu Yan and Zhen Ling + of School of Computer Science and Engineering, Southeast University, + China. + - Xinwen Fu of Department of Computer Science, University of + Massachusetts Lowell, USA. + - Yueqi Chen, Zicheng Wang, Minghao Lin of University of Colorado + Boulder, USA. + + Add Cortex-M35P port. Contributed by @urutva. + + Add embedded extension (RV32E) support to the IAR RISC-V port. + + Add ulTaskGetRunTimeCounter and ulTaskGetRunTimePercent APIs. Contributed by + @chrisnc. + + Add APIs to get the application supplied buffers from statically + created kernel objects. The following new APIs are added: + - xTaskGetStaticBuffers + - xQueueGetStaticBuffers + - xQueueGenericGetStaticBuffers + - xSemaphoreGetStaticBuffer + - xEventGroupGetStaticBuffer + - xStreamBufferGetStaticBuffers + - xMessageBufferGetStaticBuffers + These APIs enable the application writer to obtain static buffers from + the kernel object and free/reuse them at the time of deletion. Earlier + the application writer had to maintain the association of static buffers + and the kernel object in the application. Contributed by @Dazza0. + + Add Thread Local Storage (TLS) support using picolibc function. Contributed + by @keith-packard. + + Add configTICK_TYPE_WIDTH_IN_BITS to configure TickType_t data type. As a result, + the number of bits in an event group also increases with big data type. Contributed + by @Hadatko. + + Update eTaskGetState and uxTaskGetSystemState to return eReady for pending ready + tasks. Contributed by @Dazza0. + + Update heap_4 and heap_5 to add padding only if the resulting block is not + already aligned. + + Fix the scheduler logic in a couple of places to not preempt a task when an + equal priority task becomes ready. + + Add macros used in FreeRTOS-Plus libraries. Contributed by @Holden. + + Fix clang compiler warnings. Contributed by @phelter. + + Add assertions to ARMv8-M ports to detect when FreeRTOS APIs are called from + interrupts with priority higher than the configMAX_SYSCALL_INTERRUPT_PRIORITY. + Contributed by @urutva. + + Add xPortIsInsideInterrupt API to ARM_CM0 ports. + + Fix build warning in MSP430X port when large data model is used. + + Add the ability to use Cortex-R5 port on the parts without FPU. + + Fix build warning in heap implementations on PIC24/dsPIC. + + Update interrupt priority asserts for Cortex-M ports so that these do not fire + on QEMU which does not implement PRIO bits. + + Update ARMv7-M ports to ensure that kernel interrupts run at the lowest priority. + configKERNEL_INTERRUPT_PRIORITY is now obsolete for ARMv7-M ports and brings + these ports inline with the newer ARMv8-M ports. Contributed by @chrisnc. + + Fix build issue in POSIX GCC port on Windows Subsystem for Linux (WSL). Contributed + by @jacky309. + + Add portMEMORY_BARRIER to Microblaze port. Contributed by @bbain. + + Add portPOINTER_SIZE_TYPE definition for ATmega port. Contributed by @jputcu. + + Multiple improvements in the CMake support. Contributed by @phelte and @cookpate. + Changes between FreeRTOS V10.5.0 and FreeRTOS V10.5.1 released November 16 2022 + Updated the kernel version in manifest and SBOM diff --git a/README.md b/README.md index 952914daf46..dd79eee6ce7 100644 --- a/README.md +++ b/README.md @@ -70,7 +70,8 @@ git clone git@github.com:FreeRTOS/FreeRTOS-Kernel.git ## Repository structure - The root of this repository contains the three files that are common to every port - list.c, queue.c and tasks.c. The kernel is contained within these -three files. +three files. croutine.c implements the optional co-routine functionality - which +is normally only used on very memory limited systems. - The ```./portable``` directory contains the files that are specific to a particular microcontroller and/or compiler. See the readme file in the ```./portable``` directory for more information. diff --git a/croutine.c b/croutine.c new file mode 100644 index 00000000000..f38e96247a3 --- /dev/null +++ b/croutine.c @@ -0,0 +1,363 @@ +/* + * FreeRTOS Kernel + * Copyright (C) 2021 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 + * + */ + +#include "FreeRTOS.h" +#include "task.h" +#include "croutine.h" + +/* Remove the whole file is co-routines are not being used. */ +#if ( configUSE_CO_ROUTINES != 0 ) + +/* + * Some kernel aware debuggers require data to be viewed to be global, rather + * than file scope. + */ + #ifdef portREMOVE_STATIC_QUALIFIER + #define static + #endif + + +/* Lists for ready and blocked co-routines. --------------------*/ + static List_t pxReadyCoRoutineLists[ configMAX_CO_ROUTINE_PRIORITIES ]; /*< Prioritised ready co-routines. */ + static List_t xDelayedCoRoutineList1; /*< Delayed co-routines. */ + static List_t xDelayedCoRoutineList2; /*< Delayed co-routines (two lists are used - one for delays that have overflowed the current tick count. */ + static List_t * pxDelayedCoRoutineList = NULL; /*< Points to the delayed co-routine list currently being used. */ + static List_t * pxOverflowDelayedCoRoutineList = NULL; /*< Points to the delayed co-routine list currently being used to hold co-routines that have overflowed the current tick count. */ + static List_t xPendingReadyCoRoutineList; /*< Holds co-routines that have been readied by an external event. They cannot be added directly to the ready lists as the ready lists cannot be accessed by interrupts. */ + +/* Other file private variables. --------------------------------*/ + CRCB_t * pxCurrentCoRoutine = NULL; + static UBaseType_t uxTopCoRoutineReadyPriority = 0; + static TickType_t xCoRoutineTickCount = 0, xLastTickCount = 0, xPassedTicks = 0; + +/* The initial state of the co-routine when it is created. */ + #define corINITIAL_STATE ( 0 ) + +/* + * Place the co-routine represented by pxCRCB into the appropriate ready queue + * for the priority. It is inserted at the end of the list. + * + * This macro accesses the co-routine ready lists and therefore must not be + * used from within an ISR. + */ + #define prvAddCoRoutineToReadyQueue( pxCRCB ) \ + do { \ + if( ( pxCRCB )->uxPriority > uxTopCoRoutineReadyPriority ) \ + { \ + uxTopCoRoutineReadyPriority = ( pxCRCB )->uxPriority; \ + } \ + vListInsertEnd( ( List_t * ) &( pxReadyCoRoutineLists[ ( pxCRCB )->uxPriority ] ), &( ( pxCRCB )->xGenericListItem ) ); \ + } while( 0 ) + +/* + * Utility to ready all the lists used by the scheduler. This is called + * automatically upon the creation of the first co-routine. + */ + static void prvInitialiseCoRoutineLists( void ); + +/* + * Co-routines that are readied by an interrupt cannot be placed directly into + * the ready lists (there is no mutual exclusion). Instead they are placed in + * in the pending ready list in order that they can later be moved to the ready + * list by the co-routine scheduler. + */ + static void prvCheckPendingReadyList( void ); + +/* + * Macro that looks at the list of co-routines that are currently delayed to + * see if any require waking. + * + * Co-routines are stored in the queue in the order of their wake time - + * meaning once one co-routine has been found whose timer has not expired + * we need not look any further down the list. + */ + static void prvCheckDelayedList( void ); + +/*-----------------------------------------------------------*/ + + BaseType_t xCoRoutineCreate( crCOROUTINE_CODE pxCoRoutineCode, + UBaseType_t uxPriority, + UBaseType_t uxIndex ) + { + BaseType_t xReturn; + CRCB_t * pxCoRoutine; + + /* Allocate the memory that will store the co-routine control block. */ + pxCoRoutine = ( CRCB_t * ) pvPortMalloc( sizeof( CRCB_t ) ); + + if( pxCoRoutine ) + { + /* If pxCurrentCoRoutine is NULL then this is the first co-routine to + * be created and the co-routine data structures need initialising. */ + if( pxCurrentCoRoutine == NULL ) + { + pxCurrentCoRoutine = pxCoRoutine; + prvInitialiseCoRoutineLists(); + } + + /* Check the priority is within limits. */ + if( uxPriority >= configMAX_CO_ROUTINE_PRIORITIES ) + { + uxPriority = configMAX_CO_ROUTINE_PRIORITIES - 1; + } + + /* Fill out the co-routine control block from the function parameters. */ + pxCoRoutine->uxState = corINITIAL_STATE; + pxCoRoutine->uxPriority = uxPriority; + pxCoRoutine->uxIndex = uxIndex; + pxCoRoutine->pxCoRoutineFunction = pxCoRoutineCode; + + /* Initialise all the other co-routine control block parameters. */ + vListInitialiseItem( &( pxCoRoutine->xGenericListItem ) ); + vListInitialiseItem( &( pxCoRoutine->xEventListItem ) ); + + /* Set the co-routine control block as a link back from the ListItem_t. + * This is so we can get back to the containing CRCB from a generic item + * in a list. */ + listSET_LIST_ITEM_OWNER( &( pxCoRoutine->xGenericListItem ), pxCoRoutine ); + listSET_LIST_ITEM_OWNER( &( pxCoRoutine->xEventListItem ), pxCoRoutine ); + + /* Event lists are always in priority order. */ + listSET_LIST_ITEM_VALUE( &( pxCoRoutine->xEventListItem ), ( ( TickType_t ) configMAX_CO_ROUTINE_PRIORITIES - ( TickType_t ) uxPriority ) ); + + /* Now the co-routine has been initialised it can be added to the ready + * list at the correct priority. */ + prvAddCoRoutineToReadyQueue( pxCoRoutine ); + + xReturn = pdPASS; + } + else + { + xReturn = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY; + } + + return xReturn; + } +/*-----------------------------------------------------------*/ + + void vCoRoutineAddToDelayedList( TickType_t xTicksToDelay, + List_t * pxEventList ) + { + TickType_t xTimeToWake; + + /* Calculate the time to wake - this may overflow but this is + * not a problem. */ + xTimeToWake = xCoRoutineTickCount + xTicksToDelay; + + /* We must remove ourselves from the ready list before adding + * ourselves to the blocked list as the same list item is used for + * both lists. */ + ( void ) uxListRemove( ( ListItem_t * ) &( pxCurrentCoRoutine->xGenericListItem ) ); + + /* The list item will be inserted in wake time order. */ + listSET_LIST_ITEM_VALUE( &( pxCurrentCoRoutine->xGenericListItem ), xTimeToWake ); + + if( xTimeToWake < xCoRoutineTickCount ) + { + /* Wake time has overflowed. Place this item in the + * overflow list. */ + vListInsert( ( List_t * ) pxOverflowDelayedCoRoutineList, ( ListItem_t * ) &( pxCurrentCoRoutine->xGenericListItem ) ); + } + else + { + /* The wake time has not overflowed, so we can use the + * current block list. */ + vListInsert( ( List_t * ) pxDelayedCoRoutineList, ( ListItem_t * ) &( pxCurrentCoRoutine->xGenericListItem ) ); + } + + if( pxEventList ) + { + /* Also add the co-routine to an event list. If this is done then the + * function must be called with interrupts disabled. */ + vListInsert( pxEventList, &( pxCurrentCoRoutine->xEventListItem ) ); + } + } +/*-----------------------------------------------------------*/ + + static void prvCheckPendingReadyList( void ) + { + /* Are there any co-routines waiting to get moved to the ready list? These + * are co-routines that have been readied by an ISR. The ISR cannot access + * the ready lists itself. */ + while( listLIST_IS_EMPTY( &xPendingReadyCoRoutineList ) == pdFALSE ) + { + CRCB_t * pxUnblockedCRCB; + + /* The pending ready list can be accessed by an ISR. */ + portDISABLE_INTERRUPTS(); + { + pxUnblockedCRCB = ( CRCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( ( &xPendingReadyCoRoutineList ) ); + ( void ) uxListRemove( &( pxUnblockedCRCB->xEventListItem ) ); + } + portENABLE_INTERRUPTS(); + + ( void ) uxListRemove( &( pxUnblockedCRCB->xGenericListItem ) ); + prvAddCoRoutineToReadyQueue( pxUnblockedCRCB ); + } + } +/*-----------------------------------------------------------*/ + + static void prvCheckDelayedList( void ) + { + CRCB_t * pxCRCB; + + xPassedTicks = xTaskGetTickCount() - xLastTickCount; + + while( xPassedTicks ) + { + xCoRoutineTickCount++; + xPassedTicks--; + + /* If the tick count has overflowed we need to swap the ready lists. */ + if( xCoRoutineTickCount == 0 ) + { + List_t * pxTemp; + + /* Tick count has overflowed so we need to swap the delay lists. If there are + * any items in pxDelayedCoRoutineList here then there is an error! */ + pxTemp = pxDelayedCoRoutineList; + pxDelayedCoRoutineList = pxOverflowDelayedCoRoutineList; + pxOverflowDelayedCoRoutineList = pxTemp; + } + + /* See if this tick has made a timeout expire. */ + while( listLIST_IS_EMPTY( pxDelayedCoRoutineList ) == pdFALSE ) + { + pxCRCB = ( CRCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxDelayedCoRoutineList ); + + if( xCoRoutineTickCount < listGET_LIST_ITEM_VALUE( &( pxCRCB->xGenericListItem ) ) ) + { + /* Timeout not yet expired. */ + break; + } + + portDISABLE_INTERRUPTS(); + { + /* The event could have occurred just before this critical + * section. If this is the case then the generic list item will + * have been moved to the pending ready list and the following + * line is still valid. Also the pvContainer parameter will have + * been set to NULL so the following lines are also valid. */ + ( void ) uxListRemove( &( pxCRCB->xGenericListItem ) ); + + /* Is the co-routine waiting on an event also? */ + if( pxCRCB->xEventListItem.pxContainer ) + { + ( void ) uxListRemove( &( pxCRCB->xEventListItem ) ); + } + } + portENABLE_INTERRUPTS(); + + prvAddCoRoutineToReadyQueue( pxCRCB ); + } + } + + xLastTickCount = xCoRoutineTickCount; + } +/*-----------------------------------------------------------*/ + + void vCoRoutineSchedule( void ) + { + /* Only run a co-routine after prvInitialiseCoRoutineLists() has been + * called. prvInitialiseCoRoutineLists() is called automatically when a + * co-routine is created. */ + if( pxDelayedCoRoutineList != NULL ) + { + /* See if any co-routines readied by events need moving to the ready lists. */ + prvCheckPendingReadyList(); + + /* See if any delayed co-routines have timed out. */ + prvCheckDelayedList(); + + /* Find the highest priority queue that contains ready co-routines. */ + while( listLIST_IS_EMPTY( &( pxReadyCoRoutineLists[ uxTopCoRoutineReadyPriority ] ) ) ) + { + if( uxTopCoRoutineReadyPriority == 0 ) + { + /* No more co-routines to check. */ + return; + } + + --uxTopCoRoutineReadyPriority; + } + + /* listGET_OWNER_OF_NEXT_ENTRY walks through the list, so the co-routines + * of the same priority get an equal share of the processor time. */ + listGET_OWNER_OF_NEXT_ENTRY( pxCurrentCoRoutine, &( pxReadyCoRoutineLists[ uxTopCoRoutineReadyPriority ] ) ); + + /* Call the co-routine. */ + ( pxCurrentCoRoutine->pxCoRoutineFunction )( pxCurrentCoRoutine, pxCurrentCoRoutine->uxIndex ); + } + } +/*-----------------------------------------------------------*/ + + static void prvInitialiseCoRoutineLists( void ) + { + UBaseType_t uxPriority; + + for( uxPriority = 0; uxPriority < configMAX_CO_ROUTINE_PRIORITIES; uxPriority++ ) + { + vListInitialise( ( List_t * ) &( pxReadyCoRoutineLists[ uxPriority ] ) ); + } + + vListInitialise( ( List_t * ) &xDelayedCoRoutineList1 ); + vListInitialise( ( List_t * ) &xDelayedCoRoutineList2 ); + vListInitialise( ( List_t * ) &xPendingReadyCoRoutineList ); + + /* Start with pxDelayedCoRoutineList using list1 and the + * pxOverflowDelayedCoRoutineList using list2. */ + pxDelayedCoRoutineList = &xDelayedCoRoutineList1; + pxOverflowDelayedCoRoutineList = &xDelayedCoRoutineList2; + } +/*-----------------------------------------------------------*/ + + BaseType_t xCoRoutineRemoveFromEventList( const List_t * pxEventList ) + { + CRCB_t * pxUnblockedCRCB; + BaseType_t xReturn; + + /* This function is called from within an interrupt. It can only access + * event lists and the pending ready list. This function assumes that a + * check has already been made to ensure pxEventList is not empty. */ + pxUnblockedCRCB = ( CRCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxEventList ); + ( void ) uxListRemove( &( pxUnblockedCRCB->xEventListItem ) ); + vListInsertEnd( ( List_t * ) &( xPendingReadyCoRoutineList ), &( pxUnblockedCRCB->xEventListItem ) ); + + if( pxUnblockedCRCB->uxPriority >= pxCurrentCoRoutine->uxPriority ) + { + xReturn = pdTRUE; + } + else + { + xReturn = pdFALSE; + } + + return xReturn; + } + +#endif /* configUSE_CO_ROUTINES == 0 */ diff --git a/event_groups.c b/event_groups.c index 3143c220fe5..ea4c79f4b1e 100644 --- a/event_groups.c +++ b/event_groups.c @@ -537,15 +537,15 @@ EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup ) { - portBASE_TYPE xSavedInterruptStatus; + UBaseType_t uxSavedInterruptStatus; EventGroup_t const * const pxEventBits = xEventGroup; EventBits_t uxReturn; - xSavedInterruptStatus = taskENTER_CRITICAL_FROM_ISR(); + uxSavedInterruptStatus = taskENTER_CRITICAL_FROM_ISR(); { uxReturn = pxEventBits->uxEventBits; } - taskEXIT_CRITICAL_FROM_ISR( xSavedInterruptStatus ); + taskEXIT_CRITICAL_FROM_ISR( uxSavedInterruptStatus ); return uxReturn; } /*lint !e818 EventGroupHandle_t is a typedef used in other functions to so can't be pointer to const. */ diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt new file mode 100644 index 00000000000..46a1c3e7f5f --- /dev/null +++ b/include/CMakeLists.txt @@ -0,0 +1,15 @@ +# FreeRTOS internal cmake file. Do not use it in user top-level project + +add_library(freertos_kernel_include INTERFACE) + +target_include_directories(freertos_kernel_include + INTERFACE + . + # Note: DEPRECATED but still supported, may be removed in a future release. + $<$>:${FREERTOS_CONFIG_FILE_DIRECTORY}> +) + +target_link_libraries(freertos_kernel_include + INTERFACE + $<$:freertos_config> +) diff --git a/include/FreeRTOS.h b/include/FreeRTOS.h index 809f5a9c0bf..a9fa182934a 100644 --- a/include/FreeRTOS.h +++ b/include/FreeRTOS.h @@ -81,6 +81,11 @@ #endif #endif +/* Set configUSE_MPU_WRAPPERS_V1 to 1 to use MPU wrappers v1. */ +#ifndef configUSE_MPU_WRAPPERS_V1 + #define configUSE_MPU_WRAPPERS_V1 0 +#endif + /* Basic FreeRTOS definitions. */ #include "projdefs.h" @@ -175,6 +180,10 @@ #error Macro configTICK_TYPE_WIDTH_IN_BITS is defined to incorrect value. See the Configuration section of the FreeRTOS API documentation for details. #endif +#ifndef configUSE_CO_ROUTINES + #define configUSE_CO_ROUTINES 0 +#endif + #ifndef INCLUDE_vTaskPrioritySet #define INCLUDE_vTaskPrioritySet 0 #endif @@ -269,8 +278,10 @@ #define INCLUDE_xTaskGetCurrentTaskHandle 1 #endif -#if ( defined( configUSE_CO_ROUTINES ) && configUSE_CO_ROUTINES != 0 ) - #warning Co-routines have been removed from FreeRTOS-Kernel versions released after V10.5.1. You can view previous versions of the FreeRTOS Kernel at github.com/freertos/freertos-kernel/tree/V10.5.1 . +#if configUSE_CO_ROUTINES != 0 + #ifndef configMAX_CO_ROUTINE_PRIORITIES + #error configMAX_CO_ROUTINE_PRIORITIES must be greater than or equal to 1. + #endif #endif #ifndef configUSE_DAEMON_TASK_STARTUP_HOOK @@ -1011,10 +1022,6 @@ #define portDONT_DISCARD #endif -#ifndef portNORETURN - #define portNORETURN -#endif - #ifndef configUSE_TIME_SLICING #define configUSE_TIME_SLICING 1 #endif @@ -1216,6 +1223,7 @@ #define xTaskParameters TaskParameters_t #define xTaskStatusType TaskStatus_t #define xTimerHandle TimerHandle_t + #define xCoRoutineHandle CoRoutineHandle_t #define pdTASK_HOOK_CODE TaskHookFunction_t #define portTICK_RATE_MS portTICK_PERIOD_MS #define pcTaskGetTaskName pcTaskGetName diff --git a/include/croutine.h b/include/croutine.h new file mode 100644 index 00000000000..664e38b3764 --- /dev/null +++ b/include/croutine.h @@ -0,0 +1,755 @@ +/* + * FreeRTOS Kernel + * Copyright (C) 2021 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 CO_ROUTINE_H +#define CO_ROUTINE_H + +#ifndef INC_FREERTOS_H + #error "include FreeRTOS.h must appear in source files before include croutine.h" +#endif + +#include "list.h" + +/* *INDENT-OFF* */ +#ifdef __cplusplus + extern "C" { +#endif +/* *INDENT-ON* */ + +/* Used to hide the implementation of the co-routine control block. The + * control block structure however has to be included in the header due to + * the macro implementation of the co-routine functionality. */ +typedef void * CoRoutineHandle_t; + +/* Defines the prototype to which co-routine functions must conform. */ +typedef void (* crCOROUTINE_CODE)( CoRoutineHandle_t, + UBaseType_t ); + +typedef struct corCoRoutineControlBlock +{ + crCOROUTINE_CODE pxCoRoutineFunction; + ListItem_t xGenericListItem; /**< List item used to place the CRCB in ready and blocked queues. */ + ListItem_t xEventListItem; /**< List item used to place the CRCB in event lists. */ + UBaseType_t uxPriority; /**< The priority of the co-routine in relation to other co-routines. */ + UBaseType_t uxIndex; /**< Used to distinguish between co-routines when multiple co-routines use the same co-routine function. */ + uint16_t uxState; /**< Used internally by the co-routine implementation. */ +} CRCB_t; /* Co-routine control block. Note must be identical in size down to uxPriority with TCB_t. */ + +/** + * croutine. h + * @code{c} + * BaseType_t xCoRoutineCreate( + * crCOROUTINE_CODE pxCoRoutineCode, + * UBaseType_t uxPriority, + * UBaseType_t uxIndex + * ); + * @endcode + * + * Create a new co-routine and add it to the list of co-routines that are + * ready to run. + * + * @param pxCoRoutineCode Pointer to the co-routine function. Co-routine + * functions require special syntax - see the co-routine section of the WEB + * documentation for more information. + * + * @param uxPriority The priority with respect to other co-routines at which + * the co-routine will run. + * + * @param uxIndex Used to distinguish between different co-routines that + * execute the same function. See the example below and the co-routine section + * of the WEB documentation for further information. + * + * @return pdPASS if the co-routine was successfully created and added to a ready + * list, otherwise an error code defined with ProjDefs.h. + * + * Example usage: + * @code{c} + * // Co-routine to be created. + * void vFlashCoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex ) + * { + * // Variables in co-routines must be declared static if they must maintain value across a blocking call. + * // This may not be necessary for const variables. + * static const char cLedToFlash[ 2 ] = { 5, 6 }; + * static const TickType_t uxFlashRates[ 2 ] = { 200, 400 }; + * + * // Must start every co-routine with a call to crSTART(); + * crSTART( xHandle ); + * + * for( ;; ) + * { + * // This co-routine just delays for a fixed period, then toggles + * // an LED. Two co-routines are created using this function, so + * // the uxIndex parameter is used to tell the co-routine which + * // LED to flash and how int32_t to delay. This assumes xQueue has + * // already been created. + * vParTestToggleLED( cLedToFlash[ uxIndex ] ); + * crDELAY( xHandle, uxFlashRates[ uxIndex ] ); + * } + * + * // Must end every co-routine with a call to crEND(); + * crEND(); + * } + * + * // Function that creates two co-routines. + * void vOtherFunction( void ) + * { + * uint8_t ucParameterToPass; + * TaskHandle_t xHandle; + * + * // Create two co-routines at priority 0. The first is given index 0 + * // so (from the code above) toggles LED 5 every 200 ticks. The second + * // is given index 1 so toggles LED 6 every 400 ticks. + * for( uxIndex = 0; uxIndex < 2; uxIndex++ ) + * { + * xCoRoutineCreate( vFlashCoRoutine, 0, uxIndex ); + * } + * } + * @endcode + * \defgroup xCoRoutineCreate xCoRoutineCreate + * \ingroup Tasks + */ +BaseType_t xCoRoutineCreate( crCOROUTINE_CODE pxCoRoutineCode, + UBaseType_t uxPriority, + UBaseType_t uxIndex ); + + +/** + * croutine. h + * @code{c} + * void vCoRoutineSchedule( void ); + * @endcode + * + * Run a co-routine. + * + * vCoRoutineSchedule() executes the highest priority co-routine that is able + * to run. The co-routine will execute until it either blocks, yields or is + * preempted by a task. Co-routines execute cooperatively so one + * co-routine cannot be preempted by another, but can be preempted by a task. + * + * If an application comprises of both tasks and co-routines then + * vCoRoutineSchedule should be called from the idle task (in an idle task + * hook). + * + * Example usage: + * @code{c} + * // This idle task hook will schedule a co-routine each time it is called. + * // The rest of the idle task will execute between co-routine calls. + * void vApplicationIdleHook( void ) + * { + * vCoRoutineSchedule(); + * } + * + * // Alternatively, if you do not require any other part of the idle task to + * // execute, the idle task hook can call vCoRoutineSchedule() within an + * // infinite loop. + * void vApplicationIdleHook( void ) + * { + * for( ;; ) + * { + * vCoRoutineSchedule(); + * } + * } + * @endcode + * \defgroup vCoRoutineSchedule vCoRoutineSchedule + * \ingroup Tasks + */ +void vCoRoutineSchedule( void ); + +/** + * croutine. h + * @code{c} + * crSTART( CoRoutineHandle_t xHandle ); + * @endcode + * + * This macro MUST always be called at the start of a co-routine function. + * + * Example usage: + * @code{c} + * // Co-routine to be created. + * void vACoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex ) + * { + * // Variables in co-routines must be declared static if they must maintain value across a blocking call. + * static int32_t ulAVariable; + * + * // Must start every co-routine with a call to crSTART(); + * crSTART( xHandle ); + * + * for( ;; ) + * { + * // Co-routine functionality goes here. + * } + * + * // Must end every co-routine with a call to crEND(); + * crEND(); + * } + * @endcode + * \defgroup crSTART crSTART + * \ingroup Tasks + */ +#define crSTART( pxCRCB ) \ + switch( ( ( CRCB_t * ) ( pxCRCB ) )->uxState ) { \ + case 0: + +/** + * croutine. h + * @code{c} + * crEND(); + * @endcode + * + * This macro MUST always be called at the end of a co-routine function. + * + * Example usage: + * @code{c} + * // Co-routine to be created. + * void vACoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex ) + * { + * // Variables in co-routines must be declared static if they must maintain value across a blocking call. + * static int32_t ulAVariable; + * + * // Must start every co-routine with a call to crSTART(); + * crSTART( xHandle ); + * + * for( ;; ) + * { + * // Co-routine functionality goes here. + * } + * + * // Must end every co-routine with a call to crEND(); + * crEND(); + * } + * @endcode + * \defgroup crSTART crSTART + * \ingroup Tasks + */ +#define crEND() } + +/* + * These macros are intended for internal use by the co-routine implementation + * only. The macros should not be used directly by application writers. + */ +#define crSET_STATE0( xHandle ) \ + ( ( CRCB_t * ) ( xHandle ) )->uxState = ( __LINE__ * 2 ); return; \ + case ( __LINE__ * 2 ): +#define crSET_STATE1( xHandle ) \ + ( ( CRCB_t * ) ( xHandle ) )->uxState = ( ( __LINE__ * 2 ) + 1 ); return; \ + case ( ( __LINE__ * 2 ) + 1 ): + +/** + * croutine. h + * @code{c} + * crDELAY( CoRoutineHandle_t xHandle, TickType_t xTicksToDelay ); + * @endcode + * + * Delay a co-routine for a fixed period of time. + * + * crDELAY can only be called from the co-routine function itself - not + * from within a function called by the co-routine function. This is because + * co-routines do not maintain their own stack. + * + * @param xHandle The handle of the co-routine to delay. This is the xHandle + * parameter of the co-routine function. + * + * @param xTickToDelay The number of ticks that the co-routine should delay + * for. The actual amount of time this equates to is defined by + * configTICK_RATE_HZ (set in FreeRTOSConfig.h). The constant portTICK_PERIOD_MS + * can be used to convert ticks to milliseconds. + * + * Example usage: + * @code{c} + * // Co-routine to be created. + * void vACoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex ) + * { + * // Variables in co-routines must be declared static if they must maintain value across a blocking call. + * // This may not be necessary for const variables. + * // We are to delay for 200ms. + * static const xTickType xDelayTime = 200 / portTICK_PERIOD_MS; + * + * // Must start every co-routine with a call to crSTART(); + * crSTART( xHandle ); + * + * for( ;; ) + * { + * // Delay for 200ms. + * crDELAY( xHandle, xDelayTime ); + * + * // Do something here. + * } + * + * // Must end every co-routine with a call to crEND(); + * crEND(); + * } + * @endcode + * \defgroup crDELAY crDELAY + * \ingroup Tasks + */ +#define crDELAY( xHandle, xTicksToDelay ) \ + do { \ + if( ( xTicksToDelay ) > 0 ) \ + { \ + vCoRoutineAddToDelayedList( ( xTicksToDelay ), NULL ); \ + } \ + crSET_STATE0( ( xHandle ) ); \ + } while( 0 ) + +/** + * @code{c} + * crQUEUE_SEND( + * CoRoutineHandle_t xHandle, + * QueueHandle_t pxQueue, + * void *pvItemToQueue, + * TickType_t xTicksToWait, + * BaseType_t *pxResult + * ) + * @endcode + * + * The macro's crQUEUE_SEND() and crQUEUE_RECEIVE() are the co-routine + * equivalent to the xQueueSend() and xQueueReceive() functions used by tasks. + * + * crQUEUE_SEND and crQUEUE_RECEIVE can only be used from a co-routine whereas + * xQueueSend() and xQueueReceive() can only be used from tasks. + * + * crQUEUE_SEND can only be called from the co-routine function itself - not + * from within a function called by the co-routine function. This is because + * co-routines do not maintain their own stack. + * + * See the co-routine section of the WEB documentation for information on + * passing data between tasks and co-routines and between ISR's and + * co-routines. + * + * @param xHandle The handle of the calling co-routine. This is the xHandle + * parameter of the co-routine function. + * + * @param pxQueue The handle of the queue on which the data will be posted. + * The handle is obtained as the return value when the queue is created using + * the xQueueCreate() API function. + * + * @param pvItemToQueue A pointer to the data being posted onto the queue. + * The number of bytes of each queued item is specified when the queue is + * created. This number of bytes is copied from pvItemToQueue into the queue + * itself. + * + * @param xTickToDelay The number of ticks that the co-routine should block + * to wait for space to become available on the queue, should space not be + * available immediately. The actual amount of time this equates to is defined + * by configTICK_RATE_HZ (set in FreeRTOSConfig.h). The constant + * portTICK_PERIOD_MS can be used to convert ticks to milliseconds (see example + * below). + * + * @param pxResult The variable pointed to by pxResult will be set to pdPASS if + * data was successfully posted onto the queue, otherwise it will be set to an + * error defined within ProjDefs.h. + * + * Example usage: + * @code{c} + * // Co-routine function that blocks for a fixed period then posts a number onto + * // a queue. + * static void prvCoRoutineFlashTask( CoRoutineHandle_t xHandle, UBaseType_t uxIndex ) + * { + * // Variables in co-routines must be declared static if they must maintain value across a blocking call. + * static BaseType_t xNumberToPost = 0; + * static BaseType_t xResult; + * + * // Co-routines must begin with a call to crSTART(). + * crSTART( xHandle ); + * + * for( ;; ) + * { + * // This assumes the queue has already been created. + * crQUEUE_SEND( xHandle, xCoRoutineQueue, &xNumberToPost, NO_DELAY, &xResult ); + * + * if( xResult != pdPASS ) + * { + * // The message was not posted! + * } + * + * // Increment the number to be posted onto the queue. + * xNumberToPost++; + * + * // Delay for 100 ticks. + * crDELAY( xHandle, 100 ); + * } + * + * // Co-routines must end with a call to crEND(). + * crEND(); + * } + * @endcode + * \defgroup crQUEUE_SEND crQUEUE_SEND + * \ingroup Tasks + */ +#define crQUEUE_SEND( xHandle, pxQueue, pvItemToQueue, xTicksToWait, pxResult ) \ + do { \ + *( pxResult ) = xQueueCRSend( ( pxQueue ), ( pvItemToQueue ), ( xTicksToWait ) ); \ + if( *( pxResult ) == errQUEUE_BLOCKED ) \ + { \ + crSET_STATE0( ( xHandle ) ); \ + *pxResult = xQueueCRSend( ( pxQueue ), ( pvItemToQueue ), 0 ); \ + } \ + if( *pxResult == errQUEUE_YIELD ) \ + { \ + crSET_STATE1( ( xHandle ) ); \ + *pxResult = pdPASS; \ + } \ + } while( 0 ) + +/** + * croutine. h + * @code{c} + * crQUEUE_RECEIVE( + * CoRoutineHandle_t xHandle, + * QueueHandle_t pxQueue, + * void *pvBuffer, + * TickType_t xTicksToWait, + * BaseType_t *pxResult + * ) + * @endcode + * + * The macro's crQUEUE_SEND() and crQUEUE_RECEIVE() are the co-routine + * equivalent to the xQueueSend() and xQueueReceive() functions used by tasks. + * + * crQUEUE_SEND and crQUEUE_RECEIVE can only be used from a co-routine whereas + * xQueueSend() and xQueueReceive() can only be used from tasks. + * + * crQUEUE_RECEIVE can only be called from the co-routine function itself - not + * from within a function called by the co-routine function. This is because + * co-routines do not maintain their own stack. + * + * See the co-routine section of the WEB documentation for information on + * passing data between tasks and co-routines and between ISR's and + * co-routines. + * + * @param xHandle The handle of the calling co-routine. This is the xHandle + * parameter of the co-routine function. + * + * @param pxQueue The handle of the queue from which the data will be received. + * The handle is obtained as the return value when the queue is created using + * the xQueueCreate() API function. + * + * @param pvBuffer The buffer into which the received item is to be copied. + * The number of bytes of each queued item is specified when the queue is + * created. This number of bytes is copied into pvBuffer. + * + * @param xTickToDelay The number of ticks that the co-routine should block + * to wait for data to become available from the queue, should data not be + * available immediately. The actual amount of time this equates to is defined + * by configTICK_RATE_HZ (set in FreeRTOSConfig.h). The constant + * portTICK_PERIOD_MS can be used to convert ticks to milliseconds (see the + * crQUEUE_SEND example). + * + * @param pxResult The variable pointed to by pxResult will be set to pdPASS if + * data was successfully retrieved from the queue, otherwise it will be set to + * an error code as defined within ProjDefs.h. + * + * Example usage: + * @code{c} + * // A co-routine receives the number of an LED to flash from a queue. It + * // blocks on the queue until the number is received. + * static void prvCoRoutineFlashWorkTask( CoRoutineHandle_t xHandle, UBaseType_t uxIndex ) + * { + * // Variables in co-routines must be declared static if they must maintain value across a blocking call. + * static BaseType_t xResult; + * static UBaseType_t uxLEDToFlash; + * + * // All co-routines must start with a call to crSTART(). + * crSTART( xHandle ); + * + * for( ;; ) + * { + * // Wait for data to become available on the queue. + * crQUEUE_RECEIVE( xHandle, xCoRoutineQueue, &uxLEDToFlash, portMAX_DELAY, &xResult ); + * + * if( xResult == pdPASS ) + * { + * // We received the LED to flash - flash it! + * vParTestToggleLED( uxLEDToFlash ); + * } + * } + * + * crEND(); + * } + * @endcode + * \defgroup crQUEUE_RECEIVE crQUEUE_RECEIVE + * \ingroup Tasks + */ +#define crQUEUE_RECEIVE( xHandle, pxQueue, pvBuffer, xTicksToWait, pxResult ) \ + do { \ + *( pxResult ) = xQueueCRReceive( ( pxQueue ), ( pvBuffer ), ( xTicksToWait ) ); \ + if( *( pxResult ) == errQUEUE_BLOCKED ) \ + { \ + crSET_STATE0( ( xHandle ) ); \ + *( pxResult ) = xQueueCRReceive( ( pxQueue ), ( pvBuffer ), 0 ); \ + } \ + if( *( pxResult ) == errQUEUE_YIELD ) \ + { \ + crSET_STATE1( ( xHandle ) ); \ + *( pxResult ) = pdPASS; \ + } \ + } while( 0 ) + +/** + * croutine. h + * @code{c} + * crQUEUE_SEND_FROM_ISR( + * QueueHandle_t pxQueue, + * void *pvItemToQueue, + * BaseType_t xCoRoutinePreviouslyWoken + * ) + * @endcode + * + * The macro's crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() are the + * co-routine equivalent to the xQueueSendFromISR() and xQueueReceiveFromISR() + * functions used by tasks. + * + * crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() can only be used to + * pass data between a co-routine and and ISR, whereas xQueueSendFromISR() and + * xQueueReceiveFromISR() can only be used to pass data between a task and and + * ISR. + * + * crQUEUE_SEND_FROM_ISR can only be called from an ISR to send data to a queue + * that is being used from within a co-routine. + * + * See the co-routine section of the WEB documentation for information on + * passing data between tasks and co-routines and between ISR's and + * co-routines. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param xCoRoutinePreviouslyWoken This is included so an ISR can post onto + * the same queue multiple times from a single interrupt. The first call + * should always pass in pdFALSE. Subsequent calls should pass in + * the value returned from the previous call. + * + * @return pdTRUE if a co-routine was woken by posting onto the queue. This is + * used by the ISR to determine if a context switch may be required following + * the ISR. + * + * Example usage: + * @code{c} + * // A co-routine that blocks on a queue waiting for characters to be received. + * static void vReceivingCoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex ) + * { + * char cRxedChar; + * BaseType_t xResult; + * + * // All co-routines must start with a call to crSTART(). + * crSTART( xHandle ); + * + * for( ;; ) + * { + * // Wait for data to become available on the queue. This assumes the + * // queue xCommsRxQueue has already been created! + * crQUEUE_RECEIVE( xHandle, xCommsRxQueue, &uxLEDToFlash, portMAX_DELAY, &xResult ); + * + * // Was a character received? + * if( xResult == pdPASS ) + * { + * // Process the character here. + * } + * } + * + * // All co-routines must end with a call to crEND(). + * crEND(); + * } + * + * // An ISR that uses a queue to send characters received on a serial port to + * // a co-routine. + * void vUART_ISR( void ) + * { + * char cRxedChar; + * BaseType_t xCRWokenByPost = pdFALSE; + * + * // We loop around reading characters until there are none left in the UART. + * while( UART_RX_REG_NOT_EMPTY() ) + * { + * // Obtain the character from the UART. + * cRxedChar = UART_RX_REG; + * + * // Post the character onto a queue. xCRWokenByPost will be pdFALSE + * // the first time around the loop. If the post causes a co-routine + * // to be woken (unblocked) then xCRWokenByPost will be set to pdTRUE. + * // In this manner we can ensure that if more than one co-routine is + * // blocked on the queue only one is woken by this ISR no matter how + * // many characters are posted to the queue. + * xCRWokenByPost = crQUEUE_SEND_FROM_ISR( xCommsRxQueue, &cRxedChar, xCRWokenByPost ); + * } + * } + * @endcode + * \defgroup crQUEUE_SEND_FROM_ISR crQUEUE_SEND_FROM_ISR + * \ingroup Tasks + */ +#define crQUEUE_SEND_FROM_ISR( pxQueue, pvItemToQueue, xCoRoutinePreviouslyWoken ) \ + xQueueCRSendFromISR( ( pxQueue ), ( pvItemToQueue ), ( xCoRoutinePreviouslyWoken ) ) + + +/** + * croutine. h + * @code{c} + * crQUEUE_SEND_FROM_ISR( + * QueueHandle_t pxQueue, + * void *pvBuffer, + * BaseType_t * pxCoRoutineWoken + * ) + * @endcode + * + * The macro's crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() are the + * co-routine equivalent to the xQueueSendFromISR() and xQueueReceiveFromISR() + * functions used by tasks. + * + * crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() can only be used to + * pass data between a co-routine and and ISR, whereas xQueueSendFromISR() and + * xQueueReceiveFromISR() can only be used to pass data between a task and and + * ISR. + * + * crQUEUE_RECEIVE_FROM_ISR can only be called from an ISR to receive data + * from a queue that is being used from within a co-routine (a co-routine + * posted to the queue). + * + * See the co-routine section of the WEB documentation for information on + * passing data between tasks and co-routines and between ISR's and + * co-routines. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvBuffer A pointer to a buffer into which the received item will be + * placed. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from the queue into + * pvBuffer. + * + * @param pxCoRoutineWoken A co-routine may be blocked waiting for space to become + * available on the queue. If crQUEUE_RECEIVE_FROM_ISR causes such a + * co-routine to unblock *pxCoRoutineWoken will get set to pdTRUE, otherwise + * *pxCoRoutineWoken will remain unchanged. + * + * @return pdTRUE an item was successfully received from the queue, otherwise + * pdFALSE. + * + * Example usage: + * @code{c} + * // A co-routine that posts a character to a queue then blocks for a fixed + * // period. The character is incremented each time. + * static void vSendingCoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex ) + * { + * // cChar holds its value while this co-routine is blocked and must therefore + * // be declared static. + * static char cCharToTx = 'a'; + * BaseType_t xResult; + * + * // All co-routines must start with a call to crSTART(). + * crSTART( xHandle ); + * + * for( ;; ) + * { + * // Send the next character to the queue. + * crQUEUE_SEND( xHandle, xCoRoutineQueue, &cCharToTx, NO_DELAY, &xResult ); + * + * if( xResult == pdPASS ) + * { + * // The character was successfully posted to the queue. + * } + * else + * { + * // Could not post the character to the queue. + * } + * + * // Enable the UART Tx interrupt to cause an interrupt in this + * // hypothetical UART. The interrupt will obtain the character + * // from the queue and send it. + * ENABLE_RX_INTERRUPT(); + * + * // Increment to the next character then block for a fixed period. + * // cCharToTx will maintain its value across the delay as it is + * // declared static. + * cCharToTx++; + * if( cCharToTx > 'x' ) + * { + * cCharToTx = 'a'; + * } + * crDELAY( 100 ); + * } + * + * // All co-routines must end with a call to crEND(). + * crEND(); + * } + * + * // An ISR that uses a queue to receive characters to send on a UART. + * void vUART_ISR( void ) + * { + * char cCharToTx; + * BaseType_t xCRWokenByPost = pdFALSE; + * + * while( UART_TX_REG_EMPTY() ) + * { + * // Are there any characters in the queue waiting to be sent? + * // xCRWokenByPost will automatically be set to pdTRUE if a co-routine + * // is woken by the post - ensuring that only a single co-routine is + * // woken no matter how many times we go around this loop. + * if( crQUEUE_RECEIVE_FROM_ISR( pxQueue, &cCharToTx, &xCRWokenByPost ) ) + * { + * SEND_CHARACTER( cCharToTx ); + * } + * } + * } + * @endcode + * \defgroup crQUEUE_RECEIVE_FROM_ISR crQUEUE_RECEIVE_FROM_ISR + * \ingroup Tasks + */ +#define crQUEUE_RECEIVE_FROM_ISR( pxQueue, pvBuffer, pxCoRoutineWoken ) \ + xQueueCRReceiveFromISR( ( pxQueue ), ( pvBuffer ), ( pxCoRoutineWoken ) ) + +/* + * This function is intended for internal use by the co-routine macros only. + * The macro nature of the co-routine implementation requires that the + * prototype appears here. The function should not be used by application + * writers. + * + * Removes the current co-routine from its ready list and places it in the + * appropriate delayed list. + */ +void vCoRoutineAddToDelayedList( TickType_t xTicksToDelay, + List_t * pxEventList ); + +/* + * This function is intended for internal use by the queue implementation only. + * The function should not be used by application writers. + * + * Removes the highest priority co-routine from the event list and places it in + * the pending ready list. + */ +BaseType_t xCoRoutineRemoveFromEventList( const List_t * pxEventList ); + +/* *INDENT-OFF* */ +#ifdef __cplusplus + } +#endif +/* *INDENT-ON* */ + +#endif /* CO_ROUTINE_H */ diff --git a/include/mpu_prototypes.h b/include/mpu_prototypes.h index 08fa0519317..633efd4a817 100644 --- a/include/mpu_prototypes.h +++ b/include/mpu_prototypes.h @@ -39,20 +39,6 @@ #define MPU_PROTOTYPES_H /* MPU versions of task.h API functions. */ -BaseType_t MPU_xTaskCreate( TaskFunction_t pxTaskCode, - const char * const pcName, - const uint16_t usStackDepth, - void * const pvParameters, - UBaseType_t uxPriority, - TaskHandle_t * const pxCreatedTask ) FREERTOS_SYSTEM_CALL; -TaskHandle_t MPU_xTaskCreateStatic( TaskFunction_t pxTaskCode, - const char * const pcName, - const uint32_t ulStackDepth, - void * const pvParameters, - UBaseType_t uxPriority, - StackType_t * const puxStackBuffer, - StaticTask_t * const pxTaskBuffer ) FREERTOS_SYSTEM_CALL; -void MPU_vTaskDelete( TaskHandle_t xTaskToDelete ) FREERTOS_SYSTEM_CALL; void MPU_vTaskDelay( const TickType_t xTicksToDelay ) FREERTOS_SYSTEM_CALL; BaseType_t MPU_xTaskDelayUntil( TickType_t * const pxPreviousWakeTime, const TickType_t xTimeIncrement ) FREERTOS_SYSTEM_CALL; @@ -63,17 +49,11 @@ void MPU_vTaskGetInfo( TaskHandle_t xTask, TaskStatus_t * pxTaskStatus, BaseType_t xGetFreeStackSpace, eTaskState eState ) FREERTOS_SYSTEM_CALL; -void MPU_vTaskPrioritySet( TaskHandle_t xTask, - UBaseType_t uxNewPriority ) FREERTOS_SYSTEM_CALL; void MPU_vTaskSuspend( TaskHandle_t xTaskToSuspend ) FREERTOS_SYSTEM_CALL; void MPU_vTaskResume( TaskHandle_t xTaskToResume ) FREERTOS_SYSTEM_CALL; -void MPU_vTaskStartScheduler( void ) FREERTOS_SYSTEM_CALL; -void MPU_vTaskSuspendAll( void ) FREERTOS_SYSTEM_CALL; -BaseType_t MPU_xTaskResumeAll( void ) FREERTOS_SYSTEM_CALL; TickType_t MPU_xTaskGetTickCount( void ) FREERTOS_SYSTEM_CALL; UBaseType_t MPU_uxTaskGetNumberOfTasks( void ) FREERTOS_SYSTEM_CALL; char * MPU_pcTaskGetName( TaskHandle_t xTaskToQuery ) FREERTOS_SYSTEM_CALL; -TaskHandle_t MPU_xTaskGetHandle( const char * pcNameToQuery ) FREERTOS_SYSTEM_CALL; UBaseType_t MPU_uxTaskGetStackHighWaterMark( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL; configSTACK_DEPTH_TYPE MPU_uxTaskGetStackHighWaterMark2( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL; void MPU_vTaskSetApplicationTaskTag( TaskHandle_t xTask, @@ -84,16 +64,14 @@ void MPU_vTaskSetThreadLocalStoragePointer( TaskHandle_t xTaskToSet, void * pvValue ) FREERTOS_SYSTEM_CALL; void * MPU_pvTaskGetThreadLocalStoragePointer( TaskHandle_t xTaskToQuery, BaseType_t xIndex ) FREERTOS_SYSTEM_CALL; -BaseType_t MPU_xTaskCallApplicationTaskHook( TaskHandle_t xTask, - void * pvParameter ) FREERTOS_SYSTEM_CALL; TaskHandle_t MPU_xTaskGetIdleTaskHandle( void ) FREERTOS_SYSTEM_CALL; UBaseType_t MPU_uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray, const UBaseType_t uxArraySize, configRUN_TIME_COUNTER_TYPE * const pulTotalRunTime ) FREERTOS_SYSTEM_CALL; +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetRunTimeCounter( const TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL; +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetRunTimePercent( const TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL; configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimeCounter( void ) FREERTOS_SYSTEM_CALL; configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimePercent( void ) FREERTOS_SYSTEM_CALL; -void MPU_vTaskList( char * pcWriteBuffer ) FREERTOS_SYSTEM_CALL; -void MPU_vTaskGetRunTimeStats( char * pcWriteBuffer ) FREERTOS_SYSTEM_CALL; BaseType_t MPU_xTaskGenericNotify( TaskHandle_t xTaskToNotify, UBaseType_t uxIndexToNotify, uint32_t ulValue, @@ -112,14 +90,55 @@ BaseType_t MPU_xTaskGenericNotifyStateClear( TaskHandle_t xTask, uint32_t MPU_ulTaskGenericNotifyValueClear( TaskHandle_t xTask, UBaseType_t uxIndexToClear, uint32_t ulBitsToClear ) FREERTOS_SYSTEM_CALL; -BaseType_t MPU_xTaskIncrementTick( void ) FREERTOS_SYSTEM_CALL; -TaskHandle_t MPU_xTaskGetCurrentTaskHandle( void ) FREERTOS_SYSTEM_CALL; void MPU_vTaskSetTimeOutState( TimeOut_t * const pxTimeOut ) FREERTOS_SYSTEM_CALL; BaseType_t MPU_xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut, TickType_t * const pxTicksToWait ) FREERTOS_SYSTEM_CALL; -void MPU_vTaskMissedYield( void ) FREERTOS_SYSTEM_CALL; +TaskHandle_t MPU_xTaskGetCurrentTaskHandle( void ) FREERTOS_SYSTEM_CALL; BaseType_t MPU_xTaskGetSchedulerState( void ) FREERTOS_SYSTEM_CALL; -BaseType_t MPU_xTaskCatchUpTicks( TickType_t xTicksToCatchUp ) FREERTOS_SYSTEM_CALL; + +/* Privileged only wrappers for Task APIs. These are needed so that + * the application can use opaque handles maintained in mpu_wrappers.c + * with all the APIs. */ +BaseType_t MPU_xTaskCreate( TaskFunction_t pxTaskCode, + const char * const pcName, + const uint16_t usStackDepth, + void * const pvParameters, + UBaseType_t uxPriority, + TaskHandle_t * const pxCreatedTask ) PRIVILEGED_FUNCTION; +TaskHandle_t MPU_xTaskCreateStatic( TaskFunction_t pxTaskCode, + const char * const pcName, + const uint32_t ulStackDepth, + void * const pvParameters, + UBaseType_t uxPriority, + StackType_t * const puxStackBuffer, + StaticTask_t * const pxTaskBuffer ) PRIVILEGED_FUNCTION; +void MPU_vTaskDelete( TaskHandle_t xTaskToDelete ) PRIVILEGED_FUNCTION; +void MPU_vTaskPrioritySet( TaskHandle_t xTask, + UBaseType_t uxNewPriority ) PRIVILEGED_FUNCTION; +TaskHandle_t MPU_xTaskGetHandle( const char * pcNameToQuery ) PRIVILEGED_FUNCTION; +BaseType_t MPU_xTaskCallApplicationTaskHook( TaskHandle_t xTask, + void * pvParameter ) PRIVILEGED_FUNCTION; +BaseType_t MPU_xTaskCreateRestricted( const TaskParameters_t * const pxTaskDefinition, + TaskHandle_t * pxCreatedTask ) PRIVILEGED_FUNCTION; +BaseType_t MPU_xTaskCreateRestrictedStatic( const TaskParameters_t * const pxTaskDefinition, + TaskHandle_t * pxCreatedTask ) PRIVILEGED_FUNCTION; +void vTaskAllocateMPURegions( TaskHandle_t xTaskToModify, + const MemoryRegion_t * const xRegions ) PRIVILEGED_FUNCTION; +BaseType_t MPU_xTaskGetStaticBuffers( TaskHandle_t xTask, + StackType_t ** ppuxStackBuffer, + StaticTask_t ** ppxTaskBuffer ) PRIVILEGED_FUNCTION; +UBaseType_t MPU_uxTaskPriorityGetFromISR( const TaskHandle_t xTask ) PRIVILEGED_FUNCTION; +BaseType_t MPU_xTaskResumeFromISR( TaskHandle_t xTaskToResume ) PRIVILEGED_FUNCTION; +TaskHookFunction_t MPU_xTaskGetApplicationTaskTagFromISR( TaskHandle_t xTask ) PRIVILEGED_FUNCTION; +BaseType_t MPU_xTaskGenericNotifyFromISR( TaskHandle_t xTaskToNotify, + UBaseType_t uxIndexToNotify, + uint32_t ulValue, + eNotifyAction eAction, + uint32_t * pulPreviousNotificationValue, + BaseType_t * pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; +void MPU_vTaskGenericNotifyGiveFromISR( TaskHandle_t xTaskToNotify, + UBaseType_t uxIndexToNotify, + BaseType_t * pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; /* MPU versions of queue.h API functions. */ BaseType_t MPU_xQueueGenericSend( QueueHandle_t xQueue, @@ -136,15 +155,6 @@ BaseType_t MPU_xQueueSemaphoreTake( QueueHandle_t xQueue, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; UBaseType_t MPU_uxQueueMessagesWaiting( const QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL; UBaseType_t MPU_uxQueueSpacesAvailable( const QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL; -void MPU_vQueueDelete( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL; -QueueHandle_t MPU_xQueueCreateMutex( const uint8_t ucQueueType ) FREERTOS_SYSTEM_CALL; -QueueHandle_t MPU_xQueueCreateMutexStatic( const uint8_t ucQueueType, - StaticQueue_t * pxStaticQueue ) FREERTOS_SYSTEM_CALL; -QueueHandle_t MPU_xQueueCreateCountingSemaphore( const UBaseType_t uxMaxCount, - const UBaseType_t uxInitialCount ) FREERTOS_SYSTEM_CALL; -QueueHandle_t MPU_xQueueCreateCountingSemaphoreStatic( const UBaseType_t uxMaxCount, - const UBaseType_t uxInitialCount, - StaticQueue_t * pxStaticQueue ) FREERTOS_SYSTEM_CALL; TaskHandle_t MPU_xQueueGetMutexHolder( QueueHandle_t xSemaphore ) FREERTOS_SYSTEM_CALL; BaseType_t MPU_xQueueTakeMutexRecursive( QueueHandle_t xMutex, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; @@ -153,65 +163,97 @@ void MPU_vQueueAddToRegistry( QueueHandle_t xQueue, const char * pcName ) FREERTOS_SYSTEM_CALL; void MPU_vQueueUnregisterQueue( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL; const char * MPU_pcQueueGetName( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL; -QueueHandle_t MPU_xQueueGenericCreate( const UBaseType_t uxQueueLength, - const UBaseType_t uxItemSize, - const uint8_t ucQueueType ) FREERTOS_SYSTEM_CALL; -QueueHandle_t MPU_xQueueGenericCreateStatic( const UBaseType_t uxQueueLength, - const UBaseType_t uxItemSize, - uint8_t * pucQueueStorage, - StaticQueue_t * pxStaticQueue, - const uint8_t ucQueueType ) FREERTOS_SYSTEM_CALL; -QueueSetHandle_t MPU_xQueueCreateSet( const UBaseType_t uxEventQueueLength ) FREERTOS_SYSTEM_CALL; BaseType_t MPU_xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore, QueueSetHandle_t xQueueSet ) FREERTOS_SYSTEM_CALL; -BaseType_t MPU_xQueueRemoveFromSet( QueueSetMemberHandle_t xQueueOrSemaphore, - QueueSetHandle_t xQueueSet ) FREERTOS_SYSTEM_CALL; QueueSetMemberHandle_t MPU_xQueueSelectFromSet( QueueSetHandle_t xQueueSet, const TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; -BaseType_t MPU_xQueueGenericReset( QueueHandle_t xQueue, - BaseType_t xNewQueue ) FREERTOS_SYSTEM_CALL; void MPU_vQueueSetQueueNumber( QueueHandle_t xQueue, UBaseType_t uxQueueNumber ) FREERTOS_SYSTEM_CALL; UBaseType_t MPU_uxQueueGetQueueNumber( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL; uint8_t MPU_ucQueueGetQueueType( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL; +/* Privileged only wrappers for Queue APIs. These are needed so that + * the application can use opaque handles maintained in mpu_wrappers.c + * with all the APIs. */ +void MPU_vQueueDelete( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; +QueueHandle_t MPU_xQueueCreateMutex( const uint8_t ucQueueType ) PRIVILEGED_FUNCTION; +QueueHandle_t MPU_xQueueCreateMutexStatic( const uint8_t ucQueueType, + StaticQueue_t * pxStaticQueue ) PRIVILEGED_FUNCTION; +QueueHandle_t MPU_xQueueCreateCountingSemaphore( const UBaseType_t uxMaxCount, + const UBaseType_t uxInitialCount ) PRIVILEGED_FUNCTION; +QueueHandle_t MPU_xQueueCreateCountingSemaphoreStatic( const UBaseType_t uxMaxCount, + const UBaseType_t uxInitialCount, + StaticQueue_t * pxStaticQueue ) PRIVILEGED_FUNCTION; +QueueHandle_t MPU_xQueueGenericCreate( const UBaseType_t uxQueueLength, + const UBaseType_t uxItemSize, + const uint8_t ucQueueType ) PRIVILEGED_FUNCTION; +QueueHandle_t MPU_xQueueGenericCreateStatic( const UBaseType_t uxQueueLength, + const UBaseType_t uxItemSize, + uint8_t * pucQueueStorage, + StaticQueue_t * pxStaticQueue, + const uint8_t ucQueueType ) PRIVILEGED_FUNCTION; +QueueSetHandle_t MPU_xQueueCreateSet( const UBaseType_t uxEventQueueLength ) PRIVILEGED_FUNCTION; +BaseType_t MPU_xQueueRemoveFromSet( QueueSetMemberHandle_t xQueueOrSemaphore, + QueueSetHandle_t xQueueSet ) PRIVILEGED_FUNCTION; +BaseType_t MPU_xQueueGenericReset( QueueHandle_t xQueue, + BaseType_t xNewQueue ) PRIVILEGED_FUNCTION; +BaseType_t MPU_xQueueGenericGetStaticBuffers( QueueHandle_t xQueue, + uint8_t ** ppucQueueStorage, + StaticQueue_t ** ppxStaticQueue ) PRIVILEGED_FUNCTION; +BaseType_t MPU_xQueueGenericSendFromISR( QueueHandle_t xQueue, + const void * const pvItemToQueue, + BaseType_t * const pxHigherPriorityTaskWoken, + const BaseType_t xCopyPosition ) PRIVILEGED_FUNCTION; +BaseType_t MPU_xQueueGiveFromISR( QueueHandle_t xQueue, + BaseType_t * const pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; +BaseType_t MPU_xQueuePeekFromISR( QueueHandle_t xQueue, + void * const pvBuffer ) PRIVILEGED_FUNCTION; +BaseType_t MPU_xQueueReceiveFromISR( QueueHandle_t xQueue, + void * const pvBuffer, + BaseType_t * const pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; +BaseType_t MPU_xQueueIsQueueEmptyFromISR( const QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; +BaseType_t MPU_xQueueIsQueueFullFromISR( const QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; +UBaseType_t MPU_uxQueueMessagesWaitingFromISR( const QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; +TaskHandle_t MPU_xQueueGetMutexHolderFromISR( QueueHandle_t xSemaphore ) PRIVILEGED_FUNCTION; +QueueSetMemberHandle_t MPU_xQueueSelectFromSetFromISR( QueueSetHandle_t xQueueSet ) PRIVILEGED_FUNCTION; + /* MPU versions of timers.h API functions. */ -TimerHandle_t MPU_xTimerCreate( const char * const pcTimerName, - const TickType_t xTimerPeriodInTicks, - const UBaseType_t uxAutoReload, - void * const pvTimerID, - TimerCallbackFunction_t pxCallbackFunction ) FREERTOS_SYSTEM_CALL; -TimerHandle_t MPU_xTimerCreateStatic( const char * const pcTimerName, - const TickType_t xTimerPeriodInTicks, - const UBaseType_t uxAutoReload, - void * const pvTimerID, - TimerCallbackFunction_t pxCallbackFunction, - StaticTimer_t * pxTimerBuffer ) FREERTOS_SYSTEM_CALL; void * MPU_pvTimerGetTimerID( const TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL; void MPU_vTimerSetTimerID( TimerHandle_t xTimer, void * pvNewID ) FREERTOS_SYSTEM_CALL; BaseType_t MPU_xTimerIsTimerActive( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL; TaskHandle_t MPU_xTimerGetTimerDaemonTaskHandle( void ) FREERTOS_SYSTEM_CALL; -BaseType_t MPU_xTimerPendFunctionCall( PendedFunction_t xFunctionToPend, - void * pvParameter1, - uint32_t ulParameter2, - TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xTimerGenericCommand( TimerHandle_t xTimer, + const BaseType_t xCommandID, + const TickType_t xOptionalValue, + BaseType_t * const pxHigherPriorityTaskWoken, + const TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; const char * MPU_pcTimerGetName( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL; void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, const UBaseType_t uxAutoReload ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xTimerGetReloadMode( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL; UBaseType_t MPU_uxTimerGetReloadMode( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL; TickType_t MPU_xTimerGetPeriod( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL; TickType_t MPU_xTimerGetExpiryTime( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL; -BaseType_t MPU_xTimerCreateTimerTask( void ) FREERTOS_SYSTEM_CALL; -BaseType_t MPU_xTimerGenericCommand( TimerHandle_t xTimer, - const BaseType_t xCommandID, - const TickType_t xOptionalValue, - BaseType_t * const pxHigherPriorityTaskWoken, - const TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; + +/* Privileged only wrappers for Timer APIs. These are needed so that + * the application can use opaque handles maintained in mpu_wrappers.c + * with all the APIs. */ +TimerHandle_t MPU_xTimerCreate( const char * const pcTimerName, + const TickType_t xTimerPeriodInTicks, + const UBaseType_t uxAutoReload, + void * const pvTimerID, + TimerCallbackFunction_t pxCallbackFunction ) PRIVILEGED_FUNCTION; +TimerHandle_t MPU_xTimerCreateStatic( const char * const pcTimerName, + const TickType_t xTimerPeriodInTicks, + const UBaseType_t uxAutoReload, + void * const pvTimerID, + TimerCallbackFunction_t pxCallbackFunction, + StaticTimer_t * pxTimerBuffer ) PRIVILEGED_FUNCTION; +BaseType_t MPU_xTimerGetStaticBuffer( TimerHandle_t xTimer, + StaticTimer_t ** ppxTimerBuffer ) PRIVILEGED_FUNCTION; /* MPU versions of event_group.h API functions. */ -EventGroupHandle_t MPU_xEventGroupCreate( void ) FREERTOS_SYSTEM_CALL; -EventGroupHandle_t MPU_xEventGroupCreateStatic( StaticEventGroup_t * pxEventGroupBuffer ) FREERTOS_SYSTEM_CALL; EventBits_t MPU_xEventGroupWaitBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToWaitFor, const BaseType_t xClearOnExit, @@ -225,8 +267,26 @@ EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, const EventBits_t uxBitsToWaitFor, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; -void MPU_vEventGroupDelete( EventGroupHandle_t xEventGroup ) FREERTOS_SYSTEM_CALL; -UBaseType_t MPU_uxEventGroupGetNumber( void * xEventGroup ) FREERTOS_SYSTEM_CALL; +#if ( configUSE_TRACE_FACILITY == 1 ) + UBaseType_t MPU_uxEventGroupGetNumber( void * xEventGroup ) FREERTOS_SYSTEM_CALL; + void MPU_vEventGroupSetNumber( void * xEventGroup, + UBaseType_t uxEventGroupNumber ) FREERTOS_SYSTEM_CALL; +#endif /* ( configUSE_TRACE_FACILITY == 1 )*/ + +/* Privileged only wrappers for Event Group APIs. These are needed so that + * the application can use opaque handles maintained in mpu_wrappers.c + * with all the APIs. */ +EventGroupHandle_t MPU_xEventGroupCreate( void ) PRIVILEGED_FUNCTION; +EventGroupHandle_t MPU_xEventGroupCreateStatic( StaticEventGroup_t * pxEventGroupBuffer ) PRIVILEGED_FUNCTION; +void MPU_vEventGroupDelete( EventGroupHandle_t xEventGroup ) PRIVILEGED_FUNCTION; +BaseType_t MPU_xEventGroupGetStaticBuffer( EventGroupHandle_t xEventGroup, + StaticEventGroup_t ** ppxEventGroupBuffer ) PRIVILEGED_FUNCTION; +BaseType_t MPU_xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToClear ) PRIVILEGED_FUNCTION; +BaseType_t MPU_xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet, + BaseType_t * pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; +EventBits_t MPU_xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup ) PRIVILEGED_FUNCTION; /* MPU versions of message/stream_buffer.h API functions. */ size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, @@ -237,28 +297,45 @@ size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, void * pvRxData, size_t xBufferLengthBytes, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; -size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL; -void MPU_vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL; BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL; BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL; -BaseType_t MPU_xStreamBufferReset( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL; size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL; size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL; BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, size_t xTriggerLevel ) FREERTOS_SYSTEM_CALL; +size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL; + +/* Privileged only wrappers for Stream Buffer APIs. These are needed so that + * the application can use opaque handles maintained in mpu_wrappers.c + * with all the APIs. */ StreamBufferHandle_t MPU_xStreamBufferGenericCreate( size_t xBufferSizeBytes, size_t xTriggerLevelBytes, BaseType_t xIsMessageBuffer, StreamBufferCallbackFunction_t pxSendCompletedCallback, - StreamBufferCallbackFunction_t pxReceiveCompletedCallback ) FREERTOS_SYSTEM_CALL; + StreamBufferCallbackFunction_t pxReceiveCompletedCallback ) PRIVILEGED_FUNCTION; StreamBufferHandle_t MPU_xStreamBufferGenericCreateStatic( size_t xBufferSizeBytes, size_t xTriggerLevelBytes, BaseType_t xIsMessageBuffer, uint8_t * const pucStreamBufferStorageArea, StaticStreamBuffer_t * const pxStaticStreamBuffer, StreamBufferCallbackFunction_t pxSendCompletedCallback, - StreamBufferCallbackFunction_t pxReceiveCompletedCallback ) FREERTOS_SYSTEM_CALL; - - + StreamBufferCallbackFunction_t pxReceiveCompletedCallback ) PRIVILEGED_FUNCTION; +void MPU_vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; +BaseType_t MPU_xStreamBufferReset( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; +BaseType_t MPU_xStreamBufferGetStaticBuffers( StreamBufferHandle_t xStreamBuffers, + uint8_t * ppucStreamBufferStorageArea, + StaticStreamBuffer_t * ppxStaticStreamBuffer ) PRIVILEGED_FUNCTION; +size_t MPU_xStreamBufferSendFromISR( StreamBufferHandle_t xStreamBuffer, + const void * pvTxData, + size_t xDataLengthBytes, + BaseType_t * const pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; +size_t MPU_xStreamBufferReceiveFromISR( StreamBufferHandle_t xStreamBuffer, + void * pvRxData, + size_t xBufferLengthBytes, + BaseType_t * const pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; +BaseType_t MPU_xStreamBufferSendCompletedFromISR( StreamBufferHandle_t xStreamBuffer, + BaseType_t * pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; +BaseType_t MPU_xStreamBufferReceiveCompletedFromISR( StreamBufferHandle_t xStreamBuffer, + BaseType_t * pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; #endif /* MPU_PROTOTYPES_H */ diff --git a/include/mpu_wrappers.h b/include/mpu_wrappers.h index fb8aedfee81..020efc3ef68 100644 --- a/include/mpu_wrappers.h +++ b/include/mpu_wrappers.h @@ -47,114 +47,184 @@ */ /* Map standard task.h API functions to the MPU equivalents. */ - #define xTaskCreate MPU_xTaskCreate - #define xTaskCreateStatic MPU_xTaskCreateStatic - #define vTaskDelete MPU_vTaskDelete - #define vTaskDelay MPU_vTaskDelay - #define xTaskDelayUntil MPU_xTaskDelayUntil - #define xTaskAbortDelay MPU_xTaskAbortDelay - #define uxTaskPriorityGet MPU_uxTaskPriorityGet - #define eTaskGetState MPU_eTaskGetState - #define vTaskGetInfo MPU_vTaskGetInfo - #define vTaskPrioritySet MPU_vTaskPrioritySet - #define vTaskSuspend MPU_vTaskSuspend - #define vTaskResume MPU_vTaskResume - #define vTaskSuspendAll MPU_vTaskSuspendAll - #define xTaskResumeAll MPU_xTaskResumeAll - #define xTaskGetTickCount MPU_xTaskGetTickCount - #define uxTaskGetNumberOfTasks MPU_uxTaskGetNumberOfTasks - #define pcTaskGetName MPU_pcTaskGetName - #define xTaskGetHandle MPU_xTaskGetHandle - #define uxTaskGetStackHighWaterMark MPU_uxTaskGetStackHighWaterMark - #define uxTaskGetStackHighWaterMark2 MPU_uxTaskGetStackHighWaterMark2 - #define vTaskSetApplicationTaskTag MPU_vTaskSetApplicationTaskTag - #define xTaskGetApplicationTaskTag MPU_xTaskGetApplicationTaskTag - #define vTaskSetThreadLocalStoragePointer MPU_vTaskSetThreadLocalStoragePointer - #define pvTaskGetThreadLocalStoragePointer MPU_pvTaskGetThreadLocalStoragePointer - #define xTaskCallApplicationTaskHook MPU_xTaskCallApplicationTaskHook - #define xTaskGetIdleTaskHandle MPU_xTaskGetIdleTaskHandle - #define uxTaskGetSystemState MPU_uxTaskGetSystemState - #define vTaskList MPU_vTaskList - #define vTaskGetRunTimeStats MPU_vTaskGetRunTimeStats - #define ulTaskGetIdleRunTimeCounter MPU_ulTaskGetIdleRunTimeCounter - #define ulTaskGetIdleRunTimePercent MPU_ulTaskGetIdleRunTimePercent - #define xTaskGenericNotify MPU_xTaskGenericNotify - #define xTaskGenericNotifyWait MPU_xTaskGenericNotifyWait - #define ulTaskGenericNotifyTake MPU_ulTaskGenericNotifyTake - #define xTaskGenericNotifyStateClear MPU_xTaskGenericNotifyStateClear - #define ulTaskGenericNotifyValueClear MPU_ulTaskGenericNotifyValueClear - #define xTaskCatchUpTicks MPU_xTaskCatchUpTicks - - #define xTaskGetCurrentTaskHandle MPU_xTaskGetCurrentTaskHandle - #define vTaskSetTimeOutState MPU_vTaskSetTimeOutState - #define xTaskCheckForTimeOut MPU_xTaskCheckForTimeOut - #define xTaskGetSchedulerState MPU_xTaskGetSchedulerState + #define vTaskDelay MPU_vTaskDelay + #define xTaskDelayUntil MPU_xTaskDelayUntil + #define xTaskAbortDelay MPU_xTaskAbortDelay + #define uxTaskPriorityGet MPU_uxTaskPriorityGet + #define eTaskGetState MPU_eTaskGetState + #define vTaskGetInfo MPU_vTaskGetInfo + #define vTaskSuspend MPU_vTaskSuspend + #define vTaskResume MPU_vTaskResume + #define xTaskGetTickCount MPU_xTaskGetTickCount + #define uxTaskGetNumberOfTasks MPU_uxTaskGetNumberOfTasks + #define pcTaskGetName MPU_pcTaskGetName + #define uxTaskGetStackHighWaterMark MPU_uxTaskGetStackHighWaterMark + #define uxTaskGetStackHighWaterMark2 MPU_uxTaskGetStackHighWaterMark2 + #define vTaskSetApplicationTaskTag MPU_vTaskSetApplicationTaskTag + #define xTaskGetApplicationTaskTag MPU_xTaskGetApplicationTaskTag + #define vTaskSetThreadLocalStoragePointer MPU_vTaskSetThreadLocalStoragePointer + #define pvTaskGetThreadLocalStoragePointer MPU_pvTaskGetThreadLocalStoragePointer + #define xTaskGetIdleTaskHandle MPU_xTaskGetIdleTaskHandle + #define uxTaskGetSystemState MPU_uxTaskGetSystemState + #define ulTaskGetIdleRunTimeCounter MPU_ulTaskGetIdleRunTimeCounter + #define ulTaskGetIdleRunTimePercent MPU_ulTaskGetIdleRunTimePercent + #define xTaskGenericNotify MPU_xTaskGenericNotify + #define xTaskGenericNotifyWait MPU_xTaskGenericNotifyWait + #define ulTaskGenericNotifyTake MPU_ulTaskGenericNotifyTake + #define xTaskGenericNotifyStateClear MPU_xTaskGenericNotifyStateClear + #define ulTaskGenericNotifyValueClear MPU_ulTaskGenericNotifyValueClear + #define vTaskSetTimeOutState MPU_vTaskSetTimeOutState + #define xTaskCheckForTimeOut MPU_xTaskCheckForTimeOut + #define xTaskGetCurrentTaskHandle MPU_xTaskGetCurrentTaskHandle + #define xTaskGetSchedulerState MPU_xTaskGetSchedulerState + + #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + #define ulTaskGetRunTimeCounter MPU_ulTaskGetRunTimeCounter + #define ulTaskGetRunTimePercent MPU_ulTaskGetRunTimePercent + #endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + +/* Privileged only wrappers for Task APIs. These are needed so that + * the application can use opaque handles maintained in mpu_wrappers.c + * with all the APIs. */ + #define xTaskCreate MPU_xTaskCreate + #define xTaskCreateStatic MPU_xTaskCreateStatic + #define vTaskDelete MPU_vTaskDelete + #define vTaskPrioritySet MPU_vTaskPrioritySet + #define xTaskGetHandle MPU_xTaskGetHandle + #define xTaskCallApplicationTaskHook MPU_xTaskCallApplicationTaskHook + + #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + #define xTaskCreateRestricted MPU_xTaskCreateRestricted + #define xTaskCreateRestrictedStatic MPU_xTaskCreateRestrictedStatic + #define vTaskAllocateMPURegions MPU_vTaskAllocateMPURegions + #define xTaskGetStaticBuffers MPU_xTaskGetStaticBuffers + #define uxTaskPriorityGetFromISR MPU_uxTaskPriorityGetFromISR + #define xTaskResumeFromISR MPU_xTaskResumeFromISR + #define xTaskGetApplicationTaskTagFromISR MPU_xTaskGetApplicationTaskTagFromISR + #define xTaskGenericNotifyFromISR MPU_xTaskGenericNotifyFromISR + #define vTaskGenericNotifyGiveFromISR MPU_vTaskGenericNotifyGiveFromISR + #endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ /* Map standard queue.h API functions to the MPU equivalents. */ - #define xQueueGenericSend MPU_xQueueGenericSend - #define xQueueReceive MPU_xQueueReceive - #define xQueuePeek MPU_xQueuePeek - #define xQueueSemaphoreTake MPU_xQueueSemaphoreTake - #define uxQueueMessagesWaiting MPU_uxQueueMessagesWaiting - #define uxQueueSpacesAvailable MPU_uxQueueSpacesAvailable + #define xQueueGenericSend MPU_xQueueGenericSend + #define xQueueReceive MPU_xQueueReceive + #define xQueuePeek MPU_xQueuePeek + #define xQueueSemaphoreTake MPU_xQueueSemaphoreTake + #define uxQueueMessagesWaiting MPU_uxQueueMessagesWaiting + #define uxQueueSpacesAvailable MPU_uxQueueSpacesAvailable + #define xQueueGetMutexHolder MPU_xQueueGetMutexHolder + #define xQueueTakeMutexRecursive MPU_xQueueTakeMutexRecursive + #define xQueueGiveMutexRecursive MPU_xQueueGiveMutexRecursive + #define xQueueAddToSet MPU_xQueueAddToSet + #define xQueueSelectFromSet MPU_xQueueSelectFromSet + + #if ( configQUEUE_REGISTRY_SIZE > 0 ) + #define vQueueAddToRegistry MPU_vQueueAddToRegistry + #define vQueueUnregisterQueue MPU_vQueueUnregisterQueue + #define pcQueueGetName MPU_pcQueueGetName + #endif /* #if ( configQUEUE_REGISTRY_SIZE > 0 ) */ + +/* Privileged only wrappers for Queue APIs. These are needed so that + * the application can use opaque handles maintained in mpu_wrappers.c + * with all the APIs. */ #define vQueueDelete MPU_vQueueDelete #define xQueueCreateMutex MPU_xQueueCreateMutex #define xQueueCreateMutexStatic MPU_xQueueCreateMutexStatic #define xQueueCreateCountingSemaphore MPU_xQueueCreateCountingSemaphore #define xQueueCreateCountingSemaphoreStatic MPU_xQueueCreateCountingSemaphoreStatic - #define xQueueGetMutexHolder MPU_xQueueGetMutexHolder - #define xQueueTakeMutexRecursive MPU_xQueueTakeMutexRecursive - #define xQueueGiveMutexRecursive MPU_xQueueGiveMutexRecursive #define xQueueGenericCreate MPU_xQueueGenericCreate #define xQueueGenericCreateStatic MPU_xQueueGenericCreateStatic + #define xQueueGenericReset MPU_xQueueGenericReset #define xQueueCreateSet MPU_xQueueCreateSet - #define xQueueAddToSet MPU_xQueueAddToSet #define xQueueRemoveFromSet MPU_xQueueRemoveFromSet - #define xQueueSelectFromSet MPU_xQueueSelectFromSet - #define xQueueGenericReset MPU_xQueueGenericReset - #if ( configQUEUE_REGISTRY_SIZE > 0 ) - #define vQueueAddToRegistry MPU_vQueueAddToRegistry - #define vQueueUnregisterQueue MPU_vQueueUnregisterQueue - #define pcQueueGetName MPU_pcQueueGetName - #endif + #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + #define xQueueGenericGetStaticBuffers MPU_xQueueGenericGetStaticBuffers + #define xQueueGenericSendFromISR MPU_xQueueGenericSendFromISR + #define xQueueGiveFromISR MPU_xQueueGiveFromISR + #define xQueuePeekFromISR MPU_xQueuePeekFromISR + #define xQueueReceiveFromISR MPU_xQueueReceiveFromISR + #define xQueueIsQueueEmptyFromISR MPU_xQueueIsQueueEmptyFromISR + #define xQueueIsQueueFullFromISR MPU_xQueueIsQueueFullFromISR + #define uxQueueMessagesWaitingFromISR MPU_uxQueueMessagesWaitingFromISR + #define xQueueGetMutexHolderFromISR MPU_xQueueGetMutexHolderFromISR + #define xQueueSelectFromSetFromISR MPU_xQueueSelectFromSetFromISR + #endif /* if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ /* Map standard timer.h API functions to the MPU equivalents. */ - #define pvTimerGetTimerID MPU_pvTimerGetTimerID - #define vTimerSetTimerID MPU_vTimerSetTimerID - #define xTimerIsTimerActive MPU_xTimerIsTimerActive - #define xTimerGetTimerDaemonTaskHandle MPU_xTimerGetTimerDaemonTaskHandle - #define pcTimerGetName MPU_pcTimerGetName - #define vTimerSetReloadMode MPU_vTimerSetReloadMode - #define uxTimerGetReloadMode MPU_uxTimerGetReloadMode - #define xTimerGetPeriod MPU_xTimerGetPeriod - #define xTimerGetExpiryTime MPU_xTimerGetExpiryTime - #define xTimerGenericCommand MPU_xTimerGenericCommand + #define pvTimerGetTimerID MPU_pvTimerGetTimerID + #define vTimerSetTimerID MPU_vTimerSetTimerID + #define xTimerIsTimerActive MPU_xTimerIsTimerActive + #define xTimerGetTimerDaemonTaskHandle MPU_xTimerGetTimerDaemonTaskHandle + #define xTimerGenericCommand MPU_xTimerGenericCommand + #define pcTimerGetName MPU_pcTimerGetName + #define vTimerSetReloadMode MPU_vTimerSetReloadMode + #define uxTimerGetReloadMode MPU_uxTimerGetReloadMode + #define xTimerGetPeriod MPU_xTimerGetPeriod + #define xTimerGetExpiryTime MPU_xTimerGetExpiryTime + +/* Privileged only wrappers for Timer APIs. These are needed so that + * the application can use opaque handles maintained in mpu_wrappers.c + * with all the APIs. */ + #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + #define xTimerGetReloadMode MPU_xTimerGetReloadMode + #define xTimerCreate MPU_xTimerCreate + #define xTimerCreateStatic MPU_xTimerCreateStatic + #define xTimerGetStaticBuffer MPU_xTimerGetStaticBuffer + #endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ /* Map standard event_group.h API functions to the MPU equivalents. */ - #define xEventGroupCreate MPU_xEventGroupCreate - #define xEventGroupCreateStatic MPU_xEventGroupCreateStatic - #define xEventGroupWaitBits MPU_xEventGroupWaitBits - #define xEventGroupClearBits MPU_xEventGroupClearBits - #define xEventGroupSetBits MPU_xEventGroupSetBits - #define xEventGroupSync MPU_xEventGroupSync - #define vEventGroupDelete MPU_vEventGroupDelete + #define xEventGroupWaitBits MPU_xEventGroupWaitBits + #define xEventGroupClearBits MPU_xEventGroupClearBits + #define xEventGroupSetBits MPU_xEventGroupSetBits + #define xEventGroupSync MPU_xEventGroupSync + + #if ( ( configUSE_TRACE_FACILITY == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + #define uxEventGroupGetNumber MPU_uxEventGroupGetNumber + #define vEventGroupSetNumber MPU_vEventGroupSetNumber + #endif /* #if ( ( configUSE_TRACE_FACILITY == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ + +/* Privileged only wrappers for Event Group APIs. These are needed so that + * the application can use opaque handles maintained in mpu_wrappers.c + * with all the APIs. */ + #define xEventGroupCreate MPU_xEventGroupCreate + #define xEventGroupCreateStatic MPU_xEventGroupCreateStatic + #define vEventGroupDelete MPU_vEventGroupDelete + + #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + #define xEventGroupGetStaticBuffer MPU_xEventGroupGetStaticBuffer + #define xEventGroupClearBitsFromISR MPU_xEventGroupClearBitsFromISR + #define xEventGroupSetBitsFromISR MPU_xEventGroupSetBitsFromISR + #define xEventGroupGetBitsFromISR MPU_xEventGroupGetBitsFromISR + #endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ /* Map standard message/stream_buffer.h API functions to the MPU * equivalents. */ #define xStreamBufferSend MPU_xStreamBufferSend #define xStreamBufferReceive MPU_xStreamBufferReceive - #define xStreamBufferNextMessageLengthBytes MPU_xStreamBufferNextMessageLengthBytes - #define vStreamBufferDelete MPU_vStreamBufferDelete #define xStreamBufferIsFull MPU_xStreamBufferIsFull #define xStreamBufferIsEmpty MPU_xStreamBufferIsEmpty - #define xStreamBufferReset MPU_xStreamBufferReset #define xStreamBufferSpacesAvailable MPU_xStreamBufferSpacesAvailable #define xStreamBufferBytesAvailable MPU_xStreamBufferBytesAvailable #define xStreamBufferSetTriggerLevel MPU_xStreamBufferSetTriggerLevel - #define xStreamBufferGenericCreate MPU_xStreamBufferGenericCreate - #define xStreamBufferGenericCreateStatic MPU_xStreamBufferGenericCreateStatic + #define xStreamBufferNextMessageLengthBytes MPU_xStreamBufferNextMessageLengthBytes +/* Privileged only wrappers for Stream Buffer APIs. These are needed so that + * the application can use opaque handles maintained in mpu_wrappers.c + * with all the APIs. */ + + #define xStreamBufferGenericCreate MPU_xStreamBufferGenericCreate + #define xStreamBufferGenericCreateStatic MPU_xStreamBufferGenericCreateStatic + #define vStreamBufferDelete MPU_vStreamBufferDelete + #define xStreamBufferReset MPU_xStreamBufferReset + + #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + #define xStreamBufferGetStaticBuffers MPU_xStreamBufferGetStaticBuffers + #define xStreamBufferSendFromISR MPU_xStreamBufferSendFromISR + #define xStreamBufferReceiveFromISR MPU_xStreamBufferReceiveFromISR + #define xStreamBufferSendCompletedFromISR MPU_xStreamBufferSendCompletedFromISR + #define xStreamBufferReceiveCompletedFromISR MPU_xStreamBufferReceiveCompletedFromISR + #endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ /* Remove the privileged function macro, but keep the PRIVILEGED_DATA * macro so applications can place data in privileged access sections diff --git a/include/portable.h b/include/portable.h index 52d5434fe93..5734eb72037 100644 --- a/include/portable.h +++ b/include/portable.h @@ -110,13 +110,15 @@ StackType_t * pxEndOfStack, TaskFunction_t pxCode, void * pvParameters, - BaseType_t xRunPrivileged ) PRIVILEGED_FUNCTION; + BaseType_t xRunPrivileged, + xMPU_SETTINGS * xMPUSettings ) PRIVILEGED_FUNCTION; #else StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, TaskFunction_t pxCode, void * pvParameters, - BaseType_t xRunPrivileged ) PRIVILEGED_FUNCTION; - #endif + BaseType_t xRunPrivileged, + xMPU_SETTINGS * xMPUSettings ) PRIVILEGED_FUNCTION; + #endif /* if ( portHAS_STACK_OVERFLOW_CHECKING == 1 ) */ #else /* if ( portUSING_MPU_WRAPPERS == 1 ) */ #if ( portHAS_STACK_OVERFLOW_CHECKING == 1 ) StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, @@ -229,6 +231,22 @@ void vPortEndScheduler( void ) PRIVILEGED_FUNCTION; uint32_t ulStackDepth ) PRIVILEGED_FUNCTION; #endif +/** + * @brief Checks if the calling task is authorized to access the given buffer. + * + * @param pvBuffer The buffer which the calling task wants to access. + * @param ulBufferLength The length of the pvBuffer. + * @param ulAccessRequested The permissions that the calling task wants. + * + * @return pdTRUE if the calling task is authorized to access the buffer, + * pdFALSE otherwise. + */ +#if ( portUSING_MPU_WRAPPERS == 1 ) + BaseType_t xPortIsAuthorizedToAccessBuffer( const void * pvBuffer, + uint32_t ulBufferLength, + uint32_t ulAccessRequested ) PRIVILEGED_FUNCTION; +#endif + /* *INDENT-OFF* */ #ifdef __cplusplus } diff --git a/include/queue.h b/include/queue.h index 66c8286aef0..1c1b9822afd 100644 --- a/include/queue.h +++ b/include/queue.h @@ -1455,6 +1455,28 @@ BaseType_t xQueueIsQueueEmptyFromISR( const QueueHandle_t xQueue ) PRIVILEGED_FU BaseType_t xQueueIsQueueFullFromISR( const QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; UBaseType_t uxQueueMessagesWaitingFromISR( const QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; +/* + * The functions defined above are for passing data to and from tasks. The + * functions below are the equivalents for passing data to and from + * co-routines. + * + * These functions are called from the co-routine macro implementation and + * should not be called directly from application code. Instead use the macro + * wrappers defined within croutine.h. + */ +BaseType_t xQueueCRSendFromISR( QueueHandle_t xQueue, + const void * pvItemToQueue, + BaseType_t xCoRoutinePreviouslyWoken ); +BaseType_t xQueueCRReceiveFromISR( QueueHandle_t xQueue, + void * pvBuffer, + BaseType_t * pxTaskWoken ); +BaseType_t xQueueCRSend( QueueHandle_t xQueue, + const void * pvItemToQueue, + TickType_t xTicksToWait ); +BaseType_t xQueueCRReceive( QueueHandle_t xQueue, + void * pvBuffer, + TickType_t xTicksToWait ); + /* * For internal use only. Use xSemaphoreCreateMutex(), * xSemaphoreCreateCounting() or xSemaphoreGetMutexHolder() instead of calling @@ -1730,7 +1752,7 @@ void vQueueSetQueueNumber( QueueHandle_t xQueue, UBaseType_t uxQueueNumber ) PRIVILEGED_FUNCTION; UBaseType_t uxQueueGetQueueNumber( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; uint8_t ucQueueGetQueueType( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; - +UBaseType_t uxQueueGetQueueItemSize( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; /* *INDENT-OFF* */ #ifdef __cplusplus diff --git a/include/semphr.h b/include/semphr.h index 7977a01b84e..e93b708c51c 100644 --- a/include/semphr.h +++ b/include/semphr.h @@ -95,13 +95,13 @@ typedef QueueHandle_t SemaphoreHandle_t; */ #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) #define vSemaphoreCreateBinary( xSemaphore ) \ - { \ + do { \ ( xSemaphore ) = xQueueGenericCreate( ( UBaseType_t ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH, queueQUEUE_TYPE_BINARY_SEMAPHORE ); \ if( ( xSemaphore ) != NULL ) \ { \ ( void ) xSemaphoreGive( ( xSemaphore ) ); \ } \ - } + } while( 0 ) #endif /** @@ -1193,7 +1193,8 @@ typedef QueueHandle_t SemaphoreHandle_t; /** * semphr.h * @code{c} - * BaseType_t xSemaphoreGetStaticBuffer( SemaphoreHandle_t xSemaphore ); + * BaseType_t xSemaphoreGetStaticBuffer( SemaphoreHandle_t xSemaphore, + * StaticSemaphore_t ** ppxSemaphoreBuffer ); * @endcode * * Retrieve pointer to a statically created binary semaphore, counting semaphore, diff --git a/include/stack_macros.h b/include/stack_macros.h index 7ffc7b34338..7ead99ffd0f 100644 --- a/include/stack_macros.h +++ b/include/stack_macros.h @@ -57,13 +57,13 @@ /* Only the current stack state is to be checked. */ #define taskCHECK_FOR_STACK_OVERFLOW() \ - { \ + do { \ /* Is the currently saved stack pointer within the stack limit? */ \ if( pxCurrentTCB->pxTopOfStack <= pxCurrentTCB->pxStack + portSTACK_LIMIT_PADDING ) \ { \ vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \ } \ - } + } while( 0 ) #endif /* configCHECK_FOR_STACK_OVERFLOW == 1 */ /*-----------------------------------------------------------*/ @@ -72,14 +72,14 @@ /* Only the current stack state is to be checked. */ #define taskCHECK_FOR_STACK_OVERFLOW() \ - { \ + do { \ \ /* Is the currently saved stack pointer within the stack limit? */ \ if( pxCurrentTCB->pxTopOfStack >= pxCurrentTCB->pxEndOfStack - portSTACK_LIMIT_PADDING ) \ { \ vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \ } \ - } + } while( 0 ) #endif /* configCHECK_FOR_STACK_OVERFLOW == 1 */ /*-----------------------------------------------------------*/ @@ -106,7 +106,7 @@ #if ( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH > 0 ) ) #define taskCHECK_FOR_STACK_OVERFLOW() \ - { \ + do { \ int8_t * pcEndOfStack = ( int8_t * ) pxCurrentTCB->pxEndOfStack; \ static const uint8_t ucExpectedStackBytes[] = { tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ @@ -122,7 +122,7 @@ { \ vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \ } \ - } + } while( 0 ) #endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */ /*-----------------------------------------------------------*/ diff --git a/include/task.h b/include/task.h index 52d5d40602b..a7e1c795e31 100644 --- a/include/task.h +++ b/include/task.h @@ -66,6 +66,11 @@ #define tskMPU_REGION_NORMAL_MEMORY ( 1UL << 3UL ) #define tskMPU_REGION_DEVICE_MEMORY ( 1UL << 4UL ) +/* MPU region permissions stored in MPU settings to + * authorize access requests. */ +#define tskMPU_READ_PERMISSION ( 1UL << 0UL ) +#define tskMPU_WRITE_PERMISSION ( 1UL << 1UL ) + /* The direct to task notification feature used to have only a single notification * per task. Now there is an array of notifications per task that is dimensioned by * configTASK_NOTIFICATION_ARRAY_ENTRIES. For backward compatibility, any use of the @@ -3445,7 +3450,7 @@ void vTaskExitCritical( void ); * should be used in the implementation of portENTER_CRITICAL_FROM_ISR if port is * running a multiple core FreeRTOS. */ -portBASE_TYPE vTaskEnterCriticalFromISR( void ); +UBaseType_t vTaskEnterCriticalFromISR( void ); /* * This function is only intended for use when implementing a port of the scheduler @@ -3453,7 +3458,16 @@ portBASE_TYPE vTaskEnterCriticalFromISR( void ); * should be used in the implementation of portEXIT_CRITICAL_FROM_ISR if port is * running a multiple core FreeRTOS. */ -void vTaskExitCriticalFromISR( portBASE_TYPE xSavedInterruptStatus ); +void vTaskExitCriticalFromISR( UBaseType_t uxSavedInterruptStatus ); + +#if ( portUSING_MPU_WRAPPERS == 1 ) + +/* + * For internal use only. Get MPU settings associated with a task. + */ + xMPU_SETTINGS * xTaskGetMPUSettings( TaskHandle_t xTask ) PRIVILEGED_FUNCTION; + +#endif /* portUSING_MPU_WRAPPERS */ /* *INDENT-OFF* */ #ifdef __cplusplus diff --git a/portable/ARMv8M/copy_files.py b/portable/ARMv8M/copy_files.py index d064969809c..3609c67ef33 100644 --- a/portable/ARMv8M/copy_files.py +++ b/portable/ARMv8M/copy_files.py @@ -73,16 +73,22 @@ 'ARM_CM33' : [os.path.join('non_secure', 'portable', 'GCC', 'ARM_CM33')], 'ARM_CM33_NTZ' : [os.path.join('non_secure', 'portable', 'GCC', 'ARM_CM33_NTZ')], 'ARM_CM35P' : [os.path.join('non_secure', 'portable', 'GCC', 'ARM_CM33', 'portasm.c'), + os.path.join('non_secure', 'portable', 'GCC', 'ARM_CM33', 'mpu_wrappers_v2_asm.c'), os.path.join('non_secure', 'portable', 'GCC', 'ARM_CM35P', 'portmacro.h')], 'ARM_CM35P_NTZ' : [os.path.join('non_secure', 'portable', 'GCC', 'ARM_CM33_NTZ', 'portasm.c'), + os.path.join('non_secure', 'portable', 'GCC', 'ARM_CM33_NTZ', 'mpu_wrappers_v2_asm.c'), os.path.join('non_secure', 'portable', 'GCC', 'ARM_CM35P', 'portmacro.h')], 'ARM_CM55' : [os.path.join('non_secure', 'portable', 'GCC', 'ARM_CM33', 'portasm.c'), + os.path.join('non_secure', 'portable', 'GCC', 'ARM_CM33', 'mpu_wrappers_v2_asm.c'), os.path.join('non_secure', 'portable', 'GCC', 'ARM_CM55', 'portmacro.h')], 'ARM_CM55_NTZ' : [os.path.join('non_secure', 'portable', 'GCC', 'ARM_CM33_NTZ', 'portasm.c'), + os.path.join('non_secure', 'portable', 'GCC', 'ARM_CM33_NTZ', 'mpu_wrappers_v2_asm.c'), os.path.join('non_secure', 'portable', 'GCC', 'ARM_CM55', 'portmacro.h')], 'ARM_CM85' : [os.path.join('non_secure', 'portable', 'GCC', 'ARM_CM33', 'portasm.c'), + os.path.join('non_secure', 'portable', 'GCC', 'ARM_CM33', 'mpu_wrappers_v2_asm.c'), os.path.join('non_secure', 'portable', 'GCC', 'ARM_CM85', 'portmacro.h')], 'ARM_CM85_NTZ' : [os.path.join('non_secure', 'portable', 'GCC', 'ARM_CM33_NTZ', 'portasm.c'), + os.path.join('non_secure', 'portable', 'GCC', 'ARM_CM33_NTZ', 'mpu_wrappers_v2_asm.c'), os.path.join('non_secure', 'portable', 'GCC', 'ARM_CM85', 'portmacro.h')] }, 'IAR':{ @@ -91,16 +97,22 @@ 'ARM_CM33' : [os.path.join('non_secure', 'portable', 'IAR', 'ARM_CM33')], 'ARM_CM33_NTZ' : [os.path.join('non_secure', 'portable', 'IAR', 'ARM_CM33_NTZ')], 'ARM_CM35P' : [os.path.join('non_secure', 'portable', 'IAR', 'ARM_CM33', 'portasm.s'), + os.path.join('non_secure', 'portable', 'IAR', 'ARM_CM33', 'mpu_wrappers_v2_asm.S'), os.path.join('non_secure', 'portable', 'IAR', 'ARM_CM35P', 'portmacro.h')], 'ARM_CM35P_NTZ' : [os.path.join('non_secure', 'portable', 'IAR', 'ARM_CM33_NTZ', 'portasm.s'), + os.path.join('non_secure', 'portable', 'IAR', 'ARM_CM33_NTZ', 'mpu_wrappers_v2_asm.S'), os.path.join('non_secure', 'portable', 'IAR', 'ARM_CM35P', 'portmacro.h')], 'ARM_CM55' : [os.path.join('non_secure', 'portable', 'IAR', 'ARM_CM33', 'portasm.s'), + os.path.join('non_secure', 'portable', 'IAR', 'ARM_CM33', 'mpu_wrappers_v2_asm.S'), os.path.join('non_secure', 'portable', 'IAR', 'ARM_CM55', 'portmacro.h')], 'ARM_CM55_NTZ' : [os.path.join('non_secure', 'portable', 'IAR', 'ARM_CM33_NTZ', 'portasm.s'), + os.path.join('non_secure', 'portable', 'IAR', 'ARM_CM33_NTZ', 'mpu_wrappers_v2_asm.S'), os.path.join('non_secure', 'portable', 'IAR', 'ARM_CM55', 'portmacro.h')], 'ARM_CM85' : [os.path.join('non_secure', 'portable', 'IAR', 'ARM_CM33', 'portasm.s'), + os.path.join('non_secure', 'portable', 'IAR', 'ARM_CM33', 'mpu_wrappers_v2_asm.S'), os.path.join('non_secure', 'portable', 'IAR', 'ARM_CM85', 'portmacro.h')], 'ARM_CM85_NTZ' : [os.path.join('non_secure', 'portable', 'IAR', 'ARM_CM33_NTZ', 'portasm.s'), + os.path.join('non_secure', 'portable', 'IAR', 'ARM_CM33_NTZ', 'mpu_wrappers_v2_asm.S'), os.path.join('non_secure', 'portable', 'IAR', 'ARM_CM85', 'portmacro.h')] }, } diff --git a/portable/ARMv8M/non_secure/port.c b/portable/ARMv8M/non_secure/port.c index 7bbe1b7bc53..cab1b3668bf 100644 --- a/portable/ARMv8M/non_secure/port.c +++ b/portable/ARMv8M/non_secure/port.c @@ -107,6 +107,13 @@ #define portPRIGROUP_SHIFT ( 8UL ) /*-----------------------------------------------------------*/ +/** + * @brief Constants used during system call enter and exit. + */ +#define portPSR_STACK_PADDING_MASK ( 1UL << 9UL ) +#define portEXC_RETURN_STACK_FRAME_TYPE_MASK ( 1UL << 4UL ) +/*-----------------------------------------------------------*/ + /** * @brief Constants required to manipulate the FPU. */ @@ -123,6 +130,14 @@ #define portFPCCR_LSPEN_MASK ( 1UL << portFPCCR_LSPEN_POS ) /*-----------------------------------------------------------*/ +/** + * @brief Offsets in the stack to the parameters when inside the SVC handler. + */ +#define portOFFSET_TO_LR ( 5 ) +#define portOFFSET_TO_PC ( 6 ) +#define portOFFSET_TO_PSR ( 7 ) +/*-----------------------------------------------------------*/ + /** * @brief Constants required to manipulate the MPU. */ @@ -148,6 +163,8 @@ #define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ #define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ +#define portMPU_RBAR_ACCESS_PERMISSIONS_MASK ( 3UL << 1UL ) + #define portMPU_MAIR_ATTR0_POS ( 0UL ) #define portMPU_MAIR_ATTR0_MASK ( 0x000000ff ) @@ -191,6 +208,30 @@ /* Expected value of the portMPU_TYPE register. */ #define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) + +/* Extract first address of the MPU region as encoded in the + * RBAR (Region Base Address Register) value. */ +#define portEXTRACT_FIRST_ADDRESS_FROM_RBAR( rbar ) \ + ( ( rbar ) & portMPU_RBAR_ADDRESS_MASK ) + +/* Extract last address of the MPU region as encoded in the + * RLAR (Region Limit Address Register) value. */ +#define portEXTRACT_LAST_ADDRESS_FROM_RLAR( rlar ) \ + ( ( ( rlar ) & portMPU_RLAR_ADDRESS_MASK ) | ~portMPU_RLAR_ADDRESS_MASK ) + +/* Does addr lies within [start, end] address range? */ +#define portIS_ADDRESS_WITHIN_RANGE( addr, start, end ) \ + ( ( ( addr ) >= ( start ) ) && ( ( addr ) <= ( end ) ) ) + +/* Is the access request satisfied by the available permissions? */ +#define portIS_AUTHORIZED( accessRequest, permissions ) \ + ( ( ( permissions ) & ( accessRequest ) ) == accessRequest ) + +/* 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 ) ) ) /*-----------------------------------------------------------*/ /** @@ -311,6 +352,19 @@ static void prvTaskExitError( void ); #if ( configENABLE_MPU == 1 ) +/** + * @brief Extract MPU region's access permissions from the Region Base Address + * Register (RBAR) value. + * + * @param ulRBARValue RBAR value for the MPU region. + * + * @return uint32_t Access permissions. + */ + static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) PRIVILEGED_FUNCTION; +#endif /* configENABLE_MPU */ + +#if ( configENABLE_MPU == 1 ) + /** * @brief Setup the Memory Protection Unit (MPU). */ @@ -365,6 +419,60 @@ void SysTick_Handler( void ) PRIVILEGED_FUNCTION; * @brief C part of SVC handler. */ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIVILEGED_FUNCTION; + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + + /** + * @brief Sets up the system call stack so that upon returning from + * SVC, the system call stack is used. + * + * It is used for the system calls with up to 4 parameters. + * + * @param pulTaskStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + */ + void vSystemCallEnter( uint32_t * pulTaskStack, uint32_t ulLR ) PRIVILEGED_FUNCTION; + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + + /** + * @brief Sets up the system call stack so that upon returning from + * SVC, the system call stack is used. + * + * It is used for the system calls with 5 parameters. + * + * @param pulTaskStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + */ + void vSystemCallEnter_1( uint32_t * pulTaskStack, uint32_t ulLR ) PRIVILEGED_FUNCTION; + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + + /** + * @brief Sets up the task stack so that upon returning from + * SVC, the task stack is used again. + * + * @param pulSystemCallStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + */ + void vSystemCallExit( uint32_t * pulSystemCallStack, uint32_t ulLR ) PRIVILEGED_FUNCTION; + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + +#if ( configENABLE_MPU == 1 ) + + /** + * @brief Checks whether or not the calling task is privileged. + * + * @return pdTRUE if the calling task is privileged, pdFALSE otherwise. + */ + BaseType_t xPortIsTaskPrivileged( void ) PRIVILEGED_FUNCTION; + +#endif /* configENABLE_MPU == 1 */ /*-----------------------------------------------------------*/ /** @@ -681,6 +789,26 @@ static void prvTaskExitError( void ) } /*-----------------------------------------------------------*/ +#if ( configENABLE_MPU == 1 ) + static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) /* PRIVILEGED_FUNCTION */ + { + uint32_t ulAccessPermissions = 0; + + if( ( ulRBARValue & portMPU_RBAR_ACCESS_PERMISSIONS_MASK ) == portMPU_REGION_READ_ONLY ) + { + ulAccessPermissions = tskMPU_READ_PERMISSION; + } + + if( ( ulRBARValue & portMPU_RBAR_ACCESS_PERMISSIONS_MASK ) == portMPU_REGION_READ_WRITE ) + { + ulAccessPermissions = ( tskMPU_READ_PERMISSION | tskMPU_WRITE_PERMISSION ); + } + + return ulAccessPermissions; + } +#endif /* configENABLE_MPU */ +/*-----------------------------------------------------------*/ + #if ( configENABLE_MPU == 1 ) static void prvSetupMPU( void ) /* PRIVILEGED_FUNCTION */ { @@ -853,7 +981,7 @@ void SysTick_Handler( void ) /* PRIVILEGED_FUNCTION */ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTION portDONT_DISCARD */ { - #if ( configENABLE_MPU == 1 ) + #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) ) #if defined( __ARMCC_VERSION ) /* Declaration when these variable are defined in code instead of being @@ -865,7 +993,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO extern uint32_t __syscalls_flash_start__[]; extern uint32_t __syscalls_flash_end__[]; #endif /* defined( __ARMCC_VERSION ) */ - #endif /* configENABLE_MPU */ + #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */ uint32_t ulPC; @@ -880,7 +1008,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO /* Register are stored on the stack in the following order - R0, R1, R2, R3, * R12, LR, PC, xPSR. */ - ulPC = pulCallerStackAddress[ 6 ]; + ulPC = pulCallerStackAddress[ portOFFSET_TO_PC ]; ucSVCNumber = ( ( uint8_t * ) ulPC )[ -2 ]; switch( ucSVCNumber ) @@ -951,18 +1079,18 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO vRestoreContextOfFirstTask(); break; - #if ( configENABLE_MPU == 1 ) - case portSVC_RAISE_PRIVILEGE: + #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) ) + case portSVC_RAISE_PRIVILEGE: - /* Only raise the privilege, if the svc was raised from any of - * the system calls. */ - if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) && - ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ) - { - vRaisePrivilege(); - } - break; - #endif /* configENABLE_MPU */ + /* Only raise the privilege, if the svc was raised from any of + * the system calls. */ + if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ) + { + vRaisePrivilege(); + } + break; + #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */ default: /* Incorrect SVC call. */ @@ -971,51 +1099,455 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } /*-----------------------------------------------------------*/ -/* *INDENT-OFF* */ -#if ( configENABLE_MPU == 1 ) - StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, - StackType_t * pxEndOfStack, - TaskFunction_t pxCode, - void * pvParameters, - BaseType_t xRunPrivileged ) /* PRIVILEGED_FUNCTION */ -#else - StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, - StackType_t * pxEndOfStack, - TaskFunction_t pxCode, - void * pvParameters ) /* PRIVILEGED_FUNCTION */ -#endif /* configENABLE_MPU */ -/* *INDENT-ON* */ +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + +void vSystemCallEnter( uint32_t * pulTaskStack, uint32_t ulLR ) /* PRIVILEGED_FUNCTION */ { - /* Simulate the stack frame as it would be created by a context switch - * interrupt. */ - #if ( portPRELOAD_REGISTERS == 0 ) + extern TaskHandle_t pxCurrentTCB; + xMPU_SETTINGS * pxMpuSettings; + uint32_t * pulSystemCallStack; + uint32_t ulStackFrameSize, ulSystemCallLocation, i; + #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being + * exported from linker scripts. */ + extern uint32_t * __syscalls_flash_start__; + extern uint32_t * __syscalls_flash_end__; + #else + /* Declaration when these variable are exported from linker scripts. */ + extern uint32_t __syscalls_flash_start__[]; + extern uint32_t __syscalls_flash_end__[]; + #endif /* #if defined( __ARMCC_VERSION ) */ + + ulSystemCallLocation = pulTaskStack[ portOFFSET_TO_PC ]; + + /* If the request did not come from the system call section, do nothing. */ + if( ( ulSystemCallLocation >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulSystemCallLocation <= ( uint32_t ) __syscalls_flash_end__ ) ) { - pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ - *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ - pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pxCode; /* PC */ - pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR */ - pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ - *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ - pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */ - *pxTopOfStack = portINITIAL_EXC_RETURN; + pxMpuSettings = xTaskGetMPUSettings( pxCurrentTCB ); + pulSystemCallStack = pxMpuSettings->xSystemCallStackInfo.pulSystemCallStack; - #if ( configENABLE_MPU == 1 ) + /* This is not NULL only for the duration of the system call. */ + configASSERT( pxMpuSettings->xSystemCallStackInfo.pulTaskStack == NULL ); + + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) { - pxTopOfStack--; + if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) + { + /* Extended frame i.e. FPU in use. */ + ulStackFrameSize = 26; + __asm volatile ( + " vpush {s0} \n" /* Trigger lazy stacking. */ + " vpop {s0} \n" /* Nullify the affect of the above instruction. */ + ::: "memory" + ); + } + else + { + /* Standard frame i.e. FPU not in use. */ + ulStackFrameSize = 8; + } + } + #else + { + ulStackFrameSize = 8; + } + #endif /* configENABLE_FPU || configENABLE_MVE */ + + /* Make space on the system call stack for the stack frame. */ + pulSystemCallStack = pulSystemCallStack - ulStackFrameSize; + + /* Copy the stack frame. */ + for( i = 0; i < ulStackFrameSize; i++ ) + { + pulSystemCallStack[ i ] = pulTaskStack[ i ]; + } + + /* Store the value of the LR and PSPLIM registers before the SVC was raised. We need to + * restore it when we exit from the system call. */ + pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; + __asm volatile ( "mrs %0, psplim" : "=r" ( pxMpuSettings->xSystemCallStackInfo.ulStackLimitRegisterAtSystemCallEntry ) ); + + /* Use the pulSystemCallStack in thread mode. */ + __asm volatile ( "msr psp, %0" : : "r" ( pulSystemCallStack ) ); + __asm volatile ( "msr psplim, %0" : : "r" ( pxMpuSettings->xSystemCallStackInfo.pulSystemCallStackLimit ) ); + + /* Remember the location where we should copy the stack frame when we exit from + * the system call. */ + pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulStackFrameSize; + + /* Record if the hardware used padding to force the stack pointer + * to be double word aligned. */ + if( ( pulTaskStack[ portOFFSET_TO_PSR ] & portPSR_STACK_PADDING_MASK ) == portPSR_STACK_PADDING_MASK ) + { + pxMpuSettings->ulTaskFlags |= portSTACK_FRAME_HAS_PADDING_FLAG; + } + else + { + pxMpuSettings->ulTaskFlags &= ( ~portSTACK_FRAME_HAS_PADDING_FLAG ); + } + + /* We ensure in pxPortInitialiseStack that the system call stack is + * double word aligned and therefore, there is no need of padding. + * Clear the bit[9] of stacked xPSR. */ + pulSystemCallStack[ portOFFSET_TO_PSR ] &= ( ~portPSR_STACK_PADDING_MASK ); + + /* Raise the privilege for the duration of the system call. */ + __asm volatile ( + " mrs r0, control \n" /* Obtain current control value. */ + " movs r1, #1 \n" /* r1 = 1. */ + " bics r0, r1 \n" /* Clear nPRIV bit. */ + " msr control, r0 \n" /* Write back new control value. */ + ::: "r0", "r1", "memory" + ); + } +} - if( xRunPrivileged == pdTRUE ) +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + +void vSystemCallEnter_1( uint32_t * pulTaskStack, uint32_t ulLR ) /* PRIVILEGED_FUNCTION */ +{ + extern TaskHandle_t pxCurrentTCB; + xMPU_SETTINGS * pxMpuSettings; + uint32_t * pulSystemCallStack; + uint32_t ulStackFrameSize, ulSystemCallLocation, i; + #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being + * exported from linker scripts. */ + extern uint32_t * __syscalls_flash_start__; + extern uint32_t * __syscalls_flash_end__; + #else + /* Declaration when these variable are exported from linker scripts. */ + extern uint32_t __syscalls_flash_start__[]; + extern uint32_t __syscalls_flash_end__[]; + #endif /* #if defined( __ARMCC_VERSION ) */ + + ulSystemCallLocation = pulTaskStack[ portOFFSET_TO_PC ]; + + /* If the request did not come from the system call section, do nothing. */ + if( ( ulSystemCallLocation >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulSystemCallLocation <= ( uint32_t ) __syscalls_flash_end__ ) ) + { + pxMpuSettings = xTaskGetMPUSettings( pxCurrentTCB ); + pulSystemCallStack = pxMpuSettings->xSystemCallStackInfo.pulSystemCallStack; + + /* This is not NULL only for the duration of the system call. */ + configASSERT( pxMpuSettings->xSystemCallStackInfo.pulTaskStack == NULL ); + + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + { + if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) { - *pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */ + /* Extended frame i.e. FPU in use. */ + ulStackFrameSize = 26; + __asm volatile ( + " vpush {s0} \n" /* Trigger lazy stacking. */ + " vpop {s0} \n" /* Nullify the affect of the above instruction. */ + ::: "memory" + ); } else { - *pxTopOfStack = portINITIAL_CONTROL_UNPRIVILEGED; /* Slot used to hold this task's CONTROL value. */ + /* Standard frame i.e. FPU not in use. */ + ulStackFrameSize = 8; } } - #endif /* configENABLE_MPU */ + #else + { + ulStackFrameSize = 8; + } + #endif /* configENABLE_FPU || configENABLE_MVE */ + + /* Make space on the system call stack for the stack frame and + * the parameter passed on the stack. We only need to copy one + * parameter but we still reserve 2 spaces to keep the stack + * double word aligned. */ + pulSystemCallStack = pulSystemCallStack - ulStackFrameSize - 2UL; + + /* Copy the stack frame. */ + for( i = 0; i < ulStackFrameSize; i++ ) + { + pulSystemCallStack[ i ] = pulTaskStack[ i ]; + } + + /* Copy the parameter which is passed the stack. */ + if( ( pulTaskStack[ portOFFSET_TO_PSR ] & portPSR_STACK_PADDING_MASK ) == portPSR_STACK_PADDING_MASK ) + { + pulSystemCallStack[ ulStackFrameSize ] = pulTaskStack[ ulStackFrameSize + 1 ]; + /* Record if the hardware used padding to force the stack pointer + * to be double word aligned. */ + pxMpuSettings->ulTaskFlags |= portSTACK_FRAME_HAS_PADDING_FLAG; + } + else + { + pulSystemCallStack[ ulStackFrameSize ] = pulTaskStack[ ulStackFrameSize ]; + /* Record if the hardware used padding to force the stack pointer + * to be double word aligned. */ + pxMpuSettings->ulTaskFlags &= ( ~portSTACK_FRAME_HAS_PADDING_FLAG ); + } + + /* Store the value of the LR and PSPLIM registers before the SVC was raised. + * We need to restore it when we exit from the system call. */ + pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; + __asm volatile ( "mrs %0, psplim" : "=r" ( pxMpuSettings->xSystemCallStackInfo.ulStackLimitRegisterAtSystemCallEntry ) ); + + /* Use the pulSystemCallStack in thread mode. */ + __asm volatile ( "msr psp, %0" : : "r" ( pulSystemCallStack ) ); + __asm volatile ( "msr psplim, %0" : : "r" ( pxMpuSettings->xSystemCallStackInfo.pulSystemCallStackLimit ) ); + + /* Remember the location where we should copy the stack frame when we exit from + * the system call. */ + pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulStackFrameSize; + + /* We ensure in pxPortInitialiseStack that the system call stack is + * double word aligned and therefore, there is no need of padding. + * Clear the bit[9] of stacked xPSR. */ + pulSystemCallStack[ portOFFSET_TO_PSR ] &= ( ~portPSR_STACK_PADDING_MASK ); + + /* Raise the privilege for the duration of the system call. */ + __asm volatile ( + " mrs r0, control \n" /* Obtain current control value. */ + " movs r1, #1 \n" /* r1 = 1. */ + " bics r0, r1 \n" /* Clear nPRIV bit. */ + " msr control, r0 \n" /* Write back new control value. */ + ::: "r0", "r1", "memory" + ); + } +} + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) +void vSystemCallExit( uint32_t * pulSystemCallStack, uint32_t ulLR ) /* PRIVILEGED_FUNCTION */ +{ + extern TaskHandle_t pxCurrentTCB; + xMPU_SETTINGS * pxMpuSettings; + uint32_t * pulTaskStack; + uint32_t ulStackFrameSize, ulSystemCallLocation, i; + #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being + * exported from linker scripts. */ + extern uint32_t * __syscalls_flash_start__; + extern uint32_t * __syscalls_flash_end__; + #else + /* Declaration when these variable are exported from linker scripts. */ + extern uint32_t __syscalls_flash_start__[]; + extern uint32_t __syscalls_flash_end__[]; + #endif /* #if defined( __ARMCC_VERSION ) */ + + ulSystemCallLocation = pulSystemCallStack[ portOFFSET_TO_PC ]; + + /* If the request did not come from the system call section, do nothing. */ + if( ( ulSystemCallLocation >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulSystemCallLocation <= ( uint32_t ) __syscalls_flash_end__ ) ) + { + pxMpuSettings = xTaskGetMPUSettings( pxCurrentTCB ); + pulTaskStack = pxMpuSettings->xSystemCallStackInfo.pulTaskStack; + + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + { + if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) + { + /* Extended frame i.e. FPU in use. */ + ulStackFrameSize = 26; + __asm volatile ( + " vpush {s0} \n" /* Trigger lazy stacking. */ + " vpop {s0} \n" /* Nullify the affect of the above instruction. */ + ::: "memory" + ); + } + else + { + /* Standard frame i.e. FPU not in use. */ + ulStackFrameSize = 8; + } + } + #else + { + ulStackFrameSize = 8; + } + #endif /* configENABLE_FPU || configENABLE_MVE */ + + /* Make space on the task stack for the stack frame. */ + pulTaskStack = pulTaskStack - ulStackFrameSize; + + /* Copy the stack frame. */ + for( i = 0; i < ulStackFrameSize; i++ ) + { + pulTaskStack[ i ] = pulSystemCallStack[ i ]; + } + + /* Use the pulTaskStack in thread mode. */ + __asm volatile ( "msr psp, %0" : : "r" ( pulTaskStack ) ); + + /* Restore the LR and PSPLIM to what they were at the time of + * system call entry. */ + pulTaskStack[ portOFFSET_TO_LR ] = pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry; + __asm volatile ( "msr psplim, %0" : : "r" ( pxMpuSettings->xSystemCallStackInfo.ulStackLimitRegisterAtSystemCallEntry ) ); + + /* If the hardware used padding to force the stack pointer + * to be double word aligned, set the stacked xPSR bit[9], + * otherwise clear it. */ + if( ( pxMpuSettings->ulTaskFlags & portSTACK_FRAME_HAS_PADDING_FLAG ) == portSTACK_FRAME_HAS_PADDING_FLAG ) + { + pulTaskStack[ portOFFSET_TO_PSR ] |= portPSR_STACK_PADDING_MASK; + } + else + { + pulTaskStack[ portOFFSET_TO_PSR ] &= ( ~portPSR_STACK_PADDING_MASK ); + } + + /* This is not NULL only for the duration of the system call. */ + pxMpuSettings->xSystemCallStackInfo.pulTaskStack = NULL; + + /* Drop the privilege before returning to the thread mode. */ + __asm volatile ( + " mrs r0, control \n" /* Obtain current control value. */ + " movs r1, #1 \n" /* r1 = 1. */ + " orrs r0, r1 \n" /* Set nPRIV bit. */ + " msr control, r0 \n" /* Write back new control value. */ + ::: "r0", "r1", "memory" + ); + } +} + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configENABLE_MPU == 1 ) + +BaseType_t xPortIsTaskPrivileged( void ) /* PRIVILEGED_FUNCTION */ +{ + BaseType_t xTaskIsPrivileged = pdFALSE; + const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */ + + if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) + { + xTaskIsPrivileged = pdTRUE; + } + + return xTaskIsPrivileged; +} + +#endif /* configENABLE_MPU == 1 */ +/*-----------------------------------------------------------*/ + +#if( configENABLE_MPU == 1 ) + +StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, + StackType_t * pxEndOfStack, + TaskFunction_t pxCode, + void * pvParameters, + BaseType_t xRunPrivileged, + xMPU_SETTINGS * xMPUSettings ) /* PRIVILEGED_FUNCTION */ +{ + uint32_t ulIndex = 0; + + xMPUSettings->ulContext[ ulIndex ] = 0x04040404; /* r4. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x05050505; /* r5. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x06060606; /* r6. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x07070707; /* r7. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x08080808; /* r8. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x09090909; /* r9. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x10101010; /* r10. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x11111111; /* r11. */ + ulIndex++; + + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pvParameters; /* r0. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x01010101; /* r1. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x02020202; /* r2. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x03030303; /* r3. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x12121212; /* r12. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portTASK_RETURN_ADDRESS; /* LR. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxCode; /* PC. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = portINITIAL_XPSR; /* xPSR. */ + ulIndex++; + + #if ( configENABLE_TRUSTZONE == 1 ) + { + xMPUSettings->ulContext[ ulIndex ] = portNO_SECURE_CONTEXT; /* xSecureContext. */ + ulIndex++; + } + #endif /* configENABLE_TRUSTZONE */ + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) ( pxTopOfStack - 8 ); /* PSP with the hardware saved stack. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */ + ulIndex++; + if( xRunPrivileged == pdTRUE ) + { + xMPUSettings->ulTaskFlags |= portTASK_IS_PRIVILEGED_FLAG; + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_PRIVILEGED; /* CONTROL. */ + ulIndex++; + } + else + { + xMPUSettings->ulTaskFlags &= ( ~portTASK_IS_PRIVILEGED_FLAG ); + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_UNPRIVILEGED; /* CONTROL. */ + ulIndex++; + } + xMPUSettings->ulContext[ ulIndex ] = portINITIAL_EXC_RETURN; /* LR (EXC_RETURN). */ + ulIndex++; + + #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + { + /* Ensure that the system call stack is double word aligned. */ + xMPUSettings->xSystemCallStackInfo.pulSystemCallStack = &( xMPUSettings->xSystemCallStackInfo.ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE - 1 ] ); + xMPUSettings->xSystemCallStackInfo.pulSystemCallStack = ( uint32_t * ) ( ( uint32_t ) ( xMPUSettings->xSystemCallStackInfo.pulSystemCallStack ) & + ( uint32_t ) ( ~( portBYTE_ALIGNMENT_MASK ) ) ); + + xMPUSettings->xSystemCallStackInfo.pulSystemCallStackLimit = &( xMPUSettings->xSystemCallStackInfo.ulSystemCallStackBuffer[ 0 ] ); + xMPUSettings->xSystemCallStackInfo.pulSystemCallStackLimit = ( uint32_t * ) ( ( ( uint32_t ) ( xMPUSettings->xSystemCallStackInfo.pulSystemCallStackLimit ) + + ( uint32_t ) ( portBYTE_ALIGNMENT - 1 ) ) & + ( uint32_t ) ( ~( portBYTE_ALIGNMENT_MASK ) ) ); + + /* This is not NULL only for the duration of a system call. */ + xMPUSettings->xSystemCallStackInfo.pulTaskStack = NULL; + } + #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + + return &( xMPUSettings->ulContext[ ulIndex ] ); +} + +#else /* configENABLE_MPU */ + +StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, + StackType_t * pxEndOfStack, + TaskFunction_t pxCode, + void * pvParameters ) /* PRIVILEGED_FUNCTION */ +{ + /* Simulate the stack frame as it would be created by a context switch + * interrupt. */ + #if ( portPRELOAD_REGISTERS == 0 ) + { + pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ + *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR. */ + pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ + pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */ + *pxTopOfStack = portINITIAL_EXC_RETURN; pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ @@ -1029,55 +1561,39 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO #else /* portPRELOAD_REGISTERS */ { pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ - *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ + *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pxCode; /* PC */ + *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR */ + *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x12121212UL; /* R12 */ + *pxTopOfStack = ( StackType_t ) 0x12121212UL; /* R12. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x03030303UL; /* R3 */ + *pxTopOfStack = ( StackType_t ) 0x03030303UL; /* R3. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x02020202UL; /* R2 */ + *pxTopOfStack = ( StackType_t ) 0x02020202UL; /* R2. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x01010101UL; /* R1 */ + *pxTopOfStack = ( StackType_t ) 0x01010101UL; /* R1. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x11111111UL; /* R11 */ + *pxTopOfStack = ( StackType_t ) 0x11111111UL; /* R11. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x10101010UL; /* R10 */ + *pxTopOfStack = ( StackType_t ) 0x10101010UL; /* R10. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x09090909UL; /* R09 */ + *pxTopOfStack = ( StackType_t ) 0x09090909UL; /* R09. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x08080808UL; /* R08 */ + *pxTopOfStack = ( StackType_t ) 0x08080808UL; /* R08. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x07070707UL; /* R07 */ + *pxTopOfStack = ( StackType_t ) 0x07070707UL; /* R07. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x06060606UL; /* R06 */ + *pxTopOfStack = ( StackType_t ) 0x06060606UL; /* R06. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x05050505UL; /* R05 */ + *pxTopOfStack = ( StackType_t ) 0x05050505UL; /* R05. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x04040404UL; /* R04 */ + *pxTopOfStack = ( StackType_t ) 0x04040404UL; /* R04. */ pxTopOfStack--; - *pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN */ - - #if ( configENABLE_MPU == 1 ) - { - pxTopOfStack--; - - if( xRunPrivileged == pdTRUE ) - { - *pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */ - } - else - { - *pxTopOfStack = portINITIAL_CONTROL_UNPRIVILEGED; /* Slot used to hold this task's CONTROL value. */ - } - } - #endif /* configENABLE_MPU */ - + *pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN. */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ @@ -1092,6 +1608,8 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO return pxTopOfStack; } + +#endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ @@ -1128,6 +1646,10 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ configASSERT( ucMaxSysCallPriority ); + /* Check that the bits not implemented in hardware are zero in + * configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & ( ~ucMaxPriorityValue ) ) == 0U ); + /* Calculate the maximum acceptable priority group value for the number * of bits read back. */ @@ -1164,35 +1686,6 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulImplementedPrioBits; } - /* The interrupt priority bits are not modelled in QEMU and the assert that - * checks the number of implemented bits and __NVIC_PRIO_BITS will always fail. - * Therefore, this assert is not adding any value for QEMU targets. The config - * option `configDISABLE_INTERRUPT_PRIO_BITS_CHECK` should be defined in the - * `FreeRTOSConfig.h` for QEMU targets. */ - #ifndef configDISABLE_INTERRUPT_PRIO_BITS_CHECK - { - #ifdef __NVIC_PRIO_BITS - { - /* - * Check that the number of implemented priority bits queried from - * hardware is equal to the CMSIS __NVIC_PRIO_BITS configuration macro. - */ - configASSERT( ulImplementedPrioBits == __NVIC_PRIO_BITS ); - } - #endif /* __NVIC_PRIO_BITS */ - - #ifdef configPRIO_BITS - { - /* - * Check that the number of implemented priority bits queried from - * hardware is equal to the FreeRTOS configPRIO_BITS configuration macro. - */ - configASSERT( ulImplementedPrioBits == configPRIO_BITS ); - } - #endif /* configPRIO_BITS */ - } - #endif /* #ifndef configDISABLE_INTERRUPT_PRIO_BITS_CHECK */ - /* Shift the priority group value back to its position within the AIRCR * register. */ ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT; @@ -1372,6 +1865,54 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ +#if ( configENABLE_MPU == 1 ) + BaseType_t xPortIsAuthorizedToAccessBuffer( const void * pvBuffer, + uint32_t ulBufferLength, + uint32_t ulAccessRequested ) /* PRIVILEGED_FUNCTION */ + + { + uint32_t i, ulBufferStartAddress, ulBufferEndAddress; + BaseType_t xAccessGranted = pdFALSE; + const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */ + + if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) + { + xAccessGranted = pdTRUE; + } + else + { + if( portADD_UINT32_WILL_OVERFLOW( ( ( uint32_t ) pvBuffer ), ( ulBufferLength - 1UL ) ) == pdFALSE ) + { + ulBufferStartAddress = ( uint32_t ) pvBuffer; + ulBufferEndAddress = ( ( ( uint32_t ) pvBuffer ) + ulBufferLength - 1UL ); + + for( i = 0; i < portTOTAL_NUM_REGIONS; i++ ) + { + /* Is the MPU region enabled? */ + if( ( xTaskMpuSettings->xRegionsSettings[ i ].ulRLAR & portMPU_RLAR_REGION_ENABLE ) == portMPU_RLAR_REGION_ENABLE ) + { + if( portIS_ADDRESS_WITHIN_RANGE( ulBufferStartAddress, + portEXTRACT_FIRST_ADDRESS_FROM_RBAR( xTaskMpuSettings->xRegionsSettings[ i ].ulRBAR ), + portEXTRACT_LAST_ADDRESS_FROM_RLAR( xTaskMpuSettings->xRegionsSettings[ i ].ulRLAR ) ) && + portIS_ADDRESS_WITHIN_RANGE( ulBufferEndAddress, + portEXTRACT_FIRST_ADDRESS_FROM_RBAR( xTaskMpuSettings->xRegionsSettings[ i ].ulRBAR ), + portEXTRACT_LAST_ADDRESS_FROM_RLAR( xTaskMpuSettings->xRegionsSettings[ i ].ulRLAR ) ) && + portIS_AUTHORIZED( ulAccessRequested, + prvGetRegionAccessPermissions( xTaskMpuSettings->xRegionsSettings[ i ].ulRBAR ) ) ) + { + xAccessGranted = pdTRUE; + break; + } + } + } + } + } + + return xAccessGranted; + } +#endif /* configENABLE_MPU */ +/*-----------------------------------------------------------*/ + BaseType_t xPortIsInsideInterrupt( void ) { uint32_t ulCurrentInterrupt; diff --git a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM23/mpu_wrappers_v2_asm.c b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM23/mpu_wrappers_v2_asm.c new file mode 100644 index 00000000000..a1e5ce0828f --- /dev/null +++ b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM23/mpu_wrappers_v2_asm.c @@ -0,0 +1,2419 @@ +/* + * FreeRTOS Kernel + * Copyright (C) 2021 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 + * + */ + +/* 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. */ +#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +/* Scheduler includes. */ +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" +#include "timers.h" +#include "event_groups.h" +#include "stream_buffer.h" + +#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + +#if ( INCLUDE_xTaskDelayUntil == 1 ) + +BaseType_t MPU_xTaskDelayUntil( TickType_t * const pxPreviousWakeTime, + const TickType_t xTimeIncrement ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskDelayUntil( TickType_t * const pxPreviousWakeTime, + const TickType_t xTimeIncrement ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskDelayUntilImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xTaskDelayUntil_Unpriv \n" + " MPU_xTaskDelayUntil_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xTaskDelayUntilImpl \n" + " MPU_xTaskDelayUntil_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xTaskDelayUntilImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_xTaskDelayUntil == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_xTaskAbortDelay == 1 ) + +BaseType_t MPU_xTaskAbortDelay( TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskAbortDelay( TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskAbortDelayImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xTaskAbortDelay_Unpriv \n" + " MPU_xTaskAbortDelay_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xTaskAbortDelayImpl \n" + " MPU_xTaskAbortDelay_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xTaskAbortDelayImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_xTaskAbortDelay == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskDelay == 1 ) + +void MPU_vTaskDelay( const TickType_t xTicksToDelay ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskDelay( const TickType_t xTicksToDelay ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskDelayImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_vTaskDelay_Unpriv \n" + " MPU_vTaskDelay_Priv: \n" + " pop {r0, r1} \n" + " b MPU_vTaskDelayImpl \n" + " MPU_vTaskDelay_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_vTaskDelayImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_vTaskDelay == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_uxTaskPriorityGet == 1 ) + +UBaseType_t MPU_uxTaskPriorityGet( const TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxTaskPriorityGet( const TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxTaskPriorityGetImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_uxTaskPriorityGet_Unpriv \n" + " MPU_uxTaskPriorityGet_Priv: \n" + " pop {r0, r1} \n" + " b MPU_uxTaskPriorityGetImpl \n" + " MPU_uxTaskPriorityGet_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_uxTaskPriorityGetImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_uxTaskPriorityGet == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_eTaskGetState == 1 ) + +eTaskState MPU_eTaskGetState( TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +eTaskState MPU_eTaskGetState( TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_eTaskGetStateImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_eTaskGetState_Unpriv \n" + " MPU_eTaskGetState_Priv: \n" + " pop {r0, r1} \n" + " b MPU_eTaskGetStateImpl \n" + " MPU_eTaskGetState_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_eTaskGetStateImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_eTaskGetState == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + +void MPU_vTaskGetInfo( TaskHandle_t xTask, + TaskStatus_t * pxTaskStatus, + BaseType_t xGetFreeStackSpace, + eTaskState eState ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskGetInfo( TaskHandle_t xTask, + TaskStatus_t * pxTaskStatus, + BaseType_t xGetFreeStackSpace, + eTaskState eState ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskGetInfoImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_vTaskGetInfo_Unpriv \n" + " MPU_vTaskGetInfo_Priv: \n" + " pop {r0, r1} \n" + " b MPU_vTaskGetInfoImpl \n" + " MPU_vTaskGetInfo_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_vTaskGetInfoImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TRACE_FACILITY == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) + +TaskHandle_t MPU_xTaskGetIdleTaskHandle( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TaskHandle_t MPU_xTaskGetIdleTaskHandle( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGetIdleTaskHandleImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xTaskGetIdleTaskHandle_Unpriv \n" + " MPU_xTaskGetIdleTaskHandle_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xTaskGetIdleTaskHandleImpl \n" + " MPU_xTaskGetIdleTaskHandle_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xTaskGetIdleTaskHandleImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskSuspend == 1 ) + +void MPU_vTaskSuspend( TaskHandle_t xTaskToSuspend ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskSuspend( TaskHandle_t xTaskToSuspend ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskSuspendImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_vTaskSuspend_Unpriv \n" + " MPU_vTaskSuspend_Priv: \n" + " pop {r0, r1} \n" + " b MPU_vTaskSuspendImpl \n" + " MPU_vTaskSuspend_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_vTaskSuspendImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_vTaskSuspend == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskSuspend == 1 ) + +void MPU_vTaskResume( TaskHandle_t xTaskToResume ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskResume( TaskHandle_t xTaskToResume ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskResumeImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_vTaskResume_Unpriv \n" + " MPU_vTaskResume_Priv: \n" + " pop {r0, r1} \n" + " b MPU_vTaskResumeImpl \n" + " MPU_vTaskResume_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_vTaskResumeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_vTaskSuspend == 1 ) */ +/*-----------------------------------------------------------*/ + +TickType_t MPU_xTaskGetTickCount( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TickType_t MPU_xTaskGetTickCount( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGetTickCountImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xTaskGetTickCount_Unpriv \n" + " MPU_xTaskGetTickCount_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xTaskGetTickCountImpl \n" + " MPU_xTaskGetTickCount_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xTaskGetTickCountImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +UBaseType_t MPU_uxTaskGetNumberOfTasks( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxTaskGetNumberOfTasks( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxTaskGetNumberOfTasksImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_uxTaskGetNumberOfTasks_Unpriv \n" + " MPU_uxTaskGetNumberOfTasks_Priv: \n" + " pop {r0, r1} \n" + " b MPU_uxTaskGetNumberOfTasksImpl \n" + " MPU_uxTaskGetNumberOfTasks_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_uxTaskGetNumberOfTasksImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +char * MPU_pcTaskGetName( TaskHandle_t xTaskToQuery ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +char * MPU_pcTaskGetName( TaskHandle_t xTaskToQuery ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_pcTaskGetNameImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_pcTaskGetName_Unpriv \n" + " MPU_pcTaskGetName_Priv: \n" + " pop {r0, r1} \n" + " b MPU_pcTaskGetNameImpl \n" + " MPU_pcTaskGetName_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_pcTaskGetNameImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +#if ( configGENERATE_RUN_TIME_STATS == 1 ) + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetRunTimeCounter( const TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetRunTimeCounter( const TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_ulTaskGetRunTimeCounterImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_ulTaskGetRunTimeCounter_Unpriv \n" + " MPU_ulTaskGetRunTimeCounter_Priv: \n" + " pop {r0, r1} \n" + " b MPU_ulTaskGetRunTimeCounterImpl \n" + " MPU_ulTaskGetRunTimeCounter_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_ulTaskGetRunTimeCounterImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( ( configGENERATE_RUN_TIME_STATS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configGENERATE_RUN_TIME_STATS == 1 ) + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetRunTimePercent( const TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetRunTimePercent( const TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_ulTaskGetRunTimePercentImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_ulTaskGetRunTimePercent_Unpriv \n" + " MPU_ulTaskGetRunTimePercent_Priv: \n" + " pop {r0, r1} \n" + " b MPU_ulTaskGetRunTimePercentImpl \n" + " MPU_ulTaskGetRunTimePercent_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_ulTaskGetRunTimePercentImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( ( configGENERATE_RUN_TIME_STATS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimePercent( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimePercent( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_ulTaskGetIdleRunTimePercentImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_ulTaskGetIdleRunTimePercent_Unpriv \n" + " MPU_ulTaskGetIdleRunTimePercent_Priv: \n" + " pop {r0, r1} \n" + " b MPU_ulTaskGetIdleRunTimePercentImpl \n" + " MPU_ulTaskGetIdleRunTimePercent_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_ulTaskGetIdleRunTimePercentImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimeCounter( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimeCounter( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_ulTaskGetIdleRunTimeCounterImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_ulTaskGetIdleRunTimeCounter_Unpriv \n" + " MPU_ulTaskGetIdleRunTimeCounter_Priv: \n" + " pop {r0, r1} \n" + " b MPU_ulTaskGetIdleRunTimeCounterImpl \n" + " MPU_ulTaskGetIdleRunTimeCounter_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_ulTaskGetIdleRunTimeCounterImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_APPLICATION_TASK_TAG == 1 ) + +void MPU_vTaskSetApplicationTaskTag( TaskHandle_t xTask, + TaskHookFunction_t pxHookFunction ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskSetApplicationTaskTag( TaskHandle_t xTask, + TaskHookFunction_t pxHookFunction ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskSetApplicationTaskTagImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_vTaskSetApplicationTaskTag_Unpriv \n" + " MPU_vTaskSetApplicationTaskTag_Priv: \n" + " pop {r0, r1} \n" + " b MPU_vTaskSetApplicationTaskTagImpl \n" + " MPU_vTaskSetApplicationTaskTag_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_vTaskSetApplicationTaskTagImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_APPLICATION_TASK_TAG == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_APPLICATION_TASK_TAG == 1 ) + +TaskHookFunction_t MPU_xTaskGetApplicationTaskTag( TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TaskHookFunction_t MPU_xTaskGetApplicationTaskTag( TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGetApplicationTaskTagImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xTaskGetApplicationTaskTag_Unpriv \n" + " MPU_xTaskGetApplicationTaskTag_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xTaskGetApplicationTaskTagImpl \n" + " MPU_xTaskGetApplicationTaskTag_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xTaskGetApplicationTaskTagImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_APPLICATION_TASK_TAG == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) + +void MPU_vTaskSetThreadLocalStoragePointer( TaskHandle_t xTaskToSet, + BaseType_t xIndex, + void * pvValue ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskSetThreadLocalStoragePointer( TaskHandle_t xTaskToSet, + BaseType_t xIndex, + void * pvValue ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskSetThreadLocalStoragePointerImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_vTaskSetThreadLocalStoragePointer_Unpriv \n" + " MPU_vTaskSetThreadLocalStoragePointer_Priv: \n" + " pop {r0, r1} \n" + " b MPU_vTaskSetThreadLocalStoragePointerImpl \n" + " MPU_vTaskSetThreadLocalStoragePointer_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_vTaskSetThreadLocalStoragePointerImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) + +void * MPU_pvTaskGetThreadLocalStoragePointer( TaskHandle_t xTaskToQuery, + BaseType_t xIndex ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void * MPU_pvTaskGetThreadLocalStoragePointer( TaskHandle_t xTaskToQuery, + BaseType_t xIndex ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_pvTaskGetThreadLocalStoragePointerImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_pvTaskGetThreadLocalStoragePointer_Unpriv \n" + " MPU_pvTaskGetThreadLocalStoragePointer_Priv: \n" + " pop {r0, r1} \n" + " b MPU_pvTaskGetThreadLocalStoragePointerImpl \n" + " MPU_pvTaskGetThreadLocalStoragePointer_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_pvTaskGetThreadLocalStoragePointerImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + +UBaseType_t MPU_uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray, + const UBaseType_t uxArraySize, + configRUN_TIME_COUNTER_TYPE * const pulTotalRunTime ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray, + const UBaseType_t uxArraySize, + configRUN_TIME_COUNTER_TYPE * const pulTotalRunTime ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxTaskGetSystemStateImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_uxTaskGetSystemState_Unpriv \n" + " MPU_uxTaskGetSystemState_Priv: \n" + " pop {r0, r1} \n" + " b MPU_uxTaskGetSystemStateImpl \n" + " MPU_uxTaskGetSystemState_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_uxTaskGetSystemStateImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TRACE_FACILITY == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) + +UBaseType_t MPU_uxTaskGetStackHighWaterMark( TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxTaskGetStackHighWaterMark( TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxTaskGetStackHighWaterMarkImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_uxTaskGetStackHighWaterMark_Unpriv \n" + " MPU_uxTaskGetStackHighWaterMark_Priv: \n" + " pop {r0, r1} \n" + " b MPU_uxTaskGetStackHighWaterMarkImpl \n" + " MPU_uxTaskGetStackHighWaterMark_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_uxTaskGetStackHighWaterMarkImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) + +configSTACK_DEPTH_TYPE MPU_uxTaskGetStackHighWaterMark2( TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +configSTACK_DEPTH_TYPE MPU_uxTaskGetStackHighWaterMark2( TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxTaskGetStackHighWaterMark2Impl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_uxTaskGetStackHighWaterMark2_Unpriv \n" + " MPU_uxTaskGetStackHighWaterMark2_Priv: \n" + " pop {r0, r1} \n" + " b MPU_uxTaskGetStackHighWaterMark2Impl \n" + " MPU_uxTaskGetStackHighWaterMark2_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_uxTaskGetStackHighWaterMark2Impl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) ) + +TaskHandle_t MPU_xTaskGetCurrentTaskHandle( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TaskHandle_t MPU_xTaskGetCurrentTaskHandle( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGetCurrentTaskHandleImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xTaskGetCurrentTaskHandle_Unpriv \n" + " MPU_xTaskGetCurrentTaskHandle_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xTaskGetCurrentTaskHandleImpl \n" + " MPU_xTaskGetCurrentTaskHandle_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xTaskGetCurrentTaskHandleImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_xTaskGetSchedulerState == 1 ) + +BaseType_t MPU_xTaskGetSchedulerState( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskGetSchedulerState( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGetSchedulerStateImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xTaskGetSchedulerState_Unpriv \n" + " MPU_xTaskGetSchedulerState_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xTaskGetSchedulerStateImpl \n" + " MPU_xTaskGetSchedulerState_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xTaskGetSchedulerStateImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_xTaskGetSchedulerState == 1 ) */ +/*-----------------------------------------------------------*/ + +void MPU_vTaskSetTimeOutState( TimeOut_t * const pxTimeOut ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskSetTimeOutState( TimeOut_t * const pxTimeOut ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskSetTimeOutStateImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_vTaskSetTimeOutState_Unpriv \n" + " MPU_vTaskSetTimeOutState_Priv: \n" + " pop {r0, r1} \n" + " b MPU_vTaskSetTimeOutStateImpl \n" + " MPU_vTaskSetTimeOutState_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_vTaskSetTimeOutStateImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut, + TickType_t * const pxTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut, + TickType_t * const pxTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskCheckForTimeOutImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xTaskCheckForTimeOut_Unpriv \n" + " MPU_xTaskCheckForTimeOut_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xTaskCheckForTimeOutImpl \n" + " MPU_xTaskCheckForTimeOut_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xTaskCheckForTimeOutImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +#if ( configUSE_TASK_NOTIFICATIONS == 1 ) + +BaseType_t MPU_xTaskGenericNotify( TaskHandle_t xTaskToNotify, + UBaseType_t uxIndexToNotify, + uint32_t ulValue, + eNotifyAction eAction, + uint32_t * pulPreviousNotificationValue ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskGenericNotify( TaskHandle_t xTaskToNotify, + UBaseType_t uxIndexToNotify, + uint32_t ulValue, + eNotifyAction eAction, + uint32_t * pulPreviousNotificationValue ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGenericNotifyImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xTaskGenericNotify_Unpriv \n" + " MPU_xTaskGenericNotify_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xTaskGenericNotifyImpl \n" + " MPU_xTaskGenericNotify_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xTaskGenericNotifyImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER_1 ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TASK_NOTIFICATIONS == 1 ) + +BaseType_t MPU_xTaskGenericNotifyWait( UBaseType_t uxIndexToWaitOn, + uint32_t ulBitsToClearOnEntry, + uint32_t ulBitsToClearOnExit, + uint32_t * pulNotificationValue, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskGenericNotifyWait( UBaseType_t uxIndexToWaitOn, + uint32_t ulBitsToClearOnEntry, + uint32_t ulBitsToClearOnExit, + uint32_t * pulNotificationValue, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGenericNotifyWaitImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xTaskGenericNotifyWait_Unpriv \n" + " MPU_xTaskGenericNotifyWait_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xTaskGenericNotifyWaitImpl \n" + " MPU_xTaskGenericNotifyWait_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xTaskGenericNotifyWaitImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER_1 ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TASK_NOTIFICATIONS == 1 ) + +uint32_t MPU_ulTaskGenericNotifyTake( UBaseType_t uxIndexToWaitOn, + BaseType_t xClearCountOnExit, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +uint32_t MPU_ulTaskGenericNotifyTake( UBaseType_t uxIndexToWaitOn, + BaseType_t xClearCountOnExit, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_ulTaskGenericNotifyTakeImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_ulTaskGenericNotifyTake_Unpriv \n" + " MPU_ulTaskGenericNotifyTake_Priv: \n" + " pop {r0, r1} \n" + " b MPU_ulTaskGenericNotifyTakeImpl \n" + " MPU_ulTaskGenericNotifyTake_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_ulTaskGenericNotifyTakeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TASK_NOTIFICATIONS == 1 ) + +BaseType_t MPU_xTaskGenericNotifyStateClear( TaskHandle_t xTask, + UBaseType_t uxIndexToClear ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskGenericNotifyStateClear( TaskHandle_t xTask, + UBaseType_t uxIndexToClear ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGenericNotifyStateClearImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xTaskGenericNotifyStateClear_Unpriv \n" + " MPU_xTaskGenericNotifyStateClear_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xTaskGenericNotifyStateClearImpl \n" + " MPU_xTaskGenericNotifyStateClear_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xTaskGenericNotifyStateClearImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TASK_NOTIFICATIONS == 1 ) + +uint32_t MPU_ulTaskGenericNotifyValueClear( TaskHandle_t xTask, + UBaseType_t uxIndexToClear, + uint32_t ulBitsToClear ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +uint32_t MPU_ulTaskGenericNotifyValueClear( TaskHandle_t xTask, + UBaseType_t uxIndexToClear, + uint32_t ulBitsToClear ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_ulTaskGenericNotifyValueClearImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_ulTaskGenericNotifyValueClear_Unpriv \n" + " MPU_ulTaskGenericNotifyValueClear_Priv: \n" + " pop {r0, r1} \n" + " b MPU_ulTaskGenericNotifyValueClearImpl \n" + " MPU_ulTaskGenericNotifyValueClear_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_ulTaskGenericNotifyValueClearImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xQueueGenericSend( QueueHandle_t xQueue, + const void * const pvItemToQueue, + TickType_t xTicksToWait, + const BaseType_t xCopyPosition ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueueGenericSend( QueueHandle_t xQueue, + const void * const pvItemToQueue, + TickType_t xTicksToWait, + const BaseType_t xCopyPosition ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueGenericSendImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xQueueGenericSend_Unpriv \n" + " MPU_xQueueGenericSend_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xQueueGenericSendImpl \n" + " MPU_xQueueGenericSend_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xQueueGenericSendImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +UBaseType_t MPU_uxQueueMessagesWaiting( const QueueHandle_t xQueue ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxQueueMessagesWaiting( const QueueHandle_t xQueue ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxQueueMessagesWaitingImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_uxQueueMessagesWaiting_Unpriv \n" + " MPU_uxQueueMessagesWaiting_Priv: \n" + " pop {r0, r1} \n" + " b MPU_uxQueueMessagesWaitingImpl \n" + " MPU_uxQueueMessagesWaiting_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_uxQueueMessagesWaitingImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +UBaseType_t MPU_uxQueueSpacesAvailable( const QueueHandle_t xQueue ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxQueueSpacesAvailable( const QueueHandle_t xQueue ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxQueueSpacesAvailableImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_uxQueueSpacesAvailable_Unpriv \n" + " MPU_uxQueueSpacesAvailable_Priv: \n" + " pop {r0, r1} \n" + " b MPU_uxQueueSpacesAvailableImpl \n" + " MPU_uxQueueSpacesAvailable_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_uxQueueSpacesAvailableImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xQueueReceive( QueueHandle_t xQueue, + void * const pvBuffer, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueueReceive( QueueHandle_t xQueue, + void * const pvBuffer, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueReceiveImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xQueueReceive_Unpriv \n" + " MPU_xQueueReceive_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xQueueReceiveImpl \n" + " MPU_xQueueReceive_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xQueueReceiveImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xQueuePeek( QueueHandle_t xQueue, + void * const pvBuffer, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueuePeek( QueueHandle_t xQueue, + void * const pvBuffer, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueuePeekImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xQueuePeek_Unpriv \n" + " MPU_xQueuePeek_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xQueuePeekImpl \n" + " MPU_xQueuePeek_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xQueuePeekImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xQueueSemaphoreTake( QueueHandle_t xQueue, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueueSemaphoreTake( QueueHandle_t xQueue, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueSemaphoreTakeImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xQueueSemaphoreTake_Unpriv \n" + " MPU_xQueueSemaphoreTake_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xQueueSemaphoreTakeImpl \n" + " MPU_xQueueSemaphoreTake_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xQueueSemaphoreTakeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +#if ( ( configUSE_MUTEXES == 1 ) && ( INCLUDE_xSemaphoreGetMutexHolder == 1 ) ) + +TaskHandle_t MPU_xQueueGetMutexHolder( QueueHandle_t xSemaphore ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TaskHandle_t MPU_xQueueGetMutexHolder( QueueHandle_t xSemaphore ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueGetMutexHolderImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xQueueGetMutexHolder_Unpriv \n" + " MPU_xQueueGetMutexHolder_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xQueueGetMutexHolderImpl \n" + " MPU_xQueueGetMutexHolder_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xQueueGetMutexHolderImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( ( configUSE_MUTEXES == 1 ) && ( INCLUDE_xSemaphoreGetMutexHolder == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_RECURSIVE_MUTEXES == 1 ) + +BaseType_t MPU_xQueueTakeMutexRecursive( QueueHandle_t xMutex, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueueTakeMutexRecursive( QueueHandle_t xMutex, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueTakeMutexRecursiveImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xQueueTakeMutexRecursive_Unpriv \n" + " MPU_xQueueTakeMutexRecursive_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xQueueTakeMutexRecursiveImpl \n" + " MPU_xQueueTakeMutexRecursive_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xQueueTakeMutexRecursiveImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_RECURSIVE_MUTEXES == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_RECURSIVE_MUTEXES == 1 ) + +BaseType_t MPU_xQueueGiveMutexRecursive( QueueHandle_t pxMutex ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueueGiveMutexRecursive( QueueHandle_t pxMutex ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueGiveMutexRecursiveImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xQueueGiveMutexRecursive_Unpriv \n" + " MPU_xQueueGiveMutexRecursive_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xQueueGiveMutexRecursiveImpl \n" + " MPU_xQueueGiveMutexRecursive_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xQueueGiveMutexRecursiveImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_RECURSIVE_MUTEXES == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_QUEUE_SETS == 1 ) + +QueueSetMemberHandle_t MPU_xQueueSelectFromSet( QueueSetHandle_t xQueueSet, + const TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +QueueSetMemberHandle_t MPU_xQueueSelectFromSet( QueueSetHandle_t xQueueSet, + const TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueSelectFromSetImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xQueueSelectFromSet_Unpriv \n" + " MPU_xQueueSelectFromSet_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xQueueSelectFromSetImpl \n" + " MPU_xQueueSelectFromSet_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xQueueSelectFromSetImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_QUEUE_SETS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_QUEUE_SETS == 1 ) + +BaseType_t MPU_xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore, + QueueSetHandle_t xQueueSet ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore, + QueueSetHandle_t xQueueSet ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueAddToSetImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xQueueAddToSet_Unpriv \n" + " MPU_xQueueAddToSet_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xQueueAddToSetImpl \n" + " MPU_xQueueAddToSet_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xQueueAddToSetImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_QUEUE_SETS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configQUEUE_REGISTRY_SIZE > 0 ) + +void MPU_vQueueAddToRegistry( QueueHandle_t xQueue, + const char * pcName ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vQueueAddToRegistry( QueueHandle_t xQueue, + const char * pcName ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vQueueAddToRegistryImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_vQueueAddToRegistry_Unpriv \n" + " MPU_vQueueAddToRegistry_Priv: \n" + " pop {r0, r1} \n" + " b MPU_vQueueAddToRegistryImpl \n" + " MPU_vQueueAddToRegistry_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_vQueueAddToRegistryImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configQUEUE_REGISTRY_SIZE > 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configQUEUE_REGISTRY_SIZE > 0 ) + +void MPU_vQueueUnregisterQueue( QueueHandle_t xQueue ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vQueueUnregisterQueue( QueueHandle_t xQueue ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vQueueUnregisterQueueImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_vQueueUnregisterQueue_Unpriv \n" + " MPU_vQueueUnregisterQueue_Priv: \n" + " pop {r0, r1} \n" + " b MPU_vQueueUnregisterQueueImpl \n" + " MPU_vQueueUnregisterQueue_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_vQueueUnregisterQueueImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configQUEUE_REGISTRY_SIZE > 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configQUEUE_REGISTRY_SIZE > 0 ) + +const char * MPU_pcQueueGetName( QueueHandle_t xQueue ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +const char * MPU_pcQueueGetName( QueueHandle_t xQueue ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_pcQueueGetNameImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_pcQueueGetName_Unpriv \n" + " MPU_pcQueueGetName_Priv: \n" + " pop {r0, r1} \n" + " b MPU_pcQueueGetNameImpl \n" + " MPU_pcQueueGetName_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_pcQueueGetNameImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configQUEUE_REGISTRY_SIZE > 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +void * MPU_pvTimerGetTimerID( const TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void * MPU_pvTimerGetTimerID( const TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_pvTimerGetTimerIDImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_pvTimerGetTimerID_Unpriv \n" + " MPU_pvTimerGetTimerID_Priv: \n" + " pop {r0, r1} \n" + " b MPU_pvTimerGetTimerIDImpl \n" + " MPU_pvTimerGetTimerID_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_pvTimerGetTimerIDImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +void MPU_vTimerSetTimerID( TimerHandle_t xTimer, + void * pvNewID ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTimerSetTimerID( TimerHandle_t xTimer, + void * pvNewID ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTimerSetTimerIDImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_vTimerSetTimerID_Unpriv \n" + " MPU_vTimerSetTimerID_Priv: \n" + " pop {r0, r1} \n" + " b MPU_vTimerSetTimerIDImpl \n" + " MPU_vTimerSetTimerID_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_vTimerSetTimerIDImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +BaseType_t MPU_xTimerIsTimerActive( TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTimerIsTimerActive( TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTimerIsTimerActiveImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xTimerIsTimerActive_Unpriv \n" + " MPU_xTimerIsTimerActive_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xTimerIsTimerActiveImpl \n" + " MPU_xTimerIsTimerActive_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xTimerIsTimerActiveImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +TaskHandle_t MPU_xTimerGetTimerDaemonTaskHandle( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TaskHandle_t MPU_xTimerGetTimerDaemonTaskHandle( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTimerGetTimerDaemonTaskHandleImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xTimerGetTimerDaemonTaskHandle_Unpriv \n" + " MPU_xTimerGetTimerDaemonTaskHandle_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xTimerGetTimerDaemonTaskHandleImpl \n" + " MPU_xTimerGetTimerDaemonTaskHandle_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xTimerGetTimerDaemonTaskHandleImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +BaseType_t MPU_xTimerGenericCommand( TimerHandle_t xTimer, + const BaseType_t xCommandID, + const TickType_t xOptionalValue, + BaseType_t * const pxHigherPriorityTaskWoken, + const TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTimerGenericCommand( TimerHandle_t xTimer, + const BaseType_t xCommandID, + const TickType_t xOptionalValue, + BaseType_t * const pxHigherPriorityTaskWoken, + const TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTimerGenericCommandImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, ipsr \n" + " cmp r0, #0 \n" + " bne MPU_xTimerGenericCommand_Priv \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " beq MPU_xTimerGenericCommand_Priv \n" + " MPU_xTimerGenericCommand_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xTimerGenericCommandImpl \n" + " svc %1 \n" + " bx lr \n" + " MPU_xTimerGenericCommand_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xTimerGenericCommandImpl \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER_1 ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +const char * MPU_pcTimerGetName( TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +const char * MPU_pcTimerGetName( TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_pcTimerGetNameImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_pcTimerGetName_Unpriv \n" + " MPU_pcTimerGetName_Priv: \n" + " pop {r0, r1} \n" + " b MPU_pcTimerGetNameImpl \n" + " MPU_pcTimerGetName_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_pcTimerGetNameImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, + const BaseType_t uxAutoReload ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, + const BaseType_t uxAutoReload ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTimerSetReloadModeImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_vTimerSetReloadMode_Unpriv \n" + " MPU_vTimerSetReloadMode_Priv: \n" + " pop {r0, r1} \n" + " b MPU_vTimerSetReloadModeImpl \n" + " MPU_vTimerSetReloadMode_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_vTimerSetReloadModeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +BaseType_t MPU_xTimerGetReloadMode( TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTimerGetReloadMode( TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTimerGetReloadModeImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xTimerGetReloadMode_Unpriv \n" + " MPU_xTimerGetReloadMode_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xTimerGetReloadModeImpl \n" + " MPU_xTimerGetReloadMode_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xTimerGetReloadModeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +UBaseType_t MPU_uxTimerGetReloadMode( TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxTimerGetReloadMode( TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxTimerGetReloadModeImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_uxTimerGetReloadMode_Unpriv \n" + " MPU_uxTimerGetReloadMode_Priv: \n" + " pop {r0, r1} \n" + " b MPU_uxTimerGetReloadModeImpl \n" + " MPU_uxTimerGetReloadMode_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_uxTimerGetReloadModeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +TickType_t MPU_xTimerGetPeriod( TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TickType_t MPU_xTimerGetPeriod( TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTimerGetPeriodImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xTimerGetPeriod_Unpriv \n" + " MPU_xTimerGetPeriod_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xTimerGetPeriodImpl \n" + " MPU_xTimerGetPeriod_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xTimerGetPeriodImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +TickType_t MPU_xTimerGetExpiryTime( TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TickType_t MPU_xTimerGetExpiryTime( TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTimerGetExpiryTimeImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xTimerGetExpiryTime_Unpriv \n" + " MPU_xTimerGetExpiryTime_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xTimerGetExpiryTimeImpl \n" + " MPU_xTimerGetExpiryTime_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xTimerGetExpiryTimeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +EventBits_t MPU_xEventGroupWaitBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToWaitFor, + const BaseType_t xClearOnExit, + const BaseType_t xWaitForAllBits, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +EventBits_t MPU_xEventGroupWaitBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToWaitFor, + const BaseType_t xClearOnExit, + const BaseType_t xWaitForAllBits, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupWaitBitsImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xEventGroupWaitBits_Unpriv \n" + " MPU_xEventGroupWaitBits_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xEventGroupWaitBitsImpl \n" + " MPU_xEventGroupWaitBits_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xEventGroupWaitBitsImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER_1 ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToClear ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToClear ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupClearBitsImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xEventGroupClearBits_Unpriv \n" + " MPU_xEventGroupClearBits_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xEventGroupClearBitsImpl \n" + " MPU_xEventGroupClearBits_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xEventGroupClearBitsImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupSetBitsImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xEventGroupSetBits_Unpriv \n" + " MPU_xEventGroupSetBits_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xEventGroupSetBitsImpl \n" + " MPU_xEventGroupSetBits_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xEventGroupSetBitsImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet, + const EventBits_t uxBitsToWaitFor, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet, + const EventBits_t uxBitsToWaitFor, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupSyncImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xEventGroupSync_Unpriv \n" + " MPU_xEventGroupSync_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xEventGroupSyncImpl \n" + " MPU_xEventGroupSync_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xEventGroupSyncImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + +UBaseType_t MPU_uxEventGroupGetNumber( void * xEventGroup ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxEventGroupGetNumber( void * xEventGroup ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxEventGroupGetNumberImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_uxEventGroupGetNumber_Unpriv \n" + " MPU_uxEventGroupGetNumber_Priv: \n" + " pop {r0, r1} \n" + " b MPU_uxEventGroupGetNumberImpl \n" + " MPU_uxEventGroupGetNumber_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_uxEventGroupGetNumberImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /*( configUSE_TRACE_FACILITY == 1 )*/ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + +void MPU_vEventGroupSetNumber( void * xEventGroup, + UBaseType_t uxEventGroupNumber ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vEventGroupSetNumber( void * xEventGroup, + UBaseType_t uxEventGroupNumber ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vEventGroupSetNumberImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_vEventGroupSetNumber_Unpriv \n" + " MPU_vEventGroupSetNumber_Priv: \n" + " pop {r0, r1} \n" + " b MPU_vEventGroupSetNumberImpl \n" + " MPU_vEventGroupSetNumber_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_vEventGroupSetNumberImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /*( configUSE_TRACE_FACILITY == 1 )*/ +/*-----------------------------------------------------------*/ + +size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, + const void * pvTxData, + size_t xDataLengthBytes, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, + const void * pvTxData, + size_t xDataLengthBytes, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferSendImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xStreamBufferSend_Unpriv \n" + " MPU_xStreamBufferSend_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xStreamBufferSendImpl \n" + " MPU_xStreamBufferSend_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xStreamBufferSendImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, + void * pvRxData, + size_t xBufferLengthBytes, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, + void * pvRxData, + size_t xBufferLengthBytes, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferReceiveImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xStreamBufferReceive_Unpriv \n" + " MPU_xStreamBufferReceive_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xStreamBufferReceiveImpl \n" + " MPU_xStreamBufferReceive_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xStreamBufferReceiveImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferIsFullImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xStreamBufferIsFull_Unpriv \n" + " MPU_xStreamBufferIsFull_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xStreamBufferIsFullImpl \n" + " MPU_xStreamBufferIsFull_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xStreamBufferIsFullImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferIsEmptyImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xStreamBufferIsEmpty_Unpriv \n" + " MPU_xStreamBufferIsEmpty_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xStreamBufferIsEmptyImpl \n" + " MPU_xStreamBufferIsEmpty_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xStreamBufferIsEmptyImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferSpacesAvailableImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xStreamBufferSpacesAvailable_Unpriv \n" + " MPU_xStreamBufferSpacesAvailable_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xStreamBufferSpacesAvailableImpl \n" + " MPU_xStreamBufferSpacesAvailable_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xStreamBufferSpacesAvailableImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferBytesAvailableImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xStreamBufferBytesAvailable_Unpriv \n" + " MPU_xStreamBufferBytesAvailable_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xStreamBufferBytesAvailableImpl \n" + " MPU_xStreamBufferBytesAvailable_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xStreamBufferBytesAvailableImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, + size_t xTriggerLevel ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, + size_t xTriggerLevel ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferSetTriggerLevelImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xStreamBufferSetTriggerLevel_Unpriv \n" + " MPU_xStreamBufferSetTriggerLevel_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xStreamBufferSetTriggerLevelImpl \n" + " MPU_xStreamBufferSetTriggerLevel_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xStreamBufferSetTriggerLevelImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferNextMessageLengthBytesImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xStreamBufferNextMessageLengthBytes_Unpriv \n" + " MPU_xStreamBufferNextMessageLengthBytes_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xStreamBufferNextMessageLengthBytesImpl \n" + " MPU_xStreamBufferNextMessageLengthBytes_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xStreamBufferNextMessageLengthBytesImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ diff --git a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM23/portasm.c b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM23/portasm.c index 44f159af1fa..64a24f527ff 100644 --- a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM23/portasm.c +++ b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM23/portasm.c @@ -44,6 +44,109 @@ #error Cortex-M23 does not have a Floating Point Unit (FPU) and therefore configENABLE_FPU must be set to 0. #endif +#if ( configENABLE_MPU == 1 ) + +void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ +{ + __asm volatile + ( + " .syntax unified \n" + " \n" + " program_mpu_first_task: \n" + " ldr r3, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r0, [r3] \n" /* r0 = pxCurrentTCB.*/ + " \n" + " dmb \n" /* Complete outstanding transfers before disabling MPU. */ + " ldr r1, xMPUCTRLConst2 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ + " movs r3, #1 \n" /* r3 = 1. */ + " bics r2, r3 \n" /* r2 = r2 & ~r3 i.e. Clear the bit 0 in r2. */ + " str r2, [r1] \n" /* Disable MPU. */ + " \n" + " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */ + " ldr r1, [r0] \n" /* r1 = *r0 i.e. r1 = MAIR0. */ + " ldr r2, xMAIR0Const2 \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */ + " str r1, [r2] \n" /* Program MAIR0. */ + " \n" + " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */ + " ldr r1, xRNRConst2 \n" /* r1 = 0xe000ed98 [Location of RNR]. */ + " \n" + " movs r3, #4 \n" /* r3 = 4. */ + " str r3, [r1] \n" /* Program RNR = 4. */ + " ldmia r0!, {r4-r5} \n" /* Read first set of RBAR/RLAR registers from TCB. */ + " ldr r2, xRBARConst2 \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ + " stmia r2!, {r4-r5} \n" /* Write first set of RBAR/RLAR registers. */ + " movs r3, #5 \n" /* r3 = 5. */ + " str r3, [r1] \n" /* Program RNR = 5. */ + " ldmia r0!, {r4-r5} \n" /* Read second set of RBAR/RLAR registers from TCB. */ + " ldr r2, xRBARConst2 \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ + " stmia r2!, {r4-r5} \n" /* Write second set of RBAR/RLAR registers. */ + " movs r3, #6 \n" /* r3 = 6. */ + " str r3, [r1] \n" /* Program RNR = 6. */ + " ldmia r0!, {r4-r5} \n" /* Read third set of RBAR/RLAR registers from TCB. */ + " ldr r2, xRBARConst2 \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ + " stmia r2!, {r4-r5} \n" /* Write third set of RBAR/RLAR registers. */ + " movs r3, #7 \n" /* r3 = 6. */ + " str r3, [r1] \n" /* Program RNR = 7. */ + " ldmia r0!, {r4-r5} \n" /* Read fourth set of RBAR/RLAR registers from TCB. */ + " ldr r2, xRBARConst2 \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ + " stmia r2!, {r4-r5} \n" /* Write fourth set of RBAR/RLAR registers. */ + " \n" + " ldr r1, xMPUCTRLConst2 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ + " movs r3, #1 \n" /* r3 = 1. */ + " orrs r2, r3 \n" /* r2 = r2 | r3 i.e. Set the bit 0 in r2. */ + " str r2, [r1] \n" /* Enable MPU. */ + " dsb \n" /* Force memory writes before continuing. */ + " \n" + " restore_context_first_task: \n" + " ldr r3, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r1, [r3] \n" /* r1 = pxCurrentTCB.*/ + " ldr r2, [r1] \n" /* r2 = Location of saved context in TCB. */ + " \n" + " restore_special_regs_first_task: \n" + " subs r2, #20 \n" + " ldmia r2!, {r0, r3-r6} \n" /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, r6 = LR. */ + " subs r2, #20 \n" + " msr psp, r3 \n" + " msr psplim, r4 \n" + " msr control, r5 \n" + " mov lr, r6 \n" + " ldr r4, xSecureContextConst2 \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ + " str r0, [r4] \n" /* Restore xSecureContext. */ + " \n" + " restore_general_regs_first_task: \n" + " subs r2, #32 \n" + " ldmia r2!, {r4-r7} \n" /* r4-r7 contain half of the hardware saved context. */ + " stmia r3!, {r4-r7} \n" /* Copy half of the the hardware saved context on the task stack. */ + " ldmia r2!, {r4-r7} \n" /* r4-r7 contain rest half of the hardware saved context. */ + " stmia r3!, {r4-r7} \n" /* Copy rest half of the the hardware saved context on the task stack. */ + " subs r2, #48 \n" + " ldmia r2!, {r4-r7} \n" /* Restore r8-r11. */ + " mov r8, r4 \n" /* r8 = r4. */ + " mov r9, r5 \n" /* r9 = r5. */ + " mov r10, r6 \n" /* r10 = r6. */ + " mov r11, r7 \n" /* r11 = r7. */ + " subs r2, #32 \n" + " ldmia r2!, {r4-r7} \n" /* Restore r4-r7. */ + " subs r2, #16 \n" + " \n" + " restore_context_done_first_task: \n" + " str r2, [r1] \n" /* Save the location where the context should be saved next as the first member of TCB. */ + " bx lr \n" + " \n" + " .align 4 \n" + " pxCurrentTCBConst2: .word pxCurrentTCB \n" + " xSecureContextConst2: .word xSecureContext \n" + " xMPUCTRLConst2: .word 0xe000ed94 \n" + " xMAIR0Const2: .word 0xe000edc0 \n" + " xRNRConst2: .word 0xe000ed98 \n" + " xRBARConst2: .word 0xe000ed9c \n" + ); +} + +#else /* configENABLE_MPU */ + void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ { __asm volatile @@ -54,83 +157,24 @@ void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_ " ldr r3, [r2] \n"/* Read pxCurrentTCB. */ " ldr r0, [r3] \n"/* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ " \n" - #if ( configENABLE_MPU == 1 ) - " dmb \n"/* Complete outstanding transfers before disabling MPU. */ - " ldr r2, xMPUCTRLConst2 \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ - " ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */ - " movs r5, #1 \n"/* r5 = 1. */ - " bics r4, r5 \n"/* r4 = r4 & ~r5 i.e. Clear the bit 0 in r4. */ - " str r4, [r2] \n"/* Disable MPU. */ - " \n" - " adds r3, #4 \n"/* r3 = r3 + 4. r3 now points to MAIR0 in TCB. */ - " ldr r4, [r3] \n"/* r4 = *r3 i.e. r4 = MAIR0. */ - " ldr r2, xMAIR0Const2 \n"/* r2 = 0xe000edc0 [Location of MAIR0]. */ - " str r4, [r2] \n"/* Program MAIR0. */ - " ldr r2, xRNRConst2 \n"/* r2 = 0xe000ed98 [Location of RNR]. */ - " adds r3, #4 \n"/* r3 = r3 + 4. r3 now points to first RBAR in TCB. */ - " movs r5, #4 \n"/* r5 = 4. */ - " str r5, [r2] \n"/* Program RNR = 4. */ - " ldmia r3!, {r6,r7} \n"/* Read first set of RBAR/RLAR from TCB. */ - " ldr r4, xRBARConst2 \n"/* r4 = 0xe000ed9c [Location of RBAR]. */ - " stmia r4!, {r6,r7} \n"/* Write first set of RBAR/RLAR registers. */ - " movs r5, #5 \n"/* r5 = 5. */ - " str r5, [r2] \n"/* Program RNR = 5. */ - " ldmia r3!, {r6,r7} \n"/* Read second set of RBAR/RLAR from TCB. */ - " ldr r4, xRBARConst2 \n"/* r4 = 0xe000ed9c [Location of RBAR]. */ - " stmia r4!, {r6,r7} \n"/* Write second set of RBAR/RLAR registers. */ - " movs r5, #6 \n"/* r5 = 6. */ - " str r5, [r2] \n"/* Program RNR = 6. */ - " ldmia r3!, {r6,r7} \n"/* Read third set of RBAR/RLAR from TCB. */ - " ldr r4, xRBARConst2 \n"/* r4 = 0xe000ed9c [Location of RBAR]. */ - " stmia r4!, {r6,r7} \n"/* Write third set of RBAR/RLAR registers. */ - " movs r5, #7 \n"/* r5 = 7. */ - " str r5, [r2] \n"/* Program RNR = 7. */ - " ldmia r3!, {r6,r7} \n"/* Read fourth set of RBAR/RLAR from TCB. */ - " ldr r4, xRBARConst2 \n"/* r4 = 0xe000ed9c [Location of RBAR]. */ - " stmia r4!, {r6,r7} \n"/* Write fourth set of RBAR/RLAR registers. */ - " \n" - " ldr r2, xMPUCTRLConst2 \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ - " ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */ - " movs r5, #1 \n"/* r5 = 1. */ - " orrs r4, r5 \n"/* r4 = r4 | r5 i.e. Set the bit 0 in r4. */ - " str r4, [r2] \n"/* Enable MPU. */ - " dsb \n"/* Force memory writes before continuing. */ - #endif /* configENABLE_MPU */ - " \n" - #if ( configENABLE_MPU == 1 ) - " ldm r0!, {r1-r4} \n"/* Read from stack - r1 = xSecureContext, r2 = PSPLIM, r3 = CONTROL and r4 = EXC_RETURN. */ - " ldr r5, xSecureContextConst2 \n" - " str r1, [r5] \n"/* Set xSecureContext to this task's value for the same. */ - " msr psplim, r2 \n"/* Set this task's PSPLIM value. */ - " msr control, r3 \n"/* Set this task's CONTROL value. */ - " adds r0, #32 \n"/* Discard everything up to r0. */ - " msr psp, r0 \n"/* This is now the new top of stack to use in the task. */ - " isb \n" - " bx r4 \n"/* Finally, branch to EXC_RETURN. */ - #else /* configENABLE_MPU */ - " ldm r0!, {r1-r3} \n"/* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */ - " ldr r4, xSecureContextConst2 \n" - " str r1, [r4] \n"/* Set xSecureContext to this task's value for the same. */ - " msr psplim, r2 \n"/* Set this task's PSPLIM value. */ - " movs r1, #2 \n"/* r1 = 2. */ - " msr CONTROL, r1 \n"/* Switch to use PSP in the thread mode. */ - " adds r0, #32 \n"/* Discard everything up to r0. */ - " msr psp, r0 \n"/* This is now the new top of stack to use in the task. */ - " isb \n" - " bx r3 \n"/* Finally, branch to EXC_RETURN. */ - #endif /* configENABLE_MPU */ + " ldm r0!, {r1-r3} \n"/* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */ + " ldr r4, xSecureContextConst2 \n" + " str r1, [r4] \n"/* Set xSecureContext to this task's value for the same. */ + " msr psplim, r2 \n"/* Set this task's PSPLIM value. */ + " movs r1, #2 \n"/* r1 = 2. */ + " msr CONTROL, r1 \n"/* Switch to use PSP in the thread mode. */ + " adds r0, #32 \n"/* Discard everything up to r0. */ + " msr psp, r0 \n"/* This is now the new top of stack to use in the task. */ + " isb \n" + " bx r3 \n"/* Finally, branch to EXC_RETURN. */ " \n" " .align 4 \n" "pxCurrentTCBConst2: .word pxCurrentTCB \n" "xSecureContextConst2: .word xSecureContext \n" - #if ( configENABLE_MPU == 1 ) - "xMPUCTRLConst2: .word 0xe000ed94 \n" - "xMAIR0Const2: .word 0xe000edc0 \n" - "xRNRConst2: .word 0xe000ed98 \n" - "xRBARConst2: .word 0xe000ed9c \n" - #endif /* configENABLE_MPU */ ); } + +#endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */ @@ -237,6 +281,167 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att } /*-----------------------------------------------------------*/ +#if ( configENABLE_MPU == 1 ) + +void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern SecureContext_SaveContext \n" + " .extern SecureContext_LoadContext \n" + " \n" + " ldr r3, xSecureContextConst \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ + " ldr r0, [r3] \n" /* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */ + " ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r1, [r3] \n" /* Read pxCurrentTCB - Value of pxCurrentTCB must be in r1 as it is used as a parameter later.*/ + " ldr r2, [r1] \n" /* r2 = Location in TCB where the context should be saved. */ + " \n" + " cbz r0, save_ns_context \n" /* No secure context to save. */ + " save_s_context: \n" + " push {r0-r2, lr} \n" + " bl SecureContext_SaveContext \n" /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ + " pop {r0-r3} \n" /* LR is now in r3. */ + " mov lr, r3 \n" /* Restore LR. */ + " \n" + " save_ns_context: \n" + " mov r3, lr \n" /* r3 = LR (EXC_RETURN). */ + " lsls r3, r3, #25 \n" /* r3 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ + " bmi save_special_regs \n" /* r3 < 0 ==> Bit[6] in EXC_RETURN is 1 ==> secure stack was used to store the stack frame. */ + " \n" + " save_general_regs: \n" + " mrs r3, psp \n" + " stmia r2!, {r4-r7} \n" /* Store r4-r7. */ + " mov r4, r8 \n" /* r4 = r8. */ + " mov r5, r9 \n" /* r5 = r9. */ + " mov r6, r10 \n" /* r6 = r10. */ + " mov r7, r11 \n" /* r7 = r11. */ + " stmia r2!, {r4-r7} \n" /* Store r8-r11. */ + " ldmia r3!, {r4-r7} \n" /* Copy half of the hardware saved context into r4-r7. */ + " stmia r2!, {r4-r7} \n" /* Store the hardware saved context. */ + " ldmia r3!, {r4-r7} \n" /* Copy rest half of the hardware saved context into r4-r7. */ + " stmia r2!, {r4-r7} \n" /* Store the hardware saved context. */ + " \n" + " save_special_regs: \n" + " mrs r3, psp \n" /* r3 = PSP. */ + " mrs r4, psplim \n" /* r4 = PSPLIM. */ + " mrs r5, control \n" /* r5 = CONTROL. */ + " mov r6, lr \n" /* r6 = LR. */ + " stmia r2!, {r0, r3-r6} \n" /* Store xSecureContext, original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */ + " str r2, [r1] \n" /* Save the location from where the context should be restored as the first member of TCB. */ + " \n" + " select_next_task: \n" + " cpsid i \n" + " bl vTaskSwitchContext \n" + " cpsie i \n" + " \n" + " program_mpu: \n" + " ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r0, [r3] \n" /* r0 = pxCurrentTCB.*/ + " \n" + " dmb \n" /* Complete outstanding transfers before disabling MPU. */ + " ldr r1, xMPUCTRLConst \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ + " movs r3, #1 \n" /* r3 = 1. */ + " bics r2, r3 \n" /* r2 = r2 & ~r3 i.e. Clear the bit 0 in r2. */ + " str r2, [r1] \n" /* Disable MPU. */ + " \n" + " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */ + " ldr r1, [r0] \n" /* r1 = *r0 i.e. r1 = MAIR0. */ + " ldr r2, xMAIR0Const \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */ + " str r1, [r2] \n" /* Program MAIR0. */ + " \n" + " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */ + " ldr r1, xRNRConst \n" /* r1 = 0xe000ed98 [Location of RNR]. */ + " \n" + " movs r3, #4 \n" /* r3 = 4. */ + " str r3, [r1] \n" /* Program RNR = 4. */ + " ldmia r0!, {r4-r5} \n" /* Read first set of RBAR/RLAR registers from TCB. */ + " ldr r2, xRBARConst \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ + " stmia r2!, {r4-r5} \n" /* Write first set of RBAR/RLAR registers. */ + " movs r3, #5 \n" /* r3 = 5. */ + " str r3, [r1] \n" /* Program RNR = 5. */ + " ldmia r0!, {r4-r5} \n" /* Read second set of RBAR/RLAR registers from TCB. */ + " ldr r2, xRBARConst \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ + " stmia r2!, {r4-r5} \n" /* Write second set of RBAR/RLAR registers. */ + " movs r3, #6 \n" /* r3 = 6. */ + " str r3, [r1] \n" /* Program RNR = 6. */ + " ldmia r0!, {r4-r5} \n" /* Read third set of RBAR/RLAR registers from TCB. */ + " ldr r2, xRBARConst \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ + " stmia r2!, {r4-r5} \n" /* Write third set of RBAR/RLAR registers. */ + " movs r3, #7 \n" /* r3 = 6. */ + " str r3, [r1] \n" /* Program RNR = 7. */ + " ldmia r0!, {r4-r5} \n" /* Read fourth set of RBAR/RLAR registers from TCB. */ + " ldr r2, xRBARConst \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ + " stmia r2!, {r4-r5} \n" /* Write fourth set of RBAR/RLAR registers. */ + " \n" + " ldr r1, xMPUCTRLConst \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ + " movs r3, #1 \n" /* r3 = 1. */ + " orrs r2, r3 \n" /* r2 = r2 | r3 i.e. Set the bit 0 in r2. */ + " str r2, [r1] \n" /* Enable MPU. */ + " dsb \n" /* Force memory writes before continuing. */ + " \n" + " restore_context: \n" + " ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r1, [r3] \n" /* r1 = pxCurrentTCB.*/ + " ldr r2, [r1] \n" /* r2 = Location of saved context in TCB. */ + " \n" + " restore_special_regs: \n" + " subs r2, #20 \n" + " ldmia r2!, {r0, r3-r6} \n" /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, r6 = LR. */ + " subs r2, #20 \n" + " msr psp, r3 \n" + " msr psplim, r4 \n" + " msr control, r5 \n" + " mov lr, r6 \n" + " ldr r4, xSecureContextConst \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ + " str r0, [r4] \n" /* Restore xSecureContext. */ + " cbz r0, restore_ns_context \n" /* No secure context to restore. */ + " \n" + " restore_s_context: \n" + " push {r1-r3, lr} \n" + " bl SecureContext_LoadContext \n" /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ + " pop {r1-r4} \n" /* LR is now in r4. */ + " mov lr, r4 \n" + " \n" + " restore_ns_context: \n" + " mov r0, lr \n" /* r0 = LR (EXC_RETURN). */ + " lsls r0, r0, #25 \n" /* r0 = r0 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ + " bmi restore_context_done \n" /* r0 < 0 ==> Bit[6] in EXC_RETURN is 1 ==> secure stack was used to store the stack frame. */ + " \n" + " restore_general_regs: \n" + " subs r2, #32 \n" + " ldmia r2!, {r4-r7} \n" /* r4-r7 contain half of the hardware saved context. */ + " stmia r3!, {r4-r7} \n" /* Copy half of the the hardware saved context on the task stack. */ + " ldmia r2!, {r4-r7} \n" /* r4-r7 contain rest half of the hardware saved context. */ + " stmia r3!, {r4-r7} \n" /* Copy rest half of the the hardware saved context on the task stack. */ + " subs r2, #48 \n" + " ldmia r2!, {r4-r7} \n" /* Restore r8-r11. */ + " mov r8, r4 \n" /* r8 = r4. */ + " mov r9, r5 \n" /* r9 = r5. */ + " mov r10, r6 \n" /* r10 = r6. */ + " mov r11, r7 \n" /* r11 = r7. */ + " subs r2, #32 \n" + " ldmia r2!, {r4-r7} \n" /* Restore r4-r7. */ + " subs r2, #16 \n" + " \n" + " restore_context_done: \n" + " str r2, [r1] \n" /* Save the location where the context should be saved next as the first member of TCB. */ + " bx lr \n" + " \n" + " .align 4 \n" + " pxCurrentTCBConst: .word pxCurrentTCB \n" + " xSecureContextConst: .word xSecureContext \n" + " xMPUCTRLConst: .word 0xe000ed94 \n" + " xMAIR0Const: .word 0xe000edc0 \n" + " xRNRConst: .word 0xe000ed98 \n" + " xRBARConst: .word 0xe000ed9c \n" + ); +} + +#else /* configENABLE_MPU */ + void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ { __asm volatile @@ -260,52 +465,26 @@ void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ " bpl save_ns_context \n"/* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ " ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r3] \n"/* Read pxCurrentTCB. */ - #if ( configENABLE_MPU == 1 ) - " subs r2, r2, #16 \n"/* Make space for xSecureContext, PSPLIM, CONTROL and LR on the stack. */ - " str r2, [r1] \n"/* Save the new top of stack in TCB. */ - " mrs r1, psplim \n"/* r1 = PSPLIM. */ - " mrs r3, control \n"/* r3 = CONTROL. */ - " mov r4, lr \n"/* r4 = LR/EXC_RETURN. */ - " stmia r2!, {r0, r1, r3, r4} \n"/* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */ - #else /* configENABLE_MPU */ - " subs r2, r2, #12 \n"/* Make space for xSecureContext, PSPLIM and LR on the stack. */ - " str r2, [r1] \n"/* Save the new top of stack in TCB. */ - " mrs r1, psplim \n"/* r1 = PSPLIM. */ - " mov r3, lr \n"/* r3 = LR/EXC_RETURN. */ - " stmia r2!, {r0, r1, r3} \n"/* Store xSecureContext, PSPLIM and LR on the stack. */ - #endif /* configENABLE_MPU */ + " subs r2, r2, #12 \n"/* Make space for xSecureContext, PSPLIM and LR on the stack. */ + " str r2, [r1] \n"/* Save the new top of stack in TCB. */ + " mrs r1, psplim \n"/* r1 = PSPLIM. */ + " mov r3, lr \n"/* r3 = LR/EXC_RETURN. */ + " stmia r2!, {r0, r1, r3} \n"/* Store xSecureContext, PSPLIM and LR on the stack. */ " b select_next_task \n" " \n" " save_ns_context: \n" " ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r3] \n"/* Read pxCurrentTCB. */ - #if ( configENABLE_MPU == 1 ) - " subs r2, r2, #48 \n"/* Make space for xSecureContext, PSPLIM, CONTROL, LR and the remaining registers on the stack. */ - " str r2, [r1] \n"/* Save the new top of stack in TCB. */ - " adds r2, r2, #16 \n"/* r2 = r2 + 16. */ - " stmia r2!, {r4-r7} \n"/* Store the low registers that are not saved automatically. */ - " mov r4, r8 \n"/* r4 = r8. */ - " mov r5, r9 \n"/* r5 = r9. */ - " mov r6, r10 \n"/* r6 = r10. */ - " mov r7, r11 \n"/* r7 = r11. */ - " stmia r2!, {r4-r7} \n"/* Store the high registers that are not saved automatically. */ - " mrs r1, psplim \n"/* r1 = PSPLIM. */ - " mrs r3, control \n"/* r3 = CONTROL. */ - " mov r4, lr \n"/* r4 = LR/EXC_RETURN. */ - " subs r2, r2, #48 \n"/* r2 = r2 - 48. */ - " stmia r2!, {r0, r1, r3, r4} \n"/* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */ - #else /* configENABLE_MPU */ - " subs r2, r2, #44 \n"/* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */ - " str r2, [r1] \n"/* Save the new top of stack in TCB. */ - " mrs r1, psplim \n"/* r1 = PSPLIM. */ - " mov r3, lr \n"/* r3 = LR/EXC_RETURN. */ - " stmia r2!, {r0, r1, r3-r7} \n"/* Store xSecureContext, PSPLIM, LR and the low registers that are not saved automatically. */ - " mov r4, r8 \n"/* r4 = r8. */ - " mov r5, r9 \n"/* r5 = r9. */ - " mov r6, r10 \n"/* r6 = r10. */ - " mov r7, r11 \n"/* r7 = r11. */ - " stmia r2!, {r4-r7} \n"/* Store the high registers that are not saved automatically. */ - #endif /* configENABLE_MPU */ + " subs r2, r2, #44 \n"/* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */ + " str r2, [r1] \n"/* Save the new top of stack in TCB. */ + " mrs r1, psplim \n"/* r1 = PSPLIM. */ + " mov r3, lr \n"/* r3 = LR/EXC_RETURN. */ + " stmia r2!, {r0, r1, r3-r7} \n"/* Store xSecureContext, PSPLIM, LR and the low registers that are not saved automatically. */ + " mov r4, r8 \n"/* r4 = r8. */ + " mov r5, r9 \n"/* r5 = r9. */ + " mov r6, r10 \n"/* r6 = r10. */ + " mov r7, r11 \n"/* r7 = r11. */ + " stmia r2!, {r4-r7} \n"/* Store the high registers that are not saved automatically. */ " \n" " select_next_task: \n" " cpsid i \n" @@ -316,85 +495,22 @@ void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ " ldr r1, [r3] \n"/* Read pxCurrentTCB. */ " ldr r2, [r1] \n"/* The first item in pxCurrentTCB is the task top of stack. r2 now points to the top of stack. */ " \n" - #if ( configENABLE_MPU == 1 ) - " dmb \n"/* Complete outstanding transfers before disabling MPU. */ - " ldr r3, xMPUCTRLConst \n"/* r3 = 0xe000ed94 [Location of MPU_CTRL]. */ - " ldr r4, [r3] \n"/* Read the value of MPU_CTRL. */ - " movs r5, #1 \n"/* r5 = 1. */ - " bics r4, r5 \n"/* r4 = r4 & ~r5 i.e. Clear the bit 0 in r4. */ - " str r4, [r3] \n"/* Disable MPU. */ - " \n" - " adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */ - " ldr r4, [r1] \n"/* r4 = *r1 i.e. r4 = MAIR0. */ - " ldr r3, xMAIR0Const \n"/* r3 = 0xe000edc0 [Location of MAIR0]. */ - " str r4, [r3] \n"/* Program MAIR0. */ - " ldr r4, xRNRConst \n"/* r4 = 0xe000ed98 [Location of RNR]. */ - " adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to first RBAR in TCB. */ - " movs r5, #4 \n"/* r5 = 4. */ - " str r5, [r4] \n"/* Program RNR = 4. */ - " ldmia r1!, {r6,r7} \n"/* Read first set of RBAR/RLAR from TCB. */ - " ldr r3, xRBARConst \n"/* r3 = 0xe000ed9c [Location of RBAR]. */ - " stmia r3!, {r6,r7} \n"/* Write first set of RBAR/RLAR registers. */ - " movs r5, #5 \n"/* r5 = 5. */ - " str r5, [r4] \n"/* Program RNR = 5. */ - " ldmia r1!, {r6,r7} \n"/* Read second set of RBAR/RLAR from TCB. */ - " ldr r3, xRBARConst \n"/* r3 = 0xe000ed9c [Location of RBAR]. */ - " stmia r3!, {r6,r7} \n"/* Write second set of RBAR/RLAR registers. */ - " movs r5, #6 \n"/* r5 = 6. */ - " str r5, [r4] \n"/* Program RNR = 6. */ - " ldmia r1!, {r6,r7} \n"/* Read third set of RBAR/RLAR from TCB. */ - " ldr r3, xRBARConst \n"/* r3 = 0xe000ed9c [Location of RBAR]. */ - " stmia r3!, {r6,r7} \n"/* Write third set of RBAR/RLAR registers. */ - " movs r5, #7 \n"/* r5 = 7. */ - " str r5, [r4] \n"/* Program RNR = 7. */ - " ldmia r1!, {r6,r7} \n"/* Read fourth set of RBAR/RLAR from TCB. */ - " ldr r3, xRBARConst \n"/* r3 = 0xe000ed9c [Location of RBAR]. */ - " stmia r3!, {r6,r7} \n"/* Write fourth set of RBAR/RLAR registers. */ - " \n" - " ldr r3, xMPUCTRLConst \n"/* r3 = 0xe000ed94 [Location of MPU_CTRL]. */ - " ldr r4, [r3] \n"/* Read the value of MPU_CTRL. */ - " movs r5, #1 \n"/* r5 = 1. */ - " orrs r4, r5 \n"/* r4 = r4 | r5 i.e. Set the bit 0 in r4. */ - " str r4, [r3] \n"/* Enable MPU. */ - " dsb \n"/* Force memory writes before continuing. */ - #endif /* configENABLE_MPU */ - " \n" - #if ( configENABLE_MPU == 1 ) - " ldmia r2!, {r0, r1, r3, r4} \n"/* Read from stack - r0 = xSecureContext, r1 = PSPLIM, r3 = CONTROL and r4 = LR. */ - " msr psplim, r1 \n"/* Restore the PSPLIM register value for the task. */ - " msr control, r3 \n"/* Restore the CONTROL register value for the task. */ - " mov lr, r4 \n"/* LR = r4. */ - " ldr r3, xSecureContextConst \n"/* Read the location of xSecureContext i.e. &( xSecureContext ). */ - " str r0, [r3] \n"/* Restore the task's xSecureContext. */ - " cbz r0, restore_ns_context \n"/* If there is no secure context for the task, restore the non-secure context. */ - " ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - " ldr r1, [r3] \n"/* Read pxCurrentTCB. */ - " push {r2, r4} \n" - " bl SecureContext_LoadContext \n"/* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ - " pop {r2, r4} \n" - " mov lr, r4 \n"/* LR = r4. */ - " lsls r1, r4, #25 \n"/* r1 = r4 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ - " bpl restore_ns_context \n"/* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ - " msr psp, r2 \n"/* Remember the new top of stack for the task. */ - " bx lr \n" - #else /* configENABLE_MPU */ - " ldmia r2!, {r0, r1, r4} \n"/* Read from stack - r0 = xSecureContext, r1 = PSPLIM and r4 = LR. */ - " msr psplim, r1 \n"/* Restore the PSPLIM register value for the task. */ - " mov lr, r4 \n"/* LR = r4. */ - " ldr r3, xSecureContextConst \n"/* Read the location of xSecureContext i.e. &( xSecureContext ). */ - " str r0, [r3] \n"/* Restore the task's xSecureContext. */ - " cbz r0, restore_ns_context \n"/* If there is no secure context for the task, restore the non-secure context. */ - " ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - " ldr r1, [r3] \n"/* Read pxCurrentTCB. */ - " push {r2, r4} \n" - " bl SecureContext_LoadContext \n"/* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ - " pop {r2, r4} \n" - " mov lr, r4 \n"/* LR = r4. */ - " lsls r1, r4, #25 \n"/* r1 = r4 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ - " bpl restore_ns_context \n"/* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ - " msr psp, r2 \n"/* Remember the new top of stack for the task. */ - " bx lr \n" - #endif /* configENABLE_MPU */ + " ldmia r2!, {r0, r1, r4} \n"/* Read from stack - r0 = xSecureContext, r1 = PSPLIM and r4 = LR. */ + " msr psplim, r1 \n"/* Restore the PSPLIM register value for the task. */ + " mov lr, r4 \n"/* LR = r4. */ + " ldr r3, xSecureContextConst \n"/* Read the location of xSecureContext i.e. &( xSecureContext ). */ + " str r0, [r3] \n"/* Restore the task's xSecureContext. */ + " cbz r0, restore_ns_context \n"/* If there is no secure context for the task, restore the non-secure context. */ + " ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r1, [r3] \n"/* Read pxCurrentTCB. */ + " push {r2, r4} \n" + " bl SecureContext_LoadContext \n"/* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ + " pop {r2, r4} \n" + " mov lr, r4 \n"/* LR = r4. */ + " lsls r1, r4, #25 \n"/* r1 = r4 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ + " bpl restore_ns_context \n"/* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ + " msr psp, r2 \n"/* Remember the new top of stack for the task. */ + " bx lr \n" " \n" " restore_ns_context: \n" " adds r2, r2, #16 \n"/* Move to the high registers. */ @@ -411,16 +527,62 @@ void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ " .align 4 \n" "pxCurrentTCBConst: .word pxCurrentTCB \n" "xSecureContextConst: .word xSecureContext \n" - #if ( configENABLE_MPU == 1 ) - "xMPUCTRLConst: .word 0xe000ed94 \n" - "xMAIR0Const: .word 0xe000edc0 \n" - "xRNRConst: .word 0xe000ed98 \n" - "xRBARConst: .word 0xe000ed9c \n" - #endif /* configENABLE_MPU */ ); } + +#endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + +void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ +{ + __asm volatile + ( + ".syntax unified \n" + ".extern vPortSVCHandler_C \n" + ".extern vSystemCallEnter \n" + ".extern vSystemCallEnter_1 \n" + ".extern vSystemCallExit \n" + " \n" + "movs r0, #4 \n" + "mov r1, lr \n" + "tst r0, r1 \n" + "beq stack_on_msp \n" + "stack_on_psp: \n" + " mrs r0, psp \n" + " b route_svc \n" + "stack_on_msp: \n" + " mrs r0, msp \n" + " b route_svc \n" + " \n" + "route_svc: \n" + " ldr r2, [r0, #24] \n" + " subs r2, #2 \n" + " ldrb r3, [r2, #0] \n" + " cmp r3, %0 \n" + " beq system_call_enter \n" + " cmp r3, %1 \n" + " beq system_call_enter_1 \n" + " cmp r3, %2 \n" + " beq system_call_exit \n" + " b vPortSVCHandler_C \n" + " \n" + "system_call_enter: \n" + " b vSystemCallEnter \n" + "system_call_enter_1: \n" + " b vSystemCallEnter_1 \n" + "system_call_exit: \n" + " b vSystemCallExit \n" + " \n" + : /* No outputs. */ + :"i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_ENTER_1 ), "i" ( portSVC_SYSTEM_CALL_EXIT ) + : "r0", "r1", "r2", "r3", "memory" + ); +} + +#else /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ { __asm volatile @@ -443,6 +605,8 @@ void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ "svchandler_address_const: .word vPortSVCHandler_C \n" ); } + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ /*-----------------------------------------------------------*/ void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) /* __attribute__ (( naked )) */ diff --git a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM23/portmacro.h b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM23/portmacro.h index 746f734b8ac..5fd94c1c371 100644 --- a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM23/portmacro.h +++ b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM23/portmacro.h @@ -51,7 +51,6 @@ #define portARCH_NAME "Cortex-M23" #define portHAS_BASEPRI 0 #define portDONT_DISCARD __attribute__( ( used ) ) -#define portNORETURN __attribute__( ( noreturn ) ) /*-----------------------------------------------------------*/ /* ARMv8-M common port configurations. */ diff --git a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM23_NTZ/mpu_wrappers_v2_asm.c b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM23_NTZ/mpu_wrappers_v2_asm.c new file mode 100644 index 00000000000..a1e5ce0828f --- /dev/null +++ b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM23_NTZ/mpu_wrappers_v2_asm.c @@ -0,0 +1,2419 @@ +/* + * FreeRTOS Kernel + * Copyright (C) 2021 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 + * + */ + +/* 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. */ +#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +/* Scheduler includes. */ +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" +#include "timers.h" +#include "event_groups.h" +#include "stream_buffer.h" + +#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + +#if ( INCLUDE_xTaskDelayUntil == 1 ) + +BaseType_t MPU_xTaskDelayUntil( TickType_t * const pxPreviousWakeTime, + const TickType_t xTimeIncrement ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskDelayUntil( TickType_t * const pxPreviousWakeTime, + const TickType_t xTimeIncrement ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskDelayUntilImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xTaskDelayUntil_Unpriv \n" + " MPU_xTaskDelayUntil_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xTaskDelayUntilImpl \n" + " MPU_xTaskDelayUntil_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xTaskDelayUntilImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_xTaskDelayUntil == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_xTaskAbortDelay == 1 ) + +BaseType_t MPU_xTaskAbortDelay( TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskAbortDelay( TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskAbortDelayImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xTaskAbortDelay_Unpriv \n" + " MPU_xTaskAbortDelay_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xTaskAbortDelayImpl \n" + " MPU_xTaskAbortDelay_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xTaskAbortDelayImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_xTaskAbortDelay == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskDelay == 1 ) + +void MPU_vTaskDelay( const TickType_t xTicksToDelay ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskDelay( const TickType_t xTicksToDelay ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskDelayImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_vTaskDelay_Unpriv \n" + " MPU_vTaskDelay_Priv: \n" + " pop {r0, r1} \n" + " b MPU_vTaskDelayImpl \n" + " MPU_vTaskDelay_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_vTaskDelayImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_vTaskDelay == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_uxTaskPriorityGet == 1 ) + +UBaseType_t MPU_uxTaskPriorityGet( const TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxTaskPriorityGet( const TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxTaskPriorityGetImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_uxTaskPriorityGet_Unpriv \n" + " MPU_uxTaskPriorityGet_Priv: \n" + " pop {r0, r1} \n" + " b MPU_uxTaskPriorityGetImpl \n" + " MPU_uxTaskPriorityGet_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_uxTaskPriorityGetImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_uxTaskPriorityGet == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_eTaskGetState == 1 ) + +eTaskState MPU_eTaskGetState( TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +eTaskState MPU_eTaskGetState( TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_eTaskGetStateImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_eTaskGetState_Unpriv \n" + " MPU_eTaskGetState_Priv: \n" + " pop {r0, r1} \n" + " b MPU_eTaskGetStateImpl \n" + " MPU_eTaskGetState_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_eTaskGetStateImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_eTaskGetState == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + +void MPU_vTaskGetInfo( TaskHandle_t xTask, + TaskStatus_t * pxTaskStatus, + BaseType_t xGetFreeStackSpace, + eTaskState eState ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskGetInfo( TaskHandle_t xTask, + TaskStatus_t * pxTaskStatus, + BaseType_t xGetFreeStackSpace, + eTaskState eState ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskGetInfoImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_vTaskGetInfo_Unpriv \n" + " MPU_vTaskGetInfo_Priv: \n" + " pop {r0, r1} \n" + " b MPU_vTaskGetInfoImpl \n" + " MPU_vTaskGetInfo_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_vTaskGetInfoImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TRACE_FACILITY == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) + +TaskHandle_t MPU_xTaskGetIdleTaskHandle( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TaskHandle_t MPU_xTaskGetIdleTaskHandle( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGetIdleTaskHandleImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xTaskGetIdleTaskHandle_Unpriv \n" + " MPU_xTaskGetIdleTaskHandle_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xTaskGetIdleTaskHandleImpl \n" + " MPU_xTaskGetIdleTaskHandle_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xTaskGetIdleTaskHandleImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskSuspend == 1 ) + +void MPU_vTaskSuspend( TaskHandle_t xTaskToSuspend ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskSuspend( TaskHandle_t xTaskToSuspend ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskSuspendImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_vTaskSuspend_Unpriv \n" + " MPU_vTaskSuspend_Priv: \n" + " pop {r0, r1} \n" + " b MPU_vTaskSuspendImpl \n" + " MPU_vTaskSuspend_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_vTaskSuspendImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_vTaskSuspend == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskSuspend == 1 ) + +void MPU_vTaskResume( TaskHandle_t xTaskToResume ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskResume( TaskHandle_t xTaskToResume ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskResumeImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_vTaskResume_Unpriv \n" + " MPU_vTaskResume_Priv: \n" + " pop {r0, r1} \n" + " b MPU_vTaskResumeImpl \n" + " MPU_vTaskResume_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_vTaskResumeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_vTaskSuspend == 1 ) */ +/*-----------------------------------------------------------*/ + +TickType_t MPU_xTaskGetTickCount( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TickType_t MPU_xTaskGetTickCount( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGetTickCountImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xTaskGetTickCount_Unpriv \n" + " MPU_xTaskGetTickCount_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xTaskGetTickCountImpl \n" + " MPU_xTaskGetTickCount_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xTaskGetTickCountImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +UBaseType_t MPU_uxTaskGetNumberOfTasks( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxTaskGetNumberOfTasks( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxTaskGetNumberOfTasksImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_uxTaskGetNumberOfTasks_Unpriv \n" + " MPU_uxTaskGetNumberOfTasks_Priv: \n" + " pop {r0, r1} \n" + " b MPU_uxTaskGetNumberOfTasksImpl \n" + " MPU_uxTaskGetNumberOfTasks_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_uxTaskGetNumberOfTasksImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +char * MPU_pcTaskGetName( TaskHandle_t xTaskToQuery ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +char * MPU_pcTaskGetName( TaskHandle_t xTaskToQuery ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_pcTaskGetNameImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_pcTaskGetName_Unpriv \n" + " MPU_pcTaskGetName_Priv: \n" + " pop {r0, r1} \n" + " b MPU_pcTaskGetNameImpl \n" + " MPU_pcTaskGetName_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_pcTaskGetNameImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +#if ( configGENERATE_RUN_TIME_STATS == 1 ) + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetRunTimeCounter( const TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetRunTimeCounter( const TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_ulTaskGetRunTimeCounterImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_ulTaskGetRunTimeCounter_Unpriv \n" + " MPU_ulTaskGetRunTimeCounter_Priv: \n" + " pop {r0, r1} \n" + " b MPU_ulTaskGetRunTimeCounterImpl \n" + " MPU_ulTaskGetRunTimeCounter_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_ulTaskGetRunTimeCounterImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( ( configGENERATE_RUN_TIME_STATS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configGENERATE_RUN_TIME_STATS == 1 ) + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetRunTimePercent( const TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetRunTimePercent( const TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_ulTaskGetRunTimePercentImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_ulTaskGetRunTimePercent_Unpriv \n" + " MPU_ulTaskGetRunTimePercent_Priv: \n" + " pop {r0, r1} \n" + " b MPU_ulTaskGetRunTimePercentImpl \n" + " MPU_ulTaskGetRunTimePercent_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_ulTaskGetRunTimePercentImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( ( configGENERATE_RUN_TIME_STATS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimePercent( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimePercent( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_ulTaskGetIdleRunTimePercentImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_ulTaskGetIdleRunTimePercent_Unpriv \n" + " MPU_ulTaskGetIdleRunTimePercent_Priv: \n" + " pop {r0, r1} \n" + " b MPU_ulTaskGetIdleRunTimePercentImpl \n" + " MPU_ulTaskGetIdleRunTimePercent_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_ulTaskGetIdleRunTimePercentImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimeCounter( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimeCounter( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_ulTaskGetIdleRunTimeCounterImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_ulTaskGetIdleRunTimeCounter_Unpriv \n" + " MPU_ulTaskGetIdleRunTimeCounter_Priv: \n" + " pop {r0, r1} \n" + " b MPU_ulTaskGetIdleRunTimeCounterImpl \n" + " MPU_ulTaskGetIdleRunTimeCounter_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_ulTaskGetIdleRunTimeCounterImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_APPLICATION_TASK_TAG == 1 ) + +void MPU_vTaskSetApplicationTaskTag( TaskHandle_t xTask, + TaskHookFunction_t pxHookFunction ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskSetApplicationTaskTag( TaskHandle_t xTask, + TaskHookFunction_t pxHookFunction ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskSetApplicationTaskTagImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_vTaskSetApplicationTaskTag_Unpriv \n" + " MPU_vTaskSetApplicationTaskTag_Priv: \n" + " pop {r0, r1} \n" + " b MPU_vTaskSetApplicationTaskTagImpl \n" + " MPU_vTaskSetApplicationTaskTag_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_vTaskSetApplicationTaskTagImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_APPLICATION_TASK_TAG == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_APPLICATION_TASK_TAG == 1 ) + +TaskHookFunction_t MPU_xTaskGetApplicationTaskTag( TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TaskHookFunction_t MPU_xTaskGetApplicationTaskTag( TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGetApplicationTaskTagImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xTaskGetApplicationTaskTag_Unpriv \n" + " MPU_xTaskGetApplicationTaskTag_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xTaskGetApplicationTaskTagImpl \n" + " MPU_xTaskGetApplicationTaskTag_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xTaskGetApplicationTaskTagImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_APPLICATION_TASK_TAG == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) + +void MPU_vTaskSetThreadLocalStoragePointer( TaskHandle_t xTaskToSet, + BaseType_t xIndex, + void * pvValue ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskSetThreadLocalStoragePointer( TaskHandle_t xTaskToSet, + BaseType_t xIndex, + void * pvValue ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskSetThreadLocalStoragePointerImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_vTaskSetThreadLocalStoragePointer_Unpriv \n" + " MPU_vTaskSetThreadLocalStoragePointer_Priv: \n" + " pop {r0, r1} \n" + " b MPU_vTaskSetThreadLocalStoragePointerImpl \n" + " MPU_vTaskSetThreadLocalStoragePointer_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_vTaskSetThreadLocalStoragePointerImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) + +void * MPU_pvTaskGetThreadLocalStoragePointer( TaskHandle_t xTaskToQuery, + BaseType_t xIndex ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void * MPU_pvTaskGetThreadLocalStoragePointer( TaskHandle_t xTaskToQuery, + BaseType_t xIndex ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_pvTaskGetThreadLocalStoragePointerImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_pvTaskGetThreadLocalStoragePointer_Unpriv \n" + " MPU_pvTaskGetThreadLocalStoragePointer_Priv: \n" + " pop {r0, r1} \n" + " b MPU_pvTaskGetThreadLocalStoragePointerImpl \n" + " MPU_pvTaskGetThreadLocalStoragePointer_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_pvTaskGetThreadLocalStoragePointerImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + +UBaseType_t MPU_uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray, + const UBaseType_t uxArraySize, + configRUN_TIME_COUNTER_TYPE * const pulTotalRunTime ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray, + const UBaseType_t uxArraySize, + configRUN_TIME_COUNTER_TYPE * const pulTotalRunTime ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxTaskGetSystemStateImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_uxTaskGetSystemState_Unpriv \n" + " MPU_uxTaskGetSystemState_Priv: \n" + " pop {r0, r1} \n" + " b MPU_uxTaskGetSystemStateImpl \n" + " MPU_uxTaskGetSystemState_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_uxTaskGetSystemStateImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TRACE_FACILITY == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) + +UBaseType_t MPU_uxTaskGetStackHighWaterMark( TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxTaskGetStackHighWaterMark( TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxTaskGetStackHighWaterMarkImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_uxTaskGetStackHighWaterMark_Unpriv \n" + " MPU_uxTaskGetStackHighWaterMark_Priv: \n" + " pop {r0, r1} \n" + " b MPU_uxTaskGetStackHighWaterMarkImpl \n" + " MPU_uxTaskGetStackHighWaterMark_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_uxTaskGetStackHighWaterMarkImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) + +configSTACK_DEPTH_TYPE MPU_uxTaskGetStackHighWaterMark2( TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +configSTACK_DEPTH_TYPE MPU_uxTaskGetStackHighWaterMark2( TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxTaskGetStackHighWaterMark2Impl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_uxTaskGetStackHighWaterMark2_Unpriv \n" + " MPU_uxTaskGetStackHighWaterMark2_Priv: \n" + " pop {r0, r1} \n" + " b MPU_uxTaskGetStackHighWaterMark2Impl \n" + " MPU_uxTaskGetStackHighWaterMark2_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_uxTaskGetStackHighWaterMark2Impl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) ) + +TaskHandle_t MPU_xTaskGetCurrentTaskHandle( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TaskHandle_t MPU_xTaskGetCurrentTaskHandle( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGetCurrentTaskHandleImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xTaskGetCurrentTaskHandle_Unpriv \n" + " MPU_xTaskGetCurrentTaskHandle_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xTaskGetCurrentTaskHandleImpl \n" + " MPU_xTaskGetCurrentTaskHandle_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xTaskGetCurrentTaskHandleImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_xTaskGetSchedulerState == 1 ) + +BaseType_t MPU_xTaskGetSchedulerState( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskGetSchedulerState( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGetSchedulerStateImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xTaskGetSchedulerState_Unpriv \n" + " MPU_xTaskGetSchedulerState_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xTaskGetSchedulerStateImpl \n" + " MPU_xTaskGetSchedulerState_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xTaskGetSchedulerStateImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_xTaskGetSchedulerState == 1 ) */ +/*-----------------------------------------------------------*/ + +void MPU_vTaskSetTimeOutState( TimeOut_t * const pxTimeOut ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskSetTimeOutState( TimeOut_t * const pxTimeOut ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskSetTimeOutStateImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_vTaskSetTimeOutState_Unpriv \n" + " MPU_vTaskSetTimeOutState_Priv: \n" + " pop {r0, r1} \n" + " b MPU_vTaskSetTimeOutStateImpl \n" + " MPU_vTaskSetTimeOutState_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_vTaskSetTimeOutStateImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut, + TickType_t * const pxTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut, + TickType_t * const pxTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskCheckForTimeOutImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xTaskCheckForTimeOut_Unpriv \n" + " MPU_xTaskCheckForTimeOut_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xTaskCheckForTimeOutImpl \n" + " MPU_xTaskCheckForTimeOut_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xTaskCheckForTimeOutImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +#if ( configUSE_TASK_NOTIFICATIONS == 1 ) + +BaseType_t MPU_xTaskGenericNotify( TaskHandle_t xTaskToNotify, + UBaseType_t uxIndexToNotify, + uint32_t ulValue, + eNotifyAction eAction, + uint32_t * pulPreviousNotificationValue ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskGenericNotify( TaskHandle_t xTaskToNotify, + UBaseType_t uxIndexToNotify, + uint32_t ulValue, + eNotifyAction eAction, + uint32_t * pulPreviousNotificationValue ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGenericNotifyImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xTaskGenericNotify_Unpriv \n" + " MPU_xTaskGenericNotify_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xTaskGenericNotifyImpl \n" + " MPU_xTaskGenericNotify_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xTaskGenericNotifyImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER_1 ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TASK_NOTIFICATIONS == 1 ) + +BaseType_t MPU_xTaskGenericNotifyWait( UBaseType_t uxIndexToWaitOn, + uint32_t ulBitsToClearOnEntry, + uint32_t ulBitsToClearOnExit, + uint32_t * pulNotificationValue, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskGenericNotifyWait( UBaseType_t uxIndexToWaitOn, + uint32_t ulBitsToClearOnEntry, + uint32_t ulBitsToClearOnExit, + uint32_t * pulNotificationValue, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGenericNotifyWaitImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xTaskGenericNotifyWait_Unpriv \n" + " MPU_xTaskGenericNotifyWait_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xTaskGenericNotifyWaitImpl \n" + " MPU_xTaskGenericNotifyWait_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xTaskGenericNotifyWaitImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER_1 ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TASK_NOTIFICATIONS == 1 ) + +uint32_t MPU_ulTaskGenericNotifyTake( UBaseType_t uxIndexToWaitOn, + BaseType_t xClearCountOnExit, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +uint32_t MPU_ulTaskGenericNotifyTake( UBaseType_t uxIndexToWaitOn, + BaseType_t xClearCountOnExit, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_ulTaskGenericNotifyTakeImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_ulTaskGenericNotifyTake_Unpriv \n" + " MPU_ulTaskGenericNotifyTake_Priv: \n" + " pop {r0, r1} \n" + " b MPU_ulTaskGenericNotifyTakeImpl \n" + " MPU_ulTaskGenericNotifyTake_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_ulTaskGenericNotifyTakeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TASK_NOTIFICATIONS == 1 ) + +BaseType_t MPU_xTaskGenericNotifyStateClear( TaskHandle_t xTask, + UBaseType_t uxIndexToClear ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskGenericNotifyStateClear( TaskHandle_t xTask, + UBaseType_t uxIndexToClear ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGenericNotifyStateClearImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xTaskGenericNotifyStateClear_Unpriv \n" + " MPU_xTaskGenericNotifyStateClear_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xTaskGenericNotifyStateClearImpl \n" + " MPU_xTaskGenericNotifyStateClear_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xTaskGenericNotifyStateClearImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TASK_NOTIFICATIONS == 1 ) + +uint32_t MPU_ulTaskGenericNotifyValueClear( TaskHandle_t xTask, + UBaseType_t uxIndexToClear, + uint32_t ulBitsToClear ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +uint32_t MPU_ulTaskGenericNotifyValueClear( TaskHandle_t xTask, + UBaseType_t uxIndexToClear, + uint32_t ulBitsToClear ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_ulTaskGenericNotifyValueClearImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_ulTaskGenericNotifyValueClear_Unpriv \n" + " MPU_ulTaskGenericNotifyValueClear_Priv: \n" + " pop {r0, r1} \n" + " b MPU_ulTaskGenericNotifyValueClearImpl \n" + " MPU_ulTaskGenericNotifyValueClear_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_ulTaskGenericNotifyValueClearImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xQueueGenericSend( QueueHandle_t xQueue, + const void * const pvItemToQueue, + TickType_t xTicksToWait, + const BaseType_t xCopyPosition ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueueGenericSend( QueueHandle_t xQueue, + const void * const pvItemToQueue, + TickType_t xTicksToWait, + const BaseType_t xCopyPosition ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueGenericSendImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xQueueGenericSend_Unpriv \n" + " MPU_xQueueGenericSend_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xQueueGenericSendImpl \n" + " MPU_xQueueGenericSend_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xQueueGenericSendImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +UBaseType_t MPU_uxQueueMessagesWaiting( const QueueHandle_t xQueue ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxQueueMessagesWaiting( const QueueHandle_t xQueue ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxQueueMessagesWaitingImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_uxQueueMessagesWaiting_Unpriv \n" + " MPU_uxQueueMessagesWaiting_Priv: \n" + " pop {r0, r1} \n" + " b MPU_uxQueueMessagesWaitingImpl \n" + " MPU_uxQueueMessagesWaiting_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_uxQueueMessagesWaitingImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +UBaseType_t MPU_uxQueueSpacesAvailable( const QueueHandle_t xQueue ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxQueueSpacesAvailable( const QueueHandle_t xQueue ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxQueueSpacesAvailableImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_uxQueueSpacesAvailable_Unpriv \n" + " MPU_uxQueueSpacesAvailable_Priv: \n" + " pop {r0, r1} \n" + " b MPU_uxQueueSpacesAvailableImpl \n" + " MPU_uxQueueSpacesAvailable_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_uxQueueSpacesAvailableImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xQueueReceive( QueueHandle_t xQueue, + void * const pvBuffer, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueueReceive( QueueHandle_t xQueue, + void * const pvBuffer, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueReceiveImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xQueueReceive_Unpriv \n" + " MPU_xQueueReceive_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xQueueReceiveImpl \n" + " MPU_xQueueReceive_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xQueueReceiveImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xQueuePeek( QueueHandle_t xQueue, + void * const pvBuffer, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueuePeek( QueueHandle_t xQueue, + void * const pvBuffer, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueuePeekImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xQueuePeek_Unpriv \n" + " MPU_xQueuePeek_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xQueuePeekImpl \n" + " MPU_xQueuePeek_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xQueuePeekImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xQueueSemaphoreTake( QueueHandle_t xQueue, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueueSemaphoreTake( QueueHandle_t xQueue, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueSemaphoreTakeImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xQueueSemaphoreTake_Unpriv \n" + " MPU_xQueueSemaphoreTake_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xQueueSemaphoreTakeImpl \n" + " MPU_xQueueSemaphoreTake_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xQueueSemaphoreTakeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +#if ( ( configUSE_MUTEXES == 1 ) && ( INCLUDE_xSemaphoreGetMutexHolder == 1 ) ) + +TaskHandle_t MPU_xQueueGetMutexHolder( QueueHandle_t xSemaphore ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TaskHandle_t MPU_xQueueGetMutexHolder( QueueHandle_t xSemaphore ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueGetMutexHolderImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xQueueGetMutexHolder_Unpriv \n" + " MPU_xQueueGetMutexHolder_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xQueueGetMutexHolderImpl \n" + " MPU_xQueueGetMutexHolder_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xQueueGetMutexHolderImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( ( configUSE_MUTEXES == 1 ) && ( INCLUDE_xSemaphoreGetMutexHolder == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_RECURSIVE_MUTEXES == 1 ) + +BaseType_t MPU_xQueueTakeMutexRecursive( QueueHandle_t xMutex, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueueTakeMutexRecursive( QueueHandle_t xMutex, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueTakeMutexRecursiveImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xQueueTakeMutexRecursive_Unpriv \n" + " MPU_xQueueTakeMutexRecursive_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xQueueTakeMutexRecursiveImpl \n" + " MPU_xQueueTakeMutexRecursive_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xQueueTakeMutexRecursiveImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_RECURSIVE_MUTEXES == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_RECURSIVE_MUTEXES == 1 ) + +BaseType_t MPU_xQueueGiveMutexRecursive( QueueHandle_t pxMutex ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueueGiveMutexRecursive( QueueHandle_t pxMutex ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueGiveMutexRecursiveImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xQueueGiveMutexRecursive_Unpriv \n" + " MPU_xQueueGiveMutexRecursive_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xQueueGiveMutexRecursiveImpl \n" + " MPU_xQueueGiveMutexRecursive_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xQueueGiveMutexRecursiveImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_RECURSIVE_MUTEXES == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_QUEUE_SETS == 1 ) + +QueueSetMemberHandle_t MPU_xQueueSelectFromSet( QueueSetHandle_t xQueueSet, + const TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +QueueSetMemberHandle_t MPU_xQueueSelectFromSet( QueueSetHandle_t xQueueSet, + const TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueSelectFromSetImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xQueueSelectFromSet_Unpriv \n" + " MPU_xQueueSelectFromSet_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xQueueSelectFromSetImpl \n" + " MPU_xQueueSelectFromSet_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xQueueSelectFromSetImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_QUEUE_SETS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_QUEUE_SETS == 1 ) + +BaseType_t MPU_xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore, + QueueSetHandle_t xQueueSet ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore, + QueueSetHandle_t xQueueSet ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueAddToSetImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xQueueAddToSet_Unpriv \n" + " MPU_xQueueAddToSet_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xQueueAddToSetImpl \n" + " MPU_xQueueAddToSet_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xQueueAddToSetImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_QUEUE_SETS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configQUEUE_REGISTRY_SIZE > 0 ) + +void MPU_vQueueAddToRegistry( QueueHandle_t xQueue, + const char * pcName ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vQueueAddToRegistry( QueueHandle_t xQueue, + const char * pcName ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vQueueAddToRegistryImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_vQueueAddToRegistry_Unpriv \n" + " MPU_vQueueAddToRegistry_Priv: \n" + " pop {r0, r1} \n" + " b MPU_vQueueAddToRegistryImpl \n" + " MPU_vQueueAddToRegistry_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_vQueueAddToRegistryImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configQUEUE_REGISTRY_SIZE > 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configQUEUE_REGISTRY_SIZE > 0 ) + +void MPU_vQueueUnregisterQueue( QueueHandle_t xQueue ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vQueueUnregisterQueue( QueueHandle_t xQueue ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vQueueUnregisterQueueImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_vQueueUnregisterQueue_Unpriv \n" + " MPU_vQueueUnregisterQueue_Priv: \n" + " pop {r0, r1} \n" + " b MPU_vQueueUnregisterQueueImpl \n" + " MPU_vQueueUnregisterQueue_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_vQueueUnregisterQueueImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configQUEUE_REGISTRY_SIZE > 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configQUEUE_REGISTRY_SIZE > 0 ) + +const char * MPU_pcQueueGetName( QueueHandle_t xQueue ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +const char * MPU_pcQueueGetName( QueueHandle_t xQueue ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_pcQueueGetNameImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_pcQueueGetName_Unpriv \n" + " MPU_pcQueueGetName_Priv: \n" + " pop {r0, r1} \n" + " b MPU_pcQueueGetNameImpl \n" + " MPU_pcQueueGetName_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_pcQueueGetNameImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configQUEUE_REGISTRY_SIZE > 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +void * MPU_pvTimerGetTimerID( const TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void * MPU_pvTimerGetTimerID( const TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_pvTimerGetTimerIDImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_pvTimerGetTimerID_Unpriv \n" + " MPU_pvTimerGetTimerID_Priv: \n" + " pop {r0, r1} \n" + " b MPU_pvTimerGetTimerIDImpl \n" + " MPU_pvTimerGetTimerID_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_pvTimerGetTimerIDImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +void MPU_vTimerSetTimerID( TimerHandle_t xTimer, + void * pvNewID ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTimerSetTimerID( TimerHandle_t xTimer, + void * pvNewID ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTimerSetTimerIDImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_vTimerSetTimerID_Unpriv \n" + " MPU_vTimerSetTimerID_Priv: \n" + " pop {r0, r1} \n" + " b MPU_vTimerSetTimerIDImpl \n" + " MPU_vTimerSetTimerID_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_vTimerSetTimerIDImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +BaseType_t MPU_xTimerIsTimerActive( TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTimerIsTimerActive( TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTimerIsTimerActiveImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xTimerIsTimerActive_Unpriv \n" + " MPU_xTimerIsTimerActive_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xTimerIsTimerActiveImpl \n" + " MPU_xTimerIsTimerActive_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xTimerIsTimerActiveImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +TaskHandle_t MPU_xTimerGetTimerDaemonTaskHandle( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TaskHandle_t MPU_xTimerGetTimerDaemonTaskHandle( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTimerGetTimerDaemonTaskHandleImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xTimerGetTimerDaemonTaskHandle_Unpriv \n" + " MPU_xTimerGetTimerDaemonTaskHandle_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xTimerGetTimerDaemonTaskHandleImpl \n" + " MPU_xTimerGetTimerDaemonTaskHandle_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xTimerGetTimerDaemonTaskHandleImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +BaseType_t MPU_xTimerGenericCommand( TimerHandle_t xTimer, + const BaseType_t xCommandID, + const TickType_t xOptionalValue, + BaseType_t * const pxHigherPriorityTaskWoken, + const TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTimerGenericCommand( TimerHandle_t xTimer, + const BaseType_t xCommandID, + const TickType_t xOptionalValue, + BaseType_t * const pxHigherPriorityTaskWoken, + const TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTimerGenericCommandImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, ipsr \n" + " cmp r0, #0 \n" + " bne MPU_xTimerGenericCommand_Priv \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " beq MPU_xTimerGenericCommand_Priv \n" + " MPU_xTimerGenericCommand_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xTimerGenericCommandImpl \n" + " svc %1 \n" + " bx lr \n" + " MPU_xTimerGenericCommand_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xTimerGenericCommandImpl \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER_1 ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +const char * MPU_pcTimerGetName( TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +const char * MPU_pcTimerGetName( TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_pcTimerGetNameImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_pcTimerGetName_Unpriv \n" + " MPU_pcTimerGetName_Priv: \n" + " pop {r0, r1} \n" + " b MPU_pcTimerGetNameImpl \n" + " MPU_pcTimerGetName_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_pcTimerGetNameImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, + const BaseType_t uxAutoReload ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, + const BaseType_t uxAutoReload ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTimerSetReloadModeImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_vTimerSetReloadMode_Unpriv \n" + " MPU_vTimerSetReloadMode_Priv: \n" + " pop {r0, r1} \n" + " b MPU_vTimerSetReloadModeImpl \n" + " MPU_vTimerSetReloadMode_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_vTimerSetReloadModeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +BaseType_t MPU_xTimerGetReloadMode( TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTimerGetReloadMode( TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTimerGetReloadModeImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xTimerGetReloadMode_Unpriv \n" + " MPU_xTimerGetReloadMode_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xTimerGetReloadModeImpl \n" + " MPU_xTimerGetReloadMode_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xTimerGetReloadModeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +UBaseType_t MPU_uxTimerGetReloadMode( TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxTimerGetReloadMode( TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxTimerGetReloadModeImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_uxTimerGetReloadMode_Unpriv \n" + " MPU_uxTimerGetReloadMode_Priv: \n" + " pop {r0, r1} \n" + " b MPU_uxTimerGetReloadModeImpl \n" + " MPU_uxTimerGetReloadMode_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_uxTimerGetReloadModeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +TickType_t MPU_xTimerGetPeriod( TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TickType_t MPU_xTimerGetPeriod( TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTimerGetPeriodImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xTimerGetPeriod_Unpriv \n" + " MPU_xTimerGetPeriod_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xTimerGetPeriodImpl \n" + " MPU_xTimerGetPeriod_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xTimerGetPeriodImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +TickType_t MPU_xTimerGetExpiryTime( TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TickType_t MPU_xTimerGetExpiryTime( TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTimerGetExpiryTimeImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xTimerGetExpiryTime_Unpriv \n" + " MPU_xTimerGetExpiryTime_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xTimerGetExpiryTimeImpl \n" + " MPU_xTimerGetExpiryTime_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xTimerGetExpiryTimeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +EventBits_t MPU_xEventGroupWaitBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToWaitFor, + const BaseType_t xClearOnExit, + const BaseType_t xWaitForAllBits, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +EventBits_t MPU_xEventGroupWaitBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToWaitFor, + const BaseType_t xClearOnExit, + const BaseType_t xWaitForAllBits, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupWaitBitsImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xEventGroupWaitBits_Unpriv \n" + " MPU_xEventGroupWaitBits_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xEventGroupWaitBitsImpl \n" + " MPU_xEventGroupWaitBits_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xEventGroupWaitBitsImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER_1 ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToClear ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToClear ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupClearBitsImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xEventGroupClearBits_Unpriv \n" + " MPU_xEventGroupClearBits_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xEventGroupClearBitsImpl \n" + " MPU_xEventGroupClearBits_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xEventGroupClearBitsImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupSetBitsImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xEventGroupSetBits_Unpriv \n" + " MPU_xEventGroupSetBits_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xEventGroupSetBitsImpl \n" + " MPU_xEventGroupSetBits_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xEventGroupSetBitsImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet, + const EventBits_t uxBitsToWaitFor, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet, + const EventBits_t uxBitsToWaitFor, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupSyncImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xEventGroupSync_Unpriv \n" + " MPU_xEventGroupSync_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xEventGroupSyncImpl \n" + " MPU_xEventGroupSync_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xEventGroupSyncImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + +UBaseType_t MPU_uxEventGroupGetNumber( void * xEventGroup ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxEventGroupGetNumber( void * xEventGroup ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxEventGroupGetNumberImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_uxEventGroupGetNumber_Unpriv \n" + " MPU_uxEventGroupGetNumber_Priv: \n" + " pop {r0, r1} \n" + " b MPU_uxEventGroupGetNumberImpl \n" + " MPU_uxEventGroupGetNumber_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_uxEventGroupGetNumberImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /*( configUSE_TRACE_FACILITY == 1 )*/ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + +void MPU_vEventGroupSetNumber( void * xEventGroup, + UBaseType_t uxEventGroupNumber ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vEventGroupSetNumber( void * xEventGroup, + UBaseType_t uxEventGroupNumber ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vEventGroupSetNumberImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_vEventGroupSetNumber_Unpriv \n" + " MPU_vEventGroupSetNumber_Priv: \n" + " pop {r0, r1} \n" + " b MPU_vEventGroupSetNumberImpl \n" + " MPU_vEventGroupSetNumber_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_vEventGroupSetNumberImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /*( configUSE_TRACE_FACILITY == 1 )*/ +/*-----------------------------------------------------------*/ + +size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, + const void * pvTxData, + size_t xDataLengthBytes, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, + const void * pvTxData, + size_t xDataLengthBytes, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferSendImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xStreamBufferSend_Unpriv \n" + " MPU_xStreamBufferSend_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xStreamBufferSendImpl \n" + " MPU_xStreamBufferSend_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xStreamBufferSendImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, + void * pvRxData, + size_t xBufferLengthBytes, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, + void * pvRxData, + size_t xBufferLengthBytes, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferReceiveImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xStreamBufferReceive_Unpriv \n" + " MPU_xStreamBufferReceive_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xStreamBufferReceiveImpl \n" + " MPU_xStreamBufferReceive_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xStreamBufferReceiveImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferIsFullImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xStreamBufferIsFull_Unpriv \n" + " MPU_xStreamBufferIsFull_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xStreamBufferIsFullImpl \n" + " MPU_xStreamBufferIsFull_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xStreamBufferIsFullImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferIsEmptyImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xStreamBufferIsEmpty_Unpriv \n" + " MPU_xStreamBufferIsEmpty_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xStreamBufferIsEmptyImpl \n" + " MPU_xStreamBufferIsEmpty_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xStreamBufferIsEmptyImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferSpacesAvailableImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xStreamBufferSpacesAvailable_Unpriv \n" + " MPU_xStreamBufferSpacesAvailable_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xStreamBufferSpacesAvailableImpl \n" + " MPU_xStreamBufferSpacesAvailable_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xStreamBufferSpacesAvailableImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferBytesAvailableImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xStreamBufferBytesAvailable_Unpriv \n" + " MPU_xStreamBufferBytesAvailable_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xStreamBufferBytesAvailableImpl \n" + " MPU_xStreamBufferBytesAvailable_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xStreamBufferBytesAvailableImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, + size_t xTriggerLevel ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, + size_t xTriggerLevel ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferSetTriggerLevelImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xStreamBufferSetTriggerLevel_Unpriv \n" + " MPU_xStreamBufferSetTriggerLevel_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xStreamBufferSetTriggerLevelImpl \n" + " MPU_xStreamBufferSetTriggerLevel_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xStreamBufferSetTriggerLevelImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferNextMessageLengthBytesImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xStreamBufferNextMessageLengthBytes_Unpriv \n" + " MPU_xStreamBufferNextMessageLengthBytes_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xStreamBufferNextMessageLengthBytesImpl \n" + " MPU_xStreamBufferNextMessageLengthBytes_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xStreamBufferNextMessageLengthBytesImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ diff --git a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM23_NTZ/portasm.c b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM23_NTZ/portasm.c index 7fb7b5ade5d..b11b6e97c5e 100644 --- a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM23_NTZ/portasm.c +++ b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM23_NTZ/portasm.c @@ -44,6 +44,106 @@ #error Cortex-M23 does not have a Floating Point Unit (FPU) and therefore configENABLE_FPU must be set to 0. #endif +#if ( configENABLE_MPU == 1 ) + +void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ +{ + __asm volatile + ( + " .syntax unified \n" + " \n" + " program_mpu_first_task: \n" + " ldr r3, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r0, [r3] \n" /* r0 = pxCurrentTCB.*/ + " \n" + " dmb \n" /* Complete outstanding transfers before disabling MPU. */ + " ldr r1, xMPUCTRLConst2 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ + " movs r3, #1 \n" /* r3 = 1. */ + " bics r2, r3 \n" /* r2 = r2 & ~r3 i.e. Clear the bit 0 in r2. */ + " str r2, [r1] \n" /* Disable MPU. */ + " \n" + " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */ + " ldr r1, [r0] \n" /* r1 = *r0 i.e. r1 = MAIR0. */ + " ldr r2, xMAIR0Const2 \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */ + " str r1, [r2] \n" /* Program MAIR0. */ + " \n" + " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */ + " ldr r1, xRNRConst2 \n" /* r1 = 0xe000ed98 [Location of RNR]. */ + " \n" + " movs r3, #4 \n" /* r3 = 4. */ + " str r3, [r1] \n" /* Program RNR = 4. */ + " ldmia r0!, {r4-r5} \n" /* Read first set of RBAR/RLAR registers from TCB. */ + " ldr r2, xRBARConst2 \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ + " stmia r2!, {r4-r5} \n" /* Write first set of RBAR/RLAR registers. */ + " movs r3, #5 \n" /* r3 = 5. */ + " str r3, [r1] \n" /* Program RNR = 5. */ + " ldmia r0!, {r4-r5} \n" /* Read second set of RBAR/RLAR registers from TCB. */ + " ldr r2, xRBARConst2 \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ + " stmia r2!, {r4-r5} \n" /* Write second set of RBAR/RLAR registers. */ + " movs r3, #6 \n" /* r3 = 6. */ + " str r3, [r1] \n" /* Program RNR = 6. */ + " ldmia r0!, {r4-r5} \n" /* Read third set of RBAR/RLAR registers from TCB. */ + " ldr r2, xRBARConst2 \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ + " stmia r2!, {r4-r5} \n" /* Write third set of RBAR/RLAR registers. */ + " movs r3, #7 \n" /* r3 = 6. */ + " str r3, [r1] \n" /* Program RNR = 7. */ + " ldmia r0!, {r4-r5} \n" /* Read fourth set of RBAR/RLAR registers from TCB. */ + " ldr r2, xRBARConst2 \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ + " stmia r2!, {r4-r5} \n" /* Write fourth set of RBAR/RLAR registers. */ + " \n" + " ldr r1, xMPUCTRLConst2 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ + " movs r3, #1 \n" /* r3 = 1. */ + " orrs r2, r3 \n" /* r2 = r2 | r3 i.e. Set the bit 0 in r2. */ + " str r2, [r1] \n" /* Enable MPU. */ + " dsb \n" /* Force memory writes before continuing. */ + " \n" + " restore_context_first_task: \n" + " ldr r2, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r0, [r2] \n" /* r0 = pxCurrentTCB.*/ + " ldr r1, [r0] \n" /* r1 = Location of saved context in TCB. */ + " \n" + " restore_special_regs_first_task: \n" + " subs r1, #16 \n" + " ldmia r1!, {r2-r5} \n" /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, r5 = LR. */ + " subs r1, #16 \n" + " msr psp, r2 \n" + " msr psplim, r3 \n" + " msr control, r4 \n" + " mov lr, r5 \n" + " \n" + " restore_general_regs_first_task: \n" + " subs r1, #32 \n" + " ldmia r1!, {r4-r7} \n" /* r4-r7 contain half of the hardware saved context. */ + " stmia r2!, {r4-r7} \n" /* Copy half of the the hardware saved context on the task stack. */ + " ldmia r1!, {r4-r7} \n" /* r4-r7 contain rest half of the hardware saved context. */ + " stmia r2!, {r4-r7} \n" /* Copy rest half of the the hardware saved context on the task stack. */ + " subs r1, #48 \n" + " ldmia r1!, {r4-r7} \n" /* Restore r8-r11. */ + " mov r8, r4 \n" /* r8 = r4. */ + " mov r9, r5 \n" /* r9 = r5. */ + " mov r10, r6 \n" /* r10 = r6. */ + " mov r11, r7 \n" /* r11 = r7. */ + " subs r1, #32 \n" + " ldmia r1!, {r4-r7} \n" /* Restore r4-r7. */ + " subs r1, #16 \n" + " \n" + " restore_context_done_first_task: \n" + " str r1, [r0] \n" /* Save the location where the context should be saved next as the first member of TCB. */ + " bx lr \n" + " \n" + " .align 4 \n" + " pxCurrentTCBConst2: .word pxCurrentTCB \n" + " xMPUCTRLConst2: .word 0xe000ed94 \n" + " xMAIR0Const2: .word 0xe000edc0 \n" + " xRNRConst2: .word 0xe000ed98 \n" + " xRBARConst2: .word 0xe000ed9c \n" + ); +} + +#else /* configENABLE_MPU */ + void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ { __asm volatile @@ -54,78 +154,21 @@ void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_ " ldr r1, [r2] \n"/* Read pxCurrentTCB. */ " ldr r0, [r1] \n"/* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ " \n" - #if ( configENABLE_MPU == 1 ) - " dmb \n"/* Complete outstanding transfers before disabling MPU. */ - " ldr r2, xMPUCTRLConst2 \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ - " ldr r3, [r2] \n"/* Read the value of MPU_CTRL. */ - " movs r4, #1 \n"/* r4 = 1. */ - " bics r3, r4 \n"/* r3 = r3 & ~r4 i.e. Clear the bit 0 in r3. */ - " str r3, [r2] \n"/* Disable MPU. */ - " \n" - " adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */ - " ldr r4, [r1] \n"/* r4 = *r1 i.e. r4 = MAIR0. */ - " ldr r2, xMAIR0Const2 \n"/* r2 = 0xe000edc0 [Location of MAIR0]. */ - " str r4, [r2] \n"/* Program MAIR0. */ - " ldr r2, xRNRConst2 \n"/* r2 = 0xe000ed98 [Location of RNR]. */ - " adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to first RBAR in TCB. */ - " movs r4, #4 \n"/* r4 = 4. */ - " str r4, [r2] \n"/* Program RNR = 4. */ - " ldmia r1!, {r5,r6} \n"/* Read first set of RBAR/RLAR from TCB. */ - " ldr r3, xRBARConst2 \n"/* r3 = 0xe000ed9c [Location of RBAR]. */ - " stmia r3!, {r5,r6} \n"/* Write first set of RBAR/RLAR registers. */ - " movs r4, #5 \n"/* r4 = 5. */ - " str r4, [r2] \n"/* Program RNR = 5. */ - " ldmia r1!, {r5,r6} \n"/* Read second set of RBAR/RLAR from TCB. */ - " ldr r3, xRBARConst2 \n"/* r3 = 0xe000ed9c [Location of RBAR]. */ - " stmia r3!, {r5,r6} \n"/* Write second set of RBAR/RLAR registers. */ - " movs r4, #6 \n"/* r4 = 6. */ - " str r4, [r2] \n"/* Program RNR = 6. */ - " ldmia r1!, {r5,r6} \n"/* Read third set of RBAR/RLAR from TCB. */ - " ldr r3, xRBARConst2 \n"/* r3 = 0xe000ed9c [Location of RBAR]. */ - " stmia r3!, {r5,r6} \n"/* Write third set of RBAR/RLAR registers. */ - " movs r4, #7 \n"/* r4 = 7. */ - " str r4, [r2] \n"/* Program RNR = 7. */ - " ldmia r1!, {r5,r6} \n"/* Read fourth set of RBAR/RLAR from TCB. */ - " ldr r3, xRBARConst2 \n"/* r3 = 0xe000ed9c [Location of RBAR]. */ - " stmia r3!, {r5,r6} \n"/* Write fourth set of RBAR/RLAR registers. */ - " \n" - " ldr r2, xMPUCTRLConst2 \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ - " ldr r3, [r2] \n"/* Read the value of MPU_CTRL. */ - " movs r4, #1 \n"/* r4 = 1. */ - " orrs r3, r4 \n"/* r3 = r3 | r4 i.e. Set the bit 0 in r3. */ - " str r3, [r2] \n"/* Enable MPU. */ - " dsb \n"/* Force memory writes before continuing. */ - #endif /* configENABLE_MPU */ - " \n" - #if ( configENABLE_MPU == 1 ) - " ldm r0!, {r1-r3} \n"/* Read from stack - r1 = PSPLIM, r2 = CONTROL and r3 = EXC_RETURN. */ - " msr psplim, r1 \n"/* Set this task's PSPLIM value. */ - " msr control, r2 \n"/* Set this task's CONTROL value. */ - " adds r0, #32 \n"/* Discard everything up to r0. */ - " msr psp, r0 \n"/* This is now the new top of stack to use in the task. */ - " isb \n" - " bx r3 \n"/* Finally, branch to EXC_RETURN. */ - #else /* configENABLE_MPU */ - " ldm r0!, {r1-r2} \n"/* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */ - " msr psplim, r1 \n"/* Set this task's PSPLIM value. */ - " movs r1, #2 \n"/* r1 = 2. */ - " msr CONTROL, r1 \n"/* Switch to use PSP in the thread mode. */ - " adds r0, #32 \n"/* Discard everything up to r0. */ - " msr psp, r0 \n"/* This is now the new top of stack to use in the task. */ - " isb \n" - " bx r2 \n"/* Finally, branch to EXC_RETURN. */ - #endif /* configENABLE_MPU */ + " ldm r0!, {r1-r2} \n"/* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */ + " msr psplim, r1 \n"/* Set this task's PSPLIM value. */ + " movs r1, #2 \n"/* r1 = 2. */ + " msr CONTROL, r1 \n"/* Switch to use PSP in the thread mode. */ + " adds r0, #32 \n"/* Discard everything up to r0. */ + " msr psp, r0 \n"/* This is now the new top of stack to use in the task. */ + " isb \n" + " bx r2 \n"/* Finally, branch to EXC_RETURN. */ " \n" " .align 4 \n" "pxCurrentTCBConst2: .word pxCurrentTCB \n" - #if ( configENABLE_MPU == 1 ) - "xMPUCTRLConst2: .word 0xe000ed94 \n" - "xMAIR0Const2: .word 0xe000edc0 \n" - "xRNRConst2: .word 0xe000ed98 \n" - "xRBARConst2: .word 0xe000ed9c \n" - #endif /* configENABLE_MPU */ ); } + +#endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */ @@ -232,6 +275,136 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att } /*-----------------------------------------------------------*/ +#if ( configENABLE_MPU == 1 ) + +void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ +{ + __asm volatile + ( + " .syntax unified \n" + " \n" + " ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r0, [r2] \n" /* r0 = pxCurrentTCB. */ + " ldr r1, [r0] \n" /* r1 = Location in TCB where the context should be saved. */ + " mrs r2, psp \n" /* r2 = PSP. */ + " \n" + " save_general_regs: \n" + " stmia r1!, {r4-r7} \n" /* Store r4-r7. */ + " mov r4, r8 \n" /* r4 = r8. */ + " mov r5, r9 \n" /* r5 = r9. */ + " mov r6, r10 \n" /* r6 = r10. */ + " mov r7, r11 \n" /* r7 = r11. */ + " stmia r1!, {r4-r7} \n" /* Store r8-r11. */ + " ldmia r2!, {r4-r7} \n" /* Copy half of the hardware saved context into r4-r7. */ + " stmia r1!, {r4-r7} \n" /* Store the hardware saved context. */ + " ldmia r2!, {r4-r7} \n" /* Copy rest half of the hardware saved context into r4-r7. */ + " stmia r1!, {r4-r7} \n" /* Store the hardware saved context. */ + " \n" + " save_special_regs: \n" + " mrs r2, psp \n" /* r2 = PSP. */ + " mrs r3, psplim \n" /* r3 = PSPLIM. */ + " mrs r4, control \n" /* r4 = CONTROL. */ + " mov r5, lr \n" /* r5 = LR. */ + " stmia r1!, {r2-r5} \n" /* Store original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */ + " str r1, [r0] \n" /* Save the location from where the context should be restored as the first member of TCB. */ + " \n" + " select_next_task: \n" + " cpsid i \n" + " bl vTaskSwitchContext \n" + " cpsie i \n" + " \n" + " program_mpu: \n" + " ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r0, [r3] \n" /* r0 = pxCurrentTCB.*/ + " \n" + " dmb \n" /* Complete outstanding transfers before disabling MPU. */ + " ldr r1, xMPUCTRLConst \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ + " movs r3, #1 \n" /* r3 = 1. */ + " bics r2, r3 \n" /* r2 = r2 & ~r3 i.e. Clear the bit 0 in r2. */ + " str r2, [r1] \n" /* Disable MPU. */ + " \n" + " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */ + " ldr r1, [r0] \n" /* r1 = *r0 i.e. r1 = MAIR0. */ + " ldr r2, xMAIR0Const \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */ + " str r1, [r2] \n" /* Program MAIR0. */ + " \n" + " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */ + " ldr r1, xRNRConst \n" /* r1 = 0xe000ed98 [Location of RNR]. */ + " \n" + " movs r3, #4 \n" /* r3 = 4. */ + " str r3, [r1] \n" /* Program RNR = 4. */ + " ldmia r0!, {r4-r5} \n" /* Read first set of RBAR/RLAR registers from TCB. */ + " ldr r2, xRBARConst \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ + " stmia r2!, {r4-r5} \n" /* Write first set of RBAR/RLAR registers. */ + " movs r3, #5 \n" /* r3 = 5. */ + " str r3, [r1] \n" /* Program RNR = 5. */ + " ldmia r0!, {r4-r5} \n" /* Read second set of RBAR/RLAR registers from TCB. */ + " ldr r2, xRBARConst \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ + " stmia r2!, {r4-r5} \n" /* Write second set of RBAR/RLAR registers. */ + " movs r3, #6 \n" /* r3 = 6. */ + " str r3, [r1] \n" /* Program RNR = 6. */ + " ldmia r0!, {r4-r5} \n" /* Read third set of RBAR/RLAR registers from TCB. */ + " ldr r2, xRBARConst \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ + " stmia r2!, {r4-r5} \n" /* Write third set of RBAR/RLAR registers. */ + " movs r3, #7 \n" /* r3 = 6. */ + " str r3, [r1] \n" /* Program RNR = 7. */ + " ldmia r0!, {r4-r5} \n" /* Read fourth set of RBAR/RLAR registers from TCB. */ + " ldr r2, xRBARConst \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ + " stmia r2!, {r4-r5} \n" /* Write fourth set of RBAR/RLAR registers. */ + " \n" + " ldr r1, xMPUCTRLConst \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ + " movs r3, #1 \n" /* r3 = 1. */ + " orrs r2, r3 \n" /* r2 = r2 | r3 i.e. Set the bit 0 in r2. */ + " str r2, [r1] \n" /* Enable MPU. */ + " dsb \n" /* Force memory writes before continuing. */ + " \n" + " restore_context: \n" + " ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r0, [r2] \n" /* r0 = pxCurrentTCB.*/ + " ldr r1, [r0] \n" /* r1 = Location of saved context in TCB. */ + " \n" + " restore_special_regs: \n" + " subs r1, #16 \n" + " ldmia r1!, {r2-r5} \n" /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, r5 = LR. */ + " subs r1, #16 \n" + " msr psp, r2 \n" + " msr psplim, r3 \n" + " msr control, r4 \n" + " mov lr, r5 \n" + " \n" + " restore_general_regs: \n" + " subs r1, #32 \n" + " ldmia r1!, {r4-r7} \n" /* r4-r7 contain half of the hardware saved context. */ + " stmia r2!, {r4-r7} \n" /* Copy half of the the hardware saved context on the task stack. */ + " ldmia r1!, {r4-r7} \n" /* r4-r7 contain rest half of the hardware saved context. */ + " stmia r2!, {r4-r7} \n" /* Copy rest half of the the hardware saved context on the task stack. */ + " subs r1, #48 \n" + " ldmia r1!, {r4-r7} \n" /* Restore r8-r11. */ + " mov r8, r4 \n" /* r8 = r4. */ + " mov r9, r5 \n" /* r9 = r5. */ + " mov r10, r6 \n" /* r10 = r6. */ + " mov r11, r7 \n" /* r11 = r7. */ + " subs r1, #32 \n" + " ldmia r1!, {r4-r7} \n" /* Restore r4-r7. */ + " subs r1, #16 \n" + " \n" + " restore_context_done: \n" + " str r1, [r0] \n" /* Save the location where the context should be saved next as the first member of TCB. */ + " bx lr \n" + " \n" + " .align 4 \n" + " pxCurrentTCBConst: .word pxCurrentTCB \n" + " xMPUCTRLConst: .word 0xe000ed94 \n" + " xMAIR0Const: .word 0xe000edc0 \n" + " xRNRConst: .word 0xe000ed98 \n" + " xRBARConst: .word 0xe000ed9c \n" + ); +} + +#else /* configENABLE_MPU */ + void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ { __asm volatile @@ -241,30 +414,16 @@ void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ " mrs r0, psp \n"/* Read PSP in r0. */ " ldr r2, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r2] \n"/* Read pxCurrentTCB. */ - #if ( configENABLE_MPU == 1 ) - " subs r0, r0, #44 \n"/* Make space for PSPLIM, CONTROL, LR and the remaining registers on the stack. */ - " str r0, [r1] \n"/* Save the new top of stack in TCB. */ - " mrs r1, psplim \n"/* r1 = PSPLIM. */ - " mrs r2, control \n"/* r2 = CONTROL. */ - " mov r3, lr \n"/* r3 = LR/EXC_RETURN. */ - " stmia r0!, {r1-r7} \n"/* Store on the stack - PSPLIM, CONTROL, LR and low registers that are not automatically saved. */ - " mov r4, r8 \n"/* r4 = r8. */ - " mov r5, r9 \n"/* r5 = r9. */ - " mov r6, r10 \n"/* r6 = r10. */ - " mov r7, r11 \n"/* r7 = r11. */ - " stmia r0!, {r4-r7} \n"/* Store the high registers that are not saved automatically. */ - #else /* configENABLE_MPU */ - " subs r0, r0, #40 \n"/* Make space for PSPLIM, LR and the remaining registers on the stack. */ - " str r0, [r1] \n"/* Save the new top of stack in TCB. */ - " mrs r2, psplim \n"/* r2 = PSPLIM. */ - " mov r3, lr \n"/* r3 = LR/EXC_RETURN. */ - " stmia r0!, {r2-r7} \n"/* Store on the stack - PSPLIM, LR and low registers that are not automatically saved. */ - " mov r4, r8 \n"/* r4 = r8. */ - " mov r5, r9 \n"/* r5 = r9. */ - " mov r6, r10 \n"/* r6 = r10. */ - " mov r7, r11 \n"/* r7 = r11. */ - " stmia r0!, {r4-r7} \n"/* Store the high registers that are not saved automatically. */ - #endif /* configENABLE_MPU */ + " subs r0, r0, #40 \n"/* Make space for PSPLIM, LR and the remaining registers on the stack. */ + " str r0, [r1] \n"/* Save the new top of stack in TCB. */ + " mrs r2, psplim \n"/* r2 = PSPLIM. */ + " mov r3, lr \n"/* r3 = LR/EXC_RETURN. */ + " stmia r0!, {r2-r7} \n"/* Store on the stack - PSPLIM, LR and low registers that are not automatically saved. */ + " mov r4, r8 \n"/* r4 = r8. */ + " mov r5, r9 \n"/* r5 = r9. */ + " mov r6, r10 \n"/* r6 = r10. */ + " mov r7, r11 \n"/* r7 = r11. */ + " stmia r0!, {r4-r7} \n"/* Store the high registers that are not saved automatically. */ " \n" " cpsid i \n" " bl vTaskSwitchContext \n" @@ -274,88 +433,76 @@ void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ " ldr r1, [r2] \n"/* Read pxCurrentTCB. */ " ldr r0, [r1] \n"/* The first item in pxCurrentTCB is the task top of stack. r0 now points to the top of stack. */ " \n" - #if ( configENABLE_MPU == 1 ) - " dmb \n"/* Complete outstanding transfers before disabling MPU. */ - " ldr r2, xMPUCTRLConst \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ - " ldr r3, [r2] \n"/* Read the value of MPU_CTRL. */ - " movs r4, #1 \n"/* r4 = 1. */ - " bics r3, r4 \n"/* r3 = r3 & ~r4 i.e. Clear the bit 0 in r3. */ - " str r3, [r2] \n"/* Disable MPU. */ - " \n" - " adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */ - " ldr r4, [r1] \n"/* r4 = *r1 i.e. r4 = MAIR0. */ - " ldr r2, xMAIR0Const \n"/* r2 = 0xe000edc0 [Location of MAIR0]. */ - " str r4, [r2] \n"/* Program MAIR0. */ - " ldr r2, xRNRConst \n"/* r2 = 0xe000ed98 [Location of RNR]. */ - " adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to first RBAR in TCB. */ - " movs r4, #4 \n"/* r4 = 4. */ - " str r4, [r2] \n"/* Program RNR = 4. */ - " ldmia r1!, {r5,r6} \n"/* Read first set of RBAR/RLAR from TCB. */ - " ldr r3, xRBARConst \n"/* r3 = 0xe000ed9c [Location of RBAR]. */ - " stmia r3!, {r5,r6} \n"/* Write first set of RBAR/RLAR registers. */ - " movs r4, #5 \n"/* r4 = 5. */ - " str r4, [r2] \n"/* Program RNR = 5. */ - " ldmia r1!, {r5,r6} \n"/* Read second set of RBAR/RLAR from TCB. */ - " ldr r3, xRBARConst \n"/* r3 = 0xe000ed9c [Location of RBAR]. */ - " stmia r3!, {r5,r6} \n"/* Write second set of RBAR/RLAR registers. */ - " movs r4, #6 \n"/* r4 = 6. */ - " str r4, [r2] \n"/* Program RNR = 6. */ - " ldmia r1!, {r5,r6} \n"/* Read third set of RBAR/RLAR from TCB. */ - " ldr r3, xRBARConst \n"/* r3 = 0xe000ed9c [Location of RBAR]. */ - " stmia r3!, {r5,r6} \n"/* Write third set of RBAR/RLAR registers. */ - " movs r4, #7 \n"/* r4 = 7. */ - " str r4, [r2] \n"/* Program RNR = 7. */ - " ldmia r1!, {r5,r6} \n"/* Read fourth set of RBAR/RLAR from TCB. */ - " ldr r3, xRBARConst \n"/* r3 = 0xe000ed9c [Location of RBAR]. */ - " stmia r3!, {r5,r6} \n"/* Write fourth set of RBAR/RLAR registers. */ - " \n" - " ldr r2, xMPUCTRLConst \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ - " ldr r3, [r2] \n"/* Read the value of MPU_CTRL. */ - " movs r4, #1 \n"/* r4 = 1. */ - " orrs r3, r4 \n"/* r3 = r3 | r4 i.e. Set the bit 0 in r3. */ - " str r3, [r2] \n"/* Enable MPU. */ - " dsb \n"/* Force memory writes before continuing. */ - #endif /* configENABLE_MPU */ - " \n" - #if ( configENABLE_MPU == 1 ) - " adds r0, r0, #28 \n"/* Move to the high registers. */ - " ldmia r0!, {r4-r7} \n"/* Restore the high registers that are not automatically restored. */ - " mov r8, r4 \n"/* r8 = r4. */ - " mov r9, r5 \n"/* r9 = r5. */ - " mov r10, r6 \n"/* r10 = r6. */ - " mov r11, r7 \n"/* r11 = r7. */ - " msr psp, r0 \n"/* Remember the new top of stack for the task. */ - " subs r0, r0, #44 \n"/* Move to the starting of the saved context. */ - " ldmia r0!, {r1-r7} \n"/* Read from stack - r1 = PSPLIM, r2 = CONTROL, r3 = LR and r4-r7 restored. */ - " msr psplim, r1 \n"/* Restore the PSPLIM register value for the task. */ - " msr control, r2 \n"/* Restore the CONTROL register value for the task. */ - " bx r3 \n" - #else /* configENABLE_MPU */ - " adds r0, r0, #24 \n"/* Move to the high registers. */ - " ldmia r0!, {r4-r7} \n"/* Restore the high registers that are not automatically restored. */ - " mov r8, r4 \n"/* r8 = r4. */ - " mov r9, r5 \n"/* r9 = r5. */ - " mov r10, r6 \n"/* r10 = r6. */ - " mov r11, r7 \n"/* r11 = r7. */ - " msr psp, r0 \n"/* Remember the new top of stack for the task. */ - " subs r0, r0, #40 \n"/* Move to the starting of the saved context. */ - " ldmia r0!, {r2-r7} \n"/* Read from stack - r2 = PSPLIM, r3 = LR and r4-r7 restored. */ - " msr psplim, r2 \n"/* Restore the PSPLIM register value for the task. */ - " bx r3 \n" - #endif /* configENABLE_MPU */ + " adds r0, r0, #24 \n"/* Move to the high registers. */ + " ldmia r0!, {r4-r7} \n"/* Restore the high registers that are not automatically restored. */ + " mov r8, r4 \n"/* r8 = r4. */ + " mov r9, r5 \n"/* r9 = r5. */ + " mov r10, r6 \n"/* r10 = r6. */ + " mov r11, r7 \n"/* r11 = r7. */ + " msr psp, r0 \n"/* Remember the new top of stack for the task. */ + " subs r0, r0, #40 \n"/* Move to the starting of the saved context. */ + " ldmia r0!, {r2-r7} \n"/* Read from stack - r2 = PSPLIM, r3 = LR and r4-r7 restored. */ + " msr psplim, r2 \n"/* Restore the PSPLIM register value for the task. */ + " bx r3 \n" " \n" " .align 4 \n" "pxCurrentTCBConst: .word pxCurrentTCB \n" - #if ( configENABLE_MPU == 1 ) - "xMPUCTRLConst: .word 0xe000ed94 \n" - "xMAIR0Const: .word 0xe000edc0 \n" - "xRNRConst: .word 0xe000ed98 \n" - "xRBARConst: .word 0xe000ed9c \n" - #endif /* configENABLE_MPU */ ); } + +#endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + +void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ +{ + __asm volatile + ( + ".syntax unified \n" + ".extern vPortSVCHandler_C \n" + ".extern vSystemCallEnter \n" + ".extern vSystemCallEnter_1 \n" + ".extern vSystemCallExit \n" + " \n" + "movs r0, #4 \n" + "mov r1, lr \n" + "tst r0, r1 \n" + "beq stack_on_msp \n" + "stack_on_psp: \n" + " mrs r0, psp \n" + " b route_svc \n" + "stack_on_msp: \n" + " mrs r0, msp \n" + " b route_svc \n" + " \n" + "route_svc: \n" + " ldr r2, [r0, #24] \n" + " subs r2, #2 \n" + " ldrb r3, [r2, #0] \n" + " cmp r3, %0 \n" + " beq system_call_enter \n" + " cmp r3, %1 \n" + " beq system_call_enter_1 \n" + " cmp r3, %2 \n" + " beq system_call_exit \n" + " b vPortSVCHandler_C \n" + " \n" + "system_call_enter: \n" + " b vSystemCallEnter \n" + "system_call_enter_1: \n" + " b vSystemCallEnter_1 \n" + "system_call_exit: \n" + " b vSystemCallExit \n" + " \n" + : /* No outputs. */ + :"i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_ENTER_1 ), "i" ( portSVC_SYSTEM_CALL_EXIT ) + : "r0", "r1", "r2", "r3", "memory" + ); +} + +#else /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ { __asm volatile @@ -378,4 +525,6 @@ void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ "svchandler_address_const: .word vPortSVCHandler_C \n" ); } + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ /*-----------------------------------------------------------*/ diff --git a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM23_NTZ/portmacro.h b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM23_NTZ/portmacro.h index 746f734b8ac..5fd94c1c371 100644 --- a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM23_NTZ/portmacro.h +++ b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM23_NTZ/portmacro.h @@ -51,7 +51,6 @@ #define portARCH_NAME "Cortex-M23" #define portHAS_BASEPRI 0 #define portDONT_DISCARD __attribute__( ( used ) ) -#define portNORETURN __attribute__( ( noreturn ) ) /*-----------------------------------------------------------*/ /* ARMv8-M common port configurations. */ diff --git a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33/mpu_wrappers_v2_asm.c b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33/mpu_wrappers_v2_asm.c new file mode 100644 index 00000000000..6e2043427fe --- /dev/null +++ b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33/mpu_wrappers_v2_asm.c @@ -0,0 +1,2349 @@ +/* + * FreeRTOS Kernel + * Copyright (C) 2021 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 + * + */ + +/* 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. */ +#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +/* Scheduler includes. */ +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" +#include "timers.h" +#include "event_groups.h" +#include "stream_buffer.h" + +#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + +#if ( INCLUDE_xTaskDelayUntil == 1 ) + +BaseType_t MPU_xTaskDelayUntil( TickType_t * const pxPreviousWakeTime, + const TickType_t xTimeIncrement ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskDelayUntil( TickType_t * const pxPreviousWakeTime, + const TickType_t xTimeIncrement ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskDelayUntilImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskDelayUntil_Unpriv \n" + " MPU_xTaskDelayUntil_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskDelayUntilImpl \n" + " MPU_xTaskDelayUntil_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskDelayUntilImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_xTaskDelayUntil == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_xTaskAbortDelay == 1 ) + +BaseType_t MPU_xTaskAbortDelay( TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskAbortDelay( TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskAbortDelayImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskAbortDelay_Unpriv \n" + " MPU_xTaskAbortDelay_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskAbortDelayImpl \n" + " MPU_xTaskAbortDelay_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskAbortDelayImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_xTaskAbortDelay == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskDelay == 1 ) + +void MPU_vTaskDelay( const TickType_t xTicksToDelay ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskDelay( const TickType_t xTicksToDelay ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskDelayImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vTaskDelay_Unpriv \n" + " MPU_vTaskDelay_Priv: \n" + " pop {r0} \n" + " b MPU_vTaskDelayImpl \n" + " MPU_vTaskDelay_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vTaskDelayImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_vTaskDelay == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_uxTaskPriorityGet == 1 ) + +UBaseType_t MPU_uxTaskPriorityGet( const TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxTaskPriorityGet( const TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxTaskPriorityGetImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_uxTaskPriorityGet_Unpriv \n" + " MPU_uxTaskPriorityGet_Priv: \n" + " pop {r0} \n" + " b MPU_uxTaskPriorityGetImpl \n" + " MPU_uxTaskPriorityGet_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_uxTaskPriorityGetImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_uxTaskPriorityGet == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_eTaskGetState == 1 ) + +eTaskState MPU_eTaskGetState( TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +eTaskState MPU_eTaskGetState( TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_eTaskGetStateImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_eTaskGetState_Unpriv \n" + " MPU_eTaskGetState_Priv: \n" + " pop {r0} \n" + " b MPU_eTaskGetStateImpl \n" + " MPU_eTaskGetState_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_eTaskGetStateImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_eTaskGetState == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + +void MPU_vTaskGetInfo( TaskHandle_t xTask, + TaskStatus_t * pxTaskStatus, + BaseType_t xGetFreeStackSpace, + eTaskState eState ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskGetInfo( TaskHandle_t xTask, + TaskStatus_t * pxTaskStatus, + BaseType_t xGetFreeStackSpace, + eTaskState eState ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskGetInfoImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vTaskGetInfo_Unpriv \n" + " MPU_vTaskGetInfo_Priv: \n" + " pop {r0} \n" + " b MPU_vTaskGetInfoImpl \n" + " MPU_vTaskGetInfo_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vTaskGetInfoImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TRACE_FACILITY == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) + +TaskHandle_t MPU_xTaskGetIdleTaskHandle( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TaskHandle_t MPU_xTaskGetIdleTaskHandle( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGetIdleTaskHandleImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskGetIdleTaskHandle_Unpriv \n" + " MPU_xTaskGetIdleTaskHandle_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskGetIdleTaskHandleImpl \n" + " MPU_xTaskGetIdleTaskHandle_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskGetIdleTaskHandleImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskSuspend == 1 ) + +void MPU_vTaskSuspend( TaskHandle_t xTaskToSuspend ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskSuspend( TaskHandle_t xTaskToSuspend ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskSuspendImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vTaskSuspend_Unpriv \n" + " MPU_vTaskSuspend_Priv: \n" + " pop {r0} \n" + " b MPU_vTaskSuspendImpl \n" + " MPU_vTaskSuspend_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vTaskSuspendImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_vTaskSuspend == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskSuspend == 1 ) + +void MPU_vTaskResume( TaskHandle_t xTaskToResume ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskResume( TaskHandle_t xTaskToResume ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskResumeImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vTaskResume_Unpriv \n" + " MPU_vTaskResume_Priv: \n" + " pop {r0} \n" + " b MPU_vTaskResumeImpl \n" + " MPU_vTaskResume_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vTaskResumeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_vTaskSuspend == 1 ) */ +/*-----------------------------------------------------------*/ + +TickType_t MPU_xTaskGetTickCount( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TickType_t MPU_xTaskGetTickCount( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGetTickCountImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskGetTickCount_Unpriv \n" + " MPU_xTaskGetTickCount_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskGetTickCountImpl \n" + " MPU_xTaskGetTickCount_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskGetTickCountImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +UBaseType_t MPU_uxTaskGetNumberOfTasks( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxTaskGetNumberOfTasks( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxTaskGetNumberOfTasksImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_uxTaskGetNumberOfTasks_Unpriv \n" + " MPU_uxTaskGetNumberOfTasks_Priv: \n" + " pop {r0} \n" + " b MPU_uxTaskGetNumberOfTasksImpl \n" + " MPU_uxTaskGetNumberOfTasks_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_uxTaskGetNumberOfTasksImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +char * MPU_pcTaskGetName( TaskHandle_t xTaskToQuery ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +char * MPU_pcTaskGetName( TaskHandle_t xTaskToQuery ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_pcTaskGetNameImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_pcTaskGetName_Unpriv \n" + " MPU_pcTaskGetName_Priv: \n" + " pop {r0} \n" + " b MPU_pcTaskGetNameImpl \n" + " MPU_pcTaskGetName_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_pcTaskGetNameImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +#if ( configGENERATE_RUN_TIME_STATS == 1 ) + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetRunTimeCounter( const TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetRunTimeCounter( const TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_ulTaskGetRunTimeCounterImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_ulTaskGetRunTimeCounter_Unpriv \n" + " MPU_ulTaskGetRunTimeCounter_Priv: \n" + " pop {r0} \n" + " b MPU_ulTaskGetRunTimeCounterImpl \n" + " MPU_ulTaskGetRunTimeCounter_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_ulTaskGetRunTimeCounterImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( ( configGENERATE_RUN_TIME_STATS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configGENERATE_RUN_TIME_STATS == 1 ) + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetRunTimePercent( const TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetRunTimePercent( const TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_ulTaskGetRunTimePercentImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_ulTaskGetRunTimePercent_Unpriv \n" + " MPU_ulTaskGetRunTimePercent_Priv: \n" + " pop {r0} \n" + " b MPU_ulTaskGetRunTimePercentImpl \n" + " MPU_ulTaskGetRunTimePercent_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_ulTaskGetRunTimePercentImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( ( configGENERATE_RUN_TIME_STATS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimePercent( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimePercent( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_ulTaskGetIdleRunTimePercentImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_ulTaskGetIdleRunTimePercent_Unpriv \n" + " MPU_ulTaskGetIdleRunTimePercent_Priv: \n" + " pop {r0} \n" + " b MPU_ulTaskGetIdleRunTimePercentImpl \n" + " MPU_ulTaskGetIdleRunTimePercent_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_ulTaskGetIdleRunTimePercentImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimeCounter( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimeCounter( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_ulTaskGetIdleRunTimeCounterImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_ulTaskGetIdleRunTimeCounter_Unpriv \n" + " MPU_ulTaskGetIdleRunTimeCounter_Priv: \n" + " pop {r0} \n" + " b MPU_ulTaskGetIdleRunTimeCounterImpl \n" + " MPU_ulTaskGetIdleRunTimeCounter_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_ulTaskGetIdleRunTimeCounterImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_APPLICATION_TASK_TAG == 1 ) + +void MPU_vTaskSetApplicationTaskTag( TaskHandle_t xTask, + TaskHookFunction_t pxHookFunction ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskSetApplicationTaskTag( TaskHandle_t xTask, + TaskHookFunction_t pxHookFunction ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskSetApplicationTaskTagImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vTaskSetApplicationTaskTag_Unpriv \n" + " MPU_vTaskSetApplicationTaskTag_Priv: \n" + " pop {r0} \n" + " b MPU_vTaskSetApplicationTaskTagImpl \n" + " MPU_vTaskSetApplicationTaskTag_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vTaskSetApplicationTaskTagImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_APPLICATION_TASK_TAG == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_APPLICATION_TASK_TAG == 1 ) + +TaskHookFunction_t MPU_xTaskGetApplicationTaskTag( TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TaskHookFunction_t MPU_xTaskGetApplicationTaskTag( TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGetApplicationTaskTagImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskGetApplicationTaskTag_Unpriv \n" + " MPU_xTaskGetApplicationTaskTag_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskGetApplicationTaskTagImpl \n" + " MPU_xTaskGetApplicationTaskTag_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskGetApplicationTaskTagImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_APPLICATION_TASK_TAG == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) + +void MPU_vTaskSetThreadLocalStoragePointer( TaskHandle_t xTaskToSet, + BaseType_t xIndex, + void * pvValue ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskSetThreadLocalStoragePointer( TaskHandle_t xTaskToSet, + BaseType_t xIndex, + void * pvValue ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskSetThreadLocalStoragePointerImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vTaskSetThreadLocalStoragePointer_Unpriv \n" + " MPU_vTaskSetThreadLocalStoragePointer_Priv: \n" + " pop {r0} \n" + " b MPU_vTaskSetThreadLocalStoragePointerImpl \n" + " MPU_vTaskSetThreadLocalStoragePointer_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vTaskSetThreadLocalStoragePointerImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) + +void * MPU_pvTaskGetThreadLocalStoragePointer( TaskHandle_t xTaskToQuery, + BaseType_t xIndex ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void * MPU_pvTaskGetThreadLocalStoragePointer( TaskHandle_t xTaskToQuery, + BaseType_t xIndex ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_pvTaskGetThreadLocalStoragePointerImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_pvTaskGetThreadLocalStoragePointer_Unpriv \n" + " MPU_pvTaskGetThreadLocalStoragePointer_Priv: \n" + " pop {r0} \n" + " b MPU_pvTaskGetThreadLocalStoragePointerImpl \n" + " MPU_pvTaskGetThreadLocalStoragePointer_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_pvTaskGetThreadLocalStoragePointerImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + +UBaseType_t MPU_uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray, + const UBaseType_t uxArraySize, + configRUN_TIME_COUNTER_TYPE * const pulTotalRunTime ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray, + const UBaseType_t uxArraySize, + configRUN_TIME_COUNTER_TYPE * const pulTotalRunTime ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxTaskGetSystemStateImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_uxTaskGetSystemState_Unpriv \n" + " MPU_uxTaskGetSystemState_Priv: \n" + " pop {r0} \n" + " b MPU_uxTaskGetSystemStateImpl \n" + " MPU_uxTaskGetSystemState_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_uxTaskGetSystemStateImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TRACE_FACILITY == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) + +UBaseType_t MPU_uxTaskGetStackHighWaterMark( TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxTaskGetStackHighWaterMark( TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxTaskGetStackHighWaterMarkImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_uxTaskGetStackHighWaterMark_Unpriv \n" + " MPU_uxTaskGetStackHighWaterMark_Priv: \n" + " pop {r0} \n" + " b MPU_uxTaskGetStackHighWaterMarkImpl \n" + " MPU_uxTaskGetStackHighWaterMark_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_uxTaskGetStackHighWaterMarkImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) + +configSTACK_DEPTH_TYPE MPU_uxTaskGetStackHighWaterMark2( TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +configSTACK_DEPTH_TYPE MPU_uxTaskGetStackHighWaterMark2( TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxTaskGetStackHighWaterMark2Impl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_uxTaskGetStackHighWaterMark2_Unpriv \n" + " MPU_uxTaskGetStackHighWaterMark2_Priv: \n" + " pop {r0} \n" + " b MPU_uxTaskGetStackHighWaterMark2Impl \n" + " MPU_uxTaskGetStackHighWaterMark2_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_uxTaskGetStackHighWaterMark2Impl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) ) + +TaskHandle_t MPU_xTaskGetCurrentTaskHandle( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TaskHandle_t MPU_xTaskGetCurrentTaskHandle( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGetCurrentTaskHandleImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskGetCurrentTaskHandle_Unpriv \n" + " MPU_xTaskGetCurrentTaskHandle_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskGetCurrentTaskHandleImpl \n" + " MPU_xTaskGetCurrentTaskHandle_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskGetCurrentTaskHandleImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_xTaskGetSchedulerState == 1 ) + +BaseType_t MPU_xTaskGetSchedulerState( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskGetSchedulerState( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGetSchedulerStateImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskGetSchedulerState_Unpriv \n" + " MPU_xTaskGetSchedulerState_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskGetSchedulerStateImpl \n" + " MPU_xTaskGetSchedulerState_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskGetSchedulerStateImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_xTaskGetSchedulerState == 1 ) */ +/*-----------------------------------------------------------*/ + +void MPU_vTaskSetTimeOutState( TimeOut_t * const pxTimeOut ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskSetTimeOutState( TimeOut_t * const pxTimeOut ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskSetTimeOutStateImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vTaskSetTimeOutState_Unpriv \n" + " MPU_vTaskSetTimeOutState_Priv: \n" + " pop {r0} \n" + " b MPU_vTaskSetTimeOutStateImpl \n" + " MPU_vTaskSetTimeOutState_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vTaskSetTimeOutStateImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut, + TickType_t * const pxTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut, + TickType_t * const pxTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskCheckForTimeOutImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskCheckForTimeOut_Unpriv \n" + " MPU_xTaskCheckForTimeOut_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskCheckForTimeOutImpl \n" + " MPU_xTaskCheckForTimeOut_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskCheckForTimeOutImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +#if ( configUSE_TASK_NOTIFICATIONS == 1 ) + +BaseType_t MPU_xTaskGenericNotify( TaskHandle_t xTaskToNotify, + UBaseType_t uxIndexToNotify, + uint32_t ulValue, + eNotifyAction eAction, + uint32_t * pulPreviousNotificationValue ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskGenericNotify( TaskHandle_t xTaskToNotify, + UBaseType_t uxIndexToNotify, + uint32_t ulValue, + eNotifyAction eAction, + uint32_t * pulPreviousNotificationValue ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGenericNotifyImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskGenericNotify_Unpriv \n" + " MPU_xTaskGenericNotify_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskGenericNotifyImpl \n" + " MPU_xTaskGenericNotify_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskGenericNotifyImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER_1 ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TASK_NOTIFICATIONS == 1 ) + +BaseType_t MPU_xTaskGenericNotifyWait( UBaseType_t uxIndexToWaitOn, + uint32_t ulBitsToClearOnEntry, + uint32_t ulBitsToClearOnExit, + uint32_t * pulNotificationValue, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskGenericNotifyWait( UBaseType_t uxIndexToWaitOn, + uint32_t ulBitsToClearOnEntry, + uint32_t ulBitsToClearOnExit, + uint32_t * pulNotificationValue, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGenericNotifyWaitImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskGenericNotifyWait_Unpriv \n" + " MPU_xTaskGenericNotifyWait_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskGenericNotifyWaitImpl \n" + " MPU_xTaskGenericNotifyWait_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskGenericNotifyWaitImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER_1 ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TASK_NOTIFICATIONS == 1 ) + +uint32_t MPU_ulTaskGenericNotifyTake( UBaseType_t uxIndexToWaitOn, + BaseType_t xClearCountOnExit, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +uint32_t MPU_ulTaskGenericNotifyTake( UBaseType_t uxIndexToWaitOn, + BaseType_t xClearCountOnExit, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_ulTaskGenericNotifyTakeImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_ulTaskGenericNotifyTake_Unpriv \n" + " MPU_ulTaskGenericNotifyTake_Priv: \n" + " pop {r0} \n" + " b MPU_ulTaskGenericNotifyTakeImpl \n" + " MPU_ulTaskGenericNotifyTake_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_ulTaskGenericNotifyTakeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TASK_NOTIFICATIONS == 1 ) + +BaseType_t MPU_xTaskGenericNotifyStateClear( TaskHandle_t xTask, + UBaseType_t uxIndexToClear ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskGenericNotifyStateClear( TaskHandle_t xTask, + UBaseType_t uxIndexToClear ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGenericNotifyStateClearImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskGenericNotifyStateClear_Unpriv \n" + " MPU_xTaskGenericNotifyStateClear_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskGenericNotifyStateClearImpl \n" + " MPU_xTaskGenericNotifyStateClear_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskGenericNotifyStateClearImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TASK_NOTIFICATIONS == 1 ) + +uint32_t MPU_ulTaskGenericNotifyValueClear( TaskHandle_t xTask, + UBaseType_t uxIndexToClear, + uint32_t ulBitsToClear ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +uint32_t MPU_ulTaskGenericNotifyValueClear( TaskHandle_t xTask, + UBaseType_t uxIndexToClear, + uint32_t ulBitsToClear ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_ulTaskGenericNotifyValueClearImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_ulTaskGenericNotifyValueClear_Unpriv \n" + " MPU_ulTaskGenericNotifyValueClear_Priv: \n" + " pop {r0} \n" + " b MPU_ulTaskGenericNotifyValueClearImpl \n" + " MPU_ulTaskGenericNotifyValueClear_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_ulTaskGenericNotifyValueClearImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xQueueGenericSend( QueueHandle_t xQueue, + const void * const pvItemToQueue, + TickType_t xTicksToWait, + const BaseType_t xCopyPosition ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueueGenericSend( QueueHandle_t xQueue, + const void * const pvItemToQueue, + TickType_t xTicksToWait, + const BaseType_t xCopyPosition ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueGenericSendImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xQueueGenericSend_Unpriv \n" + " MPU_xQueueGenericSend_Priv: \n" + " pop {r0} \n" + " b MPU_xQueueGenericSendImpl \n" + " MPU_xQueueGenericSend_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xQueueGenericSendImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +UBaseType_t MPU_uxQueueMessagesWaiting( const QueueHandle_t xQueue ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxQueueMessagesWaiting( const QueueHandle_t xQueue ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxQueueMessagesWaitingImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_uxQueueMessagesWaiting_Unpriv \n" + " MPU_uxQueueMessagesWaiting_Priv: \n" + " pop {r0} \n" + " b MPU_uxQueueMessagesWaitingImpl \n" + " MPU_uxQueueMessagesWaiting_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_uxQueueMessagesWaitingImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +UBaseType_t MPU_uxQueueSpacesAvailable( const QueueHandle_t xQueue ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxQueueSpacesAvailable( const QueueHandle_t xQueue ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxQueueSpacesAvailableImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_uxQueueSpacesAvailable_Unpriv \n" + " MPU_uxQueueSpacesAvailable_Priv: \n" + " pop {r0} \n" + " b MPU_uxQueueSpacesAvailableImpl \n" + " MPU_uxQueueSpacesAvailable_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_uxQueueSpacesAvailableImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xQueueReceive( QueueHandle_t xQueue, + void * const pvBuffer, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueueReceive( QueueHandle_t xQueue, + void * const pvBuffer, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueReceiveImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xQueueReceive_Unpriv \n" + " MPU_xQueueReceive_Priv: \n" + " pop {r0} \n" + " b MPU_xQueueReceiveImpl \n" + " MPU_xQueueReceive_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xQueueReceiveImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xQueuePeek( QueueHandle_t xQueue, + void * const pvBuffer, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueuePeek( QueueHandle_t xQueue, + void * const pvBuffer, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueuePeekImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xQueuePeek_Unpriv \n" + " MPU_xQueuePeek_Priv: \n" + " pop {r0} \n" + " b MPU_xQueuePeekImpl \n" + " MPU_xQueuePeek_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xQueuePeekImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xQueueSemaphoreTake( QueueHandle_t xQueue, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueueSemaphoreTake( QueueHandle_t xQueue, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueSemaphoreTakeImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xQueueSemaphoreTake_Unpriv \n" + " MPU_xQueueSemaphoreTake_Priv: \n" + " pop {r0} \n" + " b MPU_xQueueSemaphoreTakeImpl \n" + " MPU_xQueueSemaphoreTake_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xQueueSemaphoreTakeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +#if ( ( configUSE_MUTEXES == 1 ) && ( INCLUDE_xSemaphoreGetMutexHolder == 1 ) ) + +TaskHandle_t MPU_xQueueGetMutexHolder( QueueHandle_t xSemaphore ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TaskHandle_t MPU_xQueueGetMutexHolder( QueueHandle_t xSemaphore ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueGetMutexHolderImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xQueueGetMutexHolder_Unpriv \n" + " MPU_xQueueGetMutexHolder_Priv: \n" + " pop {r0} \n" + " b MPU_xQueueGetMutexHolderImpl \n" + " MPU_xQueueGetMutexHolder_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xQueueGetMutexHolderImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( ( configUSE_MUTEXES == 1 ) && ( INCLUDE_xSemaphoreGetMutexHolder == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_RECURSIVE_MUTEXES == 1 ) + +BaseType_t MPU_xQueueTakeMutexRecursive( QueueHandle_t xMutex, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueueTakeMutexRecursive( QueueHandle_t xMutex, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueTakeMutexRecursiveImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xQueueTakeMutexRecursive_Unpriv \n" + " MPU_xQueueTakeMutexRecursive_Priv: \n" + " pop {r0} \n" + " b MPU_xQueueTakeMutexRecursiveImpl \n" + " MPU_xQueueTakeMutexRecursive_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xQueueTakeMutexRecursiveImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_RECURSIVE_MUTEXES == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_RECURSIVE_MUTEXES == 1 ) + +BaseType_t MPU_xQueueGiveMutexRecursive( QueueHandle_t pxMutex ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueueGiveMutexRecursive( QueueHandle_t pxMutex ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueGiveMutexRecursiveImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xQueueGiveMutexRecursive_Unpriv \n" + " MPU_xQueueGiveMutexRecursive_Priv: \n" + " pop {r0} \n" + " b MPU_xQueueGiveMutexRecursiveImpl \n" + " MPU_xQueueGiveMutexRecursive_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xQueueGiveMutexRecursiveImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_RECURSIVE_MUTEXES == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_QUEUE_SETS == 1 ) + +QueueSetMemberHandle_t MPU_xQueueSelectFromSet( QueueSetHandle_t xQueueSet, + const TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +QueueSetMemberHandle_t MPU_xQueueSelectFromSet( QueueSetHandle_t xQueueSet, + const TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueSelectFromSetImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xQueueSelectFromSet_Unpriv \n" + " MPU_xQueueSelectFromSet_Priv: \n" + " pop {r0} \n" + " b MPU_xQueueSelectFromSetImpl \n" + " MPU_xQueueSelectFromSet_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xQueueSelectFromSetImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_QUEUE_SETS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_QUEUE_SETS == 1 ) + +BaseType_t MPU_xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore, + QueueSetHandle_t xQueueSet ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore, + QueueSetHandle_t xQueueSet ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueAddToSetImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xQueueAddToSet_Unpriv \n" + " MPU_xQueueAddToSet_Priv: \n" + " pop {r0} \n" + " b MPU_xQueueAddToSetImpl \n" + " MPU_xQueueAddToSet_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xQueueAddToSetImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_QUEUE_SETS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configQUEUE_REGISTRY_SIZE > 0 ) + +void MPU_vQueueAddToRegistry( QueueHandle_t xQueue, + const char * pcName ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vQueueAddToRegistry( QueueHandle_t xQueue, + const char * pcName ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vQueueAddToRegistryImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vQueueAddToRegistry_Unpriv \n" + " MPU_vQueueAddToRegistry_Priv: \n" + " pop {r0} \n" + " b MPU_vQueueAddToRegistryImpl \n" + " MPU_vQueueAddToRegistry_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vQueueAddToRegistryImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configQUEUE_REGISTRY_SIZE > 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configQUEUE_REGISTRY_SIZE > 0 ) + +void MPU_vQueueUnregisterQueue( QueueHandle_t xQueue ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vQueueUnregisterQueue( QueueHandle_t xQueue ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vQueueUnregisterQueueImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vQueueUnregisterQueue_Unpriv \n" + " MPU_vQueueUnregisterQueue_Priv: \n" + " pop {r0} \n" + " b MPU_vQueueUnregisterQueueImpl \n" + " MPU_vQueueUnregisterQueue_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vQueueUnregisterQueueImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configQUEUE_REGISTRY_SIZE > 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configQUEUE_REGISTRY_SIZE > 0 ) + +const char * MPU_pcQueueGetName( QueueHandle_t xQueue ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +const char * MPU_pcQueueGetName( QueueHandle_t xQueue ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_pcQueueGetNameImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_pcQueueGetName_Unpriv \n" + " MPU_pcQueueGetName_Priv: \n" + " pop {r0} \n" + " b MPU_pcQueueGetNameImpl \n" + " MPU_pcQueueGetName_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_pcQueueGetNameImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configQUEUE_REGISTRY_SIZE > 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +void * MPU_pvTimerGetTimerID( const TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void * MPU_pvTimerGetTimerID( const TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_pvTimerGetTimerIDImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_pvTimerGetTimerID_Unpriv \n" + " MPU_pvTimerGetTimerID_Priv: \n" + " pop {r0} \n" + " b MPU_pvTimerGetTimerIDImpl \n" + " MPU_pvTimerGetTimerID_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_pvTimerGetTimerIDImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +void MPU_vTimerSetTimerID( TimerHandle_t xTimer, + void * pvNewID ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTimerSetTimerID( TimerHandle_t xTimer, + void * pvNewID ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTimerSetTimerIDImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vTimerSetTimerID_Unpriv \n" + " MPU_vTimerSetTimerID_Priv: \n" + " pop {r0} \n" + " b MPU_vTimerSetTimerIDImpl \n" + " MPU_vTimerSetTimerID_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vTimerSetTimerIDImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +BaseType_t MPU_xTimerIsTimerActive( TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTimerIsTimerActive( TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTimerIsTimerActiveImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTimerIsTimerActive_Unpriv \n" + " MPU_xTimerIsTimerActive_Priv: \n" + " pop {r0} \n" + " b MPU_xTimerIsTimerActiveImpl \n" + " MPU_xTimerIsTimerActive_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTimerIsTimerActiveImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +TaskHandle_t MPU_xTimerGetTimerDaemonTaskHandle( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TaskHandle_t MPU_xTimerGetTimerDaemonTaskHandle( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTimerGetTimerDaemonTaskHandleImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTimerGetTimerDaemonTaskHandle_Unpriv \n" + " MPU_xTimerGetTimerDaemonTaskHandle_Priv: \n" + " pop {r0} \n" + " b MPU_xTimerGetTimerDaemonTaskHandleImpl \n" + " MPU_xTimerGetTimerDaemonTaskHandle_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTimerGetTimerDaemonTaskHandleImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +BaseType_t MPU_xTimerGenericCommand( TimerHandle_t xTimer, + const BaseType_t xCommandID, + const TickType_t xOptionalValue, + BaseType_t * const pxHigherPriorityTaskWoken, + const TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTimerGenericCommand( TimerHandle_t xTimer, + const BaseType_t xCommandID, + const TickType_t xOptionalValue, + BaseType_t * const pxHigherPriorityTaskWoken, + const TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTimerGenericCommandImpl \n" + " \n" + " push {r0} \n" + " mrs r0, ipsr \n" + " cmp r0, #0 \n" + " bne MPU_xTimerGenericCommand_Priv \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " beq MPU_xTimerGenericCommand_Priv \n" + " MPU_xTimerGenericCommand_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTimerGenericCommandImpl \n" + " svc %1 \n" + " bx lr \n" + " MPU_xTimerGenericCommand_Priv: \n" + " pop {r0} \n" + " b MPU_xTimerGenericCommandImpl \n" + " \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER_1 ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +const char * MPU_pcTimerGetName( TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +const char * MPU_pcTimerGetName( TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_pcTimerGetNameImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_pcTimerGetName_Unpriv \n" + " MPU_pcTimerGetName_Priv: \n" + " pop {r0} \n" + " b MPU_pcTimerGetNameImpl \n" + " MPU_pcTimerGetName_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_pcTimerGetNameImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, + const BaseType_t uxAutoReload ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, + const BaseType_t uxAutoReload ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTimerSetReloadModeImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vTimerSetReloadMode_Unpriv \n" + " MPU_vTimerSetReloadMode_Priv: \n" + " pop {r0} \n" + " b MPU_vTimerSetReloadModeImpl \n" + " MPU_vTimerSetReloadMode_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vTimerSetReloadModeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +BaseType_t MPU_xTimerGetReloadMode( TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTimerGetReloadMode( TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTimerGetReloadModeImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTimerGetReloadMode_Unpriv \n" + " MPU_xTimerGetReloadMode_Priv: \n" + " pop {r0} \n" + " b MPU_xTimerGetReloadModeImpl \n" + " MPU_xTimerGetReloadMode_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTimerGetReloadModeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +UBaseType_t MPU_uxTimerGetReloadMode( TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxTimerGetReloadMode( TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxTimerGetReloadModeImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_uxTimerGetReloadMode_Unpriv \n" + " MPU_uxTimerGetReloadMode_Priv: \n" + " pop {r0} \n" + " b MPU_uxTimerGetReloadModeImpl \n" + " MPU_uxTimerGetReloadMode_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_uxTimerGetReloadModeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +TickType_t MPU_xTimerGetPeriod( TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TickType_t MPU_xTimerGetPeriod( TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTimerGetPeriodImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTimerGetPeriod_Unpriv \n" + " MPU_xTimerGetPeriod_Priv: \n" + " pop {r0} \n" + " b MPU_xTimerGetPeriodImpl \n" + " MPU_xTimerGetPeriod_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTimerGetPeriodImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +TickType_t MPU_xTimerGetExpiryTime( TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TickType_t MPU_xTimerGetExpiryTime( TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTimerGetExpiryTimeImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTimerGetExpiryTime_Unpriv \n" + " MPU_xTimerGetExpiryTime_Priv: \n" + " pop {r0} \n" + " b MPU_xTimerGetExpiryTimeImpl \n" + " MPU_xTimerGetExpiryTime_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTimerGetExpiryTimeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +EventBits_t MPU_xEventGroupWaitBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToWaitFor, + const BaseType_t xClearOnExit, + const BaseType_t xWaitForAllBits, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +EventBits_t MPU_xEventGroupWaitBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToWaitFor, + const BaseType_t xClearOnExit, + const BaseType_t xWaitForAllBits, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupWaitBitsImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xEventGroupWaitBits_Unpriv \n" + " MPU_xEventGroupWaitBits_Priv: \n" + " pop {r0} \n" + " b MPU_xEventGroupWaitBitsImpl \n" + " MPU_xEventGroupWaitBits_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xEventGroupWaitBitsImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER_1 ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToClear ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToClear ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupClearBitsImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xEventGroupClearBits_Unpriv \n" + " MPU_xEventGroupClearBits_Priv: \n" + " pop {r0} \n" + " b MPU_xEventGroupClearBitsImpl \n" + " MPU_xEventGroupClearBits_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xEventGroupClearBitsImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupSetBitsImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xEventGroupSetBits_Unpriv \n" + " MPU_xEventGroupSetBits_Priv: \n" + " pop {r0} \n" + " b MPU_xEventGroupSetBitsImpl \n" + " MPU_xEventGroupSetBits_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xEventGroupSetBitsImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet, + const EventBits_t uxBitsToWaitFor, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet, + const EventBits_t uxBitsToWaitFor, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupSyncImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xEventGroupSync_Unpriv \n" + " MPU_xEventGroupSync_Priv: \n" + " pop {r0} \n" + " b MPU_xEventGroupSyncImpl \n" + " MPU_xEventGroupSync_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xEventGroupSyncImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + +UBaseType_t MPU_uxEventGroupGetNumber( void * xEventGroup ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxEventGroupGetNumber( void * xEventGroup ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxEventGroupGetNumberImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_uxEventGroupGetNumber_Unpriv \n" + " MPU_uxEventGroupGetNumber_Priv: \n" + " pop {r0} \n" + " b MPU_uxEventGroupGetNumberImpl \n" + " MPU_uxEventGroupGetNumber_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_uxEventGroupGetNumberImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /*( configUSE_TRACE_FACILITY == 1 )*/ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + +void MPU_vEventGroupSetNumber( void * xEventGroup, + UBaseType_t uxEventGroupNumber ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vEventGroupSetNumber( void * xEventGroup, + UBaseType_t uxEventGroupNumber ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vEventGroupSetNumberImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vEventGroupSetNumber_Unpriv \n" + " MPU_vEventGroupSetNumber_Priv: \n" + " pop {r0} \n" + " b MPU_vEventGroupSetNumberImpl \n" + " MPU_vEventGroupSetNumber_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vEventGroupSetNumberImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /*( configUSE_TRACE_FACILITY == 1 )*/ +/*-----------------------------------------------------------*/ + +size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, + const void * pvTxData, + size_t xDataLengthBytes, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, + const void * pvTxData, + size_t xDataLengthBytes, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferSendImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferSend_Unpriv \n" + " MPU_xStreamBufferSend_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferSendImpl \n" + " MPU_xStreamBufferSend_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xStreamBufferSendImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, + void * pvRxData, + size_t xBufferLengthBytes, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, + void * pvRxData, + size_t xBufferLengthBytes, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferReceiveImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferReceive_Unpriv \n" + " MPU_xStreamBufferReceive_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferReceiveImpl \n" + " MPU_xStreamBufferReceive_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xStreamBufferReceiveImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferIsFullImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferIsFull_Unpriv \n" + " MPU_xStreamBufferIsFull_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferIsFullImpl \n" + " MPU_xStreamBufferIsFull_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xStreamBufferIsFullImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferIsEmptyImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferIsEmpty_Unpriv \n" + " MPU_xStreamBufferIsEmpty_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferIsEmptyImpl \n" + " MPU_xStreamBufferIsEmpty_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xStreamBufferIsEmptyImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferSpacesAvailableImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferSpacesAvailable_Unpriv \n" + " MPU_xStreamBufferSpacesAvailable_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferSpacesAvailableImpl \n" + " MPU_xStreamBufferSpacesAvailable_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xStreamBufferSpacesAvailableImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferBytesAvailableImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferBytesAvailable_Unpriv \n" + " MPU_xStreamBufferBytesAvailable_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferBytesAvailableImpl \n" + " MPU_xStreamBufferBytesAvailable_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xStreamBufferBytesAvailableImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, + size_t xTriggerLevel ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, + size_t xTriggerLevel ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferSetTriggerLevelImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferSetTriggerLevel_Unpriv \n" + " MPU_xStreamBufferSetTriggerLevel_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferSetTriggerLevelImpl \n" + " MPU_xStreamBufferSetTriggerLevel_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xStreamBufferSetTriggerLevelImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferNextMessageLengthBytesImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferNextMessageLengthBytes_Unpriv \n" + " MPU_xStreamBufferNextMessageLengthBytes_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferNextMessageLengthBytesImpl \n" + " MPU_xStreamBufferNextMessageLengthBytes_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xStreamBufferNextMessageLengthBytesImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ diff --git a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33/portasm.c b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33/portasm.c index 9f9b2e68d39..f7ec7d9c072 100644 --- a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33/portasm.c +++ b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33/portasm.c @@ -40,95 +40,120 @@ * header files. */ #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE +#if ( configENABLE_MPU == 1 ) + void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ { __asm volatile ( - " .syntax unified \n" - " \n" - " ldr r2, pxCurrentTCBConst2 \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - " ldr r3, [r2] \n"/* Read pxCurrentTCB. */ - " ldr r0, [r3] \n"/* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ - " \n" - #if ( configENABLE_MPU == 1 ) - " dmb \n"/* Complete outstanding transfers before disabling MPU. */ - " ldr r2, xMPUCTRLConst2 \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ - " ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */ - " bic r4, #1 \n"/* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */ - " str r4, [r2] \n"/* Disable MPU. */ - " \n" - " adds r3, #4 \n"/* r3 = r3 + 4. r3 now points to MAIR0 in TCB. */ - " ldr r4, [r3] \n"/* r4 = *r3 i.e. r4 = MAIR0. */ - " ldr r2, xMAIR0Const2 \n"/* r2 = 0xe000edc0 [Location of MAIR0]. */ - " str r4, [r2] \n"/* Program MAIR0. */ - " ldr r2, xRNRConst2 \n"/* r2 = 0xe000ed98 [Location of RNR]. */ - " movs r4, #4 \n"/* r4 = 4. */ - " str r4, [r2] \n"/* Program RNR = 4. */ - " adds r3, #4 \n"/* r3 = r3 + 4. r3 now points to first RBAR in TCB. */ - " ldr r2, xRBARConst2 \n"/* r2 = 0xe000ed9c [Location of RBAR]. */ - " ldmia r3!, {r4-r11} \n"/* Read 4 set of RBAR/RLAR registers from TCB. */ - " stmia r2!, {r4-r11} \n"/* Write 4 set of RBAR/RLAR registers using alias registers. */ - " \n" + " .syntax unified \n" + " \n" + " program_mpu_first_task: \n" + " ldr r3, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r0, [r3] \n" /* r0 = pxCurrentTCB. */ + " \n" + " dmb \n" /* Complete outstanding transfers before disabling MPU. */ + " ldr r1, xMPUCTRLConst2 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ + " bic r2, #1 \n" /* r2 = r2 & ~1 i.e. Clear the bit 0 in r2. */ + " str r2, [r1] \n" /* Disable MPU. */ + " \n" + " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */ + " ldr r1, [r0] \n" /* r1 = *r0 i.e. r1 = MAIR0. */ + " ldr r2, xMAIR0Const2 \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */ + " str r1, [r2] \n" /* Program MAIR0. */ + " \n" + " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */ + " ldr r1, xRNRConst2 \n" /* r1 = 0xe000ed98 [Location of RNR]. */ + " ldr r2, xRBARConst2 \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ + " \n" + " movs r3, #4 \n" /* r3 = 4. */ + " str r3, [r1] \n" /* Program RNR = 4. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + " \n" #if ( configTOTAL_MPU_REGIONS == 16 ) - " ldr r2, xRNRConst2 \n"/* r2 = 0xe000ed98 [Location of RNR]. */ - " movs r4, #8 \n"/* r4 = 8. */ - " str r4, [r2] \n"/* Program RNR = 8. */ - " ldr r2, xRBARConst2 \n"/* r2 = 0xe000ed9c [Location of RBAR]. */ - " ldmia r3!, {r4-r11} \n"/* Read 4 set of RBAR/RLAR registers from TCB. */ - " stmia r2!, {r4-r11} \n"/* Write 4 set of RBAR/RLAR registers using alias registers. */ - " ldr r2, xRNRConst2 \n"/* r2 = 0xe000ed98 [Location of RNR]. */ - " movs r4, #12 \n"/* r4 = 12. */ - " str r4, [r2] \n"/* Program RNR = 12. */ - " ldr r2, xRBARConst2 \n"/* r2 = 0xe000ed9c [Location of RBAR]. */ - " ldmia r3!, {r4-r11} \n"/* Read 4 set of RBAR/RLAR registers from TCB. */ - " stmia r2!, {r4-r11} \n"/* Write 4 set of RBAR/RLAR registers using alias registers. */ + " movs r3, #8 \n" /* r3 = 8. */ + " str r3, [r1] \n" /* Program RNR = 8. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + " movs r3, #12 \n" /* r3 = 12. */ + " str r3, [r1] \n" /* Program RNR = 12. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ #endif /* configTOTAL_MPU_REGIONS == 16 */ - " \n" - " ldr r2, xMPUCTRLConst2 \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ - " ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */ - " orr r4, #1 \n"/* r4 = r4 | 1 i.e. Set the bit 0 in r4. */ - " str r4, [r2] \n"/* Enable MPU. */ - " dsb \n"/* Force memory writes before continuing. */ - #endif /* configENABLE_MPU */ + " \n" + " ldr r1, xMPUCTRLConst2 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ + " orr r2, #1 \n" /* r2 = r1 | 1 i.e. Set the bit 0 in r2. */ + " str r2, [r1] \n" /* Enable MPU. */ + " dsb \n" /* Force memory writes before continuing. */ + " \n" + " restore_context_first_task: \n" + " ldr r3, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r1, [r3] \n" /* r1 = pxCurrentTCB.*/ + " ldr r2, [r1] \n" /* r2 = Location of saved context in TCB. */ + " \n" + " restore_special_regs_first_task: \n" + " ldmdb r2!, {r0, r3-r5, lr} \n" /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */ + " msr psp, r3 \n" + " msr psplim, r4 \n" + " msr control, r5 \n" + " ldr r4, xSecureContextConst2 \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ + " str r0, [r4] \n" /* Restore xSecureContext. */ + " \n" + " restore_general_regs_first_task: \n" + " ldmdb r2!, {r4-r11} \n" /* r4-r11 contain hardware saved context. */ + " stmia r3!, {r4-r11} \n" /* Copy the hardware saved context on the task stack. */ + " ldmdb r2!, {r4-r11} \n" /* r4-r11 restored. */ + " \n" + " restore_context_done_first_task: \n" + " str r2, [r1] \n" /* Save the location where the context should be saved next as the first member of TCB. */ + " mov r0, #0 \n" + " msr basepri, r0 \n" /* Ensure that interrupts are enabled when the first task starts. */ + " bx lr \n" + " \n" + " .align 4 \n" + " pxCurrentTCBConst2: .word pxCurrentTCB \n" + " xSecureContextConst2: .word xSecureContext \n" + " xMPUCTRLConst2: .word 0xe000ed94 \n" + " xMAIR0Const2: .word 0xe000edc0 \n" + " xRNRConst2: .word 0xe000ed98 \n" + " xRBARConst2: .word 0xe000ed9c \n" + ); +} + +#else /* configENABLE_MPU */ + +void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ +{ + __asm volatile + ( + " .syntax unified \n" " \n" - #if ( configENABLE_MPU == 1 ) - " ldm r0!, {r1-r4} \n"/* Read from stack - r1 = xSecureContext, r2 = PSPLIM, r3 = CONTROL and r4 = EXC_RETURN. */ - " ldr r5, xSecureContextConst2 \n" - " str r1, [r5] \n"/* Set xSecureContext to this task's value for the same. */ - " msr psplim, r2 \n"/* Set this task's PSPLIM value. */ - " msr control, r3 \n"/* Set this task's CONTROL value. */ - " adds r0, #32 \n"/* Discard everything up to r0. */ - " msr psp, r0 \n"/* This is now the new top of stack to use in the task. */ - " isb \n" - " mov r0, #0 \n" - " msr basepri, r0 \n"/* Ensure that interrupts are enabled when the first task starts. */ - " bx r4 \n"/* Finally, branch to EXC_RETURN. */ - #else /* configENABLE_MPU */ - " ldm r0!, {r1-r3} \n"/* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */ - " ldr r4, xSecureContextConst2 \n" - " str r1, [r4] \n"/* Set xSecureContext to this task's value for the same. */ - " msr psplim, r2 \n"/* Set this task's PSPLIM value. */ - " movs r1, #2 \n"/* r1 = 2. */ - " msr CONTROL, r1 \n"/* Switch to use PSP in the thread mode. */ - " adds r0, #32 \n"/* Discard everything up to r0. */ - " msr psp, r0 \n"/* This is now the new top of stack to use in the task. */ - " isb \n" - " mov r0, #0 \n" - " msr basepri, r0 \n"/* Ensure that interrupts are enabled when the first task starts. */ - " bx r3 \n"/* Finally, branch to EXC_RETURN. */ - #endif /* configENABLE_MPU */ + " ldr r2, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r3, [r2] \n" /* Read pxCurrentTCB. */ + " ldr r0, [r3] \n" /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ " \n" + " ldm r0!, {r1-r3} \n" /* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */ + " ldr r4, xSecureContextConst2 \n" + " str r1, [r4] \n" /* Set xSecureContext to this task's value for the same. */ + " msr psplim, r2 \n" /* Set this task's PSPLIM value. */ + " movs r1, #2 \n" /* r1 = 2. */ + " msr CONTROL, r1 \n" /* Switch to use PSP in the thread mode. */ + " adds r0, #32 \n" /* Discard everything up to r0. */ + " msr psp, r0 \n" /* This is now the new top of stack to use in the task. */ + " isb \n" + " mov r0, #0 \n" + " msr basepri, r0 \n" /* Ensure that interrupts are enabled when the first task starts. */ + " bx r3 \n" /* Finally, branch to EXC_RETURN. */ " .align 4 \n" "pxCurrentTCBConst2: .word pxCurrentTCB \n" "xSecureContextConst2: .word xSecureContext \n" - #if ( configENABLE_MPU == 1 ) - "xMPUCTRLConst2: .word 0xe000ed94 \n" - "xMAIR0Const2: .word 0xe000edc0 \n" - "xRNRConst2: .word 0xe000ed98 \n" - "xRBARConst2: .word 0xe000ed9c \n" - #endif /* configENABLE_MPU */ ); } + +#endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */ @@ -236,6 +261,160 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att } /*-----------------------------------------------------------*/ +#if ( configENABLE_MPU == 1 ) + +void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern SecureContext_SaveContext \n" + " .extern SecureContext_LoadContext \n" + " \n" + " ldr r3, xSecureContextConst \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ + " ldr r0, [r3] \n" /* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */ + " ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r1, [r3] \n" /* Read pxCurrentTCB - Value of pxCurrentTCB must be in r1 as it is used as a parameter later. */ + " ldr r2, [r1] \n" /* r2 = Location in TCB where the context should be saved. */ + " \n" + " cbz r0, save_ns_context \n" /* No secure context to save. */ + " save_s_context: \n" + " push {r0-r2, lr} \n" + " bl SecureContext_SaveContext \n" /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ + " pop {r0-r2, lr} \n" + " \n" + " save_ns_context: \n" + " mov r3, lr \n" /* r3 = LR (EXC_RETURN). */ + " lsls r3, r3, #25 \n" /* r3 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ + " bmi save_special_regs \n" /* r3 < 0 ==> Bit[6] in EXC_RETURN is 1 ==> secure stack was used to store the stack frame. */ + " \n" + " save_general_regs: \n" + " mrs r3, psp \n" + " \n" + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + " add r3, r3, #0x20 \n" /* Move r3 to location where s0 is saved. */ + " tst lr, #0x10 \n" + " ittt eq \n" + " vstmiaeq r2!, {s16-s31} \n" /* Store s16-s31. */ + " vldmiaeq r3, {s0-s16} \n" /* Copy hardware saved FP context into s0-s16. */ + " vstmiaeq r2!, {s0-s16} \n" /* Store hardware saved FP context. */ + " sub r3, r3, #0x20 \n" /* Set r3 back to the location of hardware saved context. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ + " \n" + " stmia r2!, {r4-r11} \n" /* Store r4-r11. */ + " ldmia r3, {r4-r11} \n" /* Copy the hardware saved context into r4-r11. */ + " stmia r2!, {r4-r11} \n" /* Store the hardware saved context. */ + " \n" + " save_special_regs: \n" + " mrs r3, psp \n" /* r3 = PSP. */ + " mrs r4, psplim \n" /* r4 = PSPLIM. */ + " mrs r5, control \n" /* r5 = CONTROL. */ + " stmia r2!, {r0, r3-r5, lr} \n" /* Store xSecureContext, original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */ + " str r2, [r1] \n" /* Save the location from where the context should be restored as the first member of TCB. */ + " \n" + " select_next_task: \n" + " mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */ + " msr basepri, r0 \n" /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + " dsb \n" + " isb \n" + " bl vTaskSwitchContext \n" + " mov r0, #0 \n" /* r0 = 0. */ + " msr basepri, r0 \n" /* Enable interrupts. */ + " \n" + " program_mpu: \n" + " ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r0, [r3] \n" /* r0 = pxCurrentTCB.*/ + " \n" + " dmb \n" /* Complete outstanding transfers before disabling MPU. */ + " ldr r1, xMPUCTRLConst \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ + " bic r2, #1 \n" /* r2 = r2 & ~1 i.e. Clear the bit 0 in r2. */ + " str r2, [r1] \n" /* Disable MPU. */ + " \n" + " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */ + " ldr r1, [r0] \n" /* r1 = *r0 i.e. r1 = MAIR0. */ + " ldr r2, xMAIR0Const \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */ + " str r1, [r2] \n" /* Program MAIR0. */ + " \n" + " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */ + " ldr r1, xRNRConst \n" /* r1 = 0xe000ed98 [Location of RNR]. */ + " ldr r2, xRBARConst \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ + " \n" + " movs r3, #4 \n" /* r3 = 4. */ + " str r3, [r1] \n" /* Program RNR = 4. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + " \n" + #if ( configTOTAL_MPU_REGIONS == 16 ) + " movs r3, #8 \n" /* r3 = 8. */ + " str r3, [r1] \n" /* Program RNR = 8. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + " movs r3, #12 \n" /* r3 = 12. */ + " str r3, [r1] \n" /* Program RNR = 12. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + #endif /* configTOTAL_MPU_REGIONS == 16 */ + " \n" + " ldr r1, xMPUCTRLConst \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ + " orr r2, #1 \n" /* r2 = r2 | 1 i.e. Set the bit 0 in r2. */ + " str r2, [r1] \n" /* Enable MPU. */ + " dsb \n" /* Force memory writes before continuing. */ + " \n" + " restore_context: \n" + " ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r1, [r3] \n" /* r1 = pxCurrentTCB.*/ + " ldr r2, [r1] \n" /* r2 = Location of saved context in TCB. */ + " \n" + " restore_special_regs: \n" + " ldmdb r2!, {r0, r3-r5, lr} \n" /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */ + " msr psp, r3 \n" + " msr psplim, r4 \n" + " msr control, r5 \n" + " ldr r4, xSecureContextConst \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ + " str r0, [r4] \n" /* Restore xSecureContext. */ + " cbz r0, restore_ns_context \n" /* No secure context to restore. */ + " \n" + " restore_s_context: \n" + " push {r1-r3, lr} \n" + " bl SecureContext_LoadContext \n" /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ + " pop {r1-r3, lr} \n" + " \n" + " restore_ns_context: \n" + " mov r0, lr \n" /* r0 = LR (EXC_RETURN). */ + " lsls r0, r0, #25 \n" /* r0 = r0 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ + " bmi restore_context_done \n" /* r0 < 0 ==> Bit[6] in EXC_RETURN is 1 ==> secure stack was used to store the stack frame. */ + " \n" + " restore_general_regs: \n" + " ldmdb r2!, {r4-r11} \n" /* r4-r11 contain hardware saved context. */ + " stmia r3!, {r4-r11} \n" /* Copy the hardware saved context on the task stack. */ + " ldmdb r2!, {r4-r11} \n" /* r4-r11 restored. */ + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + " tst lr, #0x10 \n" + " ittt eq \n" + " vldmdbeq r2!, {s0-s16} \n" /* s0-s16 contain hardware saved FP context. */ + " vstmiaeq r3!, {s0-s16} \n" /* Copy hardware saved FP context on the task stack. */ + " vldmdbeq r2!, {s16-s31} \n" /* Restore s16-s31. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ + " \n" + " restore_context_done: \n" + " str r2, [r1] \n" /* Save the location where the context should be saved next as the first member of TCB. */ + " bx lr \n" + " \n" + " .align 4 \n" + " pxCurrentTCBConst: .word pxCurrentTCB \n" + " xSecureContextConst: .word xSecureContext \n" + " xMPUCTRLConst: .word 0xe000ed94 \n" + " xMAIR0Const: .word 0xe000edc0 \n" + " xRNRConst: .word 0xe000ed98 \n" + " xRBARConst: .word 0xe000ed9c \n" + ::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) + ); +} + +#else /* configENABLE_MPU */ + void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ { __asm volatile @@ -260,20 +439,11 @@ void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ " \n" " ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r3] \n"/* Read pxCurrentTCB.*/ - #if ( configENABLE_MPU == 1 ) - " subs r2, r2, #16 \n"/* Make space for xSecureContext, PSPLIM, CONTROL and LR on the stack. */ - " str r2, [r1] \n"/* Save the new top of stack in TCB. */ - " mrs r1, psplim \n"/* r1 = PSPLIM. */ - " mrs r3, control \n"/* r3 = CONTROL. */ - " mov r4, lr \n"/* r4 = LR/EXC_RETURN. */ - " stmia r2!, {r0, r1, r3, r4} \n"/* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */ - #else /* configENABLE_MPU */ - " subs r2, r2, #12 \n"/* Make space for xSecureContext, PSPLIM and LR on the stack. */ - " str r2, [r1] \n"/* Save the new top of stack in TCB. */ - " mrs r1, psplim \n"/* r1 = PSPLIM. */ - " mov r3, lr \n"/* r3 = LR/EXC_RETURN. */ - " stmia r2!, {r0, r1, r3} \n"/* Store xSecureContext, PSPLIM and LR on the stack. */ - #endif /* configENABLE_MPU */ + " subs r2, r2, #12 \n"/* Make space for xSecureContext, PSPLIM and LR on the stack. */ + " str r2, [r1] \n"/* Save the new top of stack in TCB. */ + " mrs r1, psplim \n"/* r1 = PSPLIM. */ + " mov r3, lr \n"/* r3 = LR/EXC_RETURN. */ + " stmia r2!, {r0, r1, r3} \n"/* Store xSecureContext, PSPLIM and LR on the stack. */ " b select_next_task \n" " \n" " save_ns_context: \n" @@ -284,26 +454,14 @@ void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ " it eq \n" " vstmdbeq r2!, {s16-s31} \n"/* Store the additional FP context registers which are not saved automatically. */ #endif /* configENABLE_FPU || configENABLE_MVE */ - #if ( configENABLE_MPU == 1 ) - " subs r2, r2, #48 \n"/* Make space for xSecureContext, PSPLIM, CONTROL, LR and the remaining registers on the stack. */ - " str r2, [r1] \n"/* Save the new top of stack in TCB. */ - " adds r2, r2, #16 \n"/* r2 = r2 + 16. */ - " stm r2, {r4-r11} \n"/* Store the registers that are not saved automatically. */ - " mrs r1, psplim \n"/* r1 = PSPLIM. */ - " mrs r3, control \n"/* r3 = CONTROL. */ - " mov r4, lr \n"/* r4 = LR/EXC_RETURN. */ - " subs r2, r2, #16 \n"/* r2 = r2 - 16. */ - " stmia r2!, {r0, r1, r3, r4} \n"/* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */ - #else /* configENABLE_MPU */ - " subs r2, r2, #44 \n"/* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */ - " str r2, [r1] \n"/* Save the new top of stack in TCB. */ - " adds r2, r2, #12 \n"/* r2 = r2 + 12. */ - " stm r2, {r4-r11} \n"/* Store the registers that are not saved automatically. */ - " mrs r1, psplim \n"/* r1 = PSPLIM. */ - " mov r3, lr \n"/* r3 = LR/EXC_RETURN. */ - " subs r2, r2, #12 \n"/* r2 = r2 - 12. */ - " stmia r2!, {r0, r1, r3} \n"/* Store xSecureContext, PSPLIM and LR on the stack. */ - #endif /* configENABLE_MPU */ + " subs r2, r2, #44 \n"/* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */ + " str r2, [r1] \n"/* Save the new top of stack in TCB. */ + " adds r2, r2, #12 \n"/* r2 = r2 + 12. */ + " stm r2, {r4-r11} \n"/* Store the registers that are not saved automatically. */ + " mrs r1, psplim \n"/* r1 = PSPLIM. */ + " mov r3, lr \n"/* r3 = LR/EXC_RETURN. */ + " subs r2, r2, #12 \n"/* r2 = r2 - 12. */ + " stmia r2!, {r0, r1, r3} \n"/* Store xSecureContext, PSPLIM and LR on the stack. */ " \n" " select_next_task: \n" " mov r0, %0 \n"/* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */ @@ -318,83 +476,22 @@ void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ " ldr r1, [r3] \n"/* Read pxCurrentTCB. */ " ldr r2, [r1] \n"/* The first item in pxCurrentTCB is the task top of stack. r2 now points to the top of stack. */ " \n" - #if ( configENABLE_MPU == 1 ) - " dmb \n"/* Complete outstanding transfers before disabling MPU. */ - " ldr r3, xMPUCTRLConst \n"/* r3 = 0xe000ed94 [Location of MPU_CTRL]. */ - " ldr r4, [r3] \n"/* Read the value of MPU_CTRL. */ - " bic r4, #1 \n"/* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */ - " str r4, [r3] \n"/* Disable MPU. */ - " \n" - " adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */ - " ldr r4, [r1] \n"/* r4 = *r1 i.e. r4 = MAIR0. */ - " ldr r3, xMAIR0Const \n"/* r3 = 0xe000edc0 [Location of MAIR0]. */ - " str r4, [r3] \n"/* Program MAIR0. */ - " ldr r3, xRNRConst \n"/* r3 = 0xe000ed98 [Location of RNR]. */ - " movs r4, #4 \n"/* r4 = 4. */ - " str r4, [r3] \n"/* Program RNR = 4. */ - " adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to first RBAR in TCB. */ - " ldr r3, xRBARConst \n"/* r3 = 0xe000ed9c [Location of RBAR]. */ - " ldmia r1!, {r4-r11} \n"/* Read 4 sets of RBAR/RLAR registers from TCB. */ - " stmia r3!, {r4-r11} \n"/* Write 4 set of RBAR/RLAR registers using alias registers. */ - " \n" - #if ( configTOTAL_MPU_REGIONS == 16 ) - " ldr r3, xRNRConst \n"/* r3 = 0xe000ed98 [Location of RNR]. */ - " movs r4, #8 \n"/* r4 = 8. */ - " str r4, [r3] \n"/* Program RNR = 8. */ - " ldr r3, xRBARConst \n"/* r3 = 0xe000ed9c [Location of RBAR]. */ - " ldmia r1!, {r4-r11} \n"/* Read 4 sets of RBAR/RLAR registers from TCB. */ - " stmia r3!, {r4-r11} \n"/* Write 4 set of RBAR/RLAR registers using alias registers. */ - " ldr r3, xRNRConst \n"/* r3 = 0xe000ed98 [Location of RNR]. */ - " movs r4, #12 \n"/* r4 = 12. */ - " str r4, [r3] \n"/* Program RNR = 12. */ - " ldr r3, xRBARConst \n"/* r3 = 0xe000ed9c [Location of RBAR]. */ - " ldmia r1!, {r4-r11} \n"/* Read 4 sets of RBAR/RLAR registers from TCB. */ - " stmia r3!, {r4-r11} \n"/* Write 4 set of RBAR/RLAR registers using alias registers. */ - #endif /* configTOTAL_MPU_REGIONS == 16 */ - " \n" - " ldr r3, xMPUCTRLConst \n"/* r3 = 0xe000ed94 [Location of MPU_CTRL]. */ - " ldr r4, [r3] \n"/* Read the value of MPU_CTRL. */ - " orr r4, #1 \n"/* r4 = r4 | 1 i.e. Set the bit 0 in r4. */ - " str r4, [r3] \n"/* Enable MPU. */ - " dsb \n"/* Force memory writes before continuing. */ - #endif /* configENABLE_MPU */ - " \n" - #if ( configENABLE_MPU == 1 ) - " ldmia r2!, {r0, r1, r3, r4} \n"/* Read from stack - r0 = xSecureContext, r1 = PSPLIM, r3 = CONTROL and r4 = LR. */ - " msr psplim, r1 \n"/* Restore the PSPLIM register value for the task. */ - " msr control, r3 \n"/* Restore the CONTROL register value for the task. */ - " mov lr, r4 \n"/* LR = r4. */ - " ldr r3, xSecureContextConst \n"/* Read the location of xSecureContext i.e. &( xSecureContext ). */ - " str r0, [r3] \n"/* Restore the task's xSecureContext. */ - " cbz r0, restore_ns_context \n"/* If there is no secure context for the task, restore the non-secure context. */ - " ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - " ldr r1, [r3] \n"/* Read pxCurrentTCB. */ - " push {r2, r4} \n" - " bl SecureContext_LoadContext \n"/* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ - " pop {r2, r4} \n" - " mov lr, r4 \n"/* LR = r4. */ - " lsls r1, r4, #25 \n"/* r1 = r4 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ - " bpl restore_ns_context \n"/* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ - " msr psp, r2 \n"/* Remember the new top of stack for the task. */ - " bx lr \n" - #else /* configENABLE_MPU */ - " ldmia r2!, {r0, r1, r4} \n"/* Read from stack - r0 = xSecureContext, r1 = PSPLIM and r4 = LR. */ - " msr psplim, r1 \n"/* Restore the PSPLIM register value for the task. */ - " mov lr, r4 \n"/* LR = r4. */ - " ldr r3, xSecureContextConst \n"/* Read the location of xSecureContext i.e. &( xSecureContext ). */ - " str r0, [r3] \n"/* Restore the task's xSecureContext. */ - " cbz r0, restore_ns_context \n"/* If there is no secure context for the task, restore the non-secure context. */ - " ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - " ldr r1, [r3] \n"/* Read pxCurrentTCB. */ - " push {r2, r4} \n" - " bl SecureContext_LoadContext \n"/* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ - " pop {r2, r4} \n" - " mov lr, r4 \n"/* LR = r4. */ - " lsls r1, r4, #25 \n"/* r1 = r4 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ - " bpl restore_ns_context \n"/* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ - " msr psp, r2 \n"/* Remember the new top of stack for the task. */ - " bx lr \n" - #endif /* configENABLE_MPU */ + " ldmia r2!, {r0, r1, r4} \n"/* Read from stack - r0 = xSecureContext, r1 = PSPLIM and r4 = LR. */ + " msr psplim, r1 \n"/* Restore the PSPLIM register value for the task. */ + " mov lr, r4 \n"/* LR = r4. */ + " ldr r3, xSecureContextConst \n"/* Read the location of xSecureContext i.e. &( xSecureContext ). */ + " str r0, [r3] \n"/* Restore the task's xSecureContext. */ + " cbz r0, restore_ns_context \n"/* If there is no secure context for the task, restore the non-secure context. */ + " ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r1, [r3] \n"/* Read pxCurrentTCB. */ + " push {r2, r4} \n" + " bl SecureContext_LoadContext \n"/* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ + " pop {r2, r4} \n" + " mov lr, r4 \n"/* LR = r4. */ + " lsls r1, r4, #25 \n"/* r1 = r4 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ + " bpl restore_ns_context \n"/* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ + " msr psp, r2 \n"/* Remember the new top of stack for the task. */ + " bx lr \n" " \n" " restore_ns_context: \n" " ldmia r2!, {r4-r11} \n"/* Restore the registers that are not automatically restored. */ @@ -409,17 +506,60 @@ void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ " .align 4 \n" "pxCurrentTCBConst: .word pxCurrentTCB \n" "xSecureContextConst: .word xSecureContext \n" - #if ( configENABLE_MPU == 1 ) - "xMPUCTRLConst: .word 0xe000ed94 \n" - "xMAIR0Const: .word 0xe000edc0 \n" - "xRNRConst: .word 0xe000ed98 \n" - "xRBARConst: .word 0xe000ed9c \n" - #endif /* configENABLE_MPU */ ::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) ); } + +#endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + +void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ +{ + __asm volatile + ( + ".syntax unified \n" + ".extern vPortSVCHandler_C \n" + ".extern vSystemCallEnter \n" + ".extern vSystemCallEnter_1 \n" + ".extern vSystemCallExit \n" + " \n" + "tst lr, #4 \n" + "ite eq \n" + "mrseq r0, msp \n" + "mrsne r0, psp \n" + " \n" + "ldr r1, [r0, #24] \n" + "ldrb r2, [r1, #-2] \n" + "cmp r2, %0 \n" + "beq syscall_enter \n" + "cmp r2, %1 \n" + "beq syscall_enter_1 \n" + "cmp r2, %2 \n" + "beq syscall_exit \n" + "b vPortSVCHandler_C \n" + " \n" + "syscall_enter: \n" + " mov r1, lr \n" + " b vSystemCallEnter \n" + " \n" + "syscall_enter_1: \n" + " mov r1, lr \n" + " b vSystemCallEnter_1 \n" + " \n" + "syscall_exit: \n" + " mov r1, lr \n" + " b vSystemCallExit \n" + " \n" + : /* No outputs. */ + :"i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_ENTER_1 ), "i" ( portSVC_SYSTEM_CALL_EXIT ) + : "r0", "r1", "r2", "memory" + ); +} + +#else /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ { __asm volatile @@ -437,6 +577,8 @@ void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ "svchandler_address_const: .word vPortSVCHandler_C \n" ); } + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ /*-----------------------------------------------------------*/ void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) /* __attribute__ (( naked )) */ diff --git a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33/portmacro.h b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33/portmacro.h index 19da9b0ecfe..b9efb07ddc7 100644 --- a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33/portmacro.h +++ b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33/portmacro.h @@ -51,7 +51,6 @@ #define portARCH_NAME "Cortex-M33" #define portHAS_BASEPRI 1 #define portDONT_DISCARD __attribute__( ( used ) ) -#define portNORETURN __attribute__( ( noreturn ) ) /*-----------------------------------------------------------*/ /* ARMv8-M common port configurations. */ diff --git a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33_NTZ/mpu_wrappers_v2_asm.c b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33_NTZ/mpu_wrappers_v2_asm.c new file mode 100644 index 00000000000..6e2043427fe --- /dev/null +++ b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33_NTZ/mpu_wrappers_v2_asm.c @@ -0,0 +1,2349 @@ +/* + * FreeRTOS Kernel + * Copyright (C) 2021 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 + * + */ + +/* 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. */ +#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +/* Scheduler includes. */ +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" +#include "timers.h" +#include "event_groups.h" +#include "stream_buffer.h" + +#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + +#if ( INCLUDE_xTaskDelayUntil == 1 ) + +BaseType_t MPU_xTaskDelayUntil( TickType_t * const pxPreviousWakeTime, + const TickType_t xTimeIncrement ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskDelayUntil( TickType_t * const pxPreviousWakeTime, + const TickType_t xTimeIncrement ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskDelayUntilImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskDelayUntil_Unpriv \n" + " MPU_xTaskDelayUntil_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskDelayUntilImpl \n" + " MPU_xTaskDelayUntil_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskDelayUntilImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_xTaskDelayUntil == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_xTaskAbortDelay == 1 ) + +BaseType_t MPU_xTaskAbortDelay( TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskAbortDelay( TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskAbortDelayImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskAbortDelay_Unpriv \n" + " MPU_xTaskAbortDelay_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskAbortDelayImpl \n" + " MPU_xTaskAbortDelay_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskAbortDelayImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_xTaskAbortDelay == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskDelay == 1 ) + +void MPU_vTaskDelay( const TickType_t xTicksToDelay ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskDelay( const TickType_t xTicksToDelay ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskDelayImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vTaskDelay_Unpriv \n" + " MPU_vTaskDelay_Priv: \n" + " pop {r0} \n" + " b MPU_vTaskDelayImpl \n" + " MPU_vTaskDelay_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vTaskDelayImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_vTaskDelay == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_uxTaskPriorityGet == 1 ) + +UBaseType_t MPU_uxTaskPriorityGet( const TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxTaskPriorityGet( const TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxTaskPriorityGetImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_uxTaskPriorityGet_Unpriv \n" + " MPU_uxTaskPriorityGet_Priv: \n" + " pop {r0} \n" + " b MPU_uxTaskPriorityGetImpl \n" + " MPU_uxTaskPriorityGet_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_uxTaskPriorityGetImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_uxTaskPriorityGet == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_eTaskGetState == 1 ) + +eTaskState MPU_eTaskGetState( TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +eTaskState MPU_eTaskGetState( TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_eTaskGetStateImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_eTaskGetState_Unpriv \n" + " MPU_eTaskGetState_Priv: \n" + " pop {r0} \n" + " b MPU_eTaskGetStateImpl \n" + " MPU_eTaskGetState_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_eTaskGetStateImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_eTaskGetState == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + +void MPU_vTaskGetInfo( TaskHandle_t xTask, + TaskStatus_t * pxTaskStatus, + BaseType_t xGetFreeStackSpace, + eTaskState eState ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskGetInfo( TaskHandle_t xTask, + TaskStatus_t * pxTaskStatus, + BaseType_t xGetFreeStackSpace, + eTaskState eState ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskGetInfoImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vTaskGetInfo_Unpriv \n" + " MPU_vTaskGetInfo_Priv: \n" + " pop {r0} \n" + " b MPU_vTaskGetInfoImpl \n" + " MPU_vTaskGetInfo_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vTaskGetInfoImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TRACE_FACILITY == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) + +TaskHandle_t MPU_xTaskGetIdleTaskHandle( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TaskHandle_t MPU_xTaskGetIdleTaskHandle( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGetIdleTaskHandleImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskGetIdleTaskHandle_Unpriv \n" + " MPU_xTaskGetIdleTaskHandle_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskGetIdleTaskHandleImpl \n" + " MPU_xTaskGetIdleTaskHandle_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskGetIdleTaskHandleImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskSuspend == 1 ) + +void MPU_vTaskSuspend( TaskHandle_t xTaskToSuspend ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskSuspend( TaskHandle_t xTaskToSuspend ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskSuspendImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vTaskSuspend_Unpriv \n" + " MPU_vTaskSuspend_Priv: \n" + " pop {r0} \n" + " b MPU_vTaskSuspendImpl \n" + " MPU_vTaskSuspend_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vTaskSuspendImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_vTaskSuspend == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskSuspend == 1 ) + +void MPU_vTaskResume( TaskHandle_t xTaskToResume ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskResume( TaskHandle_t xTaskToResume ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskResumeImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vTaskResume_Unpriv \n" + " MPU_vTaskResume_Priv: \n" + " pop {r0} \n" + " b MPU_vTaskResumeImpl \n" + " MPU_vTaskResume_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vTaskResumeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_vTaskSuspend == 1 ) */ +/*-----------------------------------------------------------*/ + +TickType_t MPU_xTaskGetTickCount( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TickType_t MPU_xTaskGetTickCount( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGetTickCountImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskGetTickCount_Unpriv \n" + " MPU_xTaskGetTickCount_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskGetTickCountImpl \n" + " MPU_xTaskGetTickCount_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskGetTickCountImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +UBaseType_t MPU_uxTaskGetNumberOfTasks( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxTaskGetNumberOfTasks( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxTaskGetNumberOfTasksImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_uxTaskGetNumberOfTasks_Unpriv \n" + " MPU_uxTaskGetNumberOfTasks_Priv: \n" + " pop {r0} \n" + " b MPU_uxTaskGetNumberOfTasksImpl \n" + " MPU_uxTaskGetNumberOfTasks_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_uxTaskGetNumberOfTasksImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +char * MPU_pcTaskGetName( TaskHandle_t xTaskToQuery ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +char * MPU_pcTaskGetName( TaskHandle_t xTaskToQuery ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_pcTaskGetNameImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_pcTaskGetName_Unpriv \n" + " MPU_pcTaskGetName_Priv: \n" + " pop {r0} \n" + " b MPU_pcTaskGetNameImpl \n" + " MPU_pcTaskGetName_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_pcTaskGetNameImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +#if ( configGENERATE_RUN_TIME_STATS == 1 ) + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetRunTimeCounter( const TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetRunTimeCounter( const TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_ulTaskGetRunTimeCounterImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_ulTaskGetRunTimeCounter_Unpriv \n" + " MPU_ulTaskGetRunTimeCounter_Priv: \n" + " pop {r0} \n" + " b MPU_ulTaskGetRunTimeCounterImpl \n" + " MPU_ulTaskGetRunTimeCounter_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_ulTaskGetRunTimeCounterImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( ( configGENERATE_RUN_TIME_STATS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configGENERATE_RUN_TIME_STATS == 1 ) + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetRunTimePercent( const TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetRunTimePercent( const TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_ulTaskGetRunTimePercentImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_ulTaskGetRunTimePercent_Unpriv \n" + " MPU_ulTaskGetRunTimePercent_Priv: \n" + " pop {r0} \n" + " b MPU_ulTaskGetRunTimePercentImpl \n" + " MPU_ulTaskGetRunTimePercent_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_ulTaskGetRunTimePercentImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( ( configGENERATE_RUN_TIME_STATS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimePercent( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimePercent( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_ulTaskGetIdleRunTimePercentImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_ulTaskGetIdleRunTimePercent_Unpriv \n" + " MPU_ulTaskGetIdleRunTimePercent_Priv: \n" + " pop {r0} \n" + " b MPU_ulTaskGetIdleRunTimePercentImpl \n" + " MPU_ulTaskGetIdleRunTimePercent_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_ulTaskGetIdleRunTimePercentImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimeCounter( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimeCounter( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_ulTaskGetIdleRunTimeCounterImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_ulTaskGetIdleRunTimeCounter_Unpriv \n" + " MPU_ulTaskGetIdleRunTimeCounter_Priv: \n" + " pop {r0} \n" + " b MPU_ulTaskGetIdleRunTimeCounterImpl \n" + " MPU_ulTaskGetIdleRunTimeCounter_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_ulTaskGetIdleRunTimeCounterImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_APPLICATION_TASK_TAG == 1 ) + +void MPU_vTaskSetApplicationTaskTag( TaskHandle_t xTask, + TaskHookFunction_t pxHookFunction ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskSetApplicationTaskTag( TaskHandle_t xTask, + TaskHookFunction_t pxHookFunction ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskSetApplicationTaskTagImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vTaskSetApplicationTaskTag_Unpriv \n" + " MPU_vTaskSetApplicationTaskTag_Priv: \n" + " pop {r0} \n" + " b MPU_vTaskSetApplicationTaskTagImpl \n" + " MPU_vTaskSetApplicationTaskTag_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vTaskSetApplicationTaskTagImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_APPLICATION_TASK_TAG == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_APPLICATION_TASK_TAG == 1 ) + +TaskHookFunction_t MPU_xTaskGetApplicationTaskTag( TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TaskHookFunction_t MPU_xTaskGetApplicationTaskTag( TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGetApplicationTaskTagImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskGetApplicationTaskTag_Unpriv \n" + " MPU_xTaskGetApplicationTaskTag_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskGetApplicationTaskTagImpl \n" + " MPU_xTaskGetApplicationTaskTag_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskGetApplicationTaskTagImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_APPLICATION_TASK_TAG == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) + +void MPU_vTaskSetThreadLocalStoragePointer( TaskHandle_t xTaskToSet, + BaseType_t xIndex, + void * pvValue ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskSetThreadLocalStoragePointer( TaskHandle_t xTaskToSet, + BaseType_t xIndex, + void * pvValue ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskSetThreadLocalStoragePointerImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vTaskSetThreadLocalStoragePointer_Unpriv \n" + " MPU_vTaskSetThreadLocalStoragePointer_Priv: \n" + " pop {r0} \n" + " b MPU_vTaskSetThreadLocalStoragePointerImpl \n" + " MPU_vTaskSetThreadLocalStoragePointer_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vTaskSetThreadLocalStoragePointerImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) + +void * MPU_pvTaskGetThreadLocalStoragePointer( TaskHandle_t xTaskToQuery, + BaseType_t xIndex ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void * MPU_pvTaskGetThreadLocalStoragePointer( TaskHandle_t xTaskToQuery, + BaseType_t xIndex ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_pvTaskGetThreadLocalStoragePointerImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_pvTaskGetThreadLocalStoragePointer_Unpriv \n" + " MPU_pvTaskGetThreadLocalStoragePointer_Priv: \n" + " pop {r0} \n" + " b MPU_pvTaskGetThreadLocalStoragePointerImpl \n" + " MPU_pvTaskGetThreadLocalStoragePointer_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_pvTaskGetThreadLocalStoragePointerImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + +UBaseType_t MPU_uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray, + const UBaseType_t uxArraySize, + configRUN_TIME_COUNTER_TYPE * const pulTotalRunTime ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray, + const UBaseType_t uxArraySize, + configRUN_TIME_COUNTER_TYPE * const pulTotalRunTime ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxTaskGetSystemStateImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_uxTaskGetSystemState_Unpriv \n" + " MPU_uxTaskGetSystemState_Priv: \n" + " pop {r0} \n" + " b MPU_uxTaskGetSystemStateImpl \n" + " MPU_uxTaskGetSystemState_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_uxTaskGetSystemStateImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TRACE_FACILITY == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) + +UBaseType_t MPU_uxTaskGetStackHighWaterMark( TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxTaskGetStackHighWaterMark( TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxTaskGetStackHighWaterMarkImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_uxTaskGetStackHighWaterMark_Unpriv \n" + " MPU_uxTaskGetStackHighWaterMark_Priv: \n" + " pop {r0} \n" + " b MPU_uxTaskGetStackHighWaterMarkImpl \n" + " MPU_uxTaskGetStackHighWaterMark_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_uxTaskGetStackHighWaterMarkImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) + +configSTACK_DEPTH_TYPE MPU_uxTaskGetStackHighWaterMark2( TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +configSTACK_DEPTH_TYPE MPU_uxTaskGetStackHighWaterMark2( TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxTaskGetStackHighWaterMark2Impl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_uxTaskGetStackHighWaterMark2_Unpriv \n" + " MPU_uxTaskGetStackHighWaterMark2_Priv: \n" + " pop {r0} \n" + " b MPU_uxTaskGetStackHighWaterMark2Impl \n" + " MPU_uxTaskGetStackHighWaterMark2_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_uxTaskGetStackHighWaterMark2Impl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) ) + +TaskHandle_t MPU_xTaskGetCurrentTaskHandle( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TaskHandle_t MPU_xTaskGetCurrentTaskHandle( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGetCurrentTaskHandleImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskGetCurrentTaskHandle_Unpriv \n" + " MPU_xTaskGetCurrentTaskHandle_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskGetCurrentTaskHandleImpl \n" + " MPU_xTaskGetCurrentTaskHandle_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskGetCurrentTaskHandleImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_xTaskGetSchedulerState == 1 ) + +BaseType_t MPU_xTaskGetSchedulerState( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskGetSchedulerState( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGetSchedulerStateImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskGetSchedulerState_Unpriv \n" + " MPU_xTaskGetSchedulerState_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskGetSchedulerStateImpl \n" + " MPU_xTaskGetSchedulerState_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskGetSchedulerStateImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_xTaskGetSchedulerState == 1 ) */ +/*-----------------------------------------------------------*/ + +void MPU_vTaskSetTimeOutState( TimeOut_t * const pxTimeOut ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskSetTimeOutState( TimeOut_t * const pxTimeOut ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskSetTimeOutStateImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vTaskSetTimeOutState_Unpriv \n" + " MPU_vTaskSetTimeOutState_Priv: \n" + " pop {r0} \n" + " b MPU_vTaskSetTimeOutStateImpl \n" + " MPU_vTaskSetTimeOutState_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vTaskSetTimeOutStateImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut, + TickType_t * const pxTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut, + TickType_t * const pxTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskCheckForTimeOutImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskCheckForTimeOut_Unpriv \n" + " MPU_xTaskCheckForTimeOut_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskCheckForTimeOutImpl \n" + " MPU_xTaskCheckForTimeOut_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskCheckForTimeOutImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +#if ( configUSE_TASK_NOTIFICATIONS == 1 ) + +BaseType_t MPU_xTaskGenericNotify( TaskHandle_t xTaskToNotify, + UBaseType_t uxIndexToNotify, + uint32_t ulValue, + eNotifyAction eAction, + uint32_t * pulPreviousNotificationValue ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskGenericNotify( TaskHandle_t xTaskToNotify, + UBaseType_t uxIndexToNotify, + uint32_t ulValue, + eNotifyAction eAction, + uint32_t * pulPreviousNotificationValue ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGenericNotifyImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskGenericNotify_Unpriv \n" + " MPU_xTaskGenericNotify_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskGenericNotifyImpl \n" + " MPU_xTaskGenericNotify_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskGenericNotifyImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER_1 ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TASK_NOTIFICATIONS == 1 ) + +BaseType_t MPU_xTaskGenericNotifyWait( UBaseType_t uxIndexToWaitOn, + uint32_t ulBitsToClearOnEntry, + uint32_t ulBitsToClearOnExit, + uint32_t * pulNotificationValue, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskGenericNotifyWait( UBaseType_t uxIndexToWaitOn, + uint32_t ulBitsToClearOnEntry, + uint32_t ulBitsToClearOnExit, + uint32_t * pulNotificationValue, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGenericNotifyWaitImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskGenericNotifyWait_Unpriv \n" + " MPU_xTaskGenericNotifyWait_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskGenericNotifyWaitImpl \n" + " MPU_xTaskGenericNotifyWait_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskGenericNotifyWaitImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER_1 ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TASK_NOTIFICATIONS == 1 ) + +uint32_t MPU_ulTaskGenericNotifyTake( UBaseType_t uxIndexToWaitOn, + BaseType_t xClearCountOnExit, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +uint32_t MPU_ulTaskGenericNotifyTake( UBaseType_t uxIndexToWaitOn, + BaseType_t xClearCountOnExit, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_ulTaskGenericNotifyTakeImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_ulTaskGenericNotifyTake_Unpriv \n" + " MPU_ulTaskGenericNotifyTake_Priv: \n" + " pop {r0} \n" + " b MPU_ulTaskGenericNotifyTakeImpl \n" + " MPU_ulTaskGenericNotifyTake_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_ulTaskGenericNotifyTakeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TASK_NOTIFICATIONS == 1 ) + +BaseType_t MPU_xTaskGenericNotifyStateClear( TaskHandle_t xTask, + UBaseType_t uxIndexToClear ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskGenericNotifyStateClear( TaskHandle_t xTask, + UBaseType_t uxIndexToClear ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGenericNotifyStateClearImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskGenericNotifyStateClear_Unpriv \n" + " MPU_xTaskGenericNotifyStateClear_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskGenericNotifyStateClearImpl \n" + " MPU_xTaskGenericNotifyStateClear_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskGenericNotifyStateClearImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TASK_NOTIFICATIONS == 1 ) + +uint32_t MPU_ulTaskGenericNotifyValueClear( TaskHandle_t xTask, + UBaseType_t uxIndexToClear, + uint32_t ulBitsToClear ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +uint32_t MPU_ulTaskGenericNotifyValueClear( TaskHandle_t xTask, + UBaseType_t uxIndexToClear, + uint32_t ulBitsToClear ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_ulTaskGenericNotifyValueClearImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_ulTaskGenericNotifyValueClear_Unpriv \n" + " MPU_ulTaskGenericNotifyValueClear_Priv: \n" + " pop {r0} \n" + " b MPU_ulTaskGenericNotifyValueClearImpl \n" + " MPU_ulTaskGenericNotifyValueClear_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_ulTaskGenericNotifyValueClearImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xQueueGenericSend( QueueHandle_t xQueue, + const void * const pvItemToQueue, + TickType_t xTicksToWait, + const BaseType_t xCopyPosition ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueueGenericSend( QueueHandle_t xQueue, + const void * const pvItemToQueue, + TickType_t xTicksToWait, + const BaseType_t xCopyPosition ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueGenericSendImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xQueueGenericSend_Unpriv \n" + " MPU_xQueueGenericSend_Priv: \n" + " pop {r0} \n" + " b MPU_xQueueGenericSendImpl \n" + " MPU_xQueueGenericSend_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xQueueGenericSendImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +UBaseType_t MPU_uxQueueMessagesWaiting( const QueueHandle_t xQueue ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxQueueMessagesWaiting( const QueueHandle_t xQueue ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxQueueMessagesWaitingImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_uxQueueMessagesWaiting_Unpriv \n" + " MPU_uxQueueMessagesWaiting_Priv: \n" + " pop {r0} \n" + " b MPU_uxQueueMessagesWaitingImpl \n" + " MPU_uxQueueMessagesWaiting_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_uxQueueMessagesWaitingImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +UBaseType_t MPU_uxQueueSpacesAvailable( const QueueHandle_t xQueue ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxQueueSpacesAvailable( const QueueHandle_t xQueue ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxQueueSpacesAvailableImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_uxQueueSpacesAvailable_Unpriv \n" + " MPU_uxQueueSpacesAvailable_Priv: \n" + " pop {r0} \n" + " b MPU_uxQueueSpacesAvailableImpl \n" + " MPU_uxQueueSpacesAvailable_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_uxQueueSpacesAvailableImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xQueueReceive( QueueHandle_t xQueue, + void * const pvBuffer, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueueReceive( QueueHandle_t xQueue, + void * const pvBuffer, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueReceiveImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xQueueReceive_Unpriv \n" + " MPU_xQueueReceive_Priv: \n" + " pop {r0} \n" + " b MPU_xQueueReceiveImpl \n" + " MPU_xQueueReceive_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xQueueReceiveImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xQueuePeek( QueueHandle_t xQueue, + void * const pvBuffer, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueuePeek( QueueHandle_t xQueue, + void * const pvBuffer, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueuePeekImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xQueuePeek_Unpriv \n" + " MPU_xQueuePeek_Priv: \n" + " pop {r0} \n" + " b MPU_xQueuePeekImpl \n" + " MPU_xQueuePeek_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xQueuePeekImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xQueueSemaphoreTake( QueueHandle_t xQueue, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueueSemaphoreTake( QueueHandle_t xQueue, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueSemaphoreTakeImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xQueueSemaphoreTake_Unpriv \n" + " MPU_xQueueSemaphoreTake_Priv: \n" + " pop {r0} \n" + " b MPU_xQueueSemaphoreTakeImpl \n" + " MPU_xQueueSemaphoreTake_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xQueueSemaphoreTakeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +#if ( ( configUSE_MUTEXES == 1 ) && ( INCLUDE_xSemaphoreGetMutexHolder == 1 ) ) + +TaskHandle_t MPU_xQueueGetMutexHolder( QueueHandle_t xSemaphore ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TaskHandle_t MPU_xQueueGetMutexHolder( QueueHandle_t xSemaphore ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueGetMutexHolderImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xQueueGetMutexHolder_Unpriv \n" + " MPU_xQueueGetMutexHolder_Priv: \n" + " pop {r0} \n" + " b MPU_xQueueGetMutexHolderImpl \n" + " MPU_xQueueGetMutexHolder_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xQueueGetMutexHolderImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( ( configUSE_MUTEXES == 1 ) && ( INCLUDE_xSemaphoreGetMutexHolder == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_RECURSIVE_MUTEXES == 1 ) + +BaseType_t MPU_xQueueTakeMutexRecursive( QueueHandle_t xMutex, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueueTakeMutexRecursive( QueueHandle_t xMutex, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueTakeMutexRecursiveImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xQueueTakeMutexRecursive_Unpriv \n" + " MPU_xQueueTakeMutexRecursive_Priv: \n" + " pop {r0} \n" + " b MPU_xQueueTakeMutexRecursiveImpl \n" + " MPU_xQueueTakeMutexRecursive_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xQueueTakeMutexRecursiveImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_RECURSIVE_MUTEXES == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_RECURSIVE_MUTEXES == 1 ) + +BaseType_t MPU_xQueueGiveMutexRecursive( QueueHandle_t pxMutex ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueueGiveMutexRecursive( QueueHandle_t pxMutex ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueGiveMutexRecursiveImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xQueueGiveMutexRecursive_Unpriv \n" + " MPU_xQueueGiveMutexRecursive_Priv: \n" + " pop {r0} \n" + " b MPU_xQueueGiveMutexRecursiveImpl \n" + " MPU_xQueueGiveMutexRecursive_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xQueueGiveMutexRecursiveImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_RECURSIVE_MUTEXES == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_QUEUE_SETS == 1 ) + +QueueSetMemberHandle_t MPU_xQueueSelectFromSet( QueueSetHandle_t xQueueSet, + const TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +QueueSetMemberHandle_t MPU_xQueueSelectFromSet( QueueSetHandle_t xQueueSet, + const TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueSelectFromSetImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xQueueSelectFromSet_Unpriv \n" + " MPU_xQueueSelectFromSet_Priv: \n" + " pop {r0} \n" + " b MPU_xQueueSelectFromSetImpl \n" + " MPU_xQueueSelectFromSet_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xQueueSelectFromSetImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_QUEUE_SETS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_QUEUE_SETS == 1 ) + +BaseType_t MPU_xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore, + QueueSetHandle_t xQueueSet ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore, + QueueSetHandle_t xQueueSet ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueAddToSetImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xQueueAddToSet_Unpriv \n" + " MPU_xQueueAddToSet_Priv: \n" + " pop {r0} \n" + " b MPU_xQueueAddToSetImpl \n" + " MPU_xQueueAddToSet_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xQueueAddToSetImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_QUEUE_SETS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configQUEUE_REGISTRY_SIZE > 0 ) + +void MPU_vQueueAddToRegistry( QueueHandle_t xQueue, + const char * pcName ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vQueueAddToRegistry( QueueHandle_t xQueue, + const char * pcName ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vQueueAddToRegistryImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vQueueAddToRegistry_Unpriv \n" + " MPU_vQueueAddToRegistry_Priv: \n" + " pop {r0} \n" + " b MPU_vQueueAddToRegistryImpl \n" + " MPU_vQueueAddToRegistry_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vQueueAddToRegistryImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configQUEUE_REGISTRY_SIZE > 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configQUEUE_REGISTRY_SIZE > 0 ) + +void MPU_vQueueUnregisterQueue( QueueHandle_t xQueue ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vQueueUnregisterQueue( QueueHandle_t xQueue ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vQueueUnregisterQueueImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vQueueUnregisterQueue_Unpriv \n" + " MPU_vQueueUnregisterQueue_Priv: \n" + " pop {r0} \n" + " b MPU_vQueueUnregisterQueueImpl \n" + " MPU_vQueueUnregisterQueue_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vQueueUnregisterQueueImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configQUEUE_REGISTRY_SIZE > 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configQUEUE_REGISTRY_SIZE > 0 ) + +const char * MPU_pcQueueGetName( QueueHandle_t xQueue ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +const char * MPU_pcQueueGetName( QueueHandle_t xQueue ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_pcQueueGetNameImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_pcQueueGetName_Unpriv \n" + " MPU_pcQueueGetName_Priv: \n" + " pop {r0} \n" + " b MPU_pcQueueGetNameImpl \n" + " MPU_pcQueueGetName_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_pcQueueGetNameImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configQUEUE_REGISTRY_SIZE > 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +void * MPU_pvTimerGetTimerID( const TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void * MPU_pvTimerGetTimerID( const TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_pvTimerGetTimerIDImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_pvTimerGetTimerID_Unpriv \n" + " MPU_pvTimerGetTimerID_Priv: \n" + " pop {r0} \n" + " b MPU_pvTimerGetTimerIDImpl \n" + " MPU_pvTimerGetTimerID_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_pvTimerGetTimerIDImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +void MPU_vTimerSetTimerID( TimerHandle_t xTimer, + void * pvNewID ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTimerSetTimerID( TimerHandle_t xTimer, + void * pvNewID ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTimerSetTimerIDImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vTimerSetTimerID_Unpriv \n" + " MPU_vTimerSetTimerID_Priv: \n" + " pop {r0} \n" + " b MPU_vTimerSetTimerIDImpl \n" + " MPU_vTimerSetTimerID_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vTimerSetTimerIDImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +BaseType_t MPU_xTimerIsTimerActive( TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTimerIsTimerActive( TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTimerIsTimerActiveImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTimerIsTimerActive_Unpriv \n" + " MPU_xTimerIsTimerActive_Priv: \n" + " pop {r0} \n" + " b MPU_xTimerIsTimerActiveImpl \n" + " MPU_xTimerIsTimerActive_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTimerIsTimerActiveImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +TaskHandle_t MPU_xTimerGetTimerDaemonTaskHandle( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TaskHandle_t MPU_xTimerGetTimerDaemonTaskHandle( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTimerGetTimerDaemonTaskHandleImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTimerGetTimerDaemonTaskHandle_Unpriv \n" + " MPU_xTimerGetTimerDaemonTaskHandle_Priv: \n" + " pop {r0} \n" + " b MPU_xTimerGetTimerDaemonTaskHandleImpl \n" + " MPU_xTimerGetTimerDaemonTaskHandle_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTimerGetTimerDaemonTaskHandleImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +BaseType_t MPU_xTimerGenericCommand( TimerHandle_t xTimer, + const BaseType_t xCommandID, + const TickType_t xOptionalValue, + BaseType_t * const pxHigherPriorityTaskWoken, + const TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTimerGenericCommand( TimerHandle_t xTimer, + const BaseType_t xCommandID, + const TickType_t xOptionalValue, + BaseType_t * const pxHigherPriorityTaskWoken, + const TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTimerGenericCommandImpl \n" + " \n" + " push {r0} \n" + " mrs r0, ipsr \n" + " cmp r0, #0 \n" + " bne MPU_xTimerGenericCommand_Priv \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " beq MPU_xTimerGenericCommand_Priv \n" + " MPU_xTimerGenericCommand_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTimerGenericCommandImpl \n" + " svc %1 \n" + " bx lr \n" + " MPU_xTimerGenericCommand_Priv: \n" + " pop {r0} \n" + " b MPU_xTimerGenericCommandImpl \n" + " \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER_1 ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +const char * MPU_pcTimerGetName( TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +const char * MPU_pcTimerGetName( TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_pcTimerGetNameImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_pcTimerGetName_Unpriv \n" + " MPU_pcTimerGetName_Priv: \n" + " pop {r0} \n" + " b MPU_pcTimerGetNameImpl \n" + " MPU_pcTimerGetName_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_pcTimerGetNameImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, + const BaseType_t uxAutoReload ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, + const BaseType_t uxAutoReload ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTimerSetReloadModeImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vTimerSetReloadMode_Unpriv \n" + " MPU_vTimerSetReloadMode_Priv: \n" + " pop {r0} \n" + " b MPU_vTimerSetReloadModeImpl \n" + " MPU_vTimerSetReloadMode_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vTimerSetReloadModeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +BaseType_t MPU_xTimerGetReloadMode( TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTimerGetReloadMode( TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTimerGetReloadModeImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTimerGetReloadMode_Unpriv \n" + " MPU_xTimerGetReloadMode_Priv: \n" + " pop {r0} \n" + " b MPU_xTimerGetReloadModeImpl \n" + " MPU_xTimerGetReloadMode_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTimerGetReloadModeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +UBaseType_t MPU_uxTimerGetReloadMode( TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxTimerGetReloadMode( TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxTimerGetReloadModeImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_uxTimerGetReloadMode_Unpriv \n" + " MPU_uxTimerGetReloadMode_Priv: \n" + " pop {r0} \n" + " b MPU_uxTimerGetReloadModeImpl \n" + " MPU_uxTimerGetReloadMode_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_uxTimerGetReloadModeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +TickType_t MPU_xTimerGetPeriod( TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TickType_t MPU_xTimerGetPeriod( TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTimerGetPeriodImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTimerGetPeriod_Unpriv \n" + " MPU_xTimerGetPeriod_Priv: \n" + " pop {r0} \n" + " b MPU_xTimerGetPeriodImpl \n" + " MPU_xTimerGetPeriod_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTimerGetPeriodImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +TickType_t MPU_xTimerGetExpiryTime( TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TickType_t MPU_xTimerGetExpiryTime( TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTimerGetExpiryTimeImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTimerGetExpiryTime_Unpriv \n" + " MPU_xTimerGetExpiryTime_Priv: \n" + " pop {r0} \n" + " b MPU_xTimerGetExpiryTimeImpl \n" + " MPU_xTimerGetExpiryTime_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTimerGetExpiryTimeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +EventBits_t MPU_xEventGroupWaitBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToWaitFor, + const BaseType_t xClearOnExit, + const BaseType_t xWaitForAllBits, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +EventBits_t MPU_xEventGroupWaitBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToWaitFor, + const BaseType_t xClearOnExit, + const BaseType_t xWaitForAllBits, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupWaitBitsImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xEventGroupWaitBits_Unpriv \n" + " MPU_xEventGroupWaitBits_Priv: \n" + " pop {r0} \n" + " b MPU_xEventGroupWaitBitsImpl \n" + " MPU_xEventGroupWaitBits_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xEventGroupWaitBitsImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER_1 ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToClear ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToClear ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupClearBitsImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xEventGroupClearBits_Unpriv \n" + " MPU_xEventGroupClearBits_Priv: \n" + " pop {r0} \n" + " b MPU_xEventGroupClearBitsImpl \n" + " MPU_xEventGroupClearBits_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xEventGroupClearBitsImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupSetBitsImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xEventGroupSetBits_Unpriv \n" + " MPU_xEventGroupSetBits_Priv: \n" + " pop {r0} \n" + " b MPU_xEventGroupSetBitsImpl \n" + " MPU_xEventGroupSetBits_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xEventGroupSetBitsImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet, + const EventBits_t uxBitsToWaitFor, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet, + const EventBits_t uxBitsToWaitFor, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupSyncImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xEventGroupSync_Unpriv \n" + " MPU_xEventGroupSync_Priv: \n" + " pop {r0} \n" + " b MPU_xEventGroupSyncImpl \n" + " MPU_xEventGroupSync_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xEventGroupSyncImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + +UBaseType_t MPU_uxEventGroupGetNumber( void * xEventGroup ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxEventGroupGetNumber( void * xEventGroup ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxEventGroupGetNumberImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_uxEventGroupGetNumber_Unpriv \n" + " MPU_uxEventGroupGetNumber_Priv: \n" + " pop {r0} \n" + " b MPU_uxEventGroupGetNumberImpl \n" + " MPU_uxEventGroupGetNumber_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_uxEventGroupGetNumberImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /*( configUSE_TRACE_FACILITY == 1 )*/ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + +void MPU_vEventGroupSetNumber( void * xEventGroup, + UBaseType_t uxEventGroupNumber ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vEventGroupSetNumber( void * xEventGroup, + UBaseType_t uxEventGroupNumber ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vEventGroupSetNumberImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vEventGroupSetNumber_Unpriv \n" + " MPU_vEventGroupSetNumber_Priv: \n" + " pop {r0} \n" + " b MPU_vEventGroupSetNumberImpl \n" + " MPU_vEventGroupSetNumber_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vEventGroupSetNumberImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /*( configUSE_TRACE_FACILITY == 1 )*/ +/*-----------------------------------------------------------*/ + +size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, + const void * pvTxData, + size_t xDataLengthBytes, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, + const void * pvTxData, + size_t xDataLengthBytes, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferSendImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferSend_Unpriv \n" + " MPU_xStreamBufferSend_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferSendImpl \n" + " MPU_xStreamBufferSend_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xStreamBufferSendImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, + void * pvRxData, + size_t xBufferLengthBytes, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, + void * pvRxData, + size_t xBufferLengthBytes, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferReceiveImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferReceive_Unpriv \n" + " MPU_xStreamBufferReceive_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferReceiveImpl \n" + " MPU_xStreamBufferReceive_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xStreamBufferReceiveImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferIsFullImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferIsFull_Unpriv \n" + " MPU_xStreamBufferIsFull_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferIsFullImpl \n" + " MPU_xStreamBufferIsFull_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xStreamBufferIsFullImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferIsEmptyImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferIsEmpty_Unpriv \n" + " MPU_xStreamBufferIsEmpty_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferIsEmptyImpl \n" + " MPU_xStreamBufferIsEmpty_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xStreamBufferIsEmptyImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferSpacesAvailableImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferSpacesAvailable_Unpriv \n" + " MPU_xStreamBufferSpacesAvailable_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferSpacesAvailableImpl \n" + " MPU_xStreamBufferSpacesAvailable_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xStreamBufferSpacesAvailableImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferBytesAvailableImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferBytesAvailable_Unpriv \n" + " MPU_xStreamBufferBytesAvailable_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferBytesAvailableImpl \n" + " MPU_xStreamBufferBytesAvailable_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xStreamBufferBytesAvailableImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, + size_t xTriggerLevel ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, + size_t xTriggerLevel ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferSetTriggerLevelImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferSetTriggerLevel_Unpriv \n" + " MPU_xStreamBufferSetTriggerLevel_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferSetTriggerLevelImpl \n" + " MPU_xStreamBufferSetTriggerLevel_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xStreamBufferSetTriggerLevelImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferNextMessageLengthBytesImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferNextMessageLengthBytes_Unpriv \n" + " MPU_xStreamBufferNextMessageLengthBytes_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferNextMessageLengthBytesImpl \n" + " MPU_xStreamBufferNextMessageLengthBytes_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xStreamBufferNextMessageLengthBytesImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ diff --git a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33_NTZ/portasm.c b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33_NTZ/portasm.c index a78529d04d9..504b6bf3be3 100644 --- a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33_NTZ/portasm.c +++ b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33_NTZ/portasm.c @@ -40,6 +40,88 @@ * header files. */ #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE +#if ( configENABLE_MPU == 1 ) + +void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ +{ + __asm volatile + ( + " .syntax unified \n" + " \n" + " program_mpu_first_task: \n" + " ldr r2, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r0, [r2] \n" /* r0 = pxCurrentTCB. */ + " \n" + " dmb \n" /* Complete outstanding transfers before disabling MPU. */ + " ldr r1, xMPUCTRLConst2 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ + " bic r2, #1 \n" /* r2 = r2 & ~1 i.e. Clear the bit 0 in r2. */ + " str r2, [r1] \n" /* Disable MPU. */ + " \n" + " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */ + " ldr r1, [r0] \n" /* r1 = *r0 i.e. r1 = MAIR0. */ + " ldr r2, xMAIR0Const2 \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */ + " str r1, [r2] \n" /* Program MAIR0. */ + " \n" + " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */ + " ldr r1, xRNRConst2 \n" /* r1 = 0xe000ed98 [Location of RNR]. */ + " ldr r2, xRBARConst2 \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ + " \n" + " movs r3, #4 \n" /* r3 = 4. */ + " str r3, [r1] \n" /* Program RNR = 4. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + " \n" + #if ( configTOTAL_MPU_REGIONS == 16 ) + " movs r3, #8 \n" /* r3 = 8. */ + " str r3, [r1] \n" /* Program RNR = 8. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + " movs r3, #12 \n" /* r3 = 12. */ + " str r3, [r1] \n" /* Program RNR = 12. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + #endif /* configTOTAL_MPU_REGIONS == 16 */ + " \n" + " ldr r1, xMPUCTRLConst2 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ + " orr r2, #1 \n" /* r2 = r2 | 1 i.e. Set the bit 0 in r2. */ + " str r2, [r1] \n" /* Enable MPU. */ + " dsb \n" /* Force memory writes before continuing. */ + " \n" + " restore_context_first_task: \n" + " ldr r2, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r0, [r2] \n" /* r0 = pxCurrentTCB.*/ + " ldr r1, [r0] \n" /* r1 = Location of saved context in TCB. */ + " \n" + " restore_special_regs_first_task: \n" + " ldmdb r1!, {r2-r4, lr} \n" /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */ + " msr psp, r2 \n" + " msr psplim, r3 \n" + " msr control, r4 \n" + " \n" + " restore_general_regs_first_task: \n" + " ldmdb r1!, {r4-r11} \n" /* r4-r11 contain hardware saved context. */ + " stmia r2!, {r4-r11} \n" /* Copy the hardware saved context on the task stack. */ + " ldmdb r1!, {r4-r11} \n" /* r4-r11 restored. */ + " \n" + " restore_context_done_first_task: \n" + " str r1, [r0] \n" /* Save the location where the context should be saved next as the first member of TCB. */ + " mov r0, #0 \n" + " msr basepri, r0 \n" /* Ensure that interrupts are enabled when the first task starts. */ + " bx lr \n" + " \n" + " .align 4 \n" + " pxCurrentTCBConst2: .word pxCurrentTCB \n" + " xMPUCTRLConst2: .word 0xe000ed94 \n" + " xMAIR0Const2: .word 0xe000edc0 \n" + " xRNRConst2: .word 0xe000ed98 \n" + " xRBARConst2: .word 0xe000ed9c \n" + ); +} + +#else /* configENABLE_MPU */ + void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ { __asm volatile @@ -50,80 +132,23 @@ void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_ " ldr r1, [r2] \n"/* Read pxCurrentTCB. */ " ldr r0, [r1] \n"/* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ " \n" - #if ( configENABLE_MPU == 1 ) - " dmb \n"/* Complete outstanding transfers before disabling MPU. */ - " ldr r2, xMPUCTRLConst2 \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ - " ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */ - " bic r4, #1 \n"/* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */ - " str r4, [r2] \n"/* Disable MPU. */ - " \n" - " adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */ - " ldr r3, [r1] \n"/* r3 = *r1 i.e. r3 = MAIR0. */ - " ldr r2, xMAIR0Const2 \n"/* r2 = 0xe000edc0 [Location of MAIR0]. */ - " str r3, [r2] \n"/* Program MAIR0. */ - " ldr r2, xRNRConst2 \n"/* r2 = 0xe000ed98 [Location of RNR]. */ - " movs r3, #4 \n"/* r3 = 4. */ - " str r3, [r2] \n"/* Program RNR = 4. */ - " adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to first RBAR in TCB. */ - " ldr r2, xRBARConst2 \n"/* r2 = 0xe000ed9c [Location of RBAR]. */ - " ldmia r1!, {r4-r11} \n"/* Read 4 set of RBAR/RLAR registers from TCB. */ - " stmia r2!, {r4-r11} \n"/* Write 4 set of RBAR/RLAR registers using alias registers. */ - " \n" - #if ( configTOTAL_MPU_REGIONS == 16 ) - " ldr r2, xRNRConst2 \n"/* r2 = 0xe000ed98 [Location of RNR]. */ - " movs r3, #8 \n"/* r3 = 8. */ - " str r3, [r2] \n"/* Program RNR = 8. */ - " ldr r2, xRBARConst2 \n"/* r2 = 0xe000ed9c [Location of RBAR]. */ - " ldmia r1!, {r4-r11} \n"/* Read 4 set of RBAR/RLAR registers from TCB. */ - " stmia r2!, {r4-r11} \n"/* Write 4 set of RBAR/RLAR registers using alias registers. */ - " ldr r2, xRNRConst2 \n"/* r2 = 0xe000ed98 [Location of RNR]. */ - " movs r3, #12 \n"/* r3 = 12. */ - " str r3, [r2] \n"/* Program RNR = 12. */ - " ldr r2, xRBARConst2 \n"/* r2 = 0xe000ed9c [Location of RBAR]. */ - " ldmia r1!, {r4-r11} \n"/* Read 4 set of RBAR/RLAR registers from TCB. */ - " stmia r2!, {r4-r11} \n"/* Write 4 set of RBAR/RLAR registers using alias registers. */ - #endif /* configTOTAL_MPU_REGIONS == 16 */ - " \n" - " ldr r2, xMPUCTRLConst2 \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ - " ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */ - " orr r4, #1 \n"/* r4 = r4 | 1 i.e. Set the bit 0 in r4. */ - " str r4, [r2] \n"/* Enable MPU. */ - " dsb \n"/* Force memory writes before continuing. */ - #endif /* configENABLE_MPU */ - " \n" - #if ( configENABLE_MPU == 1 ) - " ldm r0!, {r1-r3} \n"/* Read from stack - r1 = PSPLIM, r2 = CONTROL and r3 = EXC_RETURN. */ - " msr psplim, r1 \n"/* Set this task's PSPLIM value. */ - " msr control, r2 \n"/* Set this task's CONTROL value. */ - " adds r0, #32 \n"/* Discard everything up to r0. */ - " msr psp, r0 \n"/* This is now the new top of stack to use in the task. */ - " isb \n" - " mov r0, #0 \n" - " msr basepri, r0 \n"/* Ensure that interrupts are enabled when the first task starts. */ - " bx r3 \n"/* Finally, branch to EXC_RETURN. */ - #else /* configENABLE_MPU */ - " ldm r0!, {r1-r2} \n"/* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */ - " msr psplim, r1 \n"/* Set this task's PSPLIM value. */ - " movs r1, #2 \n"/* r1 = 2. */ - " msr CONTROL, r1 \n"/* Switch to use PSP in the thread mode. */ - " adds r0, #32 \n"/* Discard everything up to r0. */ - " msr psp, r0 \n"/* This is now the new top of stack to use in the task. */ - " isb \n" - " mov r0, #0 \n" - " msr basepri, r0 \n"/* Ensure that interrupts are enabled when the first task starts. */ - " bx r2 \n"/* Finally, branch to EXC_RETURN. */ - #endif /* configENABLE_MPU */ + " ldm r0!, {r1-r2} \n"/* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */ + " msr psplim, r1 \n"/* Set this task's PSPLIM value. */ + " movs r1, #2 \n"/* r1 = 2. */ + " msr CONTROL, r1 \n"/* Switch to use PSP in the thread mode. */ + " adds r0, #32 \n"/* Discard everything up to r0. */ + " msr psp, r0 \n"/* This is now the new top of stack to use in the task. */ + " isb \n" + " mov r0, #0 \n" + " msr basepri, r0 \n"/* Ensure that interrupts are enabled when the first task starts. */ + " bx r2 \n"/* Finally, branch to EXC_RETURN. */ " \n" " .align 4 \n" "pxCurrentTCBConst2: .word pxCurrentTCB \n" - #if ( configENABLE_MPU == 1 ) - "xMPUCTRLConst2: .word 0xe000ed94 \n" - "xMAIR0Const2: .word 0xe000edc0 \n" - "xRNRConst2: .word 0xe000ed98 \n" - "xRBARConst2: .word 0xe000ed9c \n" - #endif /* configENABLE_MPU */ ); } + +#endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */ @@ -231,6 +256,129 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att } /*-----------------------------------------------------------*/ +#if ( configENABLE_MPU == 1 ) + +void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ +{ + __asm volatile + ( + " .syntax unified \n" + " \n" + " ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r0, [r2] \n" /* r0 = pxCurrentTCB. */ + " ldr r1, [r0] \n" /* r1 = Location in TCB where the context should be saved. */ + " mrs r2, psp \n" /* r2 = PSP. */ + " \n" + " save_general_regs: \n" + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + " add r2, r2, #0x20 \n" /* Move r2 to location where s0 is saved. */ + " tst lr, #0x10 \n" + " ittt eq \n" + " vstmiaeq r1!, {s16-s31} \n" /* Store s16-s31. */ + " vldmiaeq r2, {s0-s16} \n" /* Copy hardware saved FP context into s0-s16. */ + " vstmiaeq r1!, {s0-s16} \n" /* Store hardware saved FP context. */ + " sub r2, r2, #0x20 \n" /* Set r2 back to the location of hardware saved context. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ + " \n" + " stmia r1!, {r4-r11} \n" /* Store r4-r11. */ + " ldmia r2, {r4-r11} \n" /* Copy the hardware saved context into r4-r11. */ + " stmia r1!, {r4-r11} \n" /* Store the hardware saved context. */ + " \n" + " save_special_regs: \n" + " mrs r3, psplim \n" /* r3 = PSPLIM. */ + " mrs r4, control \n" /* r4 = CONTROL. */ + " stmia r1!, {r2-r4, lr} \n" /* Store original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */ + " str r1, [r0] \n" /* Save the location from where the context should be restored as the first member of TCB. */ + " \n" + " select_next_task: \n" + " mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */ + " msr basepri, r0 \n" /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + " dsb \n" + " isb \n" + " bl vTaskSwitchContext \n" + " mov r0, #0 \n" /* r0 = 0. */ + " msr basepri, r0 \n" /* Enable interrupts. */ + " \n" + " program_mpu: \n" + " ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r0, [r2] \n" /* r0 = pxCurrentTCB. */ + " \n" + " dmb \n" /* Complete outstanding transfers before disabling MPU. */ + " ldr r1, xMPUCTRLConst \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ + " bic r2, #1 \n" /* r2 = r2 & ~1 i.e. Clear the bit 0 in r2. */ + " str r2, [r1] \n" /* Disable MPU. */ + " \n" + " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */ + " ldr r1, [r0] \n" /* r1 = *r0 i.e. r1 = MAIR0. */ + " ldr r2, xMAIR0Const \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */ + " str r1, [r2] \n" /* Program MAIR0. */ + " \n" + " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */ + " ldr r1, xRNRConst \n" /* r1 = 0xe000ed98 [Location of RNR]. */ + " ldr r2, xRBARConst \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ + " \n" + " movs r3, #4 \n" /* r3 = 4. */ + " str r3, [r1] \n" /* Program RNR = 4. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + " \n" + #if ( configTOTAL_MPU_REGIONS == 16 ) + " movs r3, #8 \n" /* r3 = 8. */ + " str r3, [r1] \n" /* Program RNR = 8. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + " movs r3, #12 \n" /* r3 = 12. */ + " str r3, [r1] \n" /* Program RNR = 12. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + #endif /* configTOTAL_MPU_REGIONS == 16 */ + " \n" + " ldr r1, xMPUCTRLConst \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ + " orr r2, #1 \n" /* r2 = r2 | 1 i.e. Set the bit 0 in r2. */ + " str r2, [r1] \n" /* Enable MPU. */ + " dsb \n" /* Force memory writes before continuing. */ + " \n" + " restore_context: \n" + " ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r0, [r2] \n" /* r0 = pxCurrentTCB.*/ + " ldr r1, [r0] \n" /* r1 = Location of saved context in TCB. */ + " \n" + " restore_special_regs: \n" + " ldmdb r1!, {r2-r4, lr} \n" /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */ + " msr psp, r2 \n" + " msr psplim, r3 \n" + " msr control, r4 \n" + " \n" + " restore_general_regs: \n" + " ldmdb r1!, {r4-r11} \n" /* r4-r11 contain hardware saved context. */ + " stmia r2!, {r4-r11} \n" /* Copy the hardware saved context on the task stack. */ + " ldmdb r1!, {r4-r11} \n" /* r4-r11 restored. */ + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + " tst lr, #0x10 \n" + " ittt eq \n" + " vldmdbeq r1!, {s0-s16} \n" /* s0-s16 contain hardware saved FP context. */ + " vstmiaeq r2!, {s0-s16} \n" /* Copy hardware saved FP context on the task stack. */ + " vldmdbeq r1!, {s16-s31} \n" /* Restore s16-s31. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ + " \n" + " restore_context_done: \n" + " str r1, [r0] \n" /* Save the location where the context should be saved next as the first member of TCB. */ + " bx lr \n" + " \n" + " .align 4 \n" + " pxCurrentTCBConst: .word pxCurrentTCB \n" + " xMPUCTRLConst: .word 0xe000ed94 \n" + " xMAIR0Const: .word 0xe000edc0 \n" + " xRNRConst: .word 0xe000ed98 \n" + " xRBARConst: .word 0xe000ed9c \n" + ::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) + ); +} + +#else /* configENABLE_MPU */ + void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ { __asm volatile @@ -238,21 +386,16 @@ void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ " .syntax unified \n" " \n" " mrs r0, psp \n"/* Read PSP in r0. */ + " \n" #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) " tst lr, #0x10 \n"/* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ " it eq \n" " vstmdbeq r0!, {s16-s31} \n"/* Store the additional FP context registers which are not saved automatically. */ #endif /* configENABLE_FPU || configENABLE_MVE */ - #if ( configENABLE_MPU == 1 ) - " mrs r1, psplim \n"/* r1 = PSPLIM. */ - " mrs r2, control \n"/* r2 = CONTROL. */ - " mov r3, lr \n"/* r3 = LR/EXC_RETURN. */ - " stmdb r0!, {r1-r11} \n"/* Store on the stack - PSPLIM, CONTROL, LR and registers that are not automatically saved. */ - #else /* configENABLE_MPU */ - " mrs r2, psplim \n"/* r2 = PSPLIM. */ - " mov r3, lr \n"/* r3 = LR/EXC_RETURN. */ - " stmdb r0!, {r2-r11} \n"/* Store on the stack - PSPLIM, LR and registers that are not automatically saved. */ - #endif /* configENABLE_MPU */ + " \n" + " mrs r2, psplim \n"/* r2 = PSPLIM. */ + " mov r3, lr \n"/* r3 = LR/EXC_RETURN. */ + " stmdb r0!, {r2-r11} \n"/* Store on the stack - PSPLIM, LR and registers that are not automatically saved. */ " \n" " ldr r2, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r2] \n"/* Read pxCurrentTCB. */ @@ -270,52 +413,7 @@ void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ " ldr r1, [r2] \n"/* Read pxCurrentTCB. */ " ldr r0, [r1] \n"/* The first item in pxCurrentTCB is the task top of stack. r0 now points to the top of stack. */ " \n" - #if ( configENABLE_MPU == 1 ) - " dmb \n"/* Complete outstanding transfers before disabling MPU. */ - " ldr r2, xMPUCTRLConst \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ - " ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */ - " bic r4, #1 \n"/* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */ - " str r4, [r2] \n"/* Disable MPU. */ - " \n" - " adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */ - " ldr r3, [r1] \n"/* r3 = *r1 i.e. r3 = MAIR0. */ - " ldr r2, xMAIR0Const \n"/* r2 = 0xe000edc0 [Location of MAIR0]. */ - " str r3, [r2] \n"/* Program MAIR0. */ - " ldr r2, xRNRConst \n"/* r2 = 0xe000ed98 [Location of RNR]. */ - " movs r3, #4 \n"/* r3 = 4. */ - " str r3, [r2] \n"/* Program RNR = 4. */ - " adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to first RBAR in TCB. */ - " ldr r2, xRBARConst \n"/* r2 = 0xe000ed9c [Location of RBAR]. */ - " ldmia r1!, {r4-r11} \n"/* Read 4 sets of RBAR/RLAR registers from TCB. */ - " stmia r2!, {r4-r11} \n"/* Write 4 set of RBAR/RLAR registers using alias registers. */ - " \n" - #if ( configTOTAL_MPU_REGIONS == 16 ) - " ldr r2, xRNRConst \n"/* r2 = 0xe000ed98 [Location of RNR]. */ - " movs r3, #8 \n"/* r3 = 8. */ - " str r3, [r2] \n"/* Program RNR = 8. */ - " ldr r2, xRBARConst \n"/* r2 = 0xe000ed9c [Location of RBAR]. */ - " ldmia r1!, {r4-r11} \n"/* Read 4 sets of RBAR/RLAR registers from TCB. */ - " stmia r2!, {r4-r11} \n"/* Write 4 set of RBAR/RLAR registers using alias registers. */ - " ldr r2, xRNRConst \n"/* r2 = 0xe000ed98 [Location of RNR]. */ - " movs r3, #12 \n"/* r3 = 12. */ - " str r3, [r2] \n"/* Program RNR = 12. */ - " ldr r2, xRBARConst \n"/* r2 = 0xe000ed9c [Location of RBAR]. */ - " ldmia r1!, {r4-r11} \n"/* Read 4 sets of RBAR/RLAR registers from TCB. */ - " stmia r2!, {r4-r11} \n"/* Write 4 set of RBAR/RLAR registers using alias registers. */ - #endif /* configTOTAL_MPU_REGIONS == 16 */ - " \n" - " ldr r2, xMPUCTRLConst \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ - " ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */ - " orr r4, #1 \n"/* r4 = r4 | 1 i.e. Set the bit 0 in r4. */ - " str r4, [r2] \n"/* Enable MPU. */ - " dsb \n"/* Force memory writes before continuing. */ - #endif /* configENABLE_MPU */ - " \n" - #if ( configENABLE_MPU == 1 ) - " ldmia r0!, {r1-r11} \n"/* Read from stack - r1 = PSPLIM, r2 = CONTROL, r3 = LR and r4-r11 restored. */ - #else /* configENABLE_MPU */ - " ldmia r0!, {r2-r11} \n"/* Read from stack - r2 = PSPLIM, r3 = LR and r4-r11 restored. */ - #endif /* configENABLE_MPU */ + " ldmia r0!, {r2-r11} \n"/* Read from stack - r2 = PSPLIM, r3 = LR and r4-r11 restored. */ " \n" #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) " tst r3, #0x10 \n"/* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ @@ -323,28 +421,66 @@ void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ " vldmiaeq r0!, {s16-s31} \n"/* Restore the additional FP context registers which are not restored automatically. */ #endif /* configENABLE_FPU || configENABLE_MVE */ " \n" - #if ( configENABLE_MPU == 1 ) - " msr psplim, r1 \n"/* Restore the PSPLIM register value for the task. */ - " msr control, r2 \n"/* Restore the CONTROL register value for the task. */ - #else /* configENABLE_MPU */ - " msr psplim, r2 \n"/* Restore the PSPLIM register value for the task. */ - #endif /* configENABLE_MPU */ + " msr psplim, r2 \n"/* Restore the PSPLIM register value for the task. */ " msr psp, r0 \n"/* Remember the new top of stack for the task. */ " bx r3 \n" " \n" " .align 4 \n" "pxCurrentTCBConst: .word pxCurrentTCB \n" - #if ( configENABLE_MPU == 1 ) - "xMPUCTRLConst: .word 0xe000ed94 \n" - "xMAIR0Const: .word 0xe000edc0 \n" - "xRNRConst: .word 0xe000ed98 \n" - "xRBARConst: .word 0xe000ed9c \n" - #endif /* configENABLE_MPU */ ::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) ); } + +#endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + +void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ +{ + __asm volatile + ( + ".syntax unified \n" + ".extern vPortSVCHandler_C \n" + ".extern vSystemCallEnter \n" + ".extern vSystemCallEnter_1 \n" + ".extern vSystemCallExit \n" + " \n" + "tst lr, #4 \n" + "ite eq \n" + "mrseq r0, msp \n" + "mrsne r0, psp \n" + " \n" + "ldr r1, [r0, #24] \n" + "ldrb r2, [r1, #-2] \n" + "cmp r2, %0 \n" + "beq syscall_enter \n" + "cmp r2, %1 \n" + "beq syscall_enter_1 \n" + "cmp r2, %2 \n" + "beq syscall_exit \n" + "b vPortSVCHandler_C \n" + " \n" + "syscall_enter: \n" + " mov r1, lr \n" + " b vSystemCallEnter \n" + " \n" + "syscall_enter_1: \n" + " mov r1, lr \n" + " b vSystemCallEnter_1 \n" + " \n" + "syscall_exit: \n" + " mov r1, lr \n" + " b vSystemCallExit \n" + " \n" + : /* No outputs. */ + :"i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_ENTER_1 ), "i" ( portSVC_SYSTEM_CALL_EXIT ) + : "r0", "r1", "r2", "memory" + ); +} + +#else /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ { __asm volatile @@ -362,4 +498,6 @@ void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ "svchandler_address_const: .word vPortSVCHandler_C \n" ); } + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ /*-----------------------------------------------------------*/ diff --git a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33_NTZ/portmacro.h b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33_NTZ/portmacro.h index 19da9b0ecfe..b9efb07ddc7 100644 --- a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33_NTZ/portmacro.h +++ b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33_NTZ/portmacro.h @@ -51,7 +51,6 @@ #define portARCH_NAME "Cortex-M33" #define portHAS_BASEPRI 1 #define portDONT_DISCARD __attribute__( ( used ) ) -#define portNORETURN __attribute__( ( noreturn ) ) /*-----------------------------------------------------------*/ /* ARMv8-M common port configurations. */ diff --git a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM35P/portmacro.h b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM35P/portmacro.h index cc643459770..9545737c550 100644 --- a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM35P/portmacro.h +++ b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM35P/portmacro.h @@ -51,7 +51,6 @@ #define portARCH_NAME "Cortex-M35P" #define portHAS_BASEPRI 1 #define portDONT_DISCARD __attribute__( ( used ) ) -#define portNORETURN __attribute__( ( noreturn ) ) /*-----------------------------------------------------------*/ /* ARMv8-M common port configurations. */ diff --git a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM55/portmacro.h b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM55/portmacro.h index c9bad40cf98..12bb5e7c4b9 100644 --- a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM55/portmacro.h +++ b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM55/portmacro.h @@ -56,7 +56,6 @@ #define portARCH_NAME "Cortex-M55" #define portHAS_BASEPRI 1 #define portDONT_DISCARD __attribute__( ( used ) ) -#define portNORETURN __attribute__( ( noreturn ) ) /*-----------------------------------------------------------*/ /* ARMv8-M common port configurations. */ diff --git a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM85/portmacro.h b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM85/portmacro.h index c45dd21c29e..99f913d3491 100644 --- a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM85/portmacro.h +++ b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM85/portmacro.h @@ -56,7 +56,6 @@ #define portARCH_NAME "Cortex-M85" #define portHAS_BASEPRI 1 #define portDONT_DISCARD __attribute__( ( used ) ) -#define portNORETURN __attribute__( ( noreturn ) ) /*-----------------------------------------------------------*/ /* ARMv8-M common port configurations. */ diff --git a/portable/ARMv8M/non_secure/portable/IAR/ARM_CM23/mpu_wrappers_v2_asm.S b/portable/ARMv8M/non_secure/portable/IAR/ARM_CM23/mpu_wrappers_v2_asm.S new file mode 100644 index 00000000000..867642b5e97 --- /dev/null +++ b/portable/ARMv8M/non_secure/portable/IAR/ARM_CM23/mpu_wrappers_v2_asm.S @@ -0,0 +1,1623 @@ +/* + * FreeRTOS Kernel + * Copyright (C) 2021 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 + * + */ + + + SECTION freertos_system_calls:CODE:NOROOT(2) + THUMB +/*-----------------------------------------------------------*/ + +#include "FreeRTOSConfig.h" + +#ifndef configUSE_MPU_WRAPPERS_V1 + #define configUSE_MPU_WRAPPERS_V1 0 +#endif + +/* These must be in sync with portmacro.h. */ +#define portSVC_SYSTEM_CALL_ENTER 4 /* System calls with upto 4 parameters. */ +#define portSVC_SYSTEM_CALL_ENTER_1 5 /* System calls with 5 parameters. */ +#define portSVC_SYSTEM_CALL_EXIT 6 +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + + PUBLIC MPU_xTaskDelayUntil +MPU_xTaskDelayUntil: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xTaskDelayUntil_Unpriv + MPU_xTaskDelayUntil_Priv: + pop {r0, r1} + b MPU_xTaskDelayUntilImpl + MPU_xTaskDelayUntil_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskDelayUntilImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskAbortDelay +MPU_xTaskAbortDelay: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xTaskAbortDelay_Unpriv + MPU_xTaskAbortDelay_Priv: + pop {r0, r1} + b MPU_xTaskAbortDelayImpl + MPU_xTaskAbortDelay_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskAbortDelayImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTaskDelay +MPU_vTaskDelay: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_vTaskDelay_Unpriv + MPU_vTaskDelay_Priv: + pop {r0, r1} + b MPU_vTaskDelayImpl + MPU_vTaskDelay_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskDelayImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxTaskPriorityGet +MPU_uxTaskPriorityGet: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_uxTaskPriorityGet_Unpriv + MPU_uxTaskPriorityGet_Priv: + pop {r0, r1} + b MPU_uxTaskPriorityGetImpl + MPU_uxTaskPriorityGet_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxTaskPriorityGetImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_eTaskGetState +MPU_eTaskGetState: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_eTaskGetState_Unpriv + MPU_eTaskGetState_Priv: + pop {r0, r1} + b MPU_eTaskGetStateImpl + MPU_eTaskGetState_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_eTaskGetStateImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTaskGetInfo +MPU_vTaskGetInfo: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_vTaskGetInfo_Unpriv + MPU_vTaskGetInfo_Priv: + pop {r0, r1} + b MPU_vTaskGetInfoImpl + MPU_vTaskGetInfo_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskGetInfoImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGetIdleTaskHandle +MPU_xTaskGetIdleTaskHandle: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xTaskGetIdleTaskHandle_Unpriv + MPU_xTaskGetIdleTaskHandle_Priv: + pop {r0, r1} + b MPU_xTaskGetIdleTaskHandleImpl + MPU_xTaskGetIdleTaskHandle_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskGetIdleTaskHandleImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTaskSuspend +MPU_vTaskSuspend: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_vTaskSuspend_Unpriv + MPU_vTaskSuspend_Priv: + pop {r0, r1} + b MPU_vTaskSuspendImpl + MPU_vTaskSuspend_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskSuspendImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTaskResume +MPU_vTaskResume: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_vTaskResume_Unpriv + MPU_vTaskResume_Priv: + pop {r0, r1} + b MPU_vTaskResumeImpl + MPU_vTaskResume_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskResumeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGetTickCount +MPU_xTaskGetTickCount: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xTaskGetTickCount_Unpriv + MPU_xTaskGetTickCount_Priv: + pop {r0, r1} + b MPU_xTaskGetTickCountImpl + MPU_xTaskGetTickCount_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskGetTickCountImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxTaskGetNumberOfTasks +MPU_uxTaskGetNumberOfTasks: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_uxTaskGetNumberOfTasks_Unpriv + MPU_uxTaskGetNumberOfTasks_Priv: + pop {r0, r1} + b MPU_uxTaskGetNumberOfTasksImpl + MPU_uxTaskGetNumberOfTasks_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxTaskGetNumberOfTasksImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_pcTaskGetName +MPU_pcTaskGetName: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_pcTaskGetName_Unpriv + MPU_pcTaskGetName_Priv: + pop {r0, r1} + b MPU_pcTaskGetNameImpl + MPU_pcTaskGetName_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_pcTaskGetNameImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_ulTaskGetRunTimeCounter +MPU_ulTaskGetRunTimeCounter: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_ulTaskGetRunTimeCounter_Unpriv + MPU_ulTaskGetRunTimeCounter_Priv: + pop {r0, r1} + b MPU_ulTaskGetRunTimeCounterImpl + MPU_ulTaskGetRunTimeCounter_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_ulTaskGetRunTimeCounterImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_ulTaskGetRunTimePercent +MPU_ulTaskGetRunTimePercent: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_ulTaskGetRunTimePercent_Unpriv + MPU_ulTaskGetRunTimePercent_Priv: + pop {r0, r1} + b MPU_ulTaskGetRunTimePercentImpl + MPU_ulTaskGetRunTimePercent_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_ulTaskGetRunTimePercentImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_ulTaskGetIdleRunTimePercent +MPU_ulTaskGetIdleRunTimePercent: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_ulTaskGetIdleRunTimePercent_Unpriv + MPU_ulTaskGetIdleRunTimePercent_Priv: + pop {r0, r1} + b MPU_ulTaskGetIdleRunTimePercentImpl + MPU_ulTaskGetIdleRunTimePercent_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_ulTaskGetIdleRunTimePercentImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_ulTaskGetIdleRunTimeCounter +MPU_ulTaskGetIdleRunTimeCounter: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_ulTaskGetIdleRunTimeCounter_Unpriv + MPU_ulTaskGetIdleRunTimeCounter_Priv: + pop {r0, r1} + b MPU_ulTaskGetIdleRunTimeCounterImpl + MPU_ulTaskGetIdleRunTimeCounter_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_ulTaskGetIdleRunTimeCounterImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTaskSetApplicationTaskTag +MPU_vTaskSetApplicationTaskTag: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_vTaskSetApplicationTaskTag_Unpriv + MPU_vTaskSetApplicationTaskTag_Priv: + pop {r0, r1} + b MPU_vTaskSetApplicationTaskTagImpl + MPU_vTaskSetApplicationTaskTag_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskSetApplicationTaskTagImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGetApplicationTaskTag +MPU_xTaskGetApplicationTaskTag: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xTaskGetApplicationTaskTag_Unpriv + MPU_xTaskGetApplicationTaskTag_Priv: + pop {r0, r1} + b MPU_xTaskGetApplicationTaskTagImpl + MPU_xTaskGetApplicationTaskTag_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskGetApplicationTaskTagImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTaskSetThreadLocalStoragePointer +MPU_vTaskSetThreadLocalStoragePointer: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_vTaskSetThreadLocalStoragePointer_Unpriv + MPU_vTaskSetThreadLocalStoragePointer_Priv: + pop {r0, r1} + b MPU_vTaskSetThreadLocalStoragePointerImpl + MPU_vTaskSetThreadLocalStoragePointer_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskSetThreadLocalStoragePointerImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_pvTaskGetThreadLocalStoragePointer +MPU_pvTaskGetThreadLocalStoragePointer: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_pvTaskGetThreadLocalStoragePointer_Unpriv + MPU_pvTaskGetThreadLocalStoragePointer_Priv: + pop {r0, r1} + b MPU_pvTaskGetThreadLocalStoragePointerImpl + MPU_pvTaskGetThreadLocalStoragePointer_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_pvTaskGetThreadLocalStoragePointerImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxTaskGetSystemState +MPU_uxTaskGetSystemState: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_uxTaskGetSystemState_Unpriv + MPU_uxTaskGetSystemState_Priv: + pop {r0, r1} + b MPU_uxTaskGetSystemStateImpl + MPU_uxTaskGetSystemState_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxTaskGetSystemStateImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxTaskGetStackHighWaterMark +MPU_uxTaskGetStackHighWaterMark: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_uxTaskGetStackHighWaterMark_Unpriv + MPU_uxTaskGetStackHighWaterMark_Priv: + pop {r0, r1} + b MPU_uxTaskGetStackHighWaterMarkImpl + MPU_uxTaskGetStackHighWaterMark_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxTaskGetStackHighWaterMarkImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxTaskGetStackHighWaterMark2 +MPU_uxTaskGetStackHighWaterMark2: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_uxTaskGetStackHighWaterMark2_Unpriv + MPU_uxTaskGetStackHighWaterMark2_Priv: + pop {r0, r1} + b MPU_uxTaskGetStackHighWaterMark2Impl + MPU_uxTaskGetStackHighWaterMark2_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxTaskGetStackHighWaterMark2Impl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGetCurrentTaskHandle +MPU_xTaskGetCurrentTaskHandle: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xTaskGetCurrentTaskHandle_Unpriv + MPU_xTaskGetCurrentTaskHandle_Priv: + pop {r0, r1} + b MPU_xTaskGetCurrentTaskHandleImpl + MPU_xTaskGetCurrentTaskHandle_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskGetCurrentTaskHandleImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGetSchedulerState +MPU_xTaskGetSchedulerState: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xTaskGetSchedulerState_Unpriv + MPU_xTaskGetSchedulerState_Priv: + pop {r0, r1} + b MPU_xTaskGetSchedulerStateImpl + MPU_xTaskGetSchedulerState_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskGetSchedulerStateImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTaskSetTimeOutState +MPU_vTaskSetTimeOutState: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_vTaskSetTimeOutState_Unpriv + MPU_vTaskSetTimeOutState_Priv: + pop {r0, r1} + b MPU_vTaskSetTimeOutStateImpl + MPU_vTaskSetTimeOutState_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskSetTimeOutStateImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskCheckForTimeOut +MPU_xTaskCheckForTimeOut: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xTaskCheckForTimeOut_Unpriv + MPU_xTaskCheckForTimeOut_Priv: + pop {r0, r1} + b MPU_xTaskCheckForTimeOutImpl + MPU_xTaskCheckForTimeOut_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskCheckForTimeOutImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGenericNotify +MPU_xTaskGenericNotify: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xTaskGenericNotify_Unpriv + MPU_xTaskGenericNotify_Priv: + pop {r0, r1} + b MPU_xTaskGenericNotifyImpl + MPU_xTaskGenericNotify_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER_1 + bl MPU_xTaskGenericNotifyImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGenericNotifyWait +MPU_xTaskGenericNotifyWait: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xTaskGenericNotifyWait_Unpriv + MPU_xTaskGenericNotifyWait_Priv: + pop {r0, r1} + b MPU_xTaskGenericNotifyWaitImpl + MPU_xTaskGenericNotifyWait_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER_1 + bl MPU_xTaskGenericNotifyWaitImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_ulTaskGenericNotifyTake +MPU_ulTaskGenericNotifyTake: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_ulTaskGenericNotifyTake_Unpriv + MPU_ulTaskGenericNotifyTake_Priv: + pop {r0, r1} + b MPU_ulTaskGenericNotifyTakeImpl + MPU_ulTaskGenericNotifyTake_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_ulTaskGenericNotifyTakeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGenericNotifyStateClear +MPU_xTaskGenericNotifyStateClear: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xTaskGenericNotifyStateClear_Unpriv + MPU_xTaskGenericNotifyStateClear_Priv: + pop {r0, r1} + b MPU_xTaskGenericNotifyStateClearImpl + MPU_xTaskGenericNotifyStateClear_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskGenericNotifyStateClearImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_ulTaskGenericNotifyValueClear +MPU_ulTaskGenericNotifyValueClear: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_ulTaskGenericNotifyValueClear_Unpriv + MPU_ulTaskGenericNotifyValueClear_Priv: + pop {r0, r1} + b MPU_ulTaskGenericNotifyValueClearImpl + MPU_ulTaskGenericNotifyValueClear_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_ulTaskGenericNotifyValueClearImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueGenericSend +MPU_xQueueGenericSend: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xQueueGenericSend_Unpriv + MPU_xQueueGenericSend_Priv: + pop {r0, r1} + b MPU_xQueueGenericSendImpl + MPU_xQueueGenericSend_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueGenericSendImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxQueueMessagesWaiting +MPU_uxQueueMessagesWaiting: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_uxQueueMessagesWaiting_Unpriv + MPU_uxQueueMessagesWaiting_Priv: + pop {r0, r1} + b MPU_uxQueueMessagesWaitingImpl + MPU_uxQueueMessagesWaiting_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxQueueMessagesWaitingImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxQueueSpacesAvailable +MPU_uxQueueSpacesAvailable: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_uxQueueSpacesAvailable_Unpriv + MPU_uxQueueSpacesAvailable_Priv: + pop {r0, r1} + b MPU_uxQueueSpacesAvailableImpl + MPU_uxQueueSpacesAvailable_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxQueueSpacesAvailableImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueReceive +MPU_xQueueReceive: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xQueueReceive_Unpriv + MPU_xQueueReceive_Priv: + pop {r0, r1} + b MPU_xQueueReceiveImpl + MPU_xQueueReceive_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueReceiveImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueuePeek +MPU_xQueuePeek: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xQueuePeek_Unpriv + MPU_xQueuePeek_Priv: + pop {r0, r1} + b MPU_xQueuePeekImpl + MPU_xQueuePeek_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueuePeekImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueSemaphoreTake +MPU_xQueueSemaphoreTake: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xQueueSemaphoreTake_Unpriv + MPU_xQueueSemaphoreTake_Priv: + pop {r0, r1} + b MPU_xQueueSemaphoreTakeImpl + MPU_xQueueSemaphoreTake_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueSemaphoreTakeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueGetMutexHolder +MPU_xQueueGetMutexHolder: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xQueueGetMutexHolder_Unpriv + MPU_xQueueGetMutexHolder_Priv: + pop {r0, r1} + b MPU_xQueueGetMutexHolderImpl + MPU_xQueueGetMutexHolder_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueGetMutexHolderImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueTakeMutexRecursive +MPU_xQueueTakeMutexRecursive: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xQueueTakeMutexRecursive_Unpriv + MPU_xQueueTakeMutexRecursive_Priv: + pop {r0, r1} + b MPU_xQueueTakeMutexRecursiveImpl + MPU_xQueueTakeMutexRecursive_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueTakeMutexRecursiveImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueGiveMutexRecursive +MPU_xQueueGiveMutexRecursive: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xQueueGiveMutexRecursive_Unpriv + MPU_xQueueGiveMutexRecursive_Priv: + pop {r0, r1} + b MPU_xQueueGiveMutexRecursiveImpl + MPU_xQueueGiveMutexRecursive_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueGiveMutexRecursiveImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueSelectFromSet +MPU_xQueueSelectFromSet: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xQueueSelectFromSet_Unpriv + MPU_xQueueSelectFromSet_Priv: + pop {r0, r1} + b MPU_xQueueSelectFromSetImpl + MPU_xQueueSelectFromSet_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueSelectFromSetImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueAddToSet +MPU_xQueueAddToSet: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xQueueAddToSet_Unpriv + MPU_xQueueAddToSet_Priv: + pop {r0, r1} + b MPU_xQueueAddToSetImpl + MPU_xQueueAddToSet_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueAddToSetImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vQueueAddToRegistry +MPU_vQueueAddToRegistry: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_vQueueAddToRegistry_Unpriv + MPU_vQueueAddToRegistry_Priv: + pop {r0, r1} + b MPU_vQueueAddToRegistryImpl + MPU_vQueueAddToRegistry_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vQueueAddToRegistryImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vQueueUnregisterQueue +MPU_vQueueUnregisterQueue: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_vQueueUnregisterQueue_Unpriv + MPU_vQueueUnregisterQueue_Priv: + pop {r0, r1} + b MPU_vQueueUnregisterQueueImpl + MPU_vQueueUnregisterQueue_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vQueueUnregisterQueueImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_pcQueueGetName +MPU_pcQueueGetName: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_pcQueueGetName_Unpriv + MPU_pcQueueGetName_Priv: + pop {r0, r1} + b MPU_pcQueueGetNameImpl + MPU_pcQueueGetName_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_pcQueueGetNameImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_pvTimerGetTimerID +MPU_pvTimerGetTimerID: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_pvTimerGetTimerID_Unpriv + MPU_pvTimerGetTimerID_Priv: + pop {r0, r1} + b MPU_pvTimerGetTimerIDImpl + MPU_pvTimerGetTimerID_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_pvTimerGetTimerIDImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTimerSetTimerID +MPU_vTimerSetTimerID: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_vTimerSetTimerID_Unpriv + MPU_vTimerSetTimerID_Priv: + pop {r0, r1} + b MPU_vTimerSetTimerIDImpl + MPU_vTimerSetTimerID_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTimerSetTimerIDImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTimerIsTimerActive +MPU_xTimerIsTimerActive: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xTimerIsTimerActive_Unpriv + MPU_xTimerIsTimerActive_Priv: + pop {r0, r1} + b MPU_xTimerIsTimerActiveImpl + MPU_xTimerIsTimerActive_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTimerIsTimerActiveImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTimerGetTimerDaemonTaskHandle +MPU_xTimerGetTimerDaemonTaskHandle: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xTimerGetTimerDaemonTaskHandle_Unpriv + MPU_xTimerGetTimerDaemonTaskHandle_Priv: + pop {r0, r1} + b MPU_xTimerGetTimerDaemonTaskHandleImpl + MPU_xTimerGetTimerDaemonTaskHandle_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTimerGetTimerDaemonTaskHandleImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTimerGenericCommand +MPU_xTimerGenericCommand: + push {r0, r1} + /* This function can be called from ISR also and therefore, we need a check + * to take privileged path, if called from ISR. */ + mrs r0, ipsr + cmp r0, #0 + bne MPU_xTimerGenericCommand_Priv + mrs r0, control + movs r1, #1 + tst r0, r1 + beq MPU_xTimerGenericCommand_Priv + MPU_xTimerGenericCommand_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER_1 + bl MPU_xTimerGenericCommandImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr + MPU_xTimerGenericCommand_Priv: + pop {r0, r1} + b MPU_xTimerGenericCommandImpl + +/*-----------------------------------------------------------*/ + + PUBLIC MPU_pcTimerGetName +MPU_pcTimerGetName: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_pcTimerGetName_Unpriv + MPU_pcTimerGetName_Priv: + pop {r0, r1} + b MPU_pcTimerGetNameImpl + MPU_pcTimerGetName_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_pcTimerGetNameImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTimerSetReloadMode +MPU_vTimerSetReloadMode: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_vTimerSetReloadMode_Unpriv + MPU_vTimerSetReloadMode_Priv: + pop {r0, r1} + b MPU_vTimerSetReloadModeImpl + MPU_vTimerSetReloadMode_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTimerSetReloadModeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTimerGetReloadMode +MPU_xTimerGetReloadMode: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xTimerGetReloadMode_Unpriv + MPU_xTimerGetReloadMode_Priv: + pop {r0, r1} + b MPU_xTimerGetReloadModeImpl + MPU_xTimerGetReloadMode_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTimerGetReloadModeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxTimerGetReloadMode +MPU_uxTimerGetReloadMode: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_uxTimerGetReloadMode_Unpriv + MPU_uxTimerGetReloadMode_Priv: + pop {r0, r1} + b MPU_uxTimerGetReloadModeImpl + MPU_uxTimerGetReloadMode_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxTimerGetReloadModeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTimerGetPeriod +MPU_xTimerGetPeriod: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xTimerGetPeriod_Unpriv + MPU_xTimerGetPeriod_Priv: + pop {r0, r1} + b MPU_xTimerGetPeriodImpl + MPU_xTimerGetPeriod_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTimerGetPeriodImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTimerGetExpiryTime +MPU_xTimerGetExpiryTime: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xTimerGetExpiryTime_Unpriv + MPU_xTimerGetExpiryTime_Priv: + pop {r0, r1} + b MPU_xTimerGetExpiryTimeImpl + MPU_xTimerGetExpiryTime_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTimerGetExpiryTimeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xEventGroupWaitBits +MPU_xEventGroupWaitBits: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xEventGroupWaitBits_Unpriv + MPU_xEventGroupWaitBits_Priv: + pop {r0, r1} + b MPU_xEventGroupWaitBitsImpl + MPU_xEventGroupWaitBits_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER_1 + bl MPU_xEventGroupWaitBitsImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xEventGroupClearBits +MPU_xEventGroupClearBits: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xEventGroupClearBits_Unpriv + MPU_xEventGroupClearBits_Priv: + pop {r0, r1} + b MPU_xEventGroupClearBitsImpl + MPU_xEventGroupClearBits_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xEventGroupClearBitsImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xEventGroupSetBits +MPU_xEventGroupSetBits: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xEventGroupSetBits_Unpriv + MPU_xEventGroupSetBits_Priv: + pop {r0, r1} + b MPU_xEventGroupSetBitsImpl + MPU_xEventGroupSetBits_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xEventGroupSetBitsImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xEventGroupSync +MPU_xEventGroupSync: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xEventGroupSync_Unpriv + MPU_xEventGroupSync_Priv: + pop {r0, r1} + b MPU_xEventGroupSyncImpl + MPU_xEventGroupSync_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xEventGroupSyncImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxEventGroupGetNumber +MPU_uxEventGroupGetNumber: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_uxEventGroupGetNumber_Unpriv + MPU_uxEventGroupGetNumber_Priv: + pop {r0, r1} + b MPU_uxEventGroupGetNumberImpl + MPU_uxEventGroupGetNumber_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxEventGroupGetNumberImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vEventGroupSetNumber +MPU_vEventGroupSetNumber: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_vEventGroupSetNumber_Unpriv + MPU_vEventGroupSetNumber_Priv: + pop {r0, r1} + b MPU_vEventGroupSetNumberImpl + MPU_vEventGroupSetNumber_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vEventGroupSetNumberImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferSend +MPU_xStreamBufferSend: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xStreamBufferSend_Unpriv + MPU_xStreamBufferSend_Priv: + pop {r0, r1} + b MPU_xStreamBufferSendImpl + MPU_xStreamBufferSend_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferSendImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferReceive +MPU_xStreamBufferReceive: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xStreamBufferReceive_Unpriv + MPU_xStreamBufferReceive_Priv: + pop {r0, r1} + b MPU_xStreamBufferReceiveImpl + MPU_xStreamBufferReceive_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferReceiveImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferIsFull +MPU_xStreamBufferIsFull: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xStreamBufferIsFull_Unpriv + MPU_xStreamBufferIsFull_Priv: + pop {r0, r1} + b MPU_xStreamBufferIsFullImpl + MPU_xStreamBufferIsFull_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferIsFullImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferIsEmpty +MPU_xStreamBufferIsEmpty: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xStreamBufferIsEmpty_Unpriv + MPU_xStreamBufferIsEmpty_Priv: + pop {r0, r1} + b MPU_xStreamBufferIsEmptyImpl + MPU_xStreamBufferIsEmpty_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferIsEmptyImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferSpacesAvailable +MPU_xStreamBufferSpacesAvailable: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xStreamBufferSpacesAvailable_Unpriv + MPU_xStreamBufferSpacesAvailable_Priv: + pop {r0, r1} + b MPU_xStreamBufferSpacesAvailableImpl + MPU_xStreamBufferSpacesAvailable_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferSpacesAvailableImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferBytesAvailable +MPU_xStreamBufferBytesAvailable: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xStreamBufferBytesAvailable_Unpriv + MPU_xStreamBufferBytesAvailable_Priv: + pop {r0, r1} + b MPU_xStreamBufferBytesAvailableImpl + MPU_xStreamBufferBytesAvailable_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferBytesAvailableImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferSetTriggerLevel +MPU_xStreamBufferSetTriggerLevel: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xStreamBufferSetTriggerLevel_Unpriv + MPU_xStreamBufferSetTriggerLevel_Priv: + pop {r0, r1} + b MPU_xStreamBufferSetTriggerLevelImpl + MPU_xStreamBufferSetTriggerLevel_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferSetTriggerLevelImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferNextMessageLengthBytes +MPU_xStreamBufferNextMessageLengthBytes: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xStreamBufferNextMessageLengthBytes_Unpriv + MPU_xStreamBufferNextMessageLengthBytes_Priv: + pop {r0, r1} + b MPU_xStreamBufferNextMessageLengthBytesImpl + MPU_xStreamBufferNextMessageLengthBytes_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferNextMessageLengthBytesImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + +/* Default weak implementations in case one is not available from + * mpu_wrappers because of config options. */ + + PUBWEAK MPU_xTaskDelayUntilImpl +MPU_xTaskDelayUntilImpl: + b MPU_xTaskDelayUntilImpl + + PUBWEAK MPU_xTaskAbortDelayImpl +MPU_xTaskAbortDelayImpl: + b MPU_xTaskAbortDelayImpl + + PUBWEAK MPU_vTaskDelayImpl +MPU_vTaskDelayImpl: + b MPU_vTaskDelayImpl + + PUBWEAK MPU_uxTaskPriorityGetImpl +MPU_uxTaskPriorityGetImpl: + b MPU_uxTaskPriorityGetImpl + + PUBWEAK MPU_eTaskGetStateImpl +MPU_eTaskGetStateImpl: + b MPU_eTaskGetStateImpl + + PUBWEAK MPU_vTaskGetInfoImpl +MPU_vTaskGetInfoImpl: + b MPU_vTaskGetInfoImpl + + PUBWEAK MPU_xTaskGetIdleTaskHandleImpl +MPU_xTaskGetIdleTaskHandleImpl: + b MPU_xTaskGetIdleTaskHandleImpl + + PUBWEAK MPU_vTaskSuspendImpl +MPU_vTaskSuspendImpl: + b MPU_vTaskSuspendImpl + + PUBWEAK MPU_vTaskResumeImpl +MPU_vTaskResumeImpl: + b MPU_vTaskResumeImpl + + PUBWEAK MPU_xTaskGetTickCountImpl +MPU_xTaskGetTickCountImpl: + b MPU_xTaskGetTickCountImpl + + PUBWEAK MPU_uxTaskGetNumberOfTasksImpl +MPU_uxTaskGetNumberOfTasksImpl: + b MPU_uxTaskGetNumberOfTasksImpl + + PUBWEAK MPU_pcTaskGetNameImpl +MPU_pcTaskGetNameImpl: + b MPU_pcTaskGetNameImpl + + PUBWEAK MPU_ulTaskGetRunTimeCounterImpl +MPU_ulTaskGetRunTimeCounterImpl: + b MPU_ulTaskGetRunTimeCounterImpl + + PUBWEAK MPU_ulTaskGetRunTimePercentImpl +MPU_ulTaskGetRunTimePercentImpl: + b MPU_ulTaskGetRunTimePercentImpl + + PUBWEAK MPU_ulTaskGetIdleRunTimePercentImpl +MPU_ulTaskGetIdleRunTimePercentImpl: + b MPU_ulTaskGetIdleRunTimePercentImpl + + PUBWEAK MPU_ulTaskGetIdleRunTimeCounterImpl +MPU_ulTaskGetIdleRunTimeCounterImpl: + b MPU_ulTaskGetIdleRunTimeCounterImpl + + PUBWEAK MPU_vTaskSetApplicationTaskTagImpl +MPU_vTaskSetApplicationTaskTagImpl: + b MPU_vTaskSetApplicationTaskTagImpl + + PUBWEAK MPU_xTaskGetApplicationTaskTagImpl +MPU_xTaskGetApplicationTaskTagImpl: + b MPU_xTaskGetApplicationTaskTagImpl + + PUBWEAK MPU_vTaskSetThreadLocalStoragePointerImpl +MPU_vTaskSetThreadLocalStoragePointerImpl: + b MPU_vTaskSetThreadLocalStoragePointerImpl + + PUBWEAK MPU_pvTaskGetThreadLocalStoragePointerImpl +MPU_pvTaskGetThreadLocalStoragePointerImpl: + b MPU_pvTaskGetThreadLocalStoragePointerImpl + + PUBWEAK MPU_uxTaskGetSystemStateImpl +MPU_uxTaskGetSystemStateImpl: + b MPU_uxTaskGetSystemStateImpl + + PUBWEAK MPU_uxTaskGetStackHighWaterMarkImpl +MPU_uxTaskGetStackHighWaterMarkImpl: + b MPU_uxTaskGetStackHighWaterMarkImpl + + PUBWEAK MPU_uxTaskGetStackHighWaterMark2Impl +MPU_uxTaskGetStackHighWaterMark2Impl: + b MPU_uxTaskGetStackHighWaterMark2Impl + + PUBWEAK MPU_xTaskGetCurrentTaskHandleImpl +MPU_xTaskGetCurrentTaskHandleImpl: + b MPU_xTaskGetCurrentTaskHandleImpl + + PUBWEAK MPU_xTaskGetSchedulerStateImpl +MPU_xTaskGetSchedulerStateImpl: + b MPU_xTaskGetSchedulerStateImpl + + PUBWEAK MPU_vTaskSetTimeOutStateImpl +MPU_vTaskSetTimeOutStateImpl: + b MPU_vTaskSetTimeOutStateImpl + + PUBWEAK MPU_xTaskCheckForTimeOutImpl +MPU_xTaskCheckForTimeOutImpl: + b MPU_xTaskCheckForTimeOutImpl + + PUBWEAK MPU_xTaskGenericNotifyImpl +MPU_xTaskGenericNotifyImpl: + b MPU_xTaskGenericNotifyImpl + + PUBWEAK MPU_xTaskGenericNotifyWaitImpl +MPU_xTaskGenericNotifyWaitImpl: + b MPU_xTaskGenericNotifyWaitImpl + + PUBWEAK MPU_ulTaskGenericNotifyTakeImpl +MPU_ulTaskGenericNotifyTakeImpl: + b MPU_ulTaskGenericNotifyTakeImpl + + PUBWEAK MPU_xTaskGenericNotifyStateClearImpl +MPU_xTaskGenericNotifyStateClearImpl: + b MPU_xTaskGenericNotifyStateClearImpl + + PUBWEAK MPU_ulTaskGenericNotifyValueClearImpl +MPU_ulTaskGenericNotifyValueClearImpl: + b MPU_ulTaskGenericNotifyValueClearImpl + + PUBWEAK MPU_xQueueGenericSendImpl +MPU_xQueueGenericSendImpl: + b MPU_xQueueGenericSendImpl + + PUBWEAK MPU_uxQueueMessagesWaitingImpl +MPU_uxQueueMessagesWaitingImpl: + b MPU_uxQueueMessagesWaitingImpl + + PUBWEAK MPU_uxQueueSpacesAvailableImpl +MPU_uxQueueSpacesAvailableImpl: + b MPU_uxQueueSpacesAvailableImpl + + PUBWEAK MPU_xQueueReceiveImpl +MPU_xQueueReceiveImpl: + b MPU_xQueueReceiveImpl + + PUBWEAK MPU_xQueuePeekImpl +MPU_xQueuePeekImpl: + b MPU_xQueuePeekImpl + + PUBWEAK MPU_xQueueSemaphoreTakeImpl +MPU_xQueueSemaphoreTakeImpl: + b MPU_xQueueSemaphoreTakeImpl + + PUBWEAK MPU_xQueueGetMutexHolderImpl +MPU_xQueueGetMutexHolderImpl: + b MPU_xQueueGetMutexHolderImpl + + PUBWEAK MPU_xQueueTakeMutexRecursiveImpl +MPU_xQueueTakeMutexRecursiveImpl: + b MPU_xQueueTakeMutexRecursiveImpl + + PUBWEAK MPU_xQueueGiveMutexRecursiveImpl +MPU_xQueueGiveMutexRecursiveImpl: + b MPU_xQueueGiveMutexRecursiveImpl + + PUBWEAK MPU_xQueueSelectFromSetImpl +MPU_xQueueSelectFromSetImpl: + b MPU_xQueueSelectFromSetImpl + + PUBWEAK MPU_xQueueAddToSetImpl +MPU_xQueueAddToSetImpl: + b MPU_xQueueAddToSetImpl + + PUBWEAK MPU_vQueueAddToRegistryImpl +MPU_vQueueAddToRegistryImpl: + b MPU_vQueueAddToRegistryImpl + + PUBWEAK MPU_vQueueUnregisterQueueImpl +MPU_vQueueUnregisterQueueImpl: + b MPU_vQueueUnregisterQueueImpl + + PUBWEAK MPU_pcQueueGetNameImpl +MPU_pcQueueGetNameImpl: + b MPU_pcQueueGetNameImpl + + PUBWEAK MPU_pvTimerGetTimerIDImpl +MPU_pvTimerGetTimerIDImpl: + b MPU_pvTimerGetTimerIDImpl + + PUBWEAK MPU_vTimerSetTimerIDImpl +MPU_vTimerSetTimerIDImpl: + b MPU_vTimerSetTimerIDImpl + + PUBWEAK MPU_xTimerIsTimerActiveImpl +MPU_xTimerIsTimerActiveImpl: + b MPU_xTimerIsTimerActiveImpl + + PUBWEAK MPU_xTimerGetTimerDaemonTaskHandleImpl +MPU_xTimerGetTimerDaemonTaskHandleImpl: + b MPU_xTimerGetTimerDaemonTaskHandleImpl + + PUBWEAK MPU_xTimerGenericCommandImpl +MPU_xTimerGenericCommandImpl: + b MPU_xTimerGenericCommandImpl + + PUBWEAK MPU_pcTimerGetNameImpl +MPU_pcTimerGetNameImpl: + b MPU_pcTimerGetNameImpl + + PUBWEAK MPU_vTimerSetReloadModeImpl +MPU_vTimerSetReloadModeImpl: + b MPU_vTimerSetReloadModeImpl + + PUBWEAK MPU_xTimerGetReloadModeImpl +MPU_xTimerGetReloadModeImpl: + b MPU_xTimerGetReloadModeImpl + + PUBWEAK MPU_uxTimerGetReloadModeImpl +MPU_uxTimerGetReloadModeImpl: + b MPU_uxTimerGetReloadModeImpl + + PUBWEAK MPU_xTimerGetPeriodImpl +MPU_xTimerGetPeriodImpl: + b MPU_xTimerGetPeriodImpl + + PUBWEAK MPU_xTimerGetExpiryTimeImpl +MPU_xTimerGetExpiryTimeImpl: + b MPU_xTimerGetExpiryTimeImpl + + PUBWEAK MPU_xEventGroupWaitBitsImpl +MPU_xEventGroupWaitBitsImpl: + b MPU_xEventGroupWaitBitsImpl + + PUBWEAK MPU_xEventGroupClearBitsImpl +MPU_xEventGroupClearBitsImpl: + b MPU_xEventGroupClearBitsImpl + + PUBWEAK MPU_xEventGroupSetBitsImpl +MPU_xEventGroupSetBitsImpl: + b MPU_xEventGroupSetBitsImpl + + PUBWEAK MPU_xEventGroupSyncImpl +MPU_xEventGroupSyncImpl: + b MPU_xEventGroupSyncImpl + + PUBWEAK MPU_uxEventGroupGetNumberImpl +MPU_uxEventGroupGetNumberImpl: + b MPU_uxEventGroupGetNumberImpl + + PUBWEAK MPU_vEventGroupSetNumberImpl +MPU_vEventGroupSetNumberImpl: + b MPU_vEventGroupSetNumberImpl + + PUBWEAK MPU_xStreamBufferSendImpl +MPU_xStreamBufferSendImpl: + b MPU_xStreamBufferSendImpl + + PUBWEAK MPU_xStreamBufferReceiveImpl +MPU_xStreamBufferReceiveImpl: + b MPU_xStreamBufferReceiveImpl + + PUBWEAK MPU_xStreamBufferIsFullImpl +MPU_xStreamBufferIsFullImpl: + b MPU_xStreamBufferIsFullImpl + + PUBWEAK MPU_xStreamBufferIsEmptyImpl +MPU_xStreamBufferIsEmptyImpl: + b MPU_xStreamBufferIsEmptyImpl + + PUBWEAK MPU_xStreamBufferSpacesAvailableImpl +MPU_xStreamBufferSpacesAvailableImpl: + b MPU_xStreamBufferSpacesAvailableImpl + + PUBWEAK MPU_xStreamBufferBytesAvailableImpl +MPU_xStreamBufferBytesAvailableImpl: + b MPU_xStreamBufferBytesAvailableImpl + + PUBWEAK MPU_xStreamBufferSetTriggerLevelImpl +MPU_xStreamBufferSetTriggerLevelImpl: + b MPU_xStreamBufferSetTriggerLevelImpl + + PUBWEAK MPU_xStreamBufferNextMessageLengthBytesImpl +MPU_xStreamBufferNextMessageLengthBytesImpl: + b MPU_xStreamBufferNextMessageLengthBytesImpl + +/*-----------------------------------------------------------*/ + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + + END diff --git a/portable/ARMv8M/non_secure/portable/IAR/ARM_CM23/portasm.s b/portable/ARMv8M/non_secure/portable/IAR/ARM_CM23/portasm.s index fffed8df619..648ae005010 100644 --- a/portable/ARMv8M/non_secure/portable/IAR/ARM_CM23/portasm.s +++ b/portable/ARMv8M/non_secure/portable/IAR/ARM_CM23/portasm.s @@ -33,12 +33,21 @@ the code is included in C files but excluded by the preprocessor in assembly files (__ICCARM__ is defined by the IAR C compiler but not by the IAR assembler. */ #include "FreeRTOSConfig.h" +#ifndef configUSE_MPU_WRAPPERS_V1 + #define configUSE_MPU_WRAPPERS_V1 0 +#endif + EXTERN pxCurrentTCB EXTERN xSecureContext EXTERN vTaskSwitchContext EXTERN vPortSVCHandler_C EXTERN SecureContext_SaveContext EXTERN SecureContext_LoadContext +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + EXTERN vSystemCallEnter + EXTERN vSystemCallEnter_1 + EXTERN vSystemCallExit +#endif PUBLIC xIsPrivileged PUBLIC vResetPrivilege @@ -98,65 +107,99 @@ vPortAllocateSecureContext: THUMB /*-----------------------------------------------------------*/ +#if ( configENABLE_MPU == 1 ) + +vRestoreContextOfFirstTask: + program_mpu_first_task: + ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + ldr r0, [r3] /* r0 = pxCurrentTCB.*/ + + dmb /* Complete outstanding transfers before disabling MPU. */ + ldr r1, =0xe000ed94 /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + ldr r2, [r1] /* Read the value of MPU_CTRL. */ + movs r3, #1 /* r3 = 1. */ + bics r2, r3 /* r2 = r2 & ~r3 i.e. Clear the bit 0 in r2. */ + str r2, [r1] /* Disable MPU. */ + + adds r0, #4 /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */ + ldr r1, [r0] /* r1 = *r0 i.e. r1 = MAIR0. */ + ldr r2, =0xe000edc0 /* r2 = 0xe000edc0 [Location of MAIR0]. */ + str r1, [r2] /* Program MAIR0. */ + + adds r0, #4 /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */ + ldr r1, =0xe000ed98 /* r1 = 0xe000ed98 [Location of RNR]. */ + + movs r3, #4 /* r3 = 4. */ + str r3, [r1] /* Program RNR = 4. */ + ldmia r0!, {r4-r5} /* Read first set of RBAR/RLAR registers from TCB. */ + ldr r2, =0xe000ed9c /* r2 = 0xe000ed9c [Location of RBAR]. */ + stmia r2!, {r4-r5} /* Write first set of RBAR/RLAR registers. */ + movs r3, #5 /* r3 = 5. */ + str r3, [r1] /* Program RNR = 5. */ + ldmia r0!, {r4-r5} /* Read second set of RBAR/RLAR registers from TCB. */ + ldr r2, =0xe000ed9c /* r2 = 0xe000ed9c [Location of RBAR]. */ + stmia r2!, {r4-r5} /* Write second set of RBAR/RLAR registers. */ + movs r3, #6 /* r3 = 6. */ + str r3, [r1] /* Program RNR = 6. */ + ldmia r0!, {r4-r5} /* Read third set of RBAR/RLAR registers from TCB. */ + ldr r2, =0xe000ed9c /* r2 = 0xe000ed9c [Location of RBAR]. */ + stmia r2!, {r4-r5} /* Write third set of RBAR/RLAR registers. */ + movs r3, #7 /* r3 = 6. */ + str r3, [r1] /* Program RNR = 7. */ + ldmia r0!, {r4-r5} /* Read fourth set of RBAR/RLAR registers from TCB. */ + ldr r2, =0xe000ed9c /* r2 = 0xe000ed9c [Location of RBAR]. */ + stmia r2!, {r4-r5} /* Write fourth set of RBAR/RLAR registers. */ + + ldr r1, =0xe000ed94 /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + ldr r2, [r1] /* Read the value of MPU_CTRL. */ + movs r3, #1 /* r3 = 1. */ + orrs r2, r3 /* r2 = r2 | r3 i.e. Set the bit 0 in r2. */ + str r2, [r1] /* Enable MPU. */ + dsb /* Force memory writes before continuing. */ + + restore_context_first_task: + ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + ldr r1, [r3] /* r1 = pxCurrentTCB.*/ + ldr r2, [r1] /* r2 = Location of saved context in TCB. */ + + restore_special_regs_first_task: + subs r2, #20 + ldmia r2!, {r0, r3-r6} /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, r6 = LR. */ + subs r2, #20 + msr psp, r3 + msr psplim, r4 + msr control, r5 + mov lr, r6 + ldr r4, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */ + str r0, [r4] /* Restore xSecureContext. */ + + restore_general_regs_first_task: + subs r2, #32 + ldmia r2!, {r4-r7} /* r4-r7 contain half of the hardware saved context. */ + stmia r3!, {r4-r7} /* Copy half of the the hardware saved context on the task stack. */ + ldmia r2!, {r4-r7} /* r4-r7 contain rest half of the hardware saved context. */ + stmia r3!, {r4-r7} /* Copy rest half of the the hardware saved context on the task stack. */ + subs r2, #48 + ldmia r2!, {r4-r7} /* Restore r8-r11. */ + mov r8, r4 /* r8 = r4. */ + mov r9, r5 /* r9 = r5. */ + mov r10, r6 /* r10 = r6. */ + mov r11, r7 /* r11 = r7. */ + subs r2, #32 + ldmia r2!, {r4-r7} /* Restore r4-r7. */ + subs r2, #16 + + restore_context_done_first_task: + str r2, [r1] /* Save the location where the context should be saved next as the first member of TCB. */ + bx lr + +#else /* configENABLE_MPU */ + vRestoreContextOfFirstTask: ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r3, [r2] /* Read pxCurrentTCB. */ ldr r0, [r3] /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ -#if ( configENABLE_MPU == 1 ) - dmb /* Complete outstanding transfers before disabling MPU. */ - ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ - ldr r4, [r2] /* Read the value of MPU_CTRL. */ - movs r5, #1 /* r5 = 1. */ - bics r4, r5 /* r4 = r4 & ~r5 i.e. Clear the bit 0 in r4. */ - str r4, [r2] /* Disable MPU. */ - - adds r3, #4 /* r3 = r3 + 4. r3 now points to MAIR0 in TCB. */ - ldr r4, [r3] /* r4 = *r3 i.e. r4 = MAIR0. */ - ldr r2, =0xe000edc0 /* r2 = 0xe000edc0 [Location of MAIR0]. */ - str r4, [r2] /* Program MAIR0. */ - ldr r2, =0xe000ed98 /* r2 = 0xe000ed98 [Location of RNR]. */ - adds r3, #4 /* r3 = r3 + 4. r3 now points to first RBAR in TCB. */ - movs r5, #4 /* r5 = 4. */ - str r5, [r2] /* Program RNR = 4. */ - ldmia r3!, {r6,r7} /* Read first set of RBAR/RLAR from TCB. */ - ldr r4, =0xe000ed9c /* r4 = 0xe000ed9c [Location of RBAR]. */ - stmia r4!, {r6,r7} /* Write first set of RBAR/RLAR registers. */ - movs r5, #5 /* r5 = 5. */ - str r5, [r2] /* Program RNR = 5. */ - ldmia r3!, {r6,r7} /* Read second set of RBAR/RLAR from TCB. */ - ldr r4, =0xe000ed9c /* r4 = 0xe000ed9c [Location of RBAR]. */ - stmia r4!, {r6,r7} /* Write second set of RBAR/RLAR registers. */ - movs r5, #6 /* r5 = 6. */ - str r5, [r2] /* Program RNR = 6. */ - ldmia r3!, {r6,r7} /* Read third set of RBAR/RLAR from TCB. */ - ldr r4, =0xe000ed9c /* r4 = 0xe000ed9c [Location of RBAR]. */ - stmia r4!, {r6,r7} /* Write third set of RBAR/RLAR registers. */ - movs r5, #7 /* r5 = 7. */ - str r5, [r2] /* Program RNR = 7. */ - ldmia r3!, {r6,r7} /* Read fourth set of RBAR/RLAR from TCB. */ - ldr r4, =0xe000ed9c /* r4 = 0xe000ed9c [Location of RBAR]. */ - stmia r4!, {r6,r7} /* Write fourth set of RBAR/RLAR registers. */ - - ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ - ldr r4, [r2] /* Read the value of MPU_CTRL. */ - movs r5, #1 /* r5 = 1. */ - orrs r4, r5 /* r4 = r4 | r5 i.e. Set the bit 0 in r4. */ - str r4, [r2] /* Enable MPU. */ - dsb /* Force memory writes before continuing. */ -#endif /* configENABLE_MPU */ - -#if ( configENABLE_MPU == 1 ) - ldm r0!, {r1-r4} /* Read from stack - r1 = xSecureContext, r2 = PSPLIM, r3 = CONTROL and r4 = EXC_RETURN. */ - ldr r5, =xSecureContext - str r1, [r5] /* Set xSecureContext to this task's value for the same. */ - msr psplim, r2 /* Set this task's PSPLIM value. */ - msr control, r3 /* Set this task's CONTROL value. */ - adds r0, #32 /* Discard everything up to r0. */ - msr psp, r0 /* This is now the new top of stack to use in the task. */ - isb - bx r4 /* Finally, branch to EXC_RETURN. */ -#else /* configENABLE_MPU */ ldm r0!, {r1-r3} /* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */ ldr r4, =xSecureContext str r1, [r4] /* Set xSecureContext to this task's value for the same. */ @@ -167,6 +210,7 @@ vRestoreContextOfFirstTask: msr psp, r0 /* This is now the new top of stack to use in the task. */ isb bx r3 /* Finally, branch to EXC_RETURN. */ + #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ @@ -199,6 +243,149 @@ vClearInterruptMask: msr PRIMASK, r0 bx lr /*-----------------------------------------------------------*/ +#if ( configENABLE_MPU == 1 ) + +PendSV_Handler: + ldr r3, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */ + ldr r0, [r3] /* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */ + ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + ldr r1, [r3] /* Read pxCurrentTCB - Value of pxCurrentTCB must be in r1 as it is used as a parameter later.*/ + ldr r2, [r1] /* r2 = Location in TCB where the context should be saved. */ + + cbz r0, save_ns_context /* No secure context to save. */ + save_s_context: + push {r0-r2, lr} + bl SecureContext_SaveContext /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ + pop {r0-r3} /* LR is now in r3. */ + mov lr, r3 /* Restore LR. */ + + save_ns_context: + mov r3, lr /* r3 = LR (EXC_RETURN). */ + lsls r3, r3, #25 /* r3 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ + bmi save_special_regs /* r3 < 0 ==> Bit[6] in EXC_RETURN is 1 ==> secure stack was used to store the stack frame. */ + + save_general_regs: + mrs r3, psp + stmia r2!, {r4-r7} /* Store r4-r7. */ + mov r4, r8 /* r4 = r8. */ + mov r5, r9 /* r5 = r9. */ + mov r6, r10 /* r6 = r10. */ + mov r7, r11 /* r7 = r11. */ + stmia r2!, {r4-r7} /* Store r8-r11. */ + ldmia r3!, {r4-r7} /* Copy half of the hardware saved context into r4-r7. */ + stmia r2!, {r4-r7} /* Store the hardware saved context. */ + ldmia r3!, {r4-r7} /* Copy rest half of the hardware saved context into r4-r7. */ + stmia r2!, {r4-r7} /* Store the hardware saved context. */ + + save_special_regs: + mrs r3, psp /* r3 = PSP. */ + mrs r4, psplim /* r4 = PSPLIM. */ + mrs r5, control /* r5 = CONTROL. */ + mov r6, lr /* r6 = LR. */ + stmia r2!, {r0, r3-r6} /* Store xSecureContext, original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */ + str r2, [r1] /* Save the location from where the context should be restored as the first member of TCB. */ + + select_next_task: + cpsid i + bl vTaskSwitchContext + cpsie i + + program_mpu: + ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + ldr r0, [r3] /* r0 = pxCurrentTCB.*/ + + dmb /* Complete outstanding transfers before disabling MPU. */ + ldr r1, =0xe000ed94 /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + ldr r2, [r1] /* Read the value of MPU_CTRL. */ + movs r3, #1 /* r3 = 1. */ + bics r2, r3 /* r2 = r2 & ~r3 i.e. Clear the bit 0 in r2. */ + str r2, [r1] /* Disable MPU. */ + + adds r0, #4 /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */ + ldr r1, [r0] /* r1 = *r0 i.e. r1 = MAIR0. */ + ldr r2, =0xe000edc0 /* r2 = 0xe000edc0 [Location of MAIR0]. */ + str r1, [r2] /* Program MAIR0. */ + + adds r0, #4 /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */ + ldr r1, =0xe000ed98 /* r1 = 0xe000ed98 [Location of RNR]. */ + + movs r3, #4 /* r3 = 4. */ + str r3, [r1] /* Program RNR = 4. */ + ldmia r0!, {r4-r5} /* Read first set of RBAR/RLAR registers from TCB. */ + ldr r2, =0xe000ed9c /* r2 = 0xe000ed9c [Location of RBAR]. */ + stmia r2!, {r4-r5} /* Write first set of RBAR/RLAR registers. */ + movs r3, #5 /* r3 = 5. */ + str r3, [r1] /* Program RNR = 5. */ + ldmia r0!, {r4-r5} /* Read second set of RBAR/RLAR registers from TCB. */ + ldr r2, =0xe000ed9c /* r2 = 0xe000ed9c [Location of RBAR]. */ + stmia r2!, {r4-r5} /* Write second set of RBAR/RLAR registers. */ + movs r3, #6 /* r3 = 6. */ + str r3, [r1] /* Program RNR = 6. */ + ldmia r0!, {r4-r5} /* Read third set of RBAR/RLAR registers from TCB. */ + ldr r2, =0xe000ed9c /* r2 = 0xe000ed9c [Location of RBAR]. */ + stmia r2!, {r4-r5} /* Write third set of RBAR/RLAR registers. */ + movs r3, #7 /* r3 = 6. */ + str r3, [r1] /* Program RNR = 7. */ + ldmia r0!, {r4-r5} /* Read fourth set of RBAR/RLAR registers from TCB. */ + ldr r2, =0xe000ed9c /* r2 = 0xe000ed9c [Location of RBAR]. */ + stmia r2!, {r4-r5} /* Write fourth set of RBAR/RLAR registers. */ + + ldr r1, =0xe000ed94 /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + ldr r2, [r1] /* Read the value of MPU_CTRL. */ + movs r3, #1 /* r3 = 1. */ + orrs r2, r3 /* r2 = r2 | r3 i.e. Set the bit 0 in r2. */ + str r2, [r1] /* Enable MPU. */ + dsb /* Force memory writes before continuing. */ + + restore_context: + ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + ldr r1, [r3] /* r1 = pxCurrentTCB.*/ + ldr r2, [r1] /* r2 = Location of saved context in TCB. */ + + restore_special_regs: + subs r2, #20 + ldmia r2!, {r0, r3-r6} /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, r6 = LR. */ + subs r2, #20 + msr psp, r3 + msr psplim, r4 + msr control, r5 + mov lr, r6 + ldr r4, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */ + str r0, [r4] /* Restore xSecureContext. */ + cbz r0, restore_ns_context /* No secure context to restore. */ + + restore_s_context: + push {r1-r3, lr} + bl SecureContext_LoadContext /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ + pop {r1-r4} /* LR is now in r4. */ + mov lr, r4 + + restore_ns_context: + mov r0, lr /* r0 = LR (EXC_RETURN). */ + lsls r0, r0, #25 /* r0 = r0 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ + bmi restore_context_done /* r0 < 0 ==> Bit[6] in EXC_RETURN is 1 ==> secure stack was used to store the stack frame. */ + + restore_general_regs: + subs r2, #32 + ldmia r2!, {r4-r7} /* r4-r7 contain half of the hardware saved context. */ + stmia r3!, {r4-r7} /* Copy half of the the hardware saved context on the task stack. */ + ldmia r2!, {r4-r7} /* r4-r7 contain rest half of the hardware saved context. */ + stmia r3!, {r4-r7} /* Copy rest half of the the hardware saved context on the task stack. */ + subs r2, #48 + ldmia r2!, {r4-r7} /* Restore r8-r11. */ + mov r8, r4 /* r8 = r4. */ + mov r9, r5 /* r9 = r5. */ + mov r10, r6 /* r10 = r6. */ + mov r11, r7 /* r11 = r7. */ + subs r2, #32 + ldmia r2!, {r4-r7} /* Restore r4-r7. */ + subs r2, #16 + + restore_context_done: + str r2, [r1] /* Save the location where the context should be saved next as the first member of TCB. */ + bx lr + +#else /* configENABLE_MPU */ PendSV_Handler: ldr r3, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */ @@ -216,41 +403,18 @@ PendSV_Handler: bpl save_ns_context /* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r3] /* Read pxCurrentTCB. */ -#if ( configENABLE_MPU == 1 ) - subs r2, r2, #16 /* Make space for xSecureContext, PSPLIM, CONTROL and LR on the stack. */ - str r2, [r1] /* Save the new top of stack in TCB. */ - mrs r1, psplim /* r1 = PSPLIM. */ - mrs r3, control /* r3 = CONTROL. */ - mov r4, lr /* r4 = LR/EXC_RETURN. */ - stmia r2!, {r0, r1, r3, r4} /* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */ -#else /* configENABLE_MPU */ + subs r2, r2, #12 /* Make space for xSecureContext, PSPLIM and LR on the stack. */ str r2, [r1] /* Save the new top of stack in TCB. */ mrs r1, psplim /* r1 = PSPLIM. */ mov r3, lr /* r3 = LR/EXC_RETURN. */ stmia r2!, {r0, r1, r3} /* Store xSecureContext, PSPLIM and LR on the stack. */ -#endif /* configENABLE_MPU */ + b select_next_task save_ns_context: ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r3] /* Read pxCurrentTCB. */ - #if ( configENABLE_MPU == 1 ) - subs r2, r2, #48 /* Make space for xSecureContext, PSPLIM, CONTROL, LR and the remaining registers on the stack. */ - str r2, [r1] /* Save the new top of stack in TCB. */ - adds r2, r2, #16 /* r2 = r2 + 16. */ - stmia r2!, {r4-r7} /* Store the low registers that are not saved automatically. */ - mov r4, r8 /* r4 = r8. */ - mov r5, r9 /* r5 = r9. */ - mov r6, r10 /* r6 = r10. */ - mov r7, r11 /* r7 = r11. */ - stmia r2!, {r4-r7} /* Store the high registers that are not saved automatically. */ - mrs r1, psplim /* r1 = PSPLIM. */ - mrs r3, control /* r3 = CONTROL. */ - mov r4, lr /* r4 = LR/EXC_RETURN. */ - subs r2, r2, #48 /* r2 = r2 - 48. */ - stmia r2!, {r0, r1, r3, r4} /* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */ - #else /* configENABLE_MPU */ subs r2, r2, #44 /* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */ str r2, [r1] /* Save the new top of stack in TCB. */ mrs r1, psplim /* r1 = PSPLIM. */ @@ -261,7 +425,6 @@ PendSV_Handler: mov r6, r10 /* r6 = r10. */ mov r7, r11 /* r7 = r11. */ stmia r2!, {r4-r7} /* Store the high registers that are not saved automatically. */ - #endif /* configENABLE_MPU */ select_next_task: cpsid i @@ -272,68 +435,6 @@ PendSV_Handler: ldr r1, [r3] /* Read pxCurrentTCB. */ ldr r2, [r1] /* The first item in pxCurrentTCB is the task top of stack. r2 now points to the top of stack. */ - #if ( configENABLE_MPU == 1 ) - dmb /* Complete outstanding transfers before disabling MPU. */ - ldr r3, =0xe000ed94 /* r3 = 0xe000ed94 [Location of MPU_CTRL]. */ - ldr r4, [r3] /* Read the value of MPU_CTRL. */ - movs r5, #1 /* r5 = 1. */ - bics r4, r5 /* r4 = r4 & ~r5 i.e. Clear the bit 0 in r4. */ - str r4, [r3] /* Disable MPU. */ - - adds r1, #4 /* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */ - ldr r4, [r1] /* r4 = *r1 i.e. r4 = MAIR0. */ - ldr r3, =0xe000edc0 /* r3 = 0xe000edc0 [Location of MAIR0]. */ - str r4, [r3] /* Program MAIR0. */ - ldr r4, =0xe000ed98 /* r4 = 0xe000ed98 [Location of RNR]. */ - adds r1, #4 /* r1 = r1 + 4. r1 now points to first RBAR in TCB. */ - movs r5, #4 /* r5 = 4. */ - str r5, [r4] /* Program RNR = 4. */ - ldmia r1!, {r6,r7} /* Read first set of RBAR/RLAR from TCB. */ - ldr r3, =0xe000ed9c /* r3 = 0xe000ed9c [Location of RBAR]. */ - stmia r3!, {r6,r7} /* Write first set of RBAR/RLAR registers. */ - movs r5, #5 /* r5 = 5. */ - str r5, [r4] /* Program RNR = 5. */ - ldmia r1!, {r6,r7} /* Read second set of RBAR/RLAR from TCB. */ - ldr r3, =0xe000ed9c /* r3 = 0xe000ed9c [Location of RBAR]. */ - stmia r3!, {r6,r7} /* Write second set of RBAR/RLAR registers. */ - movs r5, #6 /* r5 = 6. */ - str r5, [r4] /* Program RNR = 6. */ - ldmia r1!, {r6,r7} /* Read third set of RBAR/RLAR from TCB. */ - ldr r3, =0xe000ed9c /* r3 = 0xe000ed9c [Location of RBAR]. */ - stmia r3!, {r6,r7} /* Write third set of RBAR/RLAR registers. */ - movs r5, #7 /* r5 = 7. */ - str r5, [r4] /* Program RNR = 7. */ - ldmia r1!, {r6,r7} /* Read fourth set of RBAR/RLAR from TCB. */ - ldr r3, =0xe000ed9c /* r3 = 0xe000ed9c [Location of RBAR]. */ - stmia r3!, {r6,r7} /* Write fourth set of RBAR/RLAR registers. */ - - ldr r3, =0xe000ed94 /* r3 = 0xe000ed94 [Location of MPU_CTRL]. */ - ldr r4, [r3] /* Read the value of MPU_CTRL. */ - movs r5, #1 /* r5 = 1. */ - orrs r4, r5 /* r4 = r4 | r5 i.e. Set the bit 0 in r4. */ - str r4, [r3] /* Enable MPU. */ - dsb /* Force memory writes before continuing. */ - #endif /* configENABLE_MPU */ - - #if ( configENABLE_MPU == 1 ) - ldmia r2!, {r0, r1, r3, r4} /* Read from stack - r0 = xSecureContext, r1 = PSPLIM, r3 = CONTROL and r4 = LR. */ - msr psplim, r1 /* Restore the PSPLIM register value for the task. */ - msr control, r3 /* Restore the CONTROL register value for the task. */ - mov lr, r4 /* LR = r4. */ - ldr r3, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */ - str r0, [r3] /* Restore the task's xSecureContext. */ - cbz r0, restore_ns_context /* If there is no secure context for the task, restore the non-secure context. */ - ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - ldr r1, [r3] /* Read pxCurrentTCB. */ - push {r2, r4} - bl SecureContext_LoadContext /* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ - pop {r2, r4} - mov lr, r4 /* LR = r4. */ - lsls r1, r4, #25 /* r1 = r4 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ - bpl restore_ns_context /* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ - msr psp, r2 /* Remember the new top of stack for the task. */ - bx lr - #else /* configENABLE_MPU */ ldmia r2!, {r0, r1, r4} /* Read from stack - r0 = xSecureContext, r1 = PSPLIM and r4 = LR. */ msr psplim, r1 /* Restore the PSPLIM register value for the task. */ mov lr, r4 /* LR = r4. */ @@ -350,7 +451,6 @@ PendSV_Handler: bpl restore_ns_context /* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ msr psp, r2 /* Remember the new top of stack for the task. */ bx lr - #endif /* configENABLE_MPU */ restore_ns_context: adds r2, r2, #16 /* Move to the high registers. */ @@ -363,8 +463,45 @@ PendSV_Handler: subs r2, r2, #32 /* Go back to the low registers. */ ldmia r2!, {r4-r7} /* Restore the low registers that are not automatically restored. */ bx lr + +#endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + +SVC_Handler: + movs r0, #4 + mov r1, lr + tst r0, r1 + beq stack_on_msp + stack_on_psp: + mrs r0, psp + b route_svc + stack_on_msp: + mrs r0, msp + b route_svc + + route_svc: + ldr r2, [r0, #24] + subs r2, #2 + ldrb r3, [r2, #0] + cmp r3, #4 /* portSVC_SYSTEM_CALL_ENTER. */ + beq system_call_enter + cmp r3, #5 /* portSVC_SYSTEM_CALL_ENTER_1. */ + beq system_call_enter_1 + cmp r3, #6 /* portSVC_SYSTEM_CALL_EXIT. */ + beq system_call_exit + b vPortSVCHandler_C + + system_call_enter: + b vSystemCallEnter + system_call_enter_1: + b vSystemCallEnter_1 + system_call_exit: + b vSystemCallExit + +#else /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + SVC_Handler: movs r0, #4 mov r1, lr @@ -375,6 +512,8 @@ SVC_Handler: stacking_used_msp: mrs r0, msp b vPortSVCHandler_C + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ /*-----------------------------------------------------------*/ vPortFreeSecureContext: diff --git a/portable/ARMv8M/non_secure/portable/IAR/ARM_CM23_NTZ/mpu_wrappers_v2_asm.S b/portable/ARMv8M/non_secure/portable/IAR/ARM_CM23_NTZ/mpu_wrappers_v2_asm.S new file mode 100644 index 00000000000..867642b5e97 --- /dev/null +++ b/portable/ARMv8M/non_secure/portable/IAR/ARM_CM23_NTZ/mpu_wrappers_v2_asm.S @@ -0,0 +1,1623 @@ +/* + * FreeRTOS Kernel + * Copyright (C) 2021 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 + * + */ + + + SECTION freertos_system_calls:CODE:NOROOT(2) + THUMB +/*-----------------------------------------------------------*/ + +#include "FreeRTOSConfig.h" + +#ifndef configUSE_MPU_WRAPPERS_V1 + #define configUSE_MPU_WRAPPERS_V1 0 +#endif + +/* These must be in sync with portmacro.h. */ +#define portSVC_SYSTEM_CALL_ENTER 4 /* System calls with upto 4 parameters. */ +#define portSVC_SYSTEM_CALL_ENTER_1 5 /* System calls with 5 parameters. */ +#define portSVC_SYSTEM_CALL_EXIT 6 +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + + PUBLIC MPU_xTaskDelayUntil +MPU_xTaskDelayUntil: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xTaskDelayUntil_Unpriv + MPU_xTaskDelayUntil_Priv: + pop {r0, r1} + b MPU_xTaskDelayUntilImpl + MPU_xTaskDelayUntil_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskDelayUntilImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskAbortDelay +MPU_xTaskAbortDelay: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xTaskAbortDelay_Unpriv + MPU_xTaskAbortDelay_Priv: + pop {r0, r1} + b MPU_xTaskAbortDelayImpl + MPU_xTaskAbortDelay_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskAbortDelayImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTaskDelay +MPU_vTaskDelay: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_vTaskDelay_Unpriv + MPU_vTaskDelay_Priv: + pop {r0, r1} + b MPU_vTaskDelayImpl + MPU_vTaskDelay_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskDelayImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxTaskPriorityGet +MPU_uxTaskPriorityGet: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_uxTaskPriorityGet_Unpriv + MPU_uxTaskPriorityGet_Priv: + pop {r0, r1} + b MPU_uxTaskPriorityGetImpl + MPU_uxTaskPriorityGet_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxTaskPriorityGetImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_eTaskGetState +MPU_eTaskGetState: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_eTaskGetState_Unpriv + MPU_eTaskGetState_Priv: + pop {r0, r1} + b MPU_eTaskGetStateImpl + MPU_eTaskGetState_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_eTaskGetStateImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTaskGetInfo +MPU_vTaskGetInfo: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_vTaskGetInfo_Unpriv + MPU_vTaskGetInfo_Priv: + pop {r0, r1} + b MPU_vTaskGetInfoImpl + MPU_vTaskGetInfo_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskGetInfoImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGetIdleTaskHandle +MPU_xTaskGetIdleTaskHandle: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xTaskGetIdleTaskHandle_Unpriv + MPU_xTaskGetIdleTaskHandle_Priv: + pop {r0, r1} + b MPU_xTaskGetIdleTaskHandleImpl + MPU_xTaskGetIdleTaskHandle_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskGetIdleTaskHandleImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTaskSuspend +MPU_vTaskSuspend: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_vTaskSuspend_Unpriv + MPU_vTaskSuspend_Priv: + pop {r0, r1} + b MPU_vTaskSuspendImpl + MPU_vTaskSuspend_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskSuspendImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTaskResume +MPU_vTaskResume: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_vTaskResume_Unpriv + MPU_vTaskResume_Priv: + pop {r0, r1} + b MPU_vTaskResumeImpl + MPU_vTaskResume_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskResumeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGetTickCount +MPU_xTaskGetTickCount: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xTaskGetTickCount_Unpriv + MPU_xTaskGetTickCount_Priv: + pop {r0, r1} + b MPU_xTaskGetTickCountImpl + MPU_xTaskGetTickCount_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskGetTickCountImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxTaskGetNumberOfTasks +MPU_uxTaskGetNumberOfTasks: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_uxTaskGetNumberOfTasks_Unpriv + MPU_uxTaskGetNumberOfTasks_Priv: + pop {r0, r1} + b MPU_uxTaskGetNumberOfTasksImpl + MPU_uxTaskGetNumberOfTasks_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxTaskGetNumberOfTasksImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_pcTaskGetName +MPU_pcTaskGetName: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_pcTaskGetName_Unpriv + MPU_pcTaskGetName_Priv: + pop {r0, r1} + b MPU_pcTaskGetNameImpl + MPU_pcTaskGetName_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_pcTaskGetNameImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_ulTaskGetRunTimeCounter +MPU_ulTaskGetRunTimeCounter: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_ulTaskGetRunTimeCounter_Unpriv + MPU_ulTaskGetRunTimeCounter_Priv: + pop {r0, r1} + b MPU_ulTaskGetRunTimeCounterImpl + MPU_ulTaskGetRunTimeCounter_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_ulTaskGetRunTimeCounterImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_ulTaskGetRunTimePercent +MPU_ulTaskGetRunTimePercent: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_ulTaskGetRunTimePercent_Unpriv + MPU_ulTaskGetRunTimePercent_Priv: + pop {r0, r1} + b MPU_ulTaskGetRunTimePercentImpl + MPU_ulTaskGetRunTimePercent_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_ulTaskGetRunTimePercentImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_ulTaskGetIdleRunTimePercent +MPU_ulTaskGetIdleRunTimePercent: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_ulTaskGetIdleRunTimePercent_Unpriv + MPU_ulTaskGetIdleRunTimePercent_Priv: + pop {r0, r1} + b MPU_ulTaskGetIdleRunTimePercentImpl + MPU_ulTaskGetIdleRunTimePercent_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_ulTaskGetIdleRunTimePercentImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_ulTaskGetIdleRunTimeCounter +MPU_ulTaskGetIdleRunTimeCounter: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_ulTaskGetIdleRunTimeCounter_Unpriv + MPU_ulTaskGetIdleRunTimeCounter_Priv: + pop {r0, r1} + b MPU_ulTaskGetIdleRunTimeCounterImpl + MPU_ulTaskGetIdleRunTimeCounter_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_ulTaskGetIdleRunTimeCounterImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTaskSetApplicationTaskTag +MPU_vTaskSetApplicationTaskTag: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_vTaskSetApplicationTaskTag_Unpriv + MPU_vTaskSetApplicationTaskTag_Priv: + pop {r0, r1} + b MPU_vTaskSetApplicationTaskTagImpl + MPU_vTaskSetApplicationTaskTag_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskSetApplicationTaskTagImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGetApplicationTaskTag +MPU_xTaskGetApplicationTaskTag: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xTaskGetApplicationTaskTag_Unpriv + MPU_xTaskGetApplicationTaskTag_Priv: + pop {r0, r1} + b MPU_xTaskGetApplicationTaskTagImpl + MPU_xTaskGetApplicationTaskTag_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskGetApplicationTaskTagImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTaskSetThreadLocalStoragePointer +MPU_vTaskSetThreadLocalStoragePointer: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_vTaskSetThreadLocalStoragePointer_Unpriv + MPU_vTaskSetThreadLocalStoragePointer_Priv: + pop {r0, r1} + b MPU_vTaskSetThreadLocalStoragePointerImpl + MPU_vTaskSetThreadLocalStoragePointer_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskSetThreadLocalStoragePointerImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_pvTaskGetThreadLocalStoragePointer +MPU_pvTaskGetThreadLocalStoragePointer: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_pvTaskGetThreadLocalStoragePointer_Unpriv + MPU_pvTaskGetThreadLocalStoragePointer_Priv: + pop {r0, r1} + b MPU_pvTaskGetThreadLocalStoragePointerImpl + MPU_pvTaskGetThreadLocalStoragePointer_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_pvTaskGetThreadLocalStoragePointerImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxTaskGetSystemState +MPU_uxTaskGetSystemState: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_uxTaskGetSystemState_Unpriv + MPU_uxTaskGetSystemState_Priv: + pop {r0, r1} + b MPU_uxTaskGetSystemStateImpl + MPU_uxTaskGetSystemState_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxTaskGetSystemStateImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxTaskGetStackHighWaterMark +MPU_uxTaskGetStackHighWaterMark: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_uxTaskGetStackHighWaterMark_Unpriv + MPU_uxTaskGetStackHighWaterMark_Priv: + pop {r0, r1} + b MPU_uxTaskGetStackHighWaterMarkImpl + MPU_uxTaskGetStackHighWaterMark_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxTaskGetStackHighWaterMarkImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxTaskGetStackHighWaterMark2 +MPU_uxTaskGetStackHighWaterMark2: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_uxTaskGetStackHighWaterMark2_Unpriv + MPU_uxTaskGetStackHighWaterMark2_Priv: + pop {r0, r1} + b MPU_uxTaskGetStackHighWaterMark2Impl + MPU_uxTaskGetStackHighWaterMark2_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxTaskGetStackHighWaterMark2Impl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGetCurrentTaskHandle +MPU_xTaskGetCurrentTaskHandle: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xTaskGetCurrentTaskHandle_Unpriv + MPU_xTaskGetCurrentTaskHandle_Priv: + pop {r0, r1} + b MPU_xTaskGetCurrentTaskHandleImpl + MPU_xTaskGetCurrentTaskHandle_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskGetCurrentTaskHandleImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGetSchedulerState +MPU_xTaskGetSchedulerState: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xTaskGetSchedulerState_Unpriv + MPU_xTaskGetSchedulerState_Priv: + pop {r0, r1} + b MPU_xTaskGetSchedulerStateImpl + MPU_xTaskGetSchedulerState_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskGetSchedulerStateImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTaskSetTimeOutState +MPU_vTaskSetTimeOutState: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_vTaskSetTimeOutState_Unpriv + MPU_vTaskSetTimeOutState_Priv: + pop {r0, r1} + b MPU_vTaskSetTimeOutStateImpl + MPU_vTaskSetTimeOutState_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskSetTimeOutStateImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskCheckForTimeOut +MPU_xTaskCheckForTimeOut: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xTaskCheckForTimeOut_Unpriv + MPU_xTaskCheckForTimeOut_Priv: + pop {r0, r1} + b MPU_xTaskCheckForTimeOutImpl + MPU_xTaskCheckForTimeOut_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskCheckForTimeOutImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGenericNotify +MPU_xTaskGenericNotify: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xTaskGenericNotify_Unpriv + MPU_xTaskGenericNotify_Priv: + pop {r0, r1} + b MPU_xTaskGenericNotifyImpl + MPU_xTaskGenericNotify_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER_1 + bl MPU_xTaskGenericNotifyImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGenericNotifyWait +MPU_xTaskGenericNotifyWait: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xTaskGenericNotifyWait_Unpriv + MPU_xTaskGenericNotifyWait_Priv: + pop {r0, r1} + b MPU_xTaskGenericNotifyWaitImpl + MPU_xTaskGenericNotifyWait_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER_1 + bl MPU_xTaskGenericNotifyWaitImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_ulTaskGenericNotifyTake +MPU_ulTaskGenericNotifyTake: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_ulTaskGenericNotifyTake_Unpriv + MPU_ulTaskGenericNotifyTake_Priv: + pop {r0, r1} + b MPU_ulTaskGenericNotifyTakeImpl + MPU_ulTaskGenericNotifyTake_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_ulTaskGenericNotifyTakeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGenericNotifyStateClear +MPU_xTaskGenericNotifyStateClear: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xTaskGenericNotifyStateClear_Unpriv + MPU_xTaskGenericNotifyStateClear_Priv: + pop {r0, r1} + b MPU_xTaskGenericNotifyStateClearImpl + MPU_xTaskGenericNotifyStateClear_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskGenericNotifyStateClearImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_ulTaskGenericNotifyValueClear +MPU_ulTaskGenericNotifyValueClear: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_ulTaskGenericNotifyValueClear_Unpriv + MPU_ulTaskGenericNotifyValueClear_Priv: + pop {r0, r1} + b MPU_ulTaskGenericNotifyValueClearImpl + MPU_ulTaskGenericNotifyValueClear_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_ulTaskGenericNotifyValueClearImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueGenericSend +MPU_xQueueGenericSend: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xQueueGenericSend_Unpriv + MPU_xQueueGenericSend_Priv: + pop {r0, r1} + b MPU_xQueueGenericSendImpl + MPU_xQueueGenericSend_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueGenericSendImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxQueueMessagesWaiting +MPU_uxQueueMessagesWaiting: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_uxQueueMessagesWaiting_Unpriv + MPU_uxQueueMessagesWaiting_Priv: + pop {r0, r1} + b MPU_uxQueueMessagesWaitingImpl + MPU_uxQueueMessagesWaiting_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxQueueMessagesWaitingImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxQueueSpacesAvailable +MPU_uxQueueSpacesAvailable: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_uxQueueSpacesAvailable_Unpriv + MPU_uxQueueSpacesAvailable_Priv: + pop {r0, r1} + b MPU_uxQueueSpacesAvailableImpl + MPU_uxQueueSpacesAvailable_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxQueueSpacesAvailableImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueReceive +MPU_xQueueReceive: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xQueueReceive_Unpriv + MPU_xQueueReceive_Priv: + pop {r0, r1} + b MPU_xQueueReceiveImpl + MPU_xQueueReceive_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueReceiveImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueuePeek +MPU_xQueuePeek: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xQueuePeek_Unpriv + MPU_xQueuePeek_Priv: + pop {r0, r1} + b MPU_xQueuePeekImpl + MPU_xQueuePeek_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueuePeekImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueSemaphoreTake +MPU_xQueueSemaphoreTake: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xQueueSemaphoreTake_Unpriv + MPU_xQueueSemaphoreTake_Priv: + pop {r0, r1} + b MPU_xQueueSemaphoreTakeImpl + MPU_xQueueSemaphoreTake_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueSemaphoreTakeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueGetMutexHolder +MPU_xQueueGetMutexHolder: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xQueueGetMutexHolder_Unpriv + MPU_xQueueGetMutexHolder_Priv: + pop {r0, r1} + b MPU_xQueueGetMutexHolderImpl + MPU_xQueueGetMutexHolder_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueGetMutexHolderImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueTakeMutexRecursive +MPU_xQueueTakeMutexRecursive: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xQueueTakeMutexRecursive_Unpriv + MPU_xQueueTakeMutexRecursive_Priv: + pop {r0, r1} + b MPU_xQueueTakeMutexRecursiveImpl + MPU_xQueueTakeMutexRecursive_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueTakeMutexRecursiveImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueGiveMutexRecursive +MPU_xQueueGiveMutexRecursive: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xQueueGiveMutexRecursive_Unpriv + MPU_xQueueGiveMutexRecursive_Priv: + pop {r0, r1} + b MPU_xQueueGiveMutexRecursiveImpl + MPU_xQueueGiveMutexRecursive_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueGiveMutexRecursiveImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueSelectFromSet +MPU_xQueueSelectFromSet: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xQueueSelectFromSet_Unpriv + MPU_xQueueSelectFromSet_Priv: + pop {r0, r1} + b MPU_xQueueSelectFromSetImpl + MPU_xQueueSelectFromSet_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueSelectFromSetImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueAddToSet +MPU_xQueueAddToSet: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xQueueAddToSet_Unpriv + MPU_xQueueAddToSet_Priv: + pop {r0, r1} + b MPU_xQueueAddToSetImpl + MPU_xQueueAddToSet_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueAddToSetImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vQueueAddToRegistry +MPU_vQueueAddToRegistry: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_vQueueAddToRegistry_Unpriv + MPU_vQueueAddToRegistry_Priv: + pop {r0, r1} + b MPU_vQueueAddToRegistryImpl + MPU_vQueueAddToRegistry_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vQueueAddToRegistryImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vQueueUnregisterQueue +MPU_vQueueUnregisterQueue: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_vQueueUnregisterQueue_Unpriv + MPU_vQueueUnregisterQueue_Priv: + pop {r0, r1} + b MPU_vQueueUnregisterQueueImpl + MPU_vQueueUnregisterQueue_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vQueueUnregisterQueueImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_pcQueueGetName +MPU_pcQueueGetName: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_pcQueueGetName_Unpriv + MPU_pcQueueGetName_Priv: + pop {r0, r1} + b MPU_pcQueueGetNameImpl + MPU_pcQueueGetName_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_pcQueueGetNameImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_pvTimerGetTimerID +MPU_pvTimerGetTimerID: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_pvTimerGetTimerID_Unpriv + MPU_pvTimerGetTimerID_Priv: + pop {r0, r1} + b MPU_pvTimerGetTimerIDImpl + MPU_pvTimerGetTimerID_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_pvTimerGetTimerIDImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTimerSetTimerID +MPU_vTimerSetTimerID: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_vTimerSetTimerID_Unpriv + MPU_vTimerSetTimerID_Priv: + pop {r0, r1} + b MPU_vTimerSetTimerIDImpl + MPU_vTimerSetTimerID_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTimerSetTimerIDImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTimerIsTimerActive +MPU_xTimerIsTimerActive: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xTimerIsTimerActive_Unpriv + MPU_xTimerIsTimerActive_Priv: + pop {r0, r1} + b MPU_xTimerIsTimerActiveImpl + MPU_xTimerIsTimerActive_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTimerIsTimerActiveImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTimerGetTimerDaemonTaskHandle +MPU_xTimerGetTimerDaemonTaskHandle: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xTimerGetTimerDaemonTaskHandle_Unpriv + MPU_xTimerGetTimerDaemonTaskHandle_Priv: + pop {r0, r1} + b MPU_xTimerGetTimerDaemonTaskHandleImpl + MPU_xTimerGetTimerDaemonTaskHandle_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTimerGetTimerDaemonTaskHandleImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTimerGenericCommand +MPU_xTimerGenericCommand: + push {r0, r1} + /* This function can be called from ISR also and therefore, we need a check + * to take privileged path, if called from ISR. */ + mrs r0, ipsr + cmp r0, #0 + bne MPU_xTimerGenericCommand_Priv + mrs r0, control + movs r1, #1 + tst r0, r1 + beq MPU_xTimerGenericCommand_Priv + MPU_xTimerGenericCommand_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER_1 + bl MPU_xTimerGenericCommandImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr + MPU_xTimerGenericCommand_Priv: + pop {r0, r1} + b MPU_xTimerGenericCommandImpl + +/*-----------------------------------------------------------*/ + + PUBLIC MPU_pcTimerGetName +MPU_pcTimerGetName: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_pcTimerGetName_Unpriv + MPU_pcTimerGetName_Priv: + pop {r0, r1} + b MPU_pcTimerGetNameImpl + MPU_pcTimerGetName_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_pcTimerGetNameImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTimerSetReloadMode +MPU_vTimerSetReloadMode: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_vTimerSetReloadMode_Unpriv + MPU_vTimerSetReloadMode_Priv: + pop {r0, r1} + b MPU_vTimerSetReloadModeImpl + MPU_vTimerSetReloadMode_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTimerSetReloadModeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTimerGetReloadMode +MPU_xTimerGetReloadMode: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xTimerGetReloadMode_Unpriv + MPU_xTimerGetReloadMode_Priv: + pop {r0, r1} + b MPU_xTimerGetReloadModeImpl + MPU_xTimerGetReloadMode_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTimerGetReloadModeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxTimerGetReloadMode +MPU_uxTimerGetReloadMode: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_uxTimerGetReloadMode_Unpriv + MPU_uxTimerGetReloadMode_Priv: + pop {r0, r1} + b MPU_uxTimerGetReloadModeImpl + MPU_uxTimerGetReloadMode_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxTimerGetReloadModeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTimerGetPeriod +MPU_xTimerGetPeriod: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xTimerGetPeriod_Unpriv + MPU_xTimerGetPeriod_Priv: + pop {r0, r1} + b MPU_xTimerGetPeriodImpl + MPU_xTimerGetPeriod_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTimerGetPeriodImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTimerGetExpiryTime +MPU_xTimerGetExpiryTime: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xTimerGetExpiryTime_Unpriv + MPU_xTimerGetExpiryTime_Priv: + pop {r0, r1} + b MPU_xTimerGetExpiryTimeImpl + MPU_xTimerGetExpiryTime_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTimerGetExpiryTimeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xEventGroupWaitBits +MPU_xEventGroupWaitBits: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xEventGroupWaitBits_Unpriv + MPU_xEventGroupWaitBits_Priv: + pop {r0, r1} + b MPU_xEventGroupWaitBitsImpl + MPU_xEventGroupWaitBits_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER_1 + bl MPU_xEventGroupWaitBitsImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xEventGroupClearBits +MPU_xEventGroupClearBits: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xEventGroupClearBits_Unpriv + MPU_xEventGroupClearBits_Priv: + pop {r0, r1} + b MPU_xEventGroupClearBitsImpl + MPU_xEventGroupClearBits_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xEventGroupClearBitsImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xEventGroupSetBits +MPU_xEventGroupSetBits: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xEventGroupSetBits_Unpriv + MPU_xEventGroupSetBits_Priv: + pop {r0, r1} + b MPU_xEventGroupSetBitsImpl + MPU_xEventGroupSetBits_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xEventGroupSetBitsImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xEventGroupSync +MPU_xEventGroupSync: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xEventGroupSync_Unpriv + MPU_xEventGroupSync_Priv: + pop {r0, r1} + b MPU_xEventGroupSyncImpl + MPU_xEventGroupSync_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xEventGroupSyncImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxEventGroupGetNumber +MPU_uxEventGroupGetNumber: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_uxEventGroupGetNumber_Unpriv + MPU_uxEventGroupGetNumber_Priv: + pop {r0, r1} + b MPU_uxEventGroupGetNumberImpl + MPU_uxEventGroupGetNumber_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxEventGroupGetNumberImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vEventGroupSetNumber +MPU_vEventGroupSetNumber: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_vEventGroupSetNumber_Unpriv + MPU_vEventGroupSetNumber_Priv: + pop {r0, r1} + b MPU_vEventGroupSetNumberImpl + MPU_vEventGroupSetNumber_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vEventGroupSetNumberImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferSend +MPU_xStreamBufferSend: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xStreamBufferSend_Unpriv + MPU_xStreamBufferSend_Priv: + pop {r0, r1} + b MPU_xStreamBufferSendImpl + MPU_xStreamBufferSend_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferSendImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferReceive +MPU_xStreamBufferReceive: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xStreamBufferReceive_Unpriv + MPU_xStreamBufferReceive_Priv: + pop {r0, r1} + b MPU_xStreamBufferReceiveImpl + MPU_xStreamBufferReceive_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferReceiveImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferIsFull +MPU_xStreamBufferIsFull: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xStreamBufferIsFull_Unpriv + MPU_xStreamBufferIsFull_Priv: + pop {r0, r1} + b MPU_xStreamBufferIsFullImpl + MPU_xStreamBufferIsFull_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferIsFullImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferIsEmpty +MPU_xStreamBufferIsEmpty: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xStreamBufferIsEmpty_Unpriv + MPU_xStreamBufferIsEmpty_Priv: + pop {r0, r1} + b MPU_xStreamBufferIsEmptyImpl + MPU_xStreamBufferIsEmpty_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferIsEmptyImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferSpacesAvailable +MPU_xStreamBufferSpacesAvailable: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xStreamBufferSpacesAvailable_Unpriv + MPU_xStreamBufferSpacesAvailable_Priv: + pop {r0, r1} + b MPU_xStreamBufferSpacesAvailableImpl + MPU_xStreamBufferSpacesAvailable_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferSpacesAvailableImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferBytesAvailable +MPU_xStreamBufferBytesAvailable: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xStreamBufferBytesAvailable_Unpriv + MPU_xStreamBufferBytesAvailable_Priv: + pop {r0, r1} + b MPU_xStreamBufferBytesAvailableImpl + MPU_xStreamBufferBytesAvailable_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferBytesAvailableImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferSetTriggerLevel +MPU_xStreamBufferSetTriggerLevel: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xStreamBufferSetTriggerLevel_Unpriv + MPU_xStreamBufferSetTriggerLevel_Priv: + pop {r0, r1} + b MPU_xStreamBufferSetTriggerLevelImpl + MPU_xStreamBufferSetTriggerLevel_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferSetTriggerLevelImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferNextMessageLengthBytes +MPU_xStreamBufferNextMessageLengthBytes: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xStreamBufferNextMessageLengthBytes_Unpriv + MPU_xStreamBufferNextMessageLengthBytes_Priv: + pop {r0, r1} + b MPU_xStreamBufferNextMessageLengthBytesImpl + MPU_xStreamBufferNextMessageLengthBytes_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferNextMessageLengthBytesImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + +/* Default weak implementations in case one is not available from + * mpu_wrappers because of config options. */ + + PUBWEAK MPU_xTaskDelayUntilImpl +MPU_xTaskDelayUntilImpl: + b MPU_xTaskDelayUntilImpl + + PUBWEAK MPU_xTaskAbortDelayImpl +MPU_xTaskAbortDelayImpl: + b MPU_xTaskAbortDelayImpl + + PUBWEAK MPU_vTaskDelayImpl +MPU_vTaskDelayImpl: + b MPU_vTaskDelayImpl + + PUBWEAK MPU_uxTaskPriorityGetImpl +MPU_uxTaskPriorityGetImpl: + b MPU_uxTaskPriorityGetImpl + + PUBWEAK MPU_eTaskGetStateImpl +MPU_eTaskGetStateImpl: + b MPU_eTaskGetStateImpl + + PUBWEAK MPU_vTaskGetInfoImpl +MPU_vTaskGetInfoImpl: + b MPU_vTaskGetInfoImpl + + PUBWEAK MPU_xTaskGetIdleTaskHandleImpl +MPU_xTaskGetIdleTaskHandleImpl: + b MPU_xTaskGetIdleTaskHandleImpl + + PUBWEAK MPU_vTaskSuspendImpl +MPU_vTaskSuspendImpl: + b MPU_vTaskSuspendImpl + + PUBWEAK MPU_vTaskResumeImpl +MPU_vTaskResumeImpl: + b MPU_vTaskResumeImpl + + PUBWEAK MPU_xTaskGetTickCountImpl +MPU_xTaskGetTickCountImpl: + b MPU_xTaskGetTickCountImpl + + PUBWEAK MPU_uxTaskGetNumberOfTasksImpl +MPU_uxTaskGetNumberOfTasksImpl: + b MPU_uxTaskGetNumberOfTasksImpl + + PUBWEAK MPU_pcTaskGetNameImpl +MPU_pcTaskGetNameImpl: + b MPU_pcTaskGetNameImpl + + PUBWEAK MPU_ulTaskGetRunTimeCounterImpl +MPU_ulTaskGetRunTimeCounterImpl: + b MPU_ulTaskGetRunTimeCounterImpl + + PUBWEAK MPU_ulTaskGetRunTimePercentImpl +MPU_ulTaskGetRunTimePercentImpl: + b MPU_ulTaskGetRunTimePercentImpl + + PUBWEAK MPU_ulTaskGetIdleRunTimePercentImpl +MPU_ulTaskGetIdleRunTimePercentImpl: + b MPU_ulTaskGetIdleRunTimePercentImpl + + PUBWEAK MPU_ulTaskGetIdleRunTimeCounterImpl +MPU_ulTaskGetIdleRunTimeCounterImpl: + b MPU_ulTaskGetIdleRunTimeCounterImpl + + PUBWEAK MPU_vTaskSetApplicationTaskTagImpl +MPU_vTaskSetApplicationTaskTagImpl: + b MPU_vTaskSetApplicationTaskTagImpl + + PUBWEAK MPU_xTaskGetApplicationTaskTagImpl +MPU_xTaskGetApplicationTaskTagImpl: + b MPU_xTaskGetApplicationTaskTagImpl + + PUBWEAK MPU_vTaskSetThreadLocalStoragePointerImpl +MPU_vTaskSetThreadLocalStoragePointerImpl: + b MPU_vTaskSetThreadLocalStoragePointerImpl + + PUBWEAK MPU_pvTaskGetThreadLocalStoragePointerImpl +MPU_pvTaskGetThreadLocalStoragePointerImpl: + b MPU_pvTaskGetThreadLocalStoragePointerImpl + + PUBWEAK MPU_uxTaskGetSystemStateImpl +MPU_uxTaskGetSystemStateImpl: + b MPU_uxTaskGetSystemStateImpl + + PUBWEAK MPU_uxTaskGetStackHighWaterMarkImpl +MPU_uxTaskGetStackHighWaterMarkImpl: + b MPU_uxTaskGetStackHighWaterMarkImpl + + PUBWEAK MPU_uxTaskGetStackHighWaterMark2Impl +MPU_uxTaskGetStackHighWaterMark2Impl: + b MPU_uxTaskGetStackHighWaterMark2Impl + + PUBWEAK MPU_xTaskGetCurrentTaskHandleImpl +MPU_xTaskGetCurrentTaskHandleImpl: + b MPU_xTaskGetCurrentTaskHandleImpl + + PUBWEAK MPU_xTaskGetSchedulerStateImpl +MPU_xTaskGetSchedulerStateImpl: + b MPU_xTaskGetSchedulerStateImpl + + PUBWEAK MPU_vTaskSetTimeOutStateImpl +MPU_vTaskSetTimeOutStateImpl: + b MPU_vTaskSetTimeOutStateImpl + + PUBWEAK MPU_xTaskCheckForTimeOutImpl +MPU_xTaskCheckForTimeOutImpl: + b MPU_xTaskCheckForTimeOutImpl + + PUBWEAK MPU_xTaskGenericNotifyImpl +MPU_xTaskGenericNotifyImpl: + b MPU_xTaskGenericNotifyImpl + + PUBWEAK MPU_xTaskGenericNotifyWaitImpl +MPU_xTaskGenericNotifyWaitImpl: + b MPU_xTaskGenericNotifyWaitImpl + + PUBWEAK MPU_ulTaskGenericNotifyTakeImpl +MPU_ulTaskGenericNotifyTakeImpl: + b MPU_ulTaskGenericNotifyTakeImpl + + PUBWEAK MPU_xTaskGenericNotifyStateClearImpl +MPU_xTaskGenericNotifyStateClearImpl: + b MPU_xTaskGenericNotifyStateClearImpl + + PUBWEAK MPU_ulTaskGenericNotifyValueClearImpl +MPU_ulTaskGenericNotifyValueClearImpl: + b MPU_ulTaskGenericNotifyValueClearImpl + + PUBWEAK MPU_xQueueGenericSendImpl +MPU_xQueueGenericSendImpl: + b MPU_xQueueGenericSendImpl + + PUBWEAK MPU_uxQueueMessagesWaitingImpl +MPU_uxQueueMessagesWaitingImpl: + b MPU_uxQueueMessagesWaitingImpl + + PUBWEAK MPU_uxQueueSpacesAvailableImpl +MPU_uxQueueSpacesAvailableImpl: + b MPU_uxQueueSpacesAvailableImpl + + PUBWEAK MPU_xQueueReceiveImpl +MPU_xQueueReceiveImpl: + b MPU_xQueueReceiveImpl + + PUBWEAK MPU_xQueuePeekImpl +MPU_xQueuePeekImpl: + b MPU_xQueuePeekImpl + + PUBWEAK MPU_xQueueSemaphoreTakeImpl +MPU_xQueueSemaphoreTakeImpl: + b MPU_xQueueSemaphoreTakeImpl + + PUBWEAK MPU_xQueueGetMutexHolderImpl +MPU_xQueueGetMutexHolderImpl: + b MPU_xQueueGetMutexHolderImpl + + PUBWEAK MPU_xQueueTakeMutexRecursiveImpl +MPU_xQueueTakeMutexRecursiveImpl: + b MPU_xQueueTakeMutexRecursiveImpl + + PUBWEAK MPU_xQueueGiveMutexRecursiveImpl +MPU_xQueueGiveMutexRecursiveImpl: + b MPU_xQueueGiveMutexRecursiveImpl + + PUBWEAK MPU_xQueueSelectFromSetImpl +MPU_xQueueSelectFromSetImpl: + b MPU_xQueueSelectFromSetImpl + + PUBWEAK MPU_xQueueAddToSetImpl +MPU_xQueueAddToSetImpl: + b MPU_xQueueAddToSetImpl + + PUBWEAK MPU_vQueueAddToRegistryImpl +MPU_vQueueAddToRegistryImpl: + b MPU_vQueueAddToRegistryImpl + + PUBWEAK MPU_vQueueUnregisterQueueImpl +MPU_vQueueUnregisterQueueImpl: + b MPU_vQueueUnregisterQueueImpl + + PUBWEAK MPU_pcQueueGetNameImpl +MPU_pcQueueGetNameImpl: + b MPU_pcQueueGetNameImpl + + PUBWEAK MPU_pvTimerGetTimerIDImpl +MPU_pvTimerGetTimerIDImpl: + b MPU_pvTimerGetTimerIDImpl + + PUBWEAK MPU_vTimerSetTimerIDImpl +MPU_vTimerSetTimerIDImpl: + b MPU_vTimerSetTimerIDImpl + + PUBWEAK MPU_xTimerIsTimerActiveImpl +MPU_xTimerIsTimerActiveImpl: + b MPU_xTimerIsTimerActiveImpl + + PUBWEAK MPU_xTimerGetTimerDaemonTaskHandleImpl +MPU_xTimerGetTimerDaemonTaskHandleImpl: + b MPU_xTimerGetTimerDaemonTaskHandleImpl + + PUBWEAK MPU_xTimerGenericCommandImpl +MPU_xTimerGenericCommandImpl: + b MPU_xTimerGenericCommandImpl + + PUBWEAK MPU_pcTimerGetNameImpl +MPU_pcTimerGetNameImpl: + b MPU_pcTimerGetNameImpl + + PUBWEAK MPU_vTimerSetReloadModeImpl +MPU_vTimerSetReloadModeImpl: + b MPU_vTimerSetReloadModeImpl + + PUBWEAK MPU_xTimerGetReloadModeImpl +MPU_xTimerGetReloadModeImpl: + b MPU_xTimerGetReloadModeImpl + + PUBWEAK MPU_uxTimerGetReloadModeImpl +MPU_uxTimerGetReloadModeImpl: + b MPU_uxTimerGetReloadModeImpl + + PUBWEAK MPU_xTimerGetPeriodImpl +MPU_xTimerGetPeriodImpl: + b MPU_xTimerGetPeriodImpl + + PUBWEAK MPU_xTimerGetExpiryTimeImpl +MPU_xTimerGetExpiryTimeImpl: + b MPU_xTimerGetExpiryTimeImpl + + PUBWEAK MPU_xEventGroupWaitBitsImpl +MPU_xEventGroupWaitBitsImpl: + b MPU_xEventGroupWaitBitsImpl + + PUBWEAK MPU_xEventGroupClearBitsImpl +MPU_xEventGroupClearBitsImpl: + b MPU_xEventGroupClearBitsImpl + + PUBWEAK MPU_xEventGroupSetBitsImpl +MPU_xEventGroupSetBitsImpl: + b MPU_xEventGroupSetBitsImpl + + PUBWEAK MPU_xEventGroupSyncImpl +MPU_xEventGroupSyncImpl: + b MPU_xEventGroupSyncImpl + + PUBWEAK MPU_uxEventGroupGetNumberImpl +MPU_uxEventGroupGetNumberImpl: + b MPU_uxEventGroupGetNumberImpl + + PUBWEAK MPU_vEventGroupSetNumberImpl +MPU_vEventGroupSetNumberImpl: + b MPU_vEventGroupSetNumberImpl + + PUBWEAK MPU_xStreamBufferSendImpl +MPU_xStreamBufferSendImpl: + b MPU_xStreamBufferSendImpl + + PUBWEAK MPU_xStreamBufferReceiveImpl +MPU_xStreamBufferReceiveImpl: + b MPU_xStreamBufferReceiveImpl + + PUBWEAK MPU_xStreamBufferIsFullImpl +MPU_xStreamBufferIsFullImpl: + b MPU_xStreamBufferIsFullImpl + + PUBWEAK MPU_xStreamBufferIsEmptyImpl +MPU_xStreamBufferIsEmptyImpl: + b MPU_xStreamBufferIsEmptyImpl + + PUBWEAK MPU_xStreamBufferSpacesAvailableImpl +MPU_xStreamBufferSpacesAvailableImpl: + b MPU_xStreamBufferSpacesAvailableImpl + + PUBWEAK MPU_xStreamBufferBytesAvailableImpl +MPU_xStreamBufferBytesAvailableImpl: + b MPU_xStreamBufferBytesAvailableImpl + + PUBWEAK MPU_xStreamBufferSetTriggerLevelImpl +MPU_xStreamBufferSetTriggerLevelImpl: + b MPU_xStreamBufferSetTriggerLevelImpl + + PUBWEAK MPU_xStreamBufferNextMessageLengthBytesImpl +MPU_xStreamBufferNextMessageLengthBytesImpl: + b MPU_xStreamBufferNextMessageLengthBytesImpl + +/*-----------------------------------------------------------*/ + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + + END diff --git a/portable/ARMv8M/non_secure/portable/IAR/ARM_CM23_NTZ/portasm.s b/portable/ARMv8M/non_secure/portable/IAR/ARM_CM23_NTZ/portasm.s index 62bd3872284..8f77c4dafb1 100644 --- a/portable/ARMv8M/non_secure/portable/IAR/ARM_CM23_NTZ/portasm.s +++ b/portable/ARMv8M/non_secure/portable/IAR/ARM_CM23_NTZ/portasm.s @@ -32,9 +32,18 @@ the code is included in C files but excluded by the preprocessor in assembly files (__ICCARM__ is defined by the IAR C compiler but not by the IAR assembler. */ #include "FreeRTOSConfig.h" +#ifndef configUSE_MPU_WRAPPERS_V1 + #define configUSE_MPU_WRAPPERS_V1 0 +#endif + EXTERN pxCurrentTCB EXTERN vTaskSwitchContext EXTERN vPortSVCHandler_C +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + EXTERN vSystemCallEnter + EXTERN vSystemCallEnter_1 + EXTERN vSystemCallExit +#endif PUBLIC xIsPrivileged PUBLIC vResetPrivilege @@ -88,63 +97,97 @@ vResetPrivilege: THUMB /*-----------------------------------------------------------*/ +#if ( configENABLE_MPU == 1 ) + +vRestoreContextOfFirstTask: + program_mpu_first_task: + ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + ldr r0, [r3] /* r0 = pxCurrentTCB.*/ + + dmb /* Complete outstanding transfers before disabling MPU. */ + ldr r1, =0xe000ed94 /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + ldr r2, [r1] /* Read the value of MPU_CTRL. */ + movs r3, #1 /* r3 = 1. */ + bics r2, r3 /* r2 = r2 & ~r3 i.e. Clear the bit 0 in r2. */ + str r2, [r1] /* Disable MPU. */ + + adds r0, #4 /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */ + ldr r1, [r0] /* r1 = *r0 i.e. r1 = MAIR0. */ + ldr r2, =0xe000edc0 /* r2 = 0xe000edc0 [Location of MAIR0]. */ + str r1, [r2] /* Program MAIR0. */ + + adds r0, #4 /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */ + ldr r1, =0xe000ed98 /* r1 = 0xe000ed98 [Location of RNR]. */ + + movs r3, #4 /* r3 = 4. */ + str r3, [r1] /* Program RNR = 4. */ + ldmia r0!, {r4-r5} /* Read first set of RBAR/RLAR registers from TCB. */ + ldr r2, =0xe000ed9c /* r2 = 0xe000ed9c [Location of RBAR]. */ + stmia r2!, {r4-r5} /* Write first set of RBAR/RLAR registers. */ + movs r3, #5 /* r3 = 5. */ + str r3, [r1] /* Program RNR = 5. */ + ldmia r0!, {r4-r5} /* Read second set of RBAR/RLAR registers from TCB. */ + ldr r2, =0xe000ed9c /* r2 = 0xe000ed9c [Location of RBAR]. */ + stmia r2!, {r4-r5} /* Write second set of RBAR/RLAR registers. */ + movs r3, #6 /* r3 = 6. */ + str r3, [r1] /* Program RNR = 6. */ + ldmia r0!, {r4-r5} /* Read third set of RBAR/RLAR registers from TCB. */ + ldr r2, =0xe000ed9c /* r2 = 0xe000ed9c [Location of RBAR]. */ + stmia r2!, {r4-r5} /* Write third set of RBAR/RLAR registers. */ + movs r3, #7 /* r3 = 6. */ + str r3, [r1] /* Program RNR = 7. */ + ldmia r0!, {r4-r5} /* Read fourth set of RBAR/RLAR registers from TCB. */ + ldr r2, =0xe000ed9c /* r2 = 0xe000ed9c [Location of RBAR]. */ + stmia r2!, {r4-r5} /* Write fourth set of RBAR/RLAR registers. */ + + ldr r1, =0xe000ed94 /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + ldr r2, [r1] /* Read the value of MPU_CTRL. */ + movs r3, #1 /* r3 = 1. */ + orrs r2, r3 /* r2 = r2 | r3 i.e. Set the bit 0 in r2. */ + str r2, [r1] /* Enable MPU. */ + dsb /* Force memory writes before continuing. */ + + restore_context_first_task: + ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + ldr r0, [r2] /* r0 = pxCurrentTCB.*/ + ldr r1, [r0] /* r1 = Location of saved context in TCB. */ + + restore_special_regs_first_task: + subs r1, #16 + ldmia r1!, {r2-r5} /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, r5 = LR. */ + subs r1, #16 + msr psp, r2 + msr psplim, r3 + msr control, r4 + mov lr, r5 + + restore_general_regs_first_task: + subs r1, #32 + ldmia r1!, {r4-r7} /* r4-r7 contain half of the hardware saved context. */ + stmia r2!, {r4-r7} /* Copy half of the the hardware saved context on the task stack. */ + ldmia r1!, {r4-r7} /* r4-r7 contain rest half of the hardware saved context. */ + stmia r2!, {r4-r7} /* Copy rest half of the the hardware saved context on the task stack. */ + subs r1, #48 + ldmia r1!, {r4-r7} /* Restore r8-r11. */ + mov r8, r4 /* r8 = r4. */ + mov r9, r5 /* r9 = r5. */ + mov r10, r6 /* r10 = r6. */ + mov r11, r7 /* r11 = r7. */ + subs r1, #32 + ldmia r1!, {r4-r7} /* Restore r4-r7. */ + subs r1, #16 + + restore_context_done_first_task: + str r1, [r0] /* Save the location where the context should be saved next as the first member of TCB. */ + bx lr + +#else /* configENABLE_MPU */ + vRestoreContextOfFirstTask: ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r2] /* Read pxCurrentTCB. */ ldr r0, [r1] /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ -#if ( configENABLE_MPU == 1 ) - dmb /* Complete outstanding transfers before disabling MPU. */ - ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ - ldr r3, [r2] /* Read the value of MPU_CTRL. */ - movs r4, #1 /* r4 = 1. */ - bics r3, r4 /* r3 = r3 & ~r4 i.e. Clear the bit 0 in r3. */ - str r3, [r2] /* Disable MPU. */ - - adds r1, #4 /* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */ - ldr r4, [r1] /* r4 = *r1 i.e. r4 = MAIR0. */ - ldr r2, =0xe000edc0 /* r2 = 0xe000edc0 [Location of MAIR0]. */ - str r4, [r2] /* Program MAIR0. */ - ldr r2, =0xe000ed98 /* r2 = 0xe000ed98 [Location of RNR]. */ - adds r1, #4 /* r1 = r1 + 4. r1 now points to first RBAR in TCB. */ - movs r4, #4 /* r4 = 4. */ - str r4, [r2] /* Program RNR = 4. */ - ldmia r1!, {r5,r6} /* Read first set of RBAR/RLAR from TCB. */ - ldr r3, =0xe000ed9c /* r3 = 0xe000ed9c [Location of RBAR]. */ - stmia r3!, {r5,r6} /* Write first set of RBAR/RLAR registers. */ - movs r4, #5 /* r4 = 5. */ - str r4, [r2] /* Program RNR = 5. */ - ldmia r1!, {r5,r6} /* Read second set of RBAR/RLAR from TCB. */ - ldr r3, =0xe000ed9c /* r3 = 0xe000ed9c [Location of RBAR]. */ - stmia r3!, {r5,r6} /* Write second set of RBAR/RLAR registers. */ - movs r4, #6 /* r4 = 6. */ - str r4, [r2] /* Program RNR = 6. */ - ldmia r1!, {r5,r6} /* Read third set of RBAR/RLAR from TCB. */ - ldr r3, =0xe000ed9c /* r3 = 0xe000ed9c [Location of RBAR]. */ - stmia r3!, {r5,r6} /* Write third set of RBAR/RLAR registers. */ - movs r4, #7 /* r4 = 7. */ - str r4, [r2] /* Program RNR = 7. */ - ldmia r1!, {r5,r6} /* Read fourth set of RBAR/RLAR from TCB. */ - ldr r3, =0xe000ed9c /* r3 = 0xe000ed9c [Location of RBAR]. */ - stmia r3!, {r5,r6} /* Write fourth set of RBAR/RLAR registers. */ - - ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ - ldr r3, [r2] /* Read the value of MPU_CTRL. */ - movs r4, #1 /* r4 = 1. */ - orrs r3, r4 /* r3 = r3 | r4 i.e. Set the bit 0 in r3. */ - str r3, [r2] /* Enable MPU. */ - dsb /* Force memory writes before continuing. */ -#endif /* configENABLE_MPU */ - -#if ( configENABLE_MPU == 1 ) - ldm r0!, {r1-r3} /* Read from stack - r1 = PSPLIM, r2 = CONTROL and r3 = EXC_RETURN. */ - msr psplim, r1 /* Set this task's PSPLIM value. */ - msr control, r2 /* Set this task's CONTROL value. */ - adds r0, #32 /* Discard everything up to r0. */ - msr psp, r0 /* This is now the new top of stack to use in the task. */ - isb - bx r3 /* Finally, branch to EXC_RETURN. */ -#else /* configENABLE_MPU */ ldm r0!, {r1-r2} /* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */ msr psplim, r1 /* Set this task's PSPLIM value. */ movs r1, #2 /* r1 = 2. */ @@ -153,6 +196,7 @@ vRestoreContextOfFirstTask: msr psp, r0 /* This is now the new top of stack to use in the task. */ isb bx r2 /* Finally, branch to EXC_RETURN. */ + #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ @@ -187,23 +231,127 @@ vClearInterruptMask: bx lr /*-----------------------------------------------------------*/ +#if ( configENABLE_MPU == 1 ) + +PendSV_Handler: + ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + ldr r0, [r2] /* r0 = pxCurrentTCB. */ + ldr r1, [r0] /* r1 = Location in TCB where the context should be saved. */ + mrs r2, psp /* r2 = PSP. */ + + save_general_regs: + stmia r1!, {r4-r7} /* Store r4-r7. */ + mov r4, r8 /* r4 = r8. */ + mov r5, r9 /* r5 = r9. */ + mov r6, r10 /* r6 = r10. */ + mov r7, r11 /* r7 = r11. */ + stmia r1!, {r4-r7} /* Store r8-r11. */ + ldmia r2!, {r4-r7} /* Copy half of the hardware saved context into r4-r7. */ + stmia r1!, {r4-r7} /* Store the hardware saved context. */ + ldmia r2!, {r4-r7} /* Copy rest half of the hardware saved context into r4-r7. */ + stmia r1!, {r4-r7} /* Store the hardware saved context. */ + + save_special_regs: + mrs r2, psp /* r2 = PSP. */ + mrs r3, psplim /* r3 = PSPLIM. */ + mrs r4, control /* r4 = CONTROL. */ + mov r5, lr /* r5 = LR. */ + stmia r1!, {r2-r5} /* Store original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */ + str r1, [r0] /* Save the location from where the context should be restored as the first member of TCB. */ + + select_next_task: + cpsid i + bl vTaskSwitchContext + cpsie i + + program_mpu: + ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + ldr r0, [r3] /* r0 = pxCurrentTCB.*/ + + dmb /* Complete outstanding transfers before disabling MPU. */ + ldr r1, =0xe000ed94 /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + ldr r2, [r1] /* Read the value of MPU_CTRL. */ + movs r3, #1 /* r3 = 1. */ + bics r2, r3 /* r2 = r2 & ~r3 i.e. Clear the bit 0 in r2. */ + str r2, [r1] /* Disable MPU. */ + + adds r0, #4 /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */ + ldr r1, [r0] /* r1 = *r0 i.e. r1 = MAIR0. */ + ldr r2, =0xe000edc0 /* r2 = 0xe000edc0 [Location of MAIR0]. */ + str r1, [r2] /* Program MAIR0. */ + + adds r0, #4 /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */ + ldr r1, =0xe000ed98 /* r1 = 0xe000ed98 [Location of RNR]. */ + + movs r3, #4 /* r3 = 4. */ + str r3, [r1] /* Program RNR = 4. */ + ldmia r0!, {r4-r5} /* Read first set of RBAR/RLAR registers from TCB. */ + ldr r2, =0xe000ed9c /* r2 = 0xe000ed9c [Location of RBAR]. */ + stmia r2!, {r4-r5} /* Write first set of RBAR/RLAR registers. */ + movs r3, #5 /* r3 = 5. */ + str r3, [r1] /* Program RNR = 5. */ + ldmia r0!, {r4-r5} /* Read second set of RBAR/RLAR registers from TCB. */ + ldr r2, =0xe000ed9c /* r2 = 0xe000ed9c [Location of RBAR]. */ + stmia r2!, {r4-r5} /* Write second set of RBAR/RLAR registers. */ + movs r3, #6 /* r3 = 6. */ + str r3, [r1] /* Program RNR = 6. */ + ldmia r0!, {r4-r5} /* Read third set of RBAR/RLAR registers from TCB. */ + ldr r2, =0xe000ed9c /* r2 = 0xe000ed9c [Location of RBAR]. */ + stmia r2!, {r4-r5} /* Write third set of RBAR/RLAR registers. */ + movs r3, #7 /* r3 = 6. */ + str r3, [r1] /* Program RNR = 7. */ + ldmia r0!, {r4-r5} /* Read fourth set of RBAR/RLAR registers from TCB. */ + ldr r2, =0xe000ed9c /* r2 = 0xe000ed9c [Location of RBAR]. */ + stmia r2!, {r4-r5} /* Write fourth set of RBAR/RLAR registers. */ + + ldr r1, =0xe000ed94 /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + ldr r2, [r1] /* Read the value of MPU_CTRL. */ + movs r3, #1 /* r3 = 1. */ + orrs r2, r3 /* r2 = r2 | r3 i.e. Set the bit 0 in r2. */ + str r2, [r1] /* Enable MPU. */ + dsb /* Force memory writes before continuing. */ + + restore_context: + ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + ldr r0, [r2] /* r0 = pxCurrentTCB.*/ + ldr r1, [r0] /* r1 = Location of saved context in TCB. */ + + restore_special_regs: + subs r1, #16 + ldmia r1!, {r2-r5} /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, r5 = LR. */ + subs r1, #16 + msr psp, r2 + msr psplim, r3 + msr control, r4 + mov lr, r5 + + restore_general_regs: + subs r1, #32 + ldmia r1!, {r4-r7} /* r4-r7 contain half of the hardware saved context. */ + stmia r2!, {r4-r7} /* Copy half of the the hardware saved context on the task stack. */ + ldmia r1!, {r4-r7} /* r4-r7 contain rest half of the hardware saved context. */ + stmia r2!, {r4-r7} /* Copy rest half of the the hardware saved context on the task stack. */ + subs r1, #48 + ldmia r1!, {r4-r7} /* Restore r8-r11. */ + mov r8, r4 /* r8 = r4. */ + mov r9, r5 /* r9 = r5. */ + mov r10, r6 /* r10 = r6. */ + mov r11, r7 /* r11 = r7. */ + subs r1, #32 + ldmia r1!, {r4-r7} /* Restore r4-r7. */ + subs r1, #16 + + restore_context_done: + str r1, [r0] /* Save the location where the context should be saved next as the first member of TCB. */ + bx lr + +#else /* configENABLE_MPU */ + PendSV_Handler: mrs r0, psp /* Read PSP in r0. */ ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r2] /* Read pxCurrentTCB. */ -#if ( configENABLE_MPU == 1 ) - subs r0, r0, #44 /* Make space for PSPLIM, CONTROL, LR and the remaining registers on the stack. */ - str r0, [r1] /* Save the new top of stack in TCB. */ - mrs r1, psplim /* r1 = PSPLIM. */ - mrs r2, control /* r2 = CONTROL. */ - mov r3, lr /* r3 = LR/EXC_RETURN. */ - stmia r0!, {r1-r7} /* Store on the stack - PSPLIM, CONTROL, LR and low registers that are not automatically saved. */ - mov r4, r8 /* r4 = r8. */ - mov r5, r9 /* r5 = r9. */ - mov r6, r10 /* r6 = r10. */ - mov r7, r11 /* r7 = r11. */ - stmia r0!, {r4-r7} /* Store the high registers that are not saved automatically. */ -#else /* configENABLE_MPU */ + subs r0, r0, #40 /* Make space for PSPLIM, LR and the remaining registers on the stack. */ str r0, [r1] /* Save the new top of stack in TCB. */ mrs r2, psplim /* r2 = PSPLIM. */ @@ -214,7 +362,6 @@ PendSV_Handler: mov r6, r10 /* r6 = r10. */ mov r7, r11 /* r7 = r11. */ stmia r0!, {r4-r7} /* Store the high registers that are not saved automatically. */ -#endif /* configENABLE_MPU */ cpsid i bl vTaskSwitchContext @@ -224,63 +371,6 @@ PendSV_Handler: ldr r1, [r2] /* Read pxCurrentTCB. */ ldr r0, [r1] /* The first item in pxCurrentTCB is the task top of stack. r0 now points to the top of stack. */ -#if ( configENABLE_MPU == 1 ) - dmb /* Complete outstanding transfers before disabling MPU. */ - ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ - ldr r3, [r2] /* Read the value of MPU_CTRL. */ - movs r4, #1 /* r4 = 1. */ - bics r3, r4 /* r3 = r3 & ~r4 i.e. Clear the bit 0 in r3. */ - str r3, [r2] /* Disable MPU. */ - - adds r1, #4 /* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */ - ldr r4, [r1] /* r4 = *r1 i.e. r4 = MAIR0. */ - ldr r2, =0xe000edc0 /* r2 = 0xe000edc0 [Location of MAIR0]. */ - str r4, [r2] /* Program MAIR0. */ - ldr r2, =0xe000ed98 /* r2 = 0xe000ed98 [Location of RNR]. */ - adds r1, #4 /* r1 = r1 + 4. r1 now points to first RBAR in TCB. */ - movs r4, #4 /* r4 = 4. */ - str r4, [r2] /* Program RNR = 4. */ - ldmia r1!, {r5,r6} /* Read first set of RBAR/RLAR from TCB. */ - ldr r3, =0xe000ed9c /* r3 = 0xe000ed9c [Location of RBAR]. */ - stmia r3!, {r5,r6} /* Write first set of RBAR/RLAR registers. */ - movs r4, #5 /* r4 = 5. */ - str r4, [r2] /* Program RNR = 5. */ - ldmia r1!, {r5,r6} /* Read second set of RBAR/RLAR from TCB. */ - ldr r3, =0xe000ed9c /* r3 = 0xe000ed9c [Location of RBAR]. */ - stmia r3!, {r5,r6} /* Write second set of RBAR/RLAR registers. */ - movs r4, #6 /* r4 = 6. */ - str r4, [r2] /* Program RNR = 6. */ - ldmia r1!, {r5,r6} /* Read third set of RBAR/RLAR from TCB. */ - ldr r3, =0xe000ed9c /* r3 = 0xe000ed9c [Location of RBAR]. */ - stmia r3!, {r5,r6} /* Write third set of RBAR/RLAR registers. */ - movs r4, #7 /* r4 = 7. */ - str r4, [r2] /* Program RNR = 7. */ - ldmia r1!, {r5,r6} /* Read fourth set of RBAR/RLAR from TCB. */ - ldr r3, =0xe000ed9c /* r3 = 0xe000ed9c [Location of RBAR]. */ - stmia r3!, {r5,r6} /* Write fourth set of RBAR/RLAR registers. */ - - ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ - ldr r3, [r2] /* Read the value of MPU_CTRL. */ - movs r4, #1 /* r4 = 1. */ - orrs r3, r4 /* r3 = r3 | r4 i.e. Set the bit 0 in r3. */ - str r3, [r2] /* Enable MPU. */ - dsb /* Force memory writes before continuing. */ -#endif /* configENABLE_MPU */ - -#if ( configENABLE_MPU == 1 ) - adds r0, r0, #28 /* Move to the high registers. */ - ldmia r0!, {r4-r7} /* Restore the high registers that are not automatically restored. */ - mov r8, r4 /* r8 = r4. */ - mov r9, r5 /* r9 = r5. */ - mov r10, r6 /* r10 = r6. */ - mov r11, r7 /* r11 = r7. */ - msr psp, r0 /* Remember the new top of stack for the task. */ - subs r0, r0, #44 /* Move to the starting of the saved context. */ - ldmia r0!, {r1-r7} /* Read from stack - r1 = PSPLIM, r2 = CONTROL, r3 = LR and r4-r7 restored. */ - msr psplim, r1 /* Restore the PSPLIM register value for the task. */ - msr control, r2 /* Restore the CONTROL register value for the task. */ - bx r3 -#else /* configENABLE_MPU */ adds r0, r0, #24 /* Move to the high registers. */ ldmia r0!, {r4-r7} /* Restore the high registers that are not automatically restored. */ mov r8, r4 /* r8 = r4. */ @@ -292,9 +382,45 @@ PendSV_Handler: ldmia r0!, {r2-r7} /* Read from stack - r2 = PSPLIM, r3 = LR and r4-r7 restored. */ msr psplim, r2 /* Restore the PSPLIM register value for the task. */ bx r3 + #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + +SVC_Handler: + movs r0, #4 + mov r1, lr + tst r0, r1 + beq stack_on_msp + stack_on_psp: + mrs r0, psp + b route_svc + stack_on_msp: + mrs r0, msp + b route_svc + + route_svc: + ldr r2, [r0, #24] + subs r2, #2 + ldrb r3, [r2, #0] + cmp r3, #4 /* portSVC_SYSTEM_CALL_ENTER. */ + beq system_call_enter + cmp r3, #5 /* portSVC_SYSTEM_CALL_ENTER_1. */ + beq system_call_enter_1 + cmp r3, #6 /* portSVC_SYSTEM_CALL_EXIT. */ + beq system_call_exit + b vPortSVCHandler_C + + system_call_enter: + b vSystemCallEnter + system_call_enter_1: + b vSystemCallEnter_1 + system_call_exit: + b vSystemCallExit + +#else /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + SVC_Handler: movs r0, #4 mov r1, lr @@ -305,6 +431,8 @@ SVC_Handler: stacking_used_msp: mrs r0, msp b vPortSVCHandler_C + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ /*-----------------------------------------------------------*/ END diff --git a/portable/ARMv8M/non_secure/portable/IAR/ARM_CM33/mpu_wrappers_v2_asm.S b/portable/ARMv8M/non_secure/portable/IAR/ARM_CM33/mpu_wrappers_v2_asm.S new file mode 100644 index 00000000000..f051a6073dd --- /dev/null +++ b/portable/ARMv8M/non_secure/portable/IAR/ARM_CM33/mpu_wrappers_v2_asm.S @@ -0,0 +1,1552 @@ +/* + * FreeRTOS Kernel + * Copyright (C) 2021 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 + * + */ + + + SECTION freertos_system_calls:CODE:NOROOT(2) + THUMB +/*-----------------------------------------------------------*/ + +#include "FreeRTOSConfig.h" + +#ifndef configUSE_MPU_WRAPPERS_V1 + #define configUSE_MPU_WRAPPERS_V1 0 +#endif + +/* These must be in sync with portmacro.h. */ +#define portSVC_SYSTEM_CALL_ENTER 4 /* System calls with upto 4 parameters. */ +#define portSVC_SYSTEM_CALL_ENTER_1 5 /* System calls with 5 parameters. */ +#define portSVC_SYSTEM_CALL_EXIT 6 +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + + PUBLIC MPU_xTaskDelayUntil +MPU_xTaskDelayUntil: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskDelayUntil_Unpriv + MPU_xTaskDelayUntil_Priv: + pop {r0} + b MPU_xTaskDelayUntilImpl + MPU_xTaskDelayUntil_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskDelayUntilImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskAbortDelay +MPU_xTaskAbortDelay: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskAbortDelay_Unpriv + MPU_xTaskAbortDelay_Priv: + pop {r0} + b MPU_xTaskAbortDelayImpl + MPU_xTaskAbortDelay_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskAbortDelayImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTaskDelay +MPU_vTaskDelay: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vTaskDelay_Unpriv + MPU_vTaskDelay_Priv: + pop {r0} + b MPU_vTaskDelayImpl + MPU_vTaskDelay_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskDelayImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxTaskPriorityGet +MPU_uxTaskPriorityGet: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_uxTaskPriorityGet_Unpriv + MPU_uxTaskPriorityGet_Priv: + pop {r0} + b MPU_uxTaskPriorityGetImpl + MPU_uxTaskPriorityGet_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxTaskPriorityGetImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_eTaskGetState +MPU_eTaskGetState: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_eTaskGetState_Unpriv + MPU_eTaskGetState_Priv: + pop {r0} + b MPU_eTaskGetStateImpl + MPU_eTaskGetState_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_eTaskGetStateImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTaskGetInfo +MPU_vTaskGetInfo: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vTaskGetInfo_Unpriv + MPU_vTaskGetInfo_Priv: + pop {r0} + b MPU_vTaskGetInfoImpl + MPU_vTaskGetInfo_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskGetInfoImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGetIdleTaskHandle +MPU_xTaskGetIdleTaskHandle: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskGetIdleTaskHandle_Unpriv + MPU_xTaskGetIdleTaskHandle_Priv: + pop {r0} + b MPU_xTaskGetIdleTaskHandleImpl + MPU_xTaskGetIdleTaskHandle_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskGetIdleTaskHandleImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTaskSuspend +MPU_vTaskSuspend: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vTaskSuspend_Unpriv + MPU_vTaskSuspend_Priv: + pop {r0} + b MPU_vTaskSuspendImpl + MPU_vTaskSuspend_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskSuspendImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTaskResume +MPU_vTaskResume: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vTaskResume_Unpriv + MPU_vTaskResume_Priv: + pop {r0} + b MPU_vTaskResumeImpl + MPU_vTaskResume_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskResumeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGetTickCount +MPU_xTaskGetTickCount: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskGetTickCount_Unpriv + MPU_xTaskGetTickCount_Priv: + pop {r0} + b MPU_xTaskGetTickCountImpl + MPU_xTaskGetTickCount_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskGetTickCountImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxTaskGetNumberOfTasks +MPU_uxTaskGetNumberOfTasks: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_uxTaskGetNumberOfTasks_Unpriv + MPU_uxTaskGetNumberOfTasks_Priv: + pop {r0} + b MPU_uxTaskGetNumberOfTasksImpl + MPU_uxTaskGetNumberOfTasks_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxTaskGetNumberOfTasksImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_pcTaskGetName +MPU_pcTaskGetName: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_pcTaskGetName_Unpriv + MPU_pcTaskGetName_Priv: + pop {r0} + b MPU_pcTaskGetNameImpl + MPU_pcTaskGetName_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_pcTaskGetNameImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_ulTaskGetRunTimeCounter +MPU_ulTaskGetRunTimeCounter: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_ulTaskGetRunTimeCounter_Unpriv + MPU_ulTaskGetRunTimeCounter_Priv: + pop {r0} + b MPU_ulTaskGetRunTimeCounterImpl + MPU_ulTaskGetRunTimeCounter_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_ulTaskGetRunTimeCounterImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_ulTaskGetRunTimePercent +MPU_ulTaskGetRunTimePercent: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_ulTaskGetRunTimePercent_Unpriv + MPU_ulTaskGetRunTimePercent_Priv: + pop {r0} + b MPU_ulTaskGetRunTimePercentImpl + MPU_ulTaskGetRunTimePercent_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_ulTaskGetRunTimePercentImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_ulTaskGetIdleRunTimePercent +MPU_ulTaskGetIdleRunTimePercent: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_ulTaskGetIdleRunTimePercent_Unpriv + MPU_ulTaskGetIdleRunTimePercent_Priv: + pop {r0} + b MPU_ulTaskGetIdleRunTimePercentImpl + MPU_ulTaskGetIdleRunTimePercent_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_ulTaskGetIdleRunTimePercentImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_ulTaskGetIdleRunTimeCounter +MPU_ulTaskGetIdleRunTimeCounter: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_ulTaskGetIdleRunTimeCounter_Unpriv + MPU_ulTaskGetIdleRunTimeCounter_Priv: + pop {r0} + b MPU_ulTaskGetIdleRunTimeCounterImpl + MPU_ulTaskGetIdleRunTimeCounter_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_ulTaskGetIdleRunTimeCounterImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTaskSetApplicationTaskTag +MPU_vTaskSetApplicationTaskTag: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vTaskSetApplicationTaskTag_Unpriv + MPU_vTaskSetApplicationTaskTag_Priv: + pop {r0} + b MPU_vTaskSetApplicationTaskTagImpl + MPU_vTaskSetApplicationTaskTag_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskSetApplicationTaskTagImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGetApplicationTaskTag +MPU_xTaskGetApplicationTaskTag: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskGetApplicationTaskTag_Unpriv + MPU_xTaskGetApplicationTaskTag_Priv: + pop {r0} + b MPU_xTaskGetApplicationTaskTagImpl + MPU_xTaskGetApplicationTaskTag_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskGetApplicationTaskTagImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTaskSetThreadLocalStoragePointer +MPU_vTaskSetThreadLocalStoragePointer: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vTaskSetThreadLocalStoragePointer_Unpriv + MPU_vTaskSetThreadLocalStoragePointer_Priv: + pop {r0} + b MPU_vTaskSetThreadLocalStoragePointerImpl + MPU_vTaskSetThreadLocalStoragePointer_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskSetThreadLocalStoragePointerImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_pvTaskGetThreadLocalStoragePointer +MPU_pvTaskGetThreadLocalStoragePointer: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_pvTaskGetThreadLocalStoragePointer_Unpriv + MPU_pvTaskGetThreadLocalStoragePointer_Priv: + pop {r0} + b MPU_pvTaskGetThreadLocalStoragePointerImpl + MPU_pvTaskGetThreadLocalStoragePointer_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_pvTaskGetThreadLocalStoragePointerImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxTaskGetSystemState +MPU_uxTaskGetSystemState: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_uxTaskGetSystemState_Unpriv + MPU_uxTaskGetSystemState_Priv: + pop {r0} + b MPU_uxTaskGetSystemStateImpl + MPU_uxTaskGetSystemState_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxTaskGetSystemStateImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxTaskGetStackHighWaterMark +MPU_uxTaskGetStackHighWaterMark: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_uxTaskGetStackHighWaterMark_Unpriv + MPU_uxTaskGetStackHighWaterMark_Priv: + pop {r0} + b MPU_uxTaskGetStackHighWaterMarkImpl + MPU_uxTaskGetStackHighWaterMark_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxTaskGetStackHighWaterMarkImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxTaskGetStackHighWaterMark2 +MPU_uxTaskGetStackHighWaterMark2: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_uxTaskGetStackHighWaterMark2_Unpriv + MPU_uxTaskGetStackHighWaterMark2_Priv: + pop {r0} + b MPU_uxTaskGetStackHighWaterMark2Impl + MPU_uxTaskGetStackHighWaterMark2_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxTaskGetStackHighWaterMark2Impl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGetCurrentTaskHandle +MPU_xTaskGetCurrentTaskHandle: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskGetCurrentTaskHandle_Unpriv + MPU_xTaskGetCurrentTaskHandle_Priv: + pop {r0} + b MPU_xTaskGetCurrentTaskHandleImpl + MPU_xTaskGetCurrentTaskHandle_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskGetCurrentTaskHandleImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGetSchedulerState +MPU_xTaskGetSchedulerState: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskGetSchedulerState_Unpriv + MPU_xTaskGetSchedulerState_Priv: + pop {r0} + b MPU_xTaskGetSchedulerStateImpl + MPU_xTaskGetSchedulerState_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskGetSchedulerStateImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTaskSetTimeOutState +MPU_vTaskSetTimeOutState: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vTaskSetTimeOutState_Unpriv + MPU_vTaskSetTimeOutState_Priv: + pop {r0} + b MPU_vTaskSetTimeOutStateImpl + MPU_vTaskSetTimeOutState_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskSetTimeOutStateImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskCheckForTimeOut +MPU_xTaskCheckForTimeOut: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskCheckForTimeOut_Unpriv + MPU_xTaskCheckForTimeOut_Priv: + pop {r0} + b MPU_xTaskCheckForTimeOutImpl + MPU_xTaskCheckForTimeOut_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskCheckForTimeOutImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGenericNotify +MPU_xTaskGenericNotify: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskGenericNotify_Unpriv + MPU_xTaskGenericNotify_Priv: + pop {r0} + b MPU_xTaskGenericNotifyImpl + MPU_xTaskGenericNotify_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER_1 + bl MPU_xTaskGenericNotifyImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGenericNotifyWait +MPU_xTaskGenericNotifyWait: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskGenericNotifyWait_Unpriv + MPU_xTaskGenericNotifyWait_Priv: + pop {r0} + b MPU_xTaskGenericNotifyWaitImpl + MPU_xTaskGenericNotifyWait_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER_1 + bl MPU_xTaskGenericNotifyWaitImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_ulTaskGenericNotifyTake +MPU_ulTaskGenericNotifyTake: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_ulTaskGenericNotifyTake_Unpriv + MPU_ulTaskGenericNotifyTake_Priv: + pop {r0} + b MPU_ulTaskGenericNotifyTakeImpl + MPU_ulTaskGenericNotifyTake_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_ulTaskGenericNotifyTakeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGenericNotifyStateClear +MPU_xTaskGenericNotifyStateClear: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskGenericNotifyStateClear_Unpriv + MPU_xTaskGenericNotifyStateClear_Priv: + pop {r0} + b MPU_xTaskGenericNotifyStateClearImpl + MPU_xTaskGenericNotifyStateClear_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskGenericNotifyStateClearImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_ulTaskGenericNotifyValueClear +MPU_ulTaskGenericNotifyValueClear: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_ulTaskGenericNotifyValueClear_Unpriv + MPU_ulTaskGenericNotifyValueClear_Priv: + pop {r0} + b MPU_ulTaskGenericNotifyValueClearImpl + MPU_ulTaskGenericNotifyValueClear_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_ulTaskGenericNotifyValueClearImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueGenericSend +MPU_xQueueGenericSend: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xQueueGenericSend_Unpriv + MPU_xQueueGenericSend_Priv: + pop {r0} + b MPU_xQueueGenericSendImpl + MPU_xQueueGenericSend_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueGenericSendImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxQueueMessagesWaiting +MPU_uxQueueMessagesWaiting: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_uxQueueMessagesWaiting_Unpriv + MPU_uxQueueMessagesWaiting_Priv: + pop {r0} + b MPU_uxQueueMessagesWaitingImpl + MPU_uxQueueMessagesWaiting_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxQueueMessagesWaitingImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxQueueSpacesAvailable +MPU_uxQueueSpacesAvailable: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_uxQueueSpacesAvailable_Unpriv + MPU_uxQueueSpacesAvailable_Priv: + pop {r0} + b MPU_uxQueueSpacesAvailableImpl + MPU_uxQueueSpacesAvailable_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxQueueSpacesAvailableImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueReceive +MPU_xQueueReceive: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xQueueReceive_Unpriv + MPU_xQueueReceive_Priv: + pop {r0} + b MPU_xQueueReceiveImpl + MPU_xQueueReceive_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueReceiveImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueuePeek +MPU_xQueuePeek: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xQueuePeek_Unpriv + MPU_xQueuePeek_Priv: + pop {r0} + b MPU_xQueuePeekImpl + MPU_xQueuePeek_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueuePeekImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueSemaphoreTake +MPU_xQueueSemaphoreTake: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xQueueSemaphoreTake_Unpriv + MPU_xQueueSemaphoreTake_Priv: + pop {r0} + b MPU_xQueueSemaphoreTakeImpl + MPU_xQueueSemaphoreTake_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueSemaphoreTakeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueGetMutexHolder +MPU_xQueueGetMutexHolder: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xQueueGetMutexHolder_Unpriv + MPU_xQueueGetMutexHolder_Priv: + pop {r0} + b MPU_xQueueGetMutexHolderImpl + MPU_xQueueGetMutexHolder_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueGetMutexHolderImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueTakeMutexRecursive +MPU_xQueueTakeMutexRecursive: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xQueueTakeMutexRecursive_Unpriv + MPU_xQueueTakeMutexRecursive_Priv: + pop {r0} + b MPU_xQueueTakeMutexRecursiveImpl + MPU_xQueueTakeMutexRecursive_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueTakeMutexRecursiveImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueGiveMutexRecursive +MPU_xQueueGiveMutexRecursive: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xQueueGiveMutexRecursive_Unpriv + MPU_xQueueGiveMutexRecursive_Priv: + pop {r0} + b MPU_xQueueGiveMutexRecursiveImpl + MPU_xQueueGiveMutexRecursive_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueGiveMutexRecursiveImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueSelectFromSet +MPU_xQueueSelectFromSet: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xQueueSelectFromSet_Unpriv + MPU_xQueueSelectFromSet_Priv: + pop {r0} + b MPU_xQueueSelectFromSetImpl + MPU_xQueueSelectFromSet_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueSelectFromSetImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueAddToSet +MPU_xQueueAddToSet: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xQueueAddToSet_Unpriv + MPU_xQueueAddToSet_Priv: + pop {r0} + b MPU_xQueueAddToSetImpl + MPU_xQueueAddToSet_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueAddToSetImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vQueueAddToRegistry +MPU_vQueueAddToRegistry: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vQueueAddToRegistry_Unpriv + MPU_vQueueAddToRegistry_Priv: + pop {r0} + b MPU_vQueueAddToRegistryImpl + MPU_vQueueAddToRegistry_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vQueueAddToRegistryImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vQueueUnregisterQueue +MPU_vQueueUnregisterQueue: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vQueueUnregisterQueue_Unpriv + MPU_vQueueUnregisterQueue_Priv: + pop {r0} + b MPU_vQueueUnregisterQueueImpl + MPU_vQueueUnregisterQueue_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vQueueUnregisterQueueImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_pcQueueGetName +MPU_pcQueueGetName: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_pcQueueGetName_Unpriv + MPU_pcQueueGetName_Priv: + pop {r0} + b MPU_pcQueueGetNameImpl + MPU_pcQueueGetName_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_pcQueueGetNameImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_pvTimerGetTimerID +MPU_pvTimerGetTimerID: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_pvTimerGetTimerID_Unpriv + MPU_pvTimerGetTimerID_Priv: + pop {r0} + b MPU_pvTimerGetTimerIDImpl + MPU_pvTimerGetTimerID_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_pvTimerGetTimerIDImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTimerSetTimerID +MPU_vTimerSetTimerID: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vTimerSetTimerID_Unpriv + MPU_vTimerSetTimerID_Priv: + pop {r0} + b MPU_vTimerSetTimerIDImpl + MPU_vTimerSetTimerID_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTimerSetTimerIDImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTimerIsTimerActive +MPU_xTimerIsTimerActive: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTimerIsTimerActive_Unpriv + MPU_xTimerIsTimerActive_Priv: + pop {r0} + b MPU_xTimerIsTimerActiveImpl + MPU_xTimerIsTimerActive_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTimerIsTimerActiveImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTimerGetTimerDaemonTaskHandle +MPU_xTimerGetTimerDaemonTaskHandle: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTimerGetTimerDaemonTaskHandle_Unpriv + MPU_xTimerGetTimerDaemonTaskHandle_Priv: + pop {r0} + b MPU_xTimerGetTimerDaemonTaskHandleImpl + MPU_xTimerGetTimerDaemonTaskHandle_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTimerGetTimerDaemonTaskHandleImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTimerGenericCommand +MPU_xTimerGenericCommand: + push {r0} + /* This function can be called from ISR also and therefore, we need a check + * to take privileged path, if called from ISR. */ + mrs r0, ipsr + cmp r0, #0 + bne MPU_xTimerGenericCommand_Priv + mrs r0, control + tst r0, #1 + beq MPU_xTimerGenericCommand_Priv + MPU_xTimerGenericCommand_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER_1 + bl MPU_xTimerGenericCommandImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr + MPU_xTimerGenericCommand_Priv: + pop {r0} + b MPU_xTimerGenericCommandImpl + +/*-----------------------------------------------------------*/ + + PUBLIC MPU_pcTimerGetName +MPU_pcTimerGetName: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_pcTimerGetName_Unpriv + MPU_pcTimerGetName_Priv: + pop {r0} + b MPU_pcTimerGetNameImpl + MPU_pcTimerGetName_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_pcTimerGetNameImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTimerSetReloadMode +MPU_vTimerSetReloadMode: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vTimerSetReloadMode_Unpriv + MPU_vTimerSetReloadMode_Priv: + pop {r0} + b MPU_vTimerSetReloadModeImpl + MPU_vTimerSetReloadMode_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTimerSetReloadModeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTimerGetReloadMode +MPU_xTimerGetReloadMode: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTimerGetReloadMode_Unpriv + MPU_xTimerGetReloadMode_Priv: + pop {r0} + b MPU_xTimerGetReloadModeImpl + MPU_xTimerGetReloadMode_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTimerGetReloadModeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxTimerGetReloadMode +MPU_uxTimerGetReloadMode: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_uxTimerGetReloadMode_Unpriv + MPU_uxTimerGetReloadMode_Priv: + pop {r0} + b MPU_uxTimerGetReloadModeImpl + MPU_uxTimerGetReloadMode_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxTimerGetReloadModeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTimerGetPeriod +MPU_xTimerGetPeriod: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTimerGetPeriod_Unpriv + MPU_xTimerGetPeriod_Priv: + pop {r0} + b MPU_xTimerGetPeriodImpl + MPU_xTimerGetPeriod_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTimerGetPeriodImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTimerGetExpiryTime +MPU_xTimerGetExpiryTime: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTimerGetExpiryTime_Unpriv + MPU_xTimerGetExpiryTime_Priv: + pop {r0} + b MPU_xTimerGetExpiryTimeImpl + MPU_xTimerGetExpiryTime_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTimerGetExpiryTimeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xEventGroupWaitBits +MPU_xEventGroupWaitBits: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xEventGroupWaitBits_Unpriv + MPU_xEventGroupWaitBits_Priv: + pop {r0} + b MPU_xEventGroupWaitBitsImpl + MPU_xEventGroupWaitBits_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER_1 + bl MPU_xEventGroupWaitBitsImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xEventGroupClearBits +MPU_xEventGroupClearBits: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xEventGroupClearBits_Unpriv + MPU_xEventGroupClearBits_Priv: + pop {r0} + b MPU_xEventGroupClearBitsImpl + MPU_xEventGroupClearBits_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xEventGroupClearBitsImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xEventGroupSetBits +MPU_xEventGroupSetBits: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xEventGroupSetBits_Unpriv + MPU_xEventGroupSetBits_Priv: + pop {r0} + b MPU_xEventGroupSetBitsImpl + MPU_xEventGroupSetBits_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xEventGroupSetBitsImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xEventGroupSync +MPU_xEventGroupSync: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xEventGroupSync_Unpriv + MPU_xEventGroupSync_Priv: + pop {r0} + b MPU_xEventGroupSyncImpl + MPU_xEventGroupSync_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xEventGroupSyncImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxEventGroupGetNumber +MPU_uxEventGroupGetNumber: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_uxEventGroupGetNumber_Unpriv + MPU_uxEventGroupGetNumber_Priv: + pop {r0} + b MPU_uxEventGroupGetNumberImpl + MPU_uxEventGroupGetNumber_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxEventGroupGetNumberImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vEventGroupSetNumber +MPU_vEventGroupSetNumber: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vEventGroupSetNumber_Unpriv + MPU_vEventGroupSetNumber_Priv: + pop {r0} + b MPU_vEventGroupSetNumberImpl + MPU_vEventGroupSetNumber_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vEventGroupSetNumberImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferSend +MPU_xStreamBufferSend: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xStreamBufferSend_Unpriv + MPU_xStreamBufferSend_Priv: + pop {r0} + b MPU_xStreamBufferSendImpl + MPU_xStreamBufferSend_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferSendImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferReceive +MPU_xStreamBufferReceive: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xStreamBufferReceive_Unpriv + MPU_xStreamBufferReceive_Priv: + pop {r0} + b MPU_xStreamBufferReceiveImpl + MPU_xStreamBufferReceive_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferReceiveImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferIsFull +MPU_xStreamBufferIsFull: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xStreamBufferIsFull_Unpriv + MPU_xStreamBufferIsFull_Priv: + pop {r0} + b MPU_xStreamBufferIsFullImpl + MPU_xStreamBufferIsFull_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferIsFullImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferIsEmpty +MPU_xStreamBufferIsEmpty: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xStreamBufferIsEmpty_Unpriv + MPU_xStreamBufferIsEmpty_Priv: + pop {r0} + b MPU_xStreamBufferIsEmptyImpl + MPU_xStreamBufferIsEmpty_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferIsEmptyImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferSpacesAvailable +MPU_xStreamBufferSpacesAvailable: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xStreamBufferSpacesAvailable_Unpriv + MPU_xStreamBufferSpacesAvailable_Priv: + pop {r0} + b MPU_xStreamBufferSpacesAvailableImpl + MPU_xStreamBufferSpacesAvailable_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferSpacesAvailableImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferBytesAvailable +MPU_xStreamBufferBytesAvailable: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xStreamBufferBytesAvailable_Unpriv + MPU_xStreamBufferBytesAvailable_Priv: + pop {r0} + b MPU_xStreamBufferBytesAvailableImpl + MPU_xStreamBufferBytesAvailable_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferBytesAvailableImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferSetTriggerLevel +MPU_xStreamBufferSetTriggerLevel: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xStreamBufferSetTriggerLevel_Unpriv + MPU_xStreamBufferSetTriggerLevel_Priv: + pop {r0} + b MPU_xStreamBufferSetTriggerLevelImpl + MPU_xStreamBufferSetTriggerLevel_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferSetTriggerLevelImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferNextMessageLengthBytes +MPU_xStreamBufferNextMessageLengthBytes: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xStreamBufferNextMessageLengthBytes_Unpriv + MPU_xStreamBufferNextMessageLengthBytes_Priv: + pop {r0} + b MPU_xStreamBufferNextMessageLengthBytesImpl + MPU_xStreamBufferNextMessageLengthBytes_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferNextMessageLengthBytesImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + +/* Default weak implementations in case one is not available from + * mpu_wrappers because of config options. */ + + PUBWEAK MPU_xTaskDelayUntilImpl +MPU_xTaskDelayUntilImpl: + b MPU_xTaskDelayUntilImpl + + PUBWEAK MPU_xTaskAbortDelayImpl +MPU_xTaskAbortDelayImpl: + b MPU_xTaskAbortDelayImpl + + PUBWEAK MPU_vTaskDelayImpl +MPU_vTaskDelayImpl: + b MPU_vTaskDelayImpl + + PUBWEAK MPU_uxTaskPriorityGetImpl +MPU_uxTaskPriorityGetImpl: + b MPU_uxTaskPriorityGetImpl + + PUBWEAK MPU_eTaskGetStateImpl +MPU_eTaskGetStateImpl: + b MPU_eTaskGetStateImpl + + PUBWEAK MPU_vTaskGetInfoImpl +MPU_vTaskGetInfoImpl: + b MPU_vTaskGetInfoImpl + + PUBWEAK MPU_xTaskGetIdleTaskHandleImpl +MPU_xTaskGetIdleTaskHandleImpl: + b MPU_xTaskGetIdleTaskHandleImpl + + PUBWEAK MPU_vTaskSuspendImpl +MPU_vTaskSuspendImpl: + b MPU_vTaskSuspendImpl + + PUBWEAK MPU_vTaskResumeImpl +MPU_vTaskResumeImpl: + b MPU_vTaskResumeImpl + + PUBWEAK MPU_xTaskGetTickCountImpl +MPU_xTaskGetTickCountImpl: + b MPU_xTaskGetTickCountImpl + + PUBWEAK MPU_uxTaskGetNumberOfTasksImpl +MPU_uxTaskGetNumberOfTasksImpl: + b MPU_uxTaskGetNumberOfTasksImpl + + PUBWEAK MPU_pcTaskGetNameImpl +MPU_pcTaskGetNameImpl: + b MPU_pcTaskGetNameImpl + + PUBWEAK MPU_ulTaskGetRunTimeCounterImpl +MPU_ulTaskGetRunTimeCounterImpl: + b MPU_ulTaskGetRunTimeCounterImpl + + PUBWEAK MPU_ulTaskGetRunTimePercentImpl +MPU_ulTaskGetRunTimePercentImpl: + b MPU_ulTaskGetRunTimePercentImpl + + PUBWEAK MPU_ulTaskGetIdleRunTimePercentImpl +MPU_ulTaskGetIdleRunTimePercentImpl: + b MPU_ulTaskGetIdleRunTimePercentImpl + + PUBWEAK MPU_ulTaskGetIdleRunTimeCounterImpl +MPU_ulTaskGetIdleRunTimeCounterImpl: + b MPU_ulTaskGetIdleRunTimeCounterImpl + + PUBWEAK MPU_vTaskSetApplicationTaskTagImpl +MPU_vTaskSetApplicationTaskTagImpl: + b MPU_vTaskSetApplicationTaskTagImpl + + PUBWEAK MPU_xTaskGetApplicationTaskTagImpl +MPU_xTaskGetApplicationTaskTagImpl: + b MPU_xTaskGetApplicationTaskTagImpl + + PUBWEAK MPU_vTaskSetThreadLocalStoragePointerImpl +MPU_vTaskSetThreadLocalStoragePointerImpl: + b MPU_vTaskSetThreadLocalStoragePointerImpl + + PUBWEAK MPU_pvTaskGetThreadLocalStoragePointerImpl +MPU_pvTaskGetThreadLocalStoragePointerImpl: + b MPU_pvTaskGetThreadLocalStoragePointerImpl + + PUBWEAK MPU_uxTaskGetSystemStateImpl +MPU_uxTaskGetSystemStateImpl: + b MPU_uxTaskGetSystemStateImpl + + PUBWEAK MPU_uxTaskGetStackHighWaterMarkImpl +MPU_uxTaskGetStackHighWaterMarkImpl: + b MPU_uxTaskGetStackHighWaterMarkImpl + + PUBWEAK MPU_uxTaskGetStackHighWaterMark2Impl +MPU_uxTaskGetStackHighWaterMark2Impl: + b MPU_uxTaskGetStackHighWaterMark2Impl + + PUBWEAK MPU_xTaskGetCurrentTaskHandleImpl +MPU_xTaskGetCurrentTaskHandleImpl: + b MPU_xTaskGetCurrentTaskHandleImpl + + PUBWEAK MPU_xTaskGetSchedulerStateImpl +MPU_xTaskGetSchedulerStateImpl: + b MPU_xTaskGetSchedulerStateImpl + + PUBWEAK MPU_vTaskSetTimeOutStateImpl +MPU_vTaskSetTimeOutStateImpl: + b MPU_vTaskSetTimeOutStateImpl + + PUBWEAK MPU_xTaskCheckForTimeOutImpl +MPU_xTaskCheckForTimeOutImpl: + b MPU_xTaskCheckForTimeOutImpl + + PUBWEAK MPU_xTaskGenericNotifyImpl +MPU_xTaskGenericNotifyImpl: + b MPU_xTaskGenericNotifyImpl + + PUBWEAK MPU_xTaskGenericNotifyWaitImpl +MPU_xTaskGenericNotifyWaitImpl: + b MPU_xTaskGenericNotifyWaitImpl + + PUBWEAK MPU_ulTaskGenericNotifyTakeImpl +MPU_ulTaskGenericNotifyTakeImpl: + b MPU_ulTaskGenericNotifyTakeImpl + + PUBWEAK MPU_xTaskGenericNotifyStateClearImpl +MPU_xTaskGenericNotifyStateClearImpl: + b MPU_xTaskGenericNotifyStateClearImpl + + PUBWEAK MPU_ulTaskGenericNotifyValueClearImpl +MPU_ulTaskGenericNotifyValueClearImpl: + b MPU_ulTaskGenericNotifyValueClearImpl + + PUBWEAK MPU_xQueueGenericSendImpl +MPU_xQueueGenericSendImpl: + b MPU_xQueueGenericSendImpl + + PUBWEAK MPU_uxQueueMessagesWaitingImpl +MPU_uxQueueMessagesWaitingImpl: + b MPU_uxQueueMessagesWaitingImpl + + PUBWEAK MPU_uxQueueSpacesAvailableImpl +MPU_uxQueueSpacesAvailableImpl: + b MPU_uxQueueSpacesAvailableImpl + + PUBWEAK MPU_xQueueReceiveImpl +MPU_xQueueReceiveImpl: + b MPU_xQueueReceiveImpl + + PUBWEAK MPU_xQueuePeekImpl +MPU_xQueuePeekImpl: + b MPU_xQueuePeekImpl + + PUBWEAK MPU_xQueueSemaphoreTakeImpl +MPU_xQueueSemaphoreTakeImpl: + b MPU_xQueueSemaphoreTakeImpl + + PUBWEAK MPU_xQueueGetMutexHolderImpl +MPU_xQueueGetMutexHolderImpl: + b MPU_xQueueGetMutexHolderImpl + + PUBWEAK MPU_xQueueTakeMutexRecursiveImpl +MPU_xQueueTakeMutexRecursiveImpl: + b MPU_xQueueTakeMutexRecursiveImpl + + PUBWEAK MPU_xQueueGiveMutexRecursiveImpl +MPU_xQueueGiveMutexRecursiveImpl: + b MPU_xQueueGiveMutexRecursiveImpl + + PUBWEAK MPU_xQueueSelectFromSetImpl +MPU_xQueueSelectFromSetImpl: + b MPU_xQueueSelectFromSetImpl + + PUBWEAK MPU_xQueueAddToSetImpl +MPU_xQueueAddToSetImpl: + b MPU_xQueueAddToSetImpl + + PUBWEAK MPU_vQueueAddToRegistryImpl +MPU_vQueueAddToRegistryImpl: + b MPU_vQueueAddToRegistryImpl + + PUBWEAK MPU_vQueueUnregisterQueueImpl +MPU_vQueueUnregisterQueueImpl: + b MPU_vQueueUnregisterQueueImpl + + PUBWEAK MPU_pcQueueGetNameImpl +MPU_pcQueueGetNameImpl: + b MPU_pcQueueGetNameImpl + + PUBWEAK MPU_pvTimerGetTimerIDImpl +MPU_pvTimerGetTimerIDImpl: + b MPU_pvTimerGetTimerIDImpl + + PUBWEAK MPU_vTimerSetTimerIDImpl +MPU_vTimerSetTimerIDImpl: + b MPU_vTimerSetTimerIDImpl + + PUBWEAK MPU_xTimerIsTimerActiveImpl +MPU_xTimerIsTimerActiveImpl: + b MPU_xTimerIsTimerActiveImpl + + PUBWEAK MPU_xTimerGetTimerDaemonTaskHandleImpl +MPU_xTimerGetTimerDaemonTaskHandleImpl: + b MPU_xTimerGetTimerDaemonTaskHandleImpl + + PUBWEAK MPU_xTimerGenericCommandImpl +MPU_xTimerGenericCommandImpl: + b MPU_xTimerGenericCommandImpl + + PUBWEAK MPU_pcTimerGetNameImpl +MPU_pcTimerGetNameImpl: + b MPU_pcTimerGetNameImpl + + PUBWEAK MPU_vTimerSetReloadModeImpl +MPU_vTimerSetReloadModeImpl: + b MPU_vTimerSetReloadModeImpl + + PUBWEAK MPU_xTimerGetReloadModeImpl +MPU_xTimerGetReloadModeImpl: + b MPU_xTimerGetReloadModeImpl + + PUBWEAK MPU_uxTimerGetReloadModeImpl +MPU_uxTimerGetReloadModeImpl: + b MPU_uxTimerGetReloadModeImpl + + PUBWEAK MPU_xTimerGetPeriodImpl +MPU_xTimerGetPeriodImpl: + b MPU_xTimerGetPeriodImpl + + PUBWEAK MPU_xTimerGetExpiryTimeImpl +MPU_xTimerGetExpiryTimeImpl: + b MPU_xTimerGetExpiryTimeImpl + + PUBWEAK MPU_xEventGroupWaitBitsImpl +MPU_xEventGroupWaitBitsImpl: + b MPU_xEventGroupWaitBitsImpl + + PUBWEAK MPU_xEventGroupClearBitsImpl +MPU_xEventGroupClearBitsImpl: + b MPU_xEventGroupClearBitsImpl + + PUBWEAK MPU_xEventGroupSetBitsImpl +MPU_xEventGroupSetBitsImpl: + b MPU_xEventGroupSetBitsImpl + + PUBWEAK MPU_xEventGroupSyncImpl +MPU_xEventGroupSyncImpl: + b MPU_xEventGroupSyncImpl + + PUBWEAK MPU_uxEventGroupGetNumberImpl +MPU_uxEventGroupGetNumberImpl: + b MPU_uxEventGroupGetNumberImpl + + PUBWEAK MPU_vEventGroupSetNumberImpl +MPU_vEventGroupSetNumberImpl: + b MPU_vEventGroupSetNumberImpl + + PUBWEAK MPU_xStreamBufferSendImpl +MPU_xStreamBufferSendImpl: + b MPU_xStreamBufferSendImpl + + PUBWEAK MPU_xStreamBufferReceiveImpl +MPU_xStreamBufferReceiveImpl: + b MPU_xStreamBufferReceiveImpl + + PUBWEAK MPU_xStreamBufferIsFullImpl +MPU_xStreamBufferIsFullImpl: + b MPU_xStreamBufferIsFullImpl + + PUBWEAK MPU_xStreamBufferIsEmptyImpl +MPU_xStreamBufferIsEmptyImpl: + b MPU_xStreamBufferIsEmptyImpl + + PUBWEAK MPU_xStreamBufferSpacesAvailableImpl +MPU_xStreamBufferSpacesAvailableImpl: + b MPU_xStreamBufferSpacesAvailableImpl + + PUBWEAK MPU_xStreamBufferBytesAvailableImpl +MPU_xStreamBufferBytesAvailableImpl: + b MPU_xStreamBufferBytesAvailableImpl + + PUBWEAK MPU_xStreamBufferSetTriggerLevelImpl +MPU_xStreamBufferSetTriggerLevelImpl: + b MPU_xStreamBufferSetTriggerLevelImpl + + PUBWEAK MPU_xStreamBufferNextMessageLengthBytesImpl +MPU_xStreamBufferNextMessageLengthBytesImpl: + b MPU_xStreamBufferNextMessageLengthBytesImpl + +/*-----------------------------------------------------------*/ + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + + END diff --git a/portable/ARMv8M/non_secure/portable/IAR/ARM_CM33/portasm.s b/portable/ARMv8M/non_secure/portable/IAR/ARM_CM33/portasm.s index a193cd7b80e..15e74ffc16b 100644 --- a/portable/ARMv8M/non_secure/portable/IAR/ARM_CM33/portasm.s +++ b/portable/ARMv8M/non_secure/portable/IAR/ARM_CM33/portasm.s @@ -32,12 +32,21 @@ the code is included in C files but excluded by the preprocessor in assembly files (__ICCARM__ is defined by the IAR C compiler but not by the IAR assembler. */ #include "FreeRTOSConfig.h" +#ifndef configUSE_MPU_WRAPPERS_V1 + #define configUSE_MPU_WRAPPERS_V1 0 +#endif + EXTERN pxCurrentTCB EXTERN xSecureContext EXTERN vTaskSwitchContext EXTERN vPortSVCHandler_C EXTERN SecureContext_SaveContext EXTERN SecureContext_LoadContext +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + EXTERN vSystemCallEnter + EXTERN vSystemCallEnter_1 + EXTERN vSystemCallExit +#endif PUBLIC xIsPrivileged PUBLIC vResetPrivilege @@ -89,50 +98,81 @@ vPortAllocateSecureContext: THUMB /*-----------------------------------------------------------*/ +#if ( configENABLE_MPU == 1 ) + +vRestoreContextOfFirstTask: + program_mpu_first_task: + ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + ldr r0, [r3] /* r0 = pxCurrentTCB. */ + + dmb /* Complete outstanding transfers before disabling MPU. */ + ldr r1, =0xe000ed94 /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + ldr r2, [r1] /* Read the value of MPU_CTRL. */ + bic r2, #1 /* r2 = r2 & ~1 i.e. Clear the bit 0 in r2. */ + str r2, [r1] /* Disable MPU. */ + + adds r0, #4 /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */ + ldr r1, [r0] /* r1 = *r0 i.e. r1 = MAIR0. */ + ldr r2, =0xe000edc0 /* r2 = 0xe000edc0 [Location of MAIR0]. */ + str r1, [r2] /* Program MAIR0. */ + + adds r0, #4 /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */ + ldr r1, =0xe000ed98 /* r1 = 0xe000ed98 [Location of RNR]. */ + ldr r2, =0xe000ed9c /* r2 = 0xe000ed9c [Location of RBAR]. */ + + movs r3, #4 /* r3 = 4. */ + str r3, [r1] /* Program RNR = 4. */ + ldmia r0!, {r4-r11} /* Read 4 set of RBAR/RLAR registers from TCB. */ + stmia r2, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ + + #if ( configTOTAL_MPU_REGIONS == 16 ) + movs r3, #8 /* r3 = 8. */ + str r3, [r1] /* Program RNR = 8. */ + ldmia r0!, {r4-r11} /* Read 4 set of RBAR/RLAR registers from TCB. */ + stmia r2, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ + movs r3, #12 /* r3 = 12. */ + str r3, [r1] /* Program RNR = 12. */ + ldmia r0!, {r4-r11} /* Read 4 set of RBAR/RLAR registers from TCB. */ + stmia r2, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ + #endif /* configTOTAL_MPU_REGIONS == 16 */ + + ldr r1, =0xe000ed94 /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + ldr r2, [r1] /* Read the value of MPU_CTRL. */ + orr r2, #1 /* r2 = r1 | 1 i.e. Set the bit 0 in r2. */ + str r2, [r1] /* Enable MPU. */ + dsb /* Force memory writes before continuing. */ + + restore_context_first_task: + ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + ldr r1, [r3] /* r1 = pxCurrentTCB.*/ + ldr r2, [r1] /* r2 = Location of saved context in TCB. */ + + restore_special_regs_first_task: + ldmdb r2!, {r0, r3-r5, lr} /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */ + msr psp, r3 + msr psplim, r4 + msr control, r5 + ldr r4, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */ + str r0, [r4] /* Restore xSecureContext. */ + + restore_general_regs_first_task: + ldmdb r2!, {r4-r11} /* r4-r11 contain hardware saved context. */ + stmia r3!, {r4-r11} /* Copy the hardware saved context on the task stack. */ + ldmdb r2!, {r4-r11} /* r4-r11 restored. */ + + restore_context_done_first_task: + str r2, [r1] /* Save the location where the context should be saved next as the first member of TCB. */ + mov r0, #0 + msr basepri, r0 /* Ensure that interrupts are enabled when the first task starts. */ + bx lr + +#else /* configENABLE_MPU */ + vRestoreContextOfFirstTask: ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r3, [r2] /* Read pxCurrentTCB. */ ldr r0, [r3] /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ -#if ( configENABLE_MPU == 1 ) - dmb /* Complete outstanding transfers before disabling MPU. */ - ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ - ldr r4, [r2] /* Read the value of MPU_CTRL. */ - bic r4, r4, #1 /* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */ - str r4, [r2] /* Disable MPU. */ - - adds r3, #4 /* r3 = r3 + 4. r3 now points to MAIR0 in TCB. */ - ldr r4, [r3] /* r4 = *r3 i.e. r4 = MAIR0. */ - ldr r2, =0xe000edc0 /* r2 = 0xe000edc0 [Location of MAIR0]. */ - str r4, [r2] /* Program MAIR0. */ - ldr r2, =0xe000ed98 /* r2 = 0xe000ed98 [Location of RNR]. */ - movs r4, #4 /* r4 = 4. */ - str r4, [r2] /* Program RNR = 4. */ - adds r3, #4 /* r3 = r3 + 4. r3 now points to first RBAR in TCB. */ - ldr r2, =0xe000ed9c /* r2 = 0xe000ed9c [Location of RBAR]. */ - ldmia r3!, {r4-r11} /* Read 4 set of RBAR/RLAR registers from TCB. */ - stmia r2!, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ - - ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ - ldr r4, [r2] /* Read the value of MPU_CTRL. */ - orr r4, r4, #1 /* r4 = r4 | 1 i.e. Set the bit 0 in r4. */ - str r4, [r2] /* Enable MPU. */ - dsb /* Force memory writes before continuing. */ -#endif /* configENABLE_MPU */ - -#if ( configENABLE_MPU == 1 ) - ldm r0!, {r1-r4} /* Read from stack - r1 = xSecureContext, r2 = PSPLIM, r3 = CONTROL and r4 = EXC_RETURN. */ - ldr r5, =xSecureContext - str r1, [r5] /* Set xSecureContext to this task's value for the same. */ - msr psplim, r2 /* Set this task's PSPLIM value. */ - msr control, r3 /* Set this task's CONTROL value. */ - adds r0, #32 /* Discard everything up to r0. */ - msr psp, r0 /* This is now the new top of stack to use in the task. */ - isb - mov r0, #0 - msr basepri, r0 /* Ensure that interrupts are enabled when the first task starts. */ - bx r4 /* Finally, branch to EXC_RETURN. */ -#else /* configENABLE_MPU */ ldm r0!, {r1-r3} /* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */ ldr r4, =xSecureContext str r1, [r4] /* Set xSecureContext to this task's value for the same. */ @@ -145,6 +185,7 @@ vRestoreContextOfFirstTask: mov r0, #0 msr basepri, r0 /* Ensure that interrupts are enabled when the first task starts. */ bx r3 /* Finally, branch to EXC_RETURN. */ + #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ @@ -183,6 +224,143 @@ vClearInterruptMask: bx lr /* Return. */ /*-----------------------------------------------------------*/ +#if ( configENABLE_MPU == 1 ) + +PendSV_Handler: + ldr r3, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */ + ldr r0, [r3] /* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */ + ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + ldr r1, [r3] /* Read pxCurrentTCB - Value of pxCurrentTCB must be in r1 as it is used as a parameter later. */ + ldr r2, [r1] /* r2 = Location in TCB where the context should be saved. */ + + cbz r0, save_ns_context /* No secure context to save. */ + save_s_context: + push {r0-r2, lr} + bl SecureContext_SaveContext /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ + pop {r0-r2, lr} + + save_ns_context: + mov r3, lr /* r3 = LR (EXC_RETURN). */ + lsls r3, r3, #25 /* r3 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ + bmi save_special_regs /* r3 < 0 ==> Bit[6] in EXC_RETURN is 1 ==> secure stack was used to store the stack frame. */ + + save_general_regs: + mrs r3, psp + + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + add r3, r3, #0x20 /* Move r3 to location where s0 is saved. */ + tst lr, #0x10 + ittt eq + vstmiaeq r2!, {s16-s31} /* Store s16-s31. */ + vldmiaeq r3, {s0-s16} /* Copy hardware saved FP context into s0-s16. */ + vstmiaeq r2!, {s0-s16} /* Store hardware saved FP context. */ + sub r3, r3, #0x20 /* Set r3 back to the location of hardware saved context. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ + + stmia r2!, {r4-r11} /* Store r4-r11. */ + ldmia r3, {r4-r11} /* Copy the hardware saved context into r4-r11. */ + stmia r2!, {r4-r11} /* Store the hardware saved context. */ + + save_special_regs: + mrs r3, psp /* r3 = PSP. */ + mrs r4, psplim /* r4 = PSPLIM. */ + mrs r5, control /* r5 = CONTROL. */ + stmia r2!, {r0, r3-r5, lr} /* Store xSecureContext, original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */ + str r2, [r1] /* Save the location from where the context should be restored as the first member of TCB. */ + + select_next_task: + mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY + msr basepri, r0 /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + dsb + isb + bl vTaskSwitchContext + mov r0, #0 /* r0 = 0. */ + msr basepri, r0 /* Enable interrupts. */ + + program_mpu: + ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + ldr r0, [r3] /* r0 = pxCurrentTCB.*/ + + dmb /* Complete outstanding transfers before disabling MPU. */ + ldr r1, =0xe000ed94 /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + ldr r2, [r1] /* Read the value of MPU_CTRL. */ + bic r2, #1 /* r2 = r2 & ~1 i.e. Clear the bit 0 in r2. */ + str r2, [r1] /* Disable MPU. */ + + adds r0, #4 /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */ + ldr r1, [r0] /* r1 = *r0 i.e. r1 = MAIR0. */ + ldr r2, =0xe000edc0 /* r2 = 0xe000edc0 [Location of MAIR0]. */ + str r1, [r2] /* Program MAIR0. */ + + adds r0, #4 /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */ + ldr r1, =0xe000ed98 /* r1 = 0xe000ed98 [Location of RNR]. */ + ldr r2, =0xe000ed9c /* r2 = 0xe000ed9c [Location of RBAR]. */ + + movs r3, #4 /* r3 = 4. */ + str r3, [r1] /* Program RNR = 4. */ + ldmia r0!, {r4-r11} /* Read 4 sets of RBAR/RLAR registers from TCB. */ + stmia r2, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ + + #if ( configTOTAL_MPU_REGIONS == 16 ) + movs r3, #8 /* r3 = 8. */ + str r3, [r1] /* Program RNR = 8. */ + ldmia r0!, {r4-r11} /* Read 4 sets of RBAR/RLAR registers from TCB. */ + stmia r2, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ + movs r3, #12 /* r3 = 12. */ + str r3, [r1] /* Program RNR = 12. */ + ldmia r0!, {r4-r11} /* Read 4 sets of RBAR/RLAR registers from TCB. */ + stmia r2, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ + #endif /* configTOTAL_MPU_REGIONS == 16 */ + + ldr r1, =0xe000ed94 /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + ldr r2, [r1] /* Read the value of MPU_CTRL. */ + orr r2, #1 /* r2 = r2 | 1 i.e. Set the bit 0 in r2. */ + str r2, [r1] /* Enable MPU. */ + dsb /* Force memory writes before continuing. */ + + restore_context: + ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + ldr r1, [r3] /* r1 = pxCurrentTCB.*/ + ldr r2, [r1] /* r2 = Location of saved context in TCB. */ + + restore_special_regs: + ldmdb r2!, {r0, r3-r5, lr} /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */ + msr psp, r3 + msr psplim, r4 + msr control, r5 + ldr r4, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */ + str r0, [r4] /* Restore xSecureContext. */ + cbz r0, restore_ns_context /* No secure context to restore. */ + + restore_s_context: + push {r1-r3, lr} + bl SecureContext_LoadContext /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ + pop {r1-r3, lr} + + restore_ns_context: + mov r0, lr /* r0 = LR (EXC_RETURN). */ + lsls r0, r0, #25 /* r0 = r0 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ + bmi restore_context_done /* r0 < 0 ==> Bit[6] in EXC_RETURN is 1 ==> secure stack was used to store the stack frame. */ + + restore_general_regs: + ldmdb r2!, {r4-r11} /* r4-r11 contain hardware saved context. */ + stmia r3!, {r4-r11} /* Copy the hardware saved context on the task stack. */ + ldmdb r2!, {r4-r11} /* r4-r11 restored. */ + + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + tst lr, #0x10 + ittt eq + vldmdbeq r2!, {s0-s16} /* s0-s16 contain hardware saved FP context. */ + vstmiaeq r3!, {s0-s16} /* Copy hardware saved FP context on the task stack. */ + vldmdbeq r2!, {s16-s31} /* Restore s16-s31. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ + + restore_context_done: + str r2, [r1] /* Save the location where the context should be saved next as the first member of TCB. */ + bx lr + +#else /* configENABLE_MPU */ + PendSV_Handler: ldr r3, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */ ldr r0, [r3] /* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */ @@ -200,20 +378,11 @@ PendSV_Handler: ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r3] /* Read pxCurrentTCB. */ -#if ( configENABLE_MPU == 1 ) - subs r2, r2, #16 /* Make space for xSecureContext, PSPLIM, CONTROL and LR on the stack. */ - str r2, [r1] /* Save the new top of stack in TCB. */ - mrs r1, psplim /* r1 = PSPLIM. */ - mrs r3, control /* r3 = CONTROL. */ - mov r4, lr /* r4 = LR/EXC_RETURN. */ - stmia r2!, {r0, r1, r3, r4} /* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */ -#else /* configENABLE_MPU */ subs r2, r2, #12 /* Make space for xSecureContext, PSPLIM and LR on the stack. */ str r2, [r1] /* Save the new top of stack in TCB. */ mrs r1, psplim /* r1 = PSPLIM. */ mov r3, lr /* r3 = LR/EXC_RETURN. */ stmia r2!, {r0, r1, r3} /* Store xSecureContext, PSPLIM and LR on the stack. */ -#endif /* configENABLE_MPU */ b select_next_task save_ns_context: @@ -224,17 +393,6 @@ PendSV_Handler: it eq vstmdbeq r2!, {s16-s31} /* Store the additional FP context registers which are not saved automatically. */ #endif /* configENABLE_FPU || configENABLE_MVE */ - #if ( configENABLE_MPU == 1 ) - subs r2, r2, #48 /* Make space for xSecureContext, PSPLIM, CONTROL, LR and the remaining registers on the stack. */ - str r2, [r1] /* Save the new top of stack in TCB. */ - adds r2, r2, #16 /* r2 = r2 + 16. */ - stm r2, {r4-r11} /* Store the registers that are not saved automatically. */ - mrs r1, psplim /* r1 = PSPLIM. */ - mrs r3, control /* r3 = CONTROL. */ - mov r4, lr /* r4 = LR/EXC_RETURN. */ - subs r2, r2, #16 /* r2 = r2 - 16. */ - stmia r2!, {r0, r1, r3, r4} /* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */ - #else /* configENABLE_MPU */ subs r2, r2, #44 /* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */ str r2, [r1] /* Save the new top of stack in TCB. */ adds r2, r2, #12 /* r2 = r2 + 12. */ @@ -243,7 +401,6 @@ PendSV_Handler: mov r3, lr /* r3 = LR/EXC_RETURN. */ subs r2, r2, #12 /* r2 = r2 - 12. */ stmia r2!, {r0, r1, r3} /* Store xSecureContext, PSPLIM and LR on the stack. */ - #endif /* configENABLE_MPU */ select_next_task: mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY @@ -258,51 +415,6 @@ PendSV_Handler: ldr r1, [r3] /* Read pxCurrentTCB. */ ldr r2, [r1] /* The first item in pxCurrentTCB is the task top of stack. r2 now points to the top of stack. */ - #if ( configENABLE_MPU == 1 ) - dmb /* Complete outstanding transfers before disabling MPU. */ - ldr r3, =0xe000ed94 /* r3 = 0xe000ed94 [Location of MPU_CTRL]. */ - ldr r4, [r3] /* Read the value of MPU_CTRL. */ - bic r4, r4, #1 /* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */ - str r4, [r3] /* Disable MPU. */ - - adds r1, #4 /* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */ - ldr r4, [r1] /* r4 = *r1 i.e. r4 = MAIR0. */ - ldr r3, =0xe000edc0 /* r3 = 0xe000edc0 [Location of MAIR0]. */ - str r4, [r3] /* Program MAIR0. */ - ldr r3, =0xe000ed98 /* r3 = 0xe000ed98 [Location of RNR]. */ - movs r4, #4 /* r4 = 4. */ - str r4, [r3] /* Program RNR = 4. */ - adds r1, #4 /* r1 = r1 + 4. r1 now points to first RBAR in TCB. */ - ldr r3, =0xe000ed9c /* r3 = 0xe000ed9c [Location of RBAR]. */ - ldmia r1!, {r4-r11} /* Read 4 sets of RBAR/RLAR registers from TCB. */ - stmia r3!, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ - - ldr r3, =0xe000ed94 /* r3 = 0xe000ed94 [Location of MPU_CTRL]. */ - ldr r4, [r3] /* Read the value of MPU_CTRL. */ - orr r4, r4, #1 /* r4 = r4 | 1 i.e. Set the bit 0 in r4. */ - str r4, [r3] /* Enable MPU. */ - dsb /* Force memory writes before continuing. */ - #endif /* configENABLE_MPU */ - - #if ( configENABLE_MPU == 1 ) - ldmia r2!, {r0, r1, r3, r4} /* Read from stack - r0 = xSecureContext, r1 = PSPLIM, r3 = CONTROL and r4 = LR. */ - msr psplim, r1 /* Restore the PSPLIM register value for the task. */ - msr control, r3 /* Restore the CONTROL register value for the task. */ - mov lr, r4 /* LR = r4. */ - ldr r3, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */ - str r0, [r3] /* Restore the task's xSecureContext. */ - cbz r0, restore_ns_context /* If there is no secure context for the task, restore the non-secure context. */ - ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - ldr r1, [r3] /* Read pxCurrentTCB. */ - push {r2, r4} - bl SecureContext_LoadContext /* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ - pop {r2, r4} - mov lr, r4 /* LR = r4. */ - lsls r1, r4, #25 /* r1 = r4 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ - bpl restore_ns_context /* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ - msr psp, r2 /* Remember the new top of stack for the task. */ - bx lr - #else /* configENABLE_MPU */ ldmia r2!, {r0, r1, r4} /* Read from stack - r0 = xSecureContext, r1 = PSPLIM and r4 = LR. */ msr psplim, r1 /* Restore the PSPLIM register value for the task. */ mov lr, r4 /* LR = r4. */ @@ -319,7 +431,6 @@ PendSV_Handler: bpl restore_ns_context /* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ msr psp, r2 /* Remember the new top of stack for the task. */ bx lr - #endif /* configENABLE_MPU */ restore_ns_context: ldmia r2!, {r4-r11} /* Restore the registers that are not automatically restored. */ @@ -330,14 +441,50 @@ PendSV_Handler: #endif /* configENABLE_FPU || configENABLE_MVE */ msr psp, r2 /* Remember the new top of stack for the task. */ bx lr + +#endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + SVC_Handler: tst lr, #4 ite eq mrseq r0, msp mrsne r0, psp + + ldr r1, [r0, #24] + ldrb r2, [r1, #-2] + cmp r2, #4 /* portSVC_SYSTEM_CALL_ENTER. */ + beq syscall_enter + cmp r2, #5 /* portSVC_SYSTEM_CALL_ENTER_1. */ + beq syscall_enter_1 + cmp r2, #6 /* portSVC_SYSTEM_CALL_EXIT. */ + beq syscall_exit b vPortSVCHandler_C + + syscall_enter: + mov r1, lr + b vSystemCallEnter + + syscall_enter_1: + mov r1, lr + b vSystemCallEnter_1 + + syscall_exit: + mov r1, lr + b vSystemCallExit + +#else /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + +SVC_Handler: + tst lr, #4 + ite eq + mrseq r0, msp + mrsne r0, psp + b vPortSVCHandler_C + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ /*-----------------------------------------------------------*/ vPortFreeSecureContext: diff --git a/portable/ARMv8M/non_secure/portable/IAR/ARM_CM33_NTZ/mpu_wrappers_v2_asm.S b/portable/ARMv8M/non_secure/portable/IAR/ARM_CM33_NTZ/mpu_wrappers_v2_asm.S new file mode 100644 index 00000000000..f051a6073dd --- /dev/null +++ b/portable/ARMv8M/non_secure/portable/IAR/ARM_CM33_NTZ/mpu_wrappers_v2_asm.S @@ -0,0 +1,1552 @@ +/* + * FreeRTOS Kernel + * Copyright (C) 2021 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 + * + */ + + + SECTION freertos_system_calls:CODE:NOROOT(2) + THUMB +/*-----------------------------------------------------------*/ + +#include "FreeRTOSConfig.h" + +#ifndef configUSE_MPU_WRAPPERS_V1 + #define configUSE_MPU_WRAPPERS_V1 0 +#endif + +/* These must be in sync with portmacro.h. */ +#define portSVC_SYSTEM_CALL_ENTER 4 /* System calls with upto 4 parameters. */ +#define portSVC_SYSTEM_CALL_ENTER_1 5 /* System calls with 5 parameters. */ +#define portSVC_SYSTEM_CALL_EXIT 6 +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + + PUBLIC MPU_xTaskDelayUntil +MPU_xTaskDelayUntil: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskDelayUntil_Unpriv + MPU_xTaskDelayUntil_Priv: + pop {r0} + b MPU_xTaskDelayUntilImpl + MPU_xTaskDelayUntil_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskDelayUntilImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskAbortDelay +MPU_xTaskAbortDelay: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskAbortDelay_Unpriv + MPU_xTaskAbortDelay_Priv: + pop {r0} + b MPU_xTaskAbortDelayImpl + MPU_xTaskAbortDelay_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskAbortDelayImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTaskDelay +MPU_vTaskDelay: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vTaskDelay_Unpriv + MPU_vTaskDelay_Priv: + pop {r0} + b MPU_vTaskDelayImpl + MPU_vTaskDelay_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskDelayImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxTaskPriorityGet +MPU_uxTaskPriorityGet: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_uxTaskPriorityGet_Unpriv + MPU_uxTaskPriorityGet_Priv: + pop {r0} + b MPU_uxTaskPriorityGetImpl + MPU_uxTaskPriorityGet_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxTaskPriorityGetImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_eTaskGetState +MPU_eTaskGetState: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_eTaskGetState_Unpriv + MPU_eTaskGetState_Priv: + pop {r0} + b MPU_eTaskGetStateImpl + MPU_eTaskGetState_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_eTaskGetStateImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTaskGetInfo +MPU_vTaskGetInfo: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vTaskGetInfo_Unpriv + MPU_vTaskGetInfo_Priv: + pop {r0} + b MPU_vTaskGetInfoImpl + MPU_vTaskGetInfo_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskGetInfoImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGetIdleTaskHandle +MPU_xTaskGetIdleTaskHandle: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskGetIdleTaskHandle_Unpriv + MPU_xTaskGetIdleTaskHandle_Priv: + pop {r0} + b MPU_xTaskGetIdleTaskHandleImpl + MPU_xTaskGetIdleTaskHandle_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskGetIdleTaskHandleImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTaskSuspend +MPU_vTaskSuspend: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vTaskSuspend_Unpriv + MPU_vTaskSuspend_Priv: + pop {r0} + b MPU_vTaskSuspendImpl + MPU_vTaskSuspend_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskSuspendImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTaskResume +MPU_vTaskResume: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vTaskResume_Unpriv + MPU_vTaskResume_Priv: + pop {r0} + b MPU_vTaskResumeImpl + MPU_vTaskResume_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskResumeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGetTickCount +MPU_xTaskGetTickCount: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskGetTickCount_Unpriv + MPU_xTaskGetTickCount_Priv: + pop {r0} + b MPU_xTaskGetTickCountImpl + MPU_xTaskGetTickCount_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskGetTickCountImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxTaskGetNumberOfTasks +MPU_uxTaskGetNumberOfTasks: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_uxTaskGetNumberOfTasks_Unpriv + MPU_uxTaskGetNumberOfTasks_Priv: + pop {r0} + b MPU_uxTaskGetNumberOfTasksImpl + MPU_uxTaskGetNumberOfTasks_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxTaskGetNumberOfTasksImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_pcTaskGetName +MPU_pcTaskGetName: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_pcTaskGetName_Unpriv + MPU_pcTaskGetName_Priv: + pop {r0} + b MPU_pcTaskGetNameImpl + MPU_pcTaskGetName_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_pcTaskGetNameImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_ulTaskGetRunTimeCounter +MPU_ulTaskGetRunTimeCounter: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_ulTaskGetRunTimeCounter_Unpriv + MPU_ulTaskGetRunTimeCounter_Priv: + pop {r0} + b MPU_ulTaskGetRunTimeCounterImpl + MPU_ulTaskGetRunTimeCounter_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_ulTaskGetRunTimeCounterImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_ulTaskGetRunTimePercent +MPU_ulTaskGetRunTimePercent: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_ulTaskGetRunTimePercent_Unpriv + MPU_ulTaskGetRunTimePercent_Priv: + pop {r0} + b MPU_ulTaskGetRunTimePercentImpl + MPU_ulTaskGetRunTimePercent_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_ulTaskGetRunTimePercentImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_ulTaskGetIdleRunTimePercent +MPU_ulTaskGetIdleRunTimePercent: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_ulTaskGetIdleRunTimePercent_Unpriv + MPU_ulTaskGetIdleRunTimePercent_Priv: + pop {r0} + b MPU_ulTaskGetIdleRunTimePercentImpl + MPU_ulTaskGetIdleRunTimePercent_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_ulTaskGetIdleRunTimePercentImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_ulTaskGetIdleRunTimeCounter +MPU_ulTaskGetIdleRunTimeCounter: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_ulTaskGetIdleRunTimeCounter_Unpriv + MPU_ulTaskGetIdleRunTimeCounter_Priv: + pop {r0} + b MPU_ulTaskGetIdleRunTimeCounterImpl + MPU_ulTaskGetIdleRunTimeCounter_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_ulTaskGetIdleRunTimeCounterImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTaskSetApplicationTaskTag +MPU_vTaskSetApplicationTaskTag: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vTaskSetApplicationTaskTag_Unpriv + MPU_vTaskSetApplicationTaskTag_Priv: + pop {r0} + b MPU_vTaskSetApplicationTaskTagImpl + MPU_vTaskSetApplicationTaskTag_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskSetApplicationTaskTagImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGetApplicationTaskTag +MPU_xTaskGetApplicationTaskTag: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskGetApplicationTaskTag_Unpriv + MPU_xTaskGetApplicationTaskTag_Priv: + pop {r0} + b MPU_xTaskGetApplicationTaskTagImpl + MPU_xTaskGetApplicationTaskTag_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskGetApplicationTaskTagImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTaskSetThreadLocalStoragePointer +MPU_vTaskSetThreadLocalStoragePointer: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vTaskSetThreadLocalStoragePointer_Unpriv + MPU_vTaskSetThreadLocalStoragePointer_Priv: + pop {r0} + b MPU_vTaskSetThreadLocalStoragePointerImpl + MPU_vTaskSetThreadLocalStoragePointer_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskSetThreadLocalStoragePointerImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_pvTaskGetThreadLocalStoragePointer +MPU_pvTaskGetThreadLocalStoragePointer: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_pvTaskGetThreadLocalStoragePointer_Unpriv + MPU_pvTaskGetThreadLocalStoragePointer_Priv: + pop {r0} + b MPU_pvTaskGetThreadLocalStoragePointerImpl + MPU_pvTaskGetThreadLocalStoragePointer_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_pvTaskGetThreadLocalStoragePointerImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxTaskGetSystemState +MPU_uxTaskGetSystemState: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_uxTaskGetSystemState_Unpriv + MPU_uxTaskGetSystemState_Priv: + pop {r0} + b MPU_uxTaskGetSystemStateImpl + MPU_uxTaskGetSystemState_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxTaskGetSystemStateImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxTaskGetStackHighWaterMark +MPU_uxTaskGetStackHighWaterMark: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_uxTaskGetStackHighWaterMark_Unpriv + MPU_uxTaskGetStackHighWaterMark_Priv: + pop {r0} + b MPU_uxTaskGetStackHighWaterMarkImpl + MPU_uxTaskGetStackHighWaterMark_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxTaskGetStackHighWaterMarkImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxTaskGetStackHighWaterMark2 +MPU_uxTaskGetStackHighWaterMark2: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_uxTaskGetStackHighWaterMark2_Unpriv + MPU_uxTaskGetStackHighWaterMark2_Priv: + pop {r0} + b MPU_uxTaskGetStackHighWaterMark2Impl + MPU_uxTaskGetStackHighWaterMark2_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxTaskGetStackHighWaterMark2Impl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGetCurrentTaskHandle +MPU_xTaskGetCurrentTaskHandle: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskGetCurrentTaskHandle_Unpriv + MPU_xTaskGetCurrentTaskHandle_Priv: + pop {r0} + b MPU_xTaskGetCurrentTaskHandleImpl + MPU_xTaskGetCurrentTaskHandle_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskGetCurrentTaskHandleImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGetSchedulerState +MPU_xTaskGetSchedulerState: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskGetSchedulerState_Unpriv + MPU_xTaskGetSchedulerState_Priv: + pop {r0} + b MPU_xTaskGetSchedulerStateImpl + MPU_xTaskGetSchedulerState_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskGetSchedulerStateImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTaskSetTimeOutState +MPU_vTaskSetTimeOutState: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vTaskSetTimeOutState_Unpriv + MPU_vTaskSetTimeOutState_Priv: + pop {r0} + b MPU_vTaskSetTimeOutStateImpl + MPU_vTaskSetTimeOutState_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskSetTimeOutStateImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskCheckForTimeOut +MPU_xTaskCheckForTimeOut: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskCheckForTimeOut_Unpriv + MPU_xTaskCheckForTimeOut_Priv: + pop {r0} + b MPU_xTaskCheckForTimeOutImpl + MPU_xTaskCheckForTimeOut_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskCheckForTimeOutImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGenericNotify +MPU_xTaskGenericNotify: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskGenericNotify_Unpriv + MPU_xTaskGenericNotify_Priv: + pop {r0} + b MPU_xTaskGenericNotifyImpl + MPU_xTaskGenericNotify_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER_1 + bl MPU_xTaskGenericNotifyImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGenericNotifyWait +MPU_xTaskGenericNotifyWait: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskGenericNotifyWait_Unpriv + MPU_xTaskGenericNotifyWait_Priv: + pop {r0} + b MPU_xTaskGenericNotifyWaitImpl + MPU_xTaskGenericNotifyWait_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER_1 + bl MPU_xTaskGenericNotifyWaitImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_ulTaskGenericNotifyTake +MPU_ulTaskGenericNotifyTake: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_ulTaskGenericNotifyTake_Unpriv + MPU_ulTaskGenericNotifyTake_Priv: + pop {r0} + b MPU_ulTaskGenericNotifyTakeImpl + MPU_ulTaskGenericNotifyTake_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_ulTaskGenericNotifyTakeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGenericNotifyStateClear +MPU_xTaskGenericNotifyStateClear: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskGenericNotifyStateClear_Unpriv + MPU_xTaskGenericNotifyStateClear_Priv: + pop {r0} + b MPU_xTaskGenericNotifyStateClearImpl + MPU_xTaskGenericNotifyStateClear_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskGenericNotifyStateClearImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_ulTaskGenericNotifyValueClear +MPU_ulTaskGenericNotifyValueClear: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_ulTaskGenericNotifyValueClear_Unpriv + MPU_ulTaskGenericNotifyValueClear_Priv: + pop {r0} + b MPU_ulTaskGenericNotifyValueClearImpl + MPU_ulTaskGenericNotifyValueClear_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_ulTaskGenericNotifyValueClearImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueGenericSend +MPU_xQueueGenericSend: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xQueueGenericSend_Unpriv + MPU_xQueueGenericSend_Priv: + pop {r0} + b MPU_xQueueGenericSendImpl + MPU_xQueueGenericSend_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueGenericSendImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxQueueMessagesWaiting +MPU_uxQueueMessagesWaiting: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_uxQueueMessagesWaiting_Unpriv + MPU_uxQueueMessagesWaiting_Priv: + pop {r0} + b MPU_uxQueueMessagesWaitingImpl + MPU_uxQueueMessagesWaiting_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxQueueMessagesWaitingImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxQueueSpacesAvailable +MPU_uxQueueSpacesAvailable: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_uxQueueSpacesAvailable_Unpriv + MPU_uxQueueSpacesAvailable_Priv: + pop {r0} + b MPU_uxQueueSpacesAvailableImpl + MPU_uxQueueSpacesAvailable_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxQueueSpacesAvailableImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueReceive +MPU_xQueueReceive: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xQueueReceive_Unpriv + MPU_xQueueReceive_Priv: + pop {r0} + b MPU_xQueueReceiveImpl + MPU_xQueueReceive_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueReceiveImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueuePeek +MPU_xQueuePeek: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xQueuePeek_Unpriv + MPU_xQueuePeek_Priv: + pop {r0} + b MPU_xQueuePeekImpl + MPU_xQueuePeek_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueuePeekImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueSemaphoreTake +MPU_xQueueSemaphoreTake: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xQueueSemaphoreTake_Unpriv + MPU_xQueueSemaphoreTake_Priv: + pop {r0} + b MPU_xQueueSemaphoreTakeImpl + MPU_xQueueSemaphoreTake_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueSemaphoreTakeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueGetMutexHolder +MPU_xQueueGetMutexHolder: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xQueueGetMutexHolder_Unpriv + MPU_xQueueGetMutexHolder_Priv: + pop {r0} + b MPU_xQueueGetMutexHolderImpl + MPU_xQueueGetMutexHolder_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueGetMutexHolderImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueTakeMutexRecursive +MPU_xQueueTakeMutexRecursive: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xQueueTakeMutexRecursive_Unpriv + MPU_xQueueTakeMutexRecursive_Priv: + pop {r0} + b MPU_xQueueTakeMutexRecursiveImpl + MPU_xQueueTakeMutexRecursive_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueTakeMutexRecursiveImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueGiveMutexRecursive +MPU_xQueueGiveMutexRecursive: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xQueueGiveMutexRecursive_Unpriv + MPU_xQueueGiveMutexRecursive_Priv: + pop {r0} + b MPU_xQueueGiveMutexRecursiveImpl + MPU_xQueueGiveMutexRecursive_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueGiveMutexRecursiveImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueSelectFromSet +MPU_xQueueSelectFromSet: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xQueueSelectFromSet_Unpriv + MPU_xQueueSelectFromSet_Priv: + pop {r0} + b MPU_xQueueSelectFromSetImpl + MPU_xQueueSelectFromSet_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueSelectFromSetImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueAddToSet +MPU_xQueueAddToSet: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xQueueAddToSet_Unpriv + MPU_xQueueAddToSet_Priv: + pop {r0} + b MPU_xQueueAddToSetImpl + MPU_xQueueAddToSet_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueAddToSetImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vQueueAddToRegistry +MPU_vQueueAddToRegistry: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vQueueAddToRegistry_Unpriv + MPU_vQueueAddToRegistry_Priv: + pop {r0} + b MPU_vQueueAddToRegistryImpl + MPU_vQueueAddToRegistry_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vQueueAddToRegistryImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vQueueUnregisterQueue +MPU_vQueueUnregisterQueue: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vQueueUnregisterQueue_Unpriv + MPU_vQueueUnregisterQueue_Priv: + pop {r0} + b MPU_vQueueUnregisterQueueImpl + MPU_vQueueUnregisterQueue_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vQueueUnregisterQueueImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_pcQueueGetName +MPU_pcQueueGetName: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_pcQueueGetName_Unpriv + MPU_pcQueueGetName_Priv: + pop {r0} + b MPU_pcQueueGetNameImpl + MPU_pcQueueGetName_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_pcQueueGetNameImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_pvTimerGetTimerID +MPU_pvTimerGetTimerID: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_pvTimerGetTimerID_Unpriv + MPU_pvTimerGetTimerID_Priv: + pop {r0} + b MPU_pvTimerGetTimerIDImpl + MPU_pvTimerGetTimerID_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_pvTimerGetTimerIDImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTimerSetTimerID +MPU_vTimerSetTimerID: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vTimerSetTimerID_Unpriv + MPU_vTimerSetTimerID_Priv: + pop {r0} + b MPU_vTimerSetTimerIDImpl + MPU_vTimerSetTimerID_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTimerSetTimerIDImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTimerIsTimerActive +MPU_xTimerIsTimerActive: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTimerIsTimerActive_Unpriv + MPU_xTimerIsTimerActive_Priv: + pop {r0} + b MPU_xTimerIsTimerActiveImpl + MPU_xTimerIsTimerActive_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTimerIsTimerActiveImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTimerGetTimerDaemonTaskHandle +MPU_xTimerGetTimerDaemonTaskHandle: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTimerGetTimerDaemonTaskHandle_Unpriv + MPU_xTimerGetTimerDaemonTaskHandle_Priv: + pop {r0} + b MPU_xTimerGetTimerDaemonTaskHandleImpl + MPU_xTimerGetTimerDaemonTaskHandle_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTimerGetTimerDaemonTaskHandleImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTimerGenericCommand +MPU_xTimerGenericCommand: + push {r0} + /* This function can be called from ISR also and therefore, we need a check + * to take privileged path, if called from ISR. */ + mrs r0, ipsr + cmp r0, #0 + bne MPU_xTimerGenericCommand_Priv + mrs r0, control + tst r0, #1 + beq MPU_xTimerGenericCommand_Priv + MPU_xTimerGenericCommand_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER_1 + bl MPU_xTimerGenericCommandImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr + MPU_xTimerGenericCommand_Priv: + pop {r0} + b MPU_xTimerGenericCommandImpl + +/*-----------------------------------------------------------*/ + + PUBLIC MPU_pcTimerGetName +MPU_pcTimerGetName: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_pcTimerGetName_Unpriv + MPU_pcTimerGetName_Priv: + pop {r0} + b MPU_pcTimerGetNameImpl + MPU_pcTimerGetName_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_pcTimerGetNameImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTimerSetReloadMode +MPU_vTimerSetReloadMode: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vTimerSetReloadMode_Unpriv + MPU_vTimerSetReloadMode_Priv: + pop {r0} + b MPU_vTimerSetReloadModeImpl + MPU_vTimerSetReloadMode_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTimerSetReloadModeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTimerGetReloadMode +MPU_xTimerGetReloadMode: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTimerGetReloadMode_Unpriv + MPU_xTimerGetReloadMode_Priv: + pop {r0} + b MPU_xTimerGetReloadModeImpl + MPU_xTimerGetReloadMode_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTimerGetReloadModeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxTimerGetReloadMode +MPU_uxTimerGetReloadMode: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_uxTimerGetReloadMode_Unpriv + MPU_uxTimerGetReloadMode_Priv: + pop {r0} + b MPU_uxTimerGetReloadModeImpl + MPU_uxTimerGetReloadMode_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxTimerGetReloadModeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTimerGetPeriod +MPU_xTimerGetPeriod: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTimerGetPeriod_Unpriv + MPU_xTimerGetPeriod_Priv: + pop {r0} + b MPU_xTimerGetPeriodImpl + MPU_xTimerGetPeriod_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTimerGetPeriodImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTimerGetExpiryTime +MPU_xTimerGetExpiryTime: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTimerGetExpiryTime_Unpriv + MPU_xTimerGetExpiryTime_Priv: + pop {r0} + b MPU_xTimerGetExpiryTimeImpl + MPU_xTimerGetExpiryTime_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTimerGetExpiryTimeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xEventGroupWaitBits +MPU_xEventGroupWaitBits: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xEventGroupWaitBits_Unpriv + MPU_xEventGroupWaitBits_Priv: + pop {r0} + b MPU_xEventGroupWaitBitsImpl + MPU_xEventGroupWaitBits_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER_1 + bl MPU_xEventGroupWaitBitsImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xEventGroupClearBits +MPU_xEventGroupClearBits: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xEventGroupClearBits_Unpriv + MPU_xEventGroupClearBits_Priv: + pop {r0} + b MPU_xEventGroupClearBitsImpl + MPU_xEventGroupClearBits_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xEventGroupClearBitsImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xEventGroupSetBits +MPU_xEventGroupSetBits: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xEventGroupSetBits_Unpriv + MPU_xEventGroupSetBits_Priv: + pop {r0} + b MPU_xEventGroupSetBitsImpl + MPU_xEventGroupSetBits_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xEventGroupSetBitsImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xEventGroupSync +MPU_xEventGroupSync: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xEventGroupSync_Unpriv + MPU_xEventGroupSync_Priv: + pop {r0} + b MPU_xEventGroupSyncImpl + MPU_xEventGroupSync_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xEventGroupSyncImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxEventGroupGetNumber +MPU_uxEventGroupGetNumber: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_uxEventGroupGetNumber_Unpriv + MPU_uxEventGroupGetNumber_Priv: + pop {r0} + b MPU_uxEventGroupGetNumberImpl + MPU_uxEventGroupGetNumber_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxEventGroupGetNumberImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vEventGroupSetNumber +MPU_vEventGroupSetNumber: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vEventGroupSetNumber_Unpriv + MPU_vEventGroupSetNumber_Priv: + pop {r0} + b MPU_vEventGroupSetNumberImpl + MPU_vEventGroupSetNumber_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vEventGroupSetNumberImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferSend +MPU_xStreamBufferSend: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xStreamBufferSend_Unpriv + MPU_xStreamBufferSend_Priv: + pop {r0} + b MPU_xStreamBufferSendImpl + MPU_xStreamBufferSend_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferSendImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferReceive +MPU_xStreamBufferReceive: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xStreamBufferReceive_Unpriv + MPU_xStreamBufferReceive_Priv: + pop {r0} + b MPU_xStreamBufferReceiveImpl + MPU_xStreamBufferReceive_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferReceiveImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferIsFull +MPU_xStreamBufferIsFull: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xStreamBufferIsFull_Unpriv + MPU_xStreamBufferIsFull_Priv: + pop {r0} + b MPU_xStreamBufferIsFullImpl + MPU_xStreamBufferIsFull_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferIsFullImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferIsEmpty +MPU_xStreamBufferIsEmpty: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xStreamBufferIsEmpty_Unpriv + MPU_xStreamBufferIsEmpty_Priv: + pop {r0} + b MPU_xStreamBufferIsEmptyImpl + MPU_xStreamBufferIsEmpty_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferIsEmptyImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferSpacesAvailable +MPU_xStreamBufferSpacesAvailable: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xStreamBufferSpacesAvailable_Unpriv + MPU_xStreamBufferSpacesAvailable_Priv: + pop {r0} + b MPU_xStreamBufferSpacesAvailableImpl + MPU_xStreamBufferSpacesAvailable_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferSpacesAvailableImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferBytesAvailable +MPU_xStreamBufferBytesAvailable: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xStreamBufferBytesAvailable_Unpriv + MPU_xStreamBufferBytesAvailable_Priv: + pop {r0} + b MPU_xStreamBufferBytesAvailableImpl + MPU_xStreamBufferBytesAvailable_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferBytesAvailableImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferSetTriggerLevel +MPU_xStreamBufferSetTriggerLevel: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xStreamBufferSetTriggerLevel_Unpriv + MPU_xStreamBufferSetTriggerLevel_Priv: + pop {r0} + b MPU_xStreamBufferSetTriggerLevelImpl + MPU_xStreamBufferSetTriggerLevel_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferSetTriggerLevelImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferNextMessageLengthBytes +MPU_xStreamBufferNextMessageLengthBytes: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xStreamBufferNextMessageLengthBytes_Unpriv + MPU_xStreamBufferNextMessageLengthBytes_Priv: + pop {r0} + b MPU_xStreamBufferNextMessageLengthBytesImpl + MPU_xStreamBufferNextMessageLengthBytes_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferNextMessageLengthBytesImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + +/* Default weak implementations in case one is not available from + * mpu_wrappers because of config options. */ + + PUBWEAK MPU_xTaskDelayUntilImpl +MPU_xTaskDelayUntilImpl: + b MPU_xTaskDelayUntilImpl + + PUBWEAK MPU_xTaskAbortDelayImpl +MPU_xTaskAbortDelayImpl: + b MPU_xTaskAbortDelayImpl + + PUBWEAK MPU_vTaskDelayImpl +MPU_vTaskDelayImpl: + b MPU_vTaskDelayImpl + + PUBWEAK MPU_uxTaskPriorityGetImpl +MPU_uxTaskPriorityGetImpl: + b MPU_uxTaskPriorityGetImpl + + PUBWEAK MPU_eTaskGetStateImpl +MPU_eTaskGetStateImpl: + b MPU_eTaskGetStateImpl + + PUBWEAK MPU_vTaskGetInfoImpl +MPU_vTaskGetInfoImpl: + b MPU_vTaskGetInfoImpl + + PUBWEAK MPU_xTaskGetIdleTaskHandleImpl +MPU_xTaskGetIdleTaskHandleImpl: + b MPU_xTaskGetIdleTaskHandleImpl + + PUBWEAK MPU_vTaskSuspendImpl +MPU_vTaskSuspendImpl: + b MPU_vTaskSuspendImpl + + PUBWEAK MPU_vTaskResumeImpl +MPU_vTaskResumeImpl: + b MPU_vTaskResumeImpl + + PUBWEAK MPU_xTaskGetTickCountImpl +MPU_xTaskGetTickCountImpl: + b MPU_xTaskGetTickCountImpl + + PUBWEAK MPU_uxTaskGetNumberOfTasksImpl +MPU_uxTaskGetNumberOfTasksImpl: + b MPU_uxTaskGetNumberOfTasksImpl + + PUBWEAK MPU_pcTaskGetNameImpl +MPU_pcTaskGetNameImpl: + b MPU_pcTaskGetNameImpl + + PUBWEAK MPU_ulTaskGetRunTimeCounterImpl +MPU_ulTaskGetRunTimeCounterImpl: + b MPU_ulTaskGetRunTimeCounterImpl + + PUBWEAK MPU_ulTaskGetRunTimePercentImpl +MPU_ulTaskGetRunTimePercentImpl: + b MPU_ulTaskGetRunTimePercentImpl + + PUBWEAK MPU_ulTaskGetIdleRunTimePercentImpl +MPU_ulTaskGetIdleRunTimePercentImpl: + b MPU_ulTaskGetIdleRunTimePercentImpl + + PUBWEAK MPU_ulTaskGetIdleRunTimeCounterImpl +MPU_ulTaskGetIdleRunTimeCounterImpl: + b MPU_ulTaskGetIdleRunTimeCounterImpl + + PUBWEAK MPU_vTaskSetApplicationTaskTagImpl +MPU_vTaskSetApplicationTaskTagImpl: + b MPU_vTaskSetApplicationTaskTagImpl + + PUBWEAK MPU_xTaskGetApplicationTaskTagImpl +MPU_xTaskGetApplicationTaskTagImpl: + b MPU_xTaskGetApplicationTaskTagImpl + + PUBWEAK MPU_vTaskSetThreadLocalStoragePointerImpl +MPU_vTaskSetThreadLocalStoragePointerImpl: + b MPU_vTaskSetThreadLocalStoragePointerImpl + + PUBWEAK MPU_pvTaskGetThreadLocalStoragePointerImpl +MPU_pvTaskGetThreadLocalStoragePointerImpl: + b MPU_pvTaskGetThreadLocalStoragePointerImpl + + PUBWEAK MPU_uxTaskGetSystemStateImpl +MPU_uxTaskGetSystemStateImpl: + b MPU_uxTaskGetSystemStateImpl + + PUBWEAK MPU_uxTaskGetStackHighWaterMarkImpl +MPU_uxTaskGetStackHighWaterMarkImpl: + b MPU_uxTaskGetStackHighWaterMarkImpl + + PUBWEAK MPU_uxTaskGetStackHighWaterMark2Impl +MPU_uxTaskGetStackHighWaterMark2Impl: + b MPU_uxTaskGetStackHighWaterMark2Impl + + PUBWEAK MPU_xTaskGetCurrentTaskHandleImpl +MPU_xTaskGetCurrentTaskHandleImpl: + b MPU_xTaskGetCurrentTaskHandleImpl + + PUBWEAK MPU_xTaskGetSchedulerStateImpl +MPU_xTaskGetSchedulerStateImpl: + b MPU_xTaskGetSchedulerStateImpl + + PUBWEAK MPU_vTaskSetTimeOutStateImpl +MPU_vTaskSetTimeOutStateImpl: + b MPU_vTaskSetTimeOutStateImpl + + PUBWEAK MPU_xTaskCheckForTimeOutImpl +MPU_xTaskCheckForTimeOutImpl: + b MPU_xTaskCheckForTimeOutImpl + + PUBWEAK MPU_xTaskGenericNotifyImpl +MPU_xTaskGenericNotifyImpl: + b MPU_xTaskGenericNotifyImpl + + PUBWEAK MPU_xTaskGenericNotifyWaitImpl +MPU_xTaskGenericNotifyWaitImpl: + b MPU_xTaskGenericNotifyWaitImpl + + PUBWEAK MPU_ulTaskGenericNotifyTakeImpl +MPU_ulTaskGenericNotifyTakeImpl: + b MPU_ulTaskGenericNotifyTakeImpl + + PUBWEAK MPU_xTaskGenericNotifyStateClearImpl +MPU_xTaskGenericNotifyStateClearImpl: + b MPU_xTaskGenericNotifyStateClearImpl + + PUBWEAK MPU_ulTaskGenericNotifyValueClearImpl +MPU_ulTaskGenericNotifyValueClearImpl: + b MPU_ulTaskGenericNotifyValueClearImpl + + PUBWEAK MPU_xQueueGenericSendImpl +MPU_xQueueGenericSendImpl: + b MPU_xQueueGenericSendImpl + + PUBWEAK MPU_uxQueueMessagesWaitingImpl +MPU_uxQueueMessagesWaitingImpl: + b MPU_uxQueueMessagesWaitingImpl + + PUBWEAK MPU_uxQueueSpacesAvailableImpl +MPU_uxQueueSpacesAvailableImpl: + b MPU_uxQueueSpacesAvailableImpl + + PUBWEAK MPU_xQueueReceiveImpl +MPU_xQueueReceiveImpl: + b MPU_xQueueReceiveImpl + + PUBWEAK MPU_xQueuePeekImpl +MPU_xQueuePeekImpl: + b MPU_xQueuePeekImpl + + PUBWEAK MPU_xQueueSemaphoreTakeImpl +MPU_xQueueSemaphoreTakeImpl: + b MPU_xQueueSemaphoreTakeImpl + + PUBWEAK MPU_xQueueGetMutexHolderImpl +MPU_xQueueGetMutexHolderImpl: + b MPU_xQueueGetMutexHolderImpl + + PUBWEAK MPU_xQueueTakeMutexRecursiveImpl +MPU_xQueueTakeMutexRecursiveImpl: + b MPU_xQueueTakeMutexRecursiveImpl + + PUBWEAK MPU_xQueueGiveMutexRecursiveImpl +MPU_xQueueGiveMutexRecursiveImpl: + b MPU_xQueueGiveMutexRecursiveImpl + + PUBWEAK MPU_xQueueSelectFromSetImpl +MPU_xQueueSelectFromSetImpl: + b MPU_xQueueSelectFromSetImpl + + PUBWEAK MPU_xQueueAddToSetImpl +MPU_xQueueAddToSetImpl: + b MPU_xQueueAddToSetImpl + + PUBWEAK MPU_vQueueAddToRegistryImpl +MPU_vQueueAddToRegistryImpl: + b MPU_vQueueAddToRegistryImpl + + PUBWEAK MPU_vQueueUnregisterQueueImpl +MPU_vQueueUnregisterQueueImpl: + b MPU_vQueueUnregisterQueueImpl + + PUBWEAK MPU_pcQueueGetNameImpl +MPU_pcQueueGetNameImpl: + b MPU_pcQueueGetNameImpl + + PUBWEAK MPU_pvTimerGetTimerIDImpl +MPU_pvTimerGetTimerIDImpl: + b MPU_pvTimerGetTimerIDImpl + + PUBWEAK MPU_vTimerSetTimerIDImpl +MPU_vTimerSetTimerIDImpl: + b MPU_vTimerSetTimerIDImpl + + PUBWEAK MPU_xTimerIsTimerActiveImpl +MPU_xTimerIsTimerActiveImpl: + b MPU_xTimerIsTimerActiveImpl + + PUBWEAK MPU_xTimerGetTimerDaemonTaskHandleImpl +MPU_xTimerGetTimerDaemonTaskHandleImpl: + b MPU_xTimerGetTimerDaemonTaskHandleImpl + + PUBWEAK MPU_xTimerGenericCommandImpl +MPU_xTimerGenericCommandImpl: + b MPU_xTimerGenericCommandImpl + + PUBWEAK MPU_pcTimerGetNameImpl +MPU_pcTimerGetNameImpl: + b MPU_pcTimerGetNameImpl + + PUBWEAK MPU_vTimerSetReloadModeImpl +MPU_vTimerSetReloadModeImpl: + b MPU_vTimerSetReloadModeImpl + + PUBWEAK MPU_xTimerGetReloadModeImpl +MPU_xTimerGetReloadModeImpl: + b MPU_xTimerGetReloadModeImpl + + PUBWEAK MPU_uxTimerGetReloadModeImpl +MPU_uxTimerGetReloadModeImpl: + b MPU_uxTimerGetReloadModeImpl + + PUBWEAK MPU_xTimerGetPeriodImpl +MPU_xTimerGetPeriodImpl: + b MPU_xTimerGetPeriodImpl + + PUBWEAK MPU_xTimerGetExpiryTimeImpl +MPU_xTimerGetExpiryTimeImpl: + b MPU_xTimerGetExpiryTimeImpl + + PUBWEAK MPU_xEventGroupWaitBitsImpl +MPU_xEventGroupWaitBitsImpl: + b MPU_xEventGroupWaitBitsImpl + + PUBWEAK MPU_xEventGroupClearBitsImpl +MPU_xEventGroupClearBitsImpl: + b MPU_xEventGroupClearBitsImpl + + PUBWEAK MPU_xEventGroupSetBitsImpl +MPU_xEventGroupSetBitsImpl: + b MPU_xEventGroupSetBitsImpl + + PUBWEAK MPU_xEventGroupSyncImpl +MPU_xEventGroupSyncImpl: + b MPU_xEventGroupSyncImpl + + PUBWEAK MPU_uxEventGroupGetNumberImpl +MPU_uxEventGroupGetNumberImpl: + b MPU_uxEventGroupGetNumberImpl + + PUBWEAK MPU_vEventGroupSetNumberImpl +MPU_vEventGroupSetNumberImpl: + b MPU_vEventGroupSetNumberImpl + + PUBWEAK MPU_xStreamBufferSendImpl +MPU_xStreamBufferSendImpl: + b MPU_xStreamBufferSendImpl + + PUBWEAK MPU_xStreamBufferReceiveImpl +MPU_xStreamBufferReceiveImpl: + b MPU_xStreamBufferReceiveImpl + + PUBWEAK MPU_xStreamBufferIsFullImpl +MPU_xStreamBufferIsFullImpl: + b MPU_xStreamBufferIsFullImpl + + PUBWEAK MPU_xStreamBufferIsEmptyImpl +MPU_xStreamBufferIsEmptyImpl: + b MPU_xStreamBufferIsEmptyImpl + + PUBWEAK MPU_xStreamBufferSpacesAvailableImpl +MPU_xStreamBufferSpacesAvailableImpl: + b MPU_xStreamBufferSpacesAvailableImpl + + PUBWEAK MPU_xStreamBufferBytesAvailableImpl +MPU_xStreamBufferBytesAvailableImpl: + b MPU_xStreamBufferBytesAvailableImpl + + PUBWEAK MPU_xStreamBufferSetTriggerLevelImpl +MPU_xStreamBufferSetTriggerLevelImpl: + b MPU_xStreamBufferSetTriggerLevelImpl + + PUBWEAK MPU_xStreamBufferNextMessageLengthBytesImpl +MPU_xStreamBufferNextMessageLengthBytesImpl: + b MPU_xStreamBufferNextMessageLengthBytesImpl + +/*-----------------------------------------------------------*/ + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + + END diff --git a/portable/ARMv8M/non_secure/portable/IAR/ARM_CM33_NTZ/portasm.s b/portable/ARMv8M/non_secure/portable/IAR/ARM_CM33_NTZ/portasm.s index 581b84d4951..ec52025270b 100644 --- a/portable/ARMv8M/non_secure/portable/IAR/ARM_CM33_NTZ/portasm.s +++ b/portable/ARMv8M/non_secure/portable/IAR/ARM_CM33_NTZ/portasm.s @@ -32,9 +32,18 @@ the code is included in C files but excluded by the preprocessor in assembly files (__ICCARM__ is defined by the IAR C compiler but not by the IAR assembler. */ #include "FreeRTOSConfig.h" +#ifndef configUSE_MPU_WRAPPERS_V1 + #define configUSE_MPU_WRAPPERS_V1 0 +#endif + EXTERN pxCurrentTCB EXTERN vTaskSwitchContext EXTERN vPortSVCHandler_C +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + EXTERN vSystemCallEnter + EXTERN vSystemCallEnter_1 + EXTERN vSystemCallExit +#endif PUBLIC xIsPrivileged PUBLIC vResetPrivilege @@ -79,48 +88,79 @@ vResetPrivilege: THUMB /*-----------------------------------------------------------*/ +#if ( configENABLE_MPU == 1 ) + +vRestoreContextOfFirstTask: + program_mpu_first_task: + ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + ldr r0, [r2] /* r0 = pxCurrentTCB. */ + + dmb /* Complete outstanding transfers before disabling MPU. */ + ldr r1, =0xe000ed94 /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + ldr r2, [r1] /* Read the value of MPU_CTRL. */ + bic r2, #1 /* r2 = r2 & ~1 i.e. Clear the bit 0 in r2. */ + str r2, [r1] /* Disable MPU. */ + + adds r0, #4 /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */ + ldr r1, [r0] /* r1 = *r0 i.e. r1 = MAIR0. */ + ldr r2, =0xe000edc0 /* r2 = 0xe000edc0 [Location of MAIR0]. */ + str r1, [r2] /* Program MAIR0. */ + + adds r0, #4 /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */ + ldr r1, =0xe000ed98 /* r1 = 0xe000ed98 [Location of RNR]. */ + ldr r2, =0xe000ed9c /* r2 = 0xe000ed9c [Location of RBAR]. */ + + movs r3, #4 /* r3 = 4. */ + str r3, [r1] /* Program RNR = 4. */ + ldmia r0!, {r4-r11} /* Read 4 sets of RBAR/RLAR registers from TCB. */ + stmia r2, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ + + #if ( configTOTAL_MPU_REGIONS == 16 ) + movs r3, #8 /* r3 = 8. */ + str r3, [r1] /* Program RNR = 8. */ + ldmia r0!, {r4-r11} /* Read 4 sets of RBAR/RLAR registers from TCB. */ + stmia r2, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ + movs r3, #12 /* r3 = 12. */ + str r3, [r1] /* Program RNR = 12. */ + ldmia r0!, {r4-r11} /* Read 4 sets of RBAR/RLAR registers from TCB. */ + stmia r2, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ + #endif /* configTOTAL_MPU_REGIONS == 16 */ + + ldr r1, =0xe000ed94 /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + ldr r2, [r1] /* Read the value of MPU_CTRL. */ + orr r2, #1 /* r2 = r2 | 1 i.e. Set the bit 0 in r2. */ + str r2, [r1] /* Enable MPU. */ + dsb /* Force memory writes before continuing. */ + + restore_context_first_task: + ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + ldr r0, [r2] /* r0 = pxCurrentTCB.*/ + ldr r1, [r0] /* r1 = Location of saved context in TCB. */ + + restore_special_regs_first_task: + ldmdb r1!, {r2-r4, lr} /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */ + msr psp, r2 + msr psplim, r3 + msr control, r4 + + restore_general_regs_first_task: + ldmdb r1!, {r4-r11} /* r4-r11 contain hardware saved context. */ + stmia r2!, {r4-r11} /* Copy the hardware saved context on the task stack. */ + ldmdb r1!, {r4-r11} /* r4-r11 restored. */ + + restore_context_done_first_task: + str r1, [r0] /* Save the location where the context should be saved next as the first member of TCB. */ + mov r0, #0 + msr basepri, r0 /* Ensure that interrupts are enabled when the first task starts. */ + bx lr + +#else /* configENABLE_MPU */ + vRestoreContextOfFirstTask: ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r2] /* Read pxCurrentTCB. */ ldr r0, [r1] /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ -#if ( configENABLE_MPU == 1 ) - dmb /* Complete outstanding transfers before disabling MPU. */ - ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ - ldr r4, [r2] /* Read the value of MPU_CTRL. */ - bic r4, r4, #1 /* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */ - str r4, [r2] /* Disable MPU. */ - - adds r1, #4 /* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */ - ldr r3, [r1] /* r3 = *r1 i.e. r3 = MAIR0. */ - ldr r2, =0xe000edc0 /* r2 = 0xe000edc0 [Location of MAIR0]. */ - str r3, [r2] /* Program MAIR0. */ - ldr r2, =0xe000ed98 /* r2 = 0xe000ed98 [Location of RNR]. */ - movs r3, #4 /* r3 = 4. */ - str r3, [r2] /* Program RNR = 4. */ - adds r1, #4 /* r1 = r1 + 4. r1 now points to first RBAR in TCB. */ - ldr r2, =0xe000ed9c /* r2 = 0xe000ed9c [Location of RBAR]. */ - ldmia r1!, {r4-r11} /* Read 4 sets of RBAR/RLAR registers from TCB. */ - stmia r2!, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ - - ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ - ldr r4, [r2] /* Read the value of MPU_CTRL. */ - orr r4, r4, #1 /* r4 = r4 | 1 i.e. Set the bit 0 in r4. */ - str r4, [r2] /* Enable MPU. */ - dsb /* Force memory writes before continuing. */ -#endif /* configENABLE_MPU */ - -#if ( configENABLE_MPU == 1 ) - ldm r0!, {r1-r3} /* Read from stack - r1 = PSPLIM, r2 = CONTROL and r3 = EXC_RETURN. */ - msr psplim, r1 /* Set this task's PSPLIM value. */ - msr control, r2 /* Set this task's CONTROL value. */ - adds r0, #32 /* Discard everything up to r0. */ - msr psp, r0 /* This is now the new top of stack to use in the task. */ - isb - mov r0, #0 - msr basepri, r0 /* Ensure that interrupts are enabled when the first task starts. */ - bx r3 /* Finally, branch to EXC_RETURN. */ -#else /* configENABLE_MPU */ ldm r0!, {r1-r2} /* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */ msr psplim, r1 /* Set this task's PSPLIM value. */ movs r1, #2 /* r1 = 2. */ @@ -131,6 +171,7 @@ vRestoreContextOfFirstTask: mov r0, #0 msr basepri, r0 /* Ensure that interrupts are enabled when the first task starts. */ bx r2 /* Finally, branch to EXC_RETURN. */ + #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ @@ -169,6 +210,114 @@ vClearInterruptMask: bx lr /* Return. */ /*-----------------------------------------------------------*/ +#if ( configENABLE_MPU == 1 ) + +PendSV_Handler: + ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + ldr r0, [r2] /* r0 = pxCurrentTCB. */ + ldr r1, [r0] /* r1 = Location in TCB where the context should be saved. */ + mrs r2, psp /* r2 = PSP. */ + + save_general_regs: + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + add r2, r2, #0x20 /* Move r2 to location where s0 is saved. */ + tst lr, #0x10 + ittt eq + vstmiaeq r1!, {s16-s31} /* Store s16-s31. */ + vldmiaeq r2, {s0-s16} /* Copy hardware saved FP context into s0-s16. */ + vstmiaeq r1!, {s0-s16} /* Store hardware saved FP context. */ + sub r2, r2, #0x20 /* Set r2 back to the location of hardware saved context. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ + + stmia r1!, {r4-r11} /* Store r4-r11. */ + ldmia r2, {r4-r11} /* Copy the hardware saved context into r4-r11. */ + stmia r1!, {r4-r11} /* Store the hardware saved context. */ + + save_special_regs: + mrs r3, psplim /* r3 = PSPLIM. */ + mrs r4, control /* r4 = CONTROL. */ + stmia r1!, {r2-r4, lr} /* Store original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */ + str r1, [r0] /* Save the location from where the context should be restored as the first member of TCB. */ + + select_next_task: + mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY + msr basepri, r0 /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + dsb + isb + bl vTaskSwitchContext + mov r0, #0 /* r0 = 0. */ + msr basepri, r0 /* Enable interrupts. */ + + program_mpu: + ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + ldr r0, [r2] /* r0 = pxCurrentTCB. */ + + dmb /* Complete outstanding transfers before disabling MPU. */ + ldr r1, =0xe000ed94 /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + ldr r2, [r1] /* Read the value of MPU_CTRL. */ + bic r2, #1 /* r2 = r2 & ~1 i.e. Clear the bit 0 in r2. */ + str r2, [r1] /* Disable MPU. */ + + adds r0, #4 /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */ + ldr r1, [r0] /* r1 = *r0 i.e. r1 = MAIR0. */ + ldr r2, =0xe000edc0 /* r2 = 0xe000edc0 [Location of MAIR0]. */ + str r1, [r2] /* Program MAIR0. */ + + adds r0, #4 /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */ + ldr r1, =0xe000ed98 /* r1 = 0xe000ed98 [Location of RNR]. */ + ldr r2, =0xe000ed9c /* r2 = 0xe000ed9c [Location of RBAR]. */ + + movs r3, #4 /* r3 = 4. */ + str r3, [r1] /* Program RNR = 4. */ + ldmia r0!, {r4-r11} /* Read 4 sets of RBAR/RLAR registers from TCB. */ + stmia r2, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ + + #if ( configTOTAL_MPU_REGIONS == 16 ) + movs r3, #8 /* r3 = 8. */ + str r3, [r1] /* Program RNR = 8. */ + ldmia r0!, {r4-r11} /* Read 4 sets of RBAR/RLAR registers from TCB. */ + stmia r2, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ + movs r3, #12 /* r3 = 12. */ + str r3, [r1] /* Program RNR = 12. */ + ldmia r0!, {r4-r11} /* Read 4 sets of RBAR/RLAR registers from TCB. */ + stmia r2, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ + #endif /* configTOTAL_MPU_REGIONS == 16 */ + + ldr r1, =0xe000ed94 /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + ldr r2, [r1] /* Read the value of MPU_CTRL. */ + orr r2, #1 /* r2 = r2 | 1 i.e. Set the bit 0 in r2. */ + str r2, [r1] /* Enable MPU. */ + dsb /* Force memory writes before continuing. */ + + restore_context: + ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + ldr r0, [r2] /* r0 = pxCurrentTCB.*/ + ldr r1, [r0] /* r1 = Location of saved context in TCB. */ + + restore_special_regs: + ldmdb r1!, {r2-r4, lr} /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */ + msr psp, r2 + msr psplim, r3 + msr control, r4 + + restore_general_regs: + ldmdb r1!, {r4-r11} /* r4-r11 contain hardware saved context. */ + stmia r2!, {r4-r11} /* Copy the hardware saved context on the task stack. */ + ldmdb r1!, {r4-r11} /* r4-r11 restored. */ + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + tst lr, #0x10 + ittt eq + vldmdbeq r1!, {s0-s16} /* s0-s16 contain hardware saved FP context. */ + vstmiaeq r2!, {s0-s16} /* Copy hardware saved FP context on the task stack. */ + vldmdbeq r1!, {s16-s31} /* Restore s16-s31. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ + + restore_context_done: + str r1, [r0] /* Save the location where the context should be saved next as the first member of TCB. */ + bx lr + +#else /* configENABLE_MPU */ + PendSV_Handler: mrs r0, psp /* Read PSP in r0. */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) @@ -176,16 +325,10 @@ PendSV_Handler: it eq vstmdbeq r0!, {s16-s31} /* Store the additional FP context registers which are not saved automatically. */ #endif /* configENABLE_FPU || configENABLE_MVE */ -#if ( configENABLE_MPU == 1 ) - mrs r1, psplim /* r1 = PSPLIM. */ - mrs r2, control /* r2 = CONTROL. */ - mov r3, lr /* r3 = LR/EXC_RETURN. */ - stmdb r0!, {r1-r11} /* Store on the stack - PSPLIM, CONTROL, LR and registers that are not automatically saved. */ -#else /* configENABLE_MPU */ + mrs r2, psplim /* r2 = PSPLIM. */ mov r3, lr /* r3 = LR/EXC_RETURN. */ stmdb r0!, {r2-r11} /* Store on the stack - PSPLIM, LR and registers that are not automatically. */ -#endif /* configENABLE_MPU */ ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r2] /* Read pxCurrentTCB. */ @@ -203,37 +346,7 @@ PendSV_Handler: ldr r1, [r2] /* Read pxCurrentTCB. */ ldr r0, [r1] /* The first item in pxCurrentTCB is the task top of stack. r0 now points to the top of stack. */ -#if ( configENABLE_MPU == 1 ) - dmb /* Complete outstanding transfers before disabling MPU. */ - ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ - ldr r4, [r2] /* Read the value of MPU_CTRL. */ - bic r4, r4, #1 /* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */ - str r4, [r2] /* Disable MPU. */ - - adds r1, #4 /* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */ - ldr r3, [r1] /* r3 = *r1 i.e. r3 = MAIR0. */ - ldr r2, =0xe000edc0 /* r2 = 0xe000edc0 [Location of MAIR0]. */ - str r3, [r2] /* Program MAIR0. */ - ldr r2, =0xe000ed98 /* r2 = 0xe000ed98 [Location of RNR]. */ - movs r3, #4 /* r3 = 4. */ - str r3, [r2] /* Program RNR = 4. */ - adds r1, #4 /* r1 = r1 + 4. r1 now points to first RBAR in TCB. */ - ldr r2, =0xe000ed9c /* r2 = 0xe000ed9c [Location of RBAR]. */ - ldmia r1!, {r4-r11} /* Read 4 sets of RBAR/RLAR registers from TCB. */ - stmia r2!, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ - - ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ - ldr r4, [r2] /* Read the value of MPU_CTRL. */ - orr r4, r4, #1 /* r4 = r4 | 1 i.e. Set the bit 0 in r4. */ - str r4, [r2] /* Enable MPU. */ - dsb /* Force memory writes before continuing. */ -#endif /* configENABLE_MPU */ - -#if ( configENABLE_MPU == 1 ) - ldmia r0!, {r1-r11} /* Read from stack - r1 = PSPLIM, r2 = CONTROL, r3 = LR and r4-r11 restored. */ -#else /* configENABLE_MPU */ ldmia r0!, {r2-r11} /* Read from stack - r2 = PSPLIM, r3 = LR and r4-r11 restored. */ -#endif /* configENABLE_MPU */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) tst r3, #0x10 /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ @@ -241,22 +354,53 @@ PendSV_Handler: vldmiaeq r0!, {s16-s31} /* Restore the additional FP context registers which are not restored automatically. */ #endif /* configENABLE_FPU || configENABLE_MVE */ - #if ( configENABLE_MPU == 1 ) - msr psplim, r1 /* Restore the PSPLIM register value for the task. */ - msr control, r2 /* Restore the CONTROL register value for the task. */ -#else /* configENABLE_MPU */ msr psplim, r2 /* Restore the PSPLIM register value for the task. */ -#endif /* configENABLE_MPU */ msr psp, r0 /* Remember the new top of stack for the task. */ bx r3 + +#endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + +SVC_Handler: + tst lr, #4 + ite eq + mrseq r0, msp + mrsne r0, psp + + ldr r1, [r0, #24] + ldrb r2, [r1, #-2] + cmp r2, #4 /* portSVC_SYSTEM_CALL_ENTER. */ + beq syscall_enter + cmp r2, #5 /* portSVC_SYSTEM_CALL_ENTER_1. */ + beq syscall_enter_1 + cmp r2, #6 /* portSVC_SYSTEM_CALL_EXIT. */ + beq syscall_exit + b vPortSVCHandler_C + + syscall_enter: + mov r1, lr + b vSystemCallEnter + + syscall_enter_1: + mov r1, lr + b vSystemCallEnter_1 + + syscall_exit: + mov r1, lr + b vSystemCallExit + +#else /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + SVC_Handler: tst lr, #4 ite eq mrseq r0, msp mrsne r0, psp b vPortSVCHandler_C + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ /*-----------------------------------------------------------*/ END diff --git a/portable/ARMv8M/non_secure/portmacrocommon.h b/portable/ARMv8M/non_secure/portmacrocommon.h index c2ca5fa7730..65ac109c802 100644 --- a/portable/ARMv8M/non_secure/portmacrocommon.h +++ b/portable/ARMv8M/non_secure/portmacrocommon.h @@ -186,23 +186,120 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #define portMPU_REGION_EXECUTE_NEVER ( 1UL ) /*-----------------------------------------------------------*/ -/** - * @brief Settings to define an MPU region. - */ -typedef struct MPURegionSettings -{ - uint32_t ulRBAR; /**< RBAR for the region. */ - uint32_t ulRLAR; /**< RLAR for the region. */ -} MPURegionSettings_t; +#if ( configENABLE_MPU == 1 ) -/** - * @brief MPU settings as stored in the TCB. - */ -typedef struct MPU_SETTINGS -{ - uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ - MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */ -} xMPU_SETTINGS; + /** + * @brief Settings to define an MPU region. + */ + typedef struct MPURegionSettings + { + uint32_t ulRBAR; /**< RBAR for the region. */ + uint32_t ulRLAR; /**< RLAR for the region. */ + } MPURegionSettings_t; + + #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + + #ifndef configSYSTEM_CALL_STACK_SIZE + #error configSYSTEM_CALL_STACK_SIZE must be defined to the desired size of the system call stack in words for using MPU wrappers v2. + #endif + + /** + * @brief System call stack. + */ + typedef struct SYSTEM_CALL_STACK_INFO + { + uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ]; + uint32_t * pulSystemCallStack; + uint32_t * pulSystemCallStackLimit; + uint32_t * pulTaskStack; + uint32_t ulLinkRegisterAtSystemCallEntry; + uint32_t ulStackLimitRegisterAtSystemCallEntry; + } xSYSTEM_CALL_STACK_INFO; + + #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + + /** + * @brief MPU settings as stored in the TCB. + */ + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + + #if( configENABLE_TRUSTZONE == 1 ) + + /* + * +-----------+---------------+----------+-----------------+------------------------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | + * | | | | PC, xPSR | CONTROL, EXC_RETURN | | + * +-----------+---------------+----------+-----------------+------------------------------+-----+ + * + * <-----------><--------------><---------><----------------><-----------------------------><----> + * 16 16 8 8 5 1 + */ + #define MAX_CONTEXT_SIZE 54 + + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ + + /* + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | + * | | | | PC, xPSR | EXC_RETURN | | + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * + * <-----------><--------------><---------><----------------><---------------------><----> + * 16 16 8 8 4 1 + */ + #define MAX_CONTEXT_SIZE 53 + + #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + + #else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ + + #if( configENABLE_TRUSTZONE == 1 ) + + /* + * +----------+-----------------+------------------------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | + * | | PC, xPSR | CONTROL, EXC_RETURN | | + * +----------+-----------------+------------------------------+-----+ + * + * <---------><----------------><------------------------------><----> + * 8 8 5 1 + */ + #define MAX_CONTEXT_SIZE 22 + + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ + + /* + * +----------+-----------------+----------------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | + * | | PC, xPSR | EXC_RETURN | | + * +----------+-----------------+----------------------+-----+ + * + * <---------><----------------><----------------------><----> + * 8 8 4 1 + */ + #define MAX_CONTEXT_SIZE 21 + + #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + + #endif /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ + + /* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ + #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) + #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) + + typedef struct MPU_SETTINGS + { + uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ + MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */ + uint32_t ulContext[ MAX_CONTEXT_SIZE ]; + uint32_t ulTaskFlags; + + #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo; + #endif + } xMPU_SETTINGS; + +#endif /* configENABLE_MPU == 1 */ /*-----------------------------------------------------------*/ /** @@ -223,6 +320,9 @@ typedef struct MPU_SETTINGS #define portSVC_FREE_SECURE_CONTEXT 1 #define portSVC_START_SCHEDULER 2 #define portSVC_RAISE_PRIVILEGE 3 +#define portSVC_SYSTEM_CALL_ENTER 4 /* System calls with upto 4 parameters. */ +#define portSVC_SYSTEM_CALL_ENTER_1 5 /* System calls with 5 parameters. */ +#define portSVC_SYSTEM_CALL_EXIT 6 /*-----------------------------------------------------------*/ /** @@ -315,6 +415,20 @@ typedef struct MPU_SETTINGS #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ +#if ( configENABLE_MPU == 1 ) + + extern BaseType_t xPortIsTaskPrivileged( void ); + + /** + * @brief Checks whether or not the calling task is privileged. + * + * @return pdTRUE if the calling task is privileged, pdFALSE otherwise. + */ + #define portIS_TASK_PRIVILEGED() xPortIsTaskPrivileged() + +#endif /* configENABLE_MPU == 1 */ +/*-----------------------------------------------------------*/ + /** * @brief Barriers. */ diff --git a/portable/CCS/ARM_CM3/port.c b/portable/CCS/ARM_CM3/port.c index f3c4e5add03..530e38ad3a2 100755 --- a/portable/CCS/ARM_CM3/port.c +++ b/portable/CCS/ARM_CM3/port.c @@ -249,6 +249,10 @@ BaseType_t xPortStartScheduler( void ) * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ configASSERT( ucMaxSysCallPriority ); + /* Check that the bits not implemented in hardware are zero in + * configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & ( ~ucMaxPriorityValue ) ) == 0U ); + /* Calculate the maximum acceptable priority group value for the number * of bits read back. */ @@ -285,28 +289,6 @@ BaseType_t xPortStartScheduler( void ) ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulImplementedPrioBits; } - #ifdef __NVIC_PRIO_BITS - { - /* - * Check that the number of implemented priority bits queried from - * hardware is at least as many as specified in the CMSIS - * __NVIC_PRIO_BITS configuration macro. - */ - configASSERT( ulImplementedPrioBits >= __NVIC_PRIO_BITS ); - } - #endif - - #ifdef configPRIO_BITS - { - /* - * Check that the number of implemented priority bits queried from - * hardware is at least as many as specified in the FreeRTOS - * configPRIO_BITS configuration macro. - */ - configASSERT( ulImplementedPrioBits >= configPRIO_BITS ); - } - #endif - /* Shift the priority group value back to its position within the AIRCR * register. */ ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT; diff --git a/portable/CCS/ARM_CM4F/port.c b/portable/CCS/ARM_CM4F/port.c index c675afe67b4..a1fc5210e39 100755 --- a/portable/CCS/ARM_CM4F/port.c +++ b/portable/CCS/ARM_CM4F/port.c @@ -268,6 +268,10 @@ BaseType_t xPortStartScheduler( void ) * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ configASSERT( ucMaxSysCallPriority ); + /* Check that the bits not implemented in hardware are zero in + * configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & ( ~ucMaxPriorityValue ) ) == 0U ); + /* Calculate the maximum acceptable priority group value for the number * of bits read back. */ @@ -304,28 +308,6 @@ BaseType_t xPortStartScheduler( void ) ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulImplementedPrioBits; } - #ifdef __NVIC_PRIO_BITS - { - /* - * Check that the number of implemented priority bits queried from - * hardware is at least as many as specified in the CMSIS - * __NVIC_PRIO_BITS configuration macro. - */ - configASSERT( ulImplementedPrioBits >= __NVIC_PRIO_BITS ); - } - #endif - - #ifdef configPRIO_BITS - { - /* - * Check that the number of implemented priority bits queried from - * hardware is at least as many as specified in the FreeRTOS - * configPRIO_BITS configuration macro. - */ - configASSERT( ulImplementedPrioBits >= configPRIO_BITS ); - } - #endif - /* Shift the priority group value back to its position within the AIRCR * register. */ ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT; diff --git a/portable/CMakeLists.txt b/portable/CMakeLists.txt index 2824df05dc0..988be152406 100644 --- a/portable/CMakeLists.txt +++ b/portable/CMakeLists.txt @@ -1035,7 +1035,7 @@ target_link_libraries(freertos_kernel_port $<$:pico_base_headers> $<$:idf::esp32> PRIVATE - freertos_kernel + freertos_kernel_include $<$:Threads::Threads> "$<$:hardware_clocks;hardware_exception>" $<$:winmm> # Windows library which implements timers diff --git a/portable/Common/mpu_wrappers.c b/portable/Common/mpu_wrappers.c index 92841e1363e..c9951956fea 100644 --- a/portable/Common/mpu_wrappers.c +++ b/portable/Common/mpu_wrappers.c @@ -48,7 +48,7 @@ #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /*-----------------------------------------------------------*/ -#if ( portUSING_MPU_WRAPPERS == 1 ) +#if ( ( portUSING_MPU_WRAPPERS == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) ) #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) BaseType_t MPU_xTaskCreate( TaskFunction_t pvTaskCode, @@ -2537,5 +2537,5 @@ #endif /*-----------------------------------------------------------*/ -#endif /* portUSING_MPU_WRAPPERS == 1 */ +#endif /* #if ( ( portUSING_MPU_WRAPPERS == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) ) */ /*-----------------------------------------------------------*/ diff --git a/portable/Common/mpu_wrappers_v2.c b/portable/Common/mpu_wrappers_v2.c new file mode 100644 index 00000000000..1e28d8e4eb3 --- /dev/null +++ b/portable/Common/mpu_wrappers_v2.c @@ -0,0 +1,4121 @@ +/* + * FreeRTOS Kernel + * Copyright (C) 2021 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 + * + */ + +/* + * Implementation of the wrapper functions used to raise the processor privilege + * before calling a standard FreeRTOS API function. + */ + +/* 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. */ +#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +/* Scheduler includes. */ +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" +#include "timers.h" +#include "event_groups.h" +#include "stream_buffer.h" +#include "mpu_prototypes.h" + +#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE +/*-----------------------------------------------------------*/ + +#if ( ( portUSING_MPU_WRAPPERS == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + + #ifndef configPROTECTED_KERNEL_OBJECT_POOL_SIZE + #error configPROTECTED_KERNEL_OBJECT_POOL_SIZE must be defined to maximum number of kernel objects in the application. + #endif + +/** + * @brief Offset added to the index before returning to the user. + * + * If the actual handle is stored at index i, ( i + INDEX_OFFSET ) + * is returned to the user. + */ + #define INDEX_OFFSET 1 + +/** + * @brief Opaque type for a kernel object. + */ + struct OpaqueObject; + typedef struct OpaqueObject * OpaqueObjectHandle_t; + +/** + * @brief Defines kernel object in the kernel object pool. + */ + typedef struct KernelObject + { + OpaqueObjectHandle_t xInternalObjectHandle; + uint32_t ulKernelObjectType; + void * pvKernelObjectData; + } KernelObject_t; + +/** + * @brief Kernel object types. + */ + #define KERNEL_OBJECT_TYPE_INVALID ( 0UL ) + #define KERNEL_OBJECT_TYPE_QUEUE ( 1UL ) + #define KERNEL_OBJECT_TYPE_TASK ( 2UL ) + #define KERNEL_OBJECT_TYPE_STREAM_BUFFER ( 3UL ) + #define KERNEL_OBJECT_TYPE_EVENT_GROUP ( 4UL ) + #define KERNEL_OBJECT_TYPE_TIMER ( 5UL ) + +/** + * @brief Checks whether an external index is valid or not. + */ + #define IS_EXTERNAL_INDEX_VALID( lIndex ) \ + ( ( ( lIndex ) >= INDEX_OFFSET ) && \ + ( ( lIndex ) < ( configPROTECTED_KERNEL_OBJECT_POOL_SIZE + INDEX_OFFSET ) ) ) + +/** + * @brief Checks whether an internal index is valid or not. + */ + #define IS_INTERNAL_INDEX_VALID( lIndex ) \ + ( ( ( lIndex ) >= 0 ) && \ + ( ( lIndex ) < ( configPROTECTED_KERNEL_OBJECT_POOL_SIZE ) ) ) + +/** + * @brief Converts an internal index into external. + */ + #define CONVERT_TO_EXTERNAL_INDEX( lIndex ) ( ( lIndex ) + INDEX_OFFSET ) + +/** + * @brief Converts an external index into internal. + */ + #define CONVERT_TO_INTERNAL_INDEX( lIndex ) ( ( lIndex ) - INDEX_OFFSET ) + +/** + * @brief Get the index of a free slot in the kernel object pool. + * + * If a free slot is found, this function marks the slot as + * "not free". + * + * @return Index of a free slot is returned, if a free slot is + * found. Otherwise -1 is returned. + */ + static int32_t MPU_GetFreeIndexInKernelObjectPool( void ) PRIVILEGED_FUNCTION; + +/** + * @brief Set the given index as free in the kernel object pool. + * + * @param lIndex The index to set as free. + */ + static void MPU_SetIndexFreeInKernelObjectPool( int32_t lIndex ) PRIVILEGED_FUNCTION; + +/** + * @brief Get the index at which a given kernel object is stored. + * + * @param xHandle The given kernel object handle. + * @param ulKernelObjectType The kernel object type. + * + * @return Index at which the kernel object is stored if it is a valid + * handle, -1 otherwise. + */ + static int32_t MPU_GetIndexForHandle( OpaqueObjectHandle_t xHandle, + uint32_t ulKernelObjectType ) PRIVILEGED_FUNCTION; + +/** + * @brief Store the given kernel object handle at the given index in + * the kernel object pool. + * + * @param lIndex Index to store the given handle at. + * @param xHandle Kernel object handle to store. + * @param pvKernelObjectData The data associated with the kernel object. + * Currently, only used for timer objects to store timer callback. + * @param ulKernelObjectType The kernel object type. + */ + static void MPU_StoreHandleAndDataAtIndex( int32_t lIndex, + OpaqueObjectHandle_t xHandle, + void * pvKernelObjectData, + uint32_t ulKernelObjectType ) PRIVILEGED_FUNCTION; + +/** + * @brief Get the kernel object handle at the given index from + * the kernel object pool. + * + * @param lIndex Index at which to get the kernel object handle. + * @param ulKernelObjectType The kernel object type. + * + * @return The kernel object handle at the index. + */ + static OpaqueObjectHandle_t MPU_GetHandleAtIndex( int32_t lIndex, + uint32_t ulKernelObjectType ) PRIVILEGED_FUNCTION; + + #if ( configUSE_TIMERS == 1 ) + +/** + * @brief The function registered as callback for all the timers. + * + * We intercept all the timer callbacks so that we can call application + * callbacks with opaque handle. + * + * @param xInternalHandle The internal timer handle. + */ + static void MPU_TimerCallback( TimerHandle_t xInternalHandle ) PRIVILEGED_FUNCTION; + + #endif /* #if ( configUSE_TIMERS == 1 ) */ + +/* + * Wrappers to keep all the casting in one place. + */ + #define MPU_StoreQueueHandleAtIndex( lIndex, xHandle ) MPU_StoreHandleAndDataAtIndex( lIndex, ( OpaqueObjectHandle_t ) xHandle, NULL, KERNEL_OBJECT_TYPE_QUEUE ) + #define MPU_GetQueueHandleAtIndex( lIndex ) ( QueueHandle_t ) MPU_GetHandleAtIndex( lIndex, KERNEL_OBJECT_TYPE_QUEUE ) + + #if ( configUSE_QUEUE_SETS == 1 ) + #define MPU_StoreQueueSetHandleAtIndex( lIndex, xHandle ) MPU_StoreHandleAndDataAtIndex( lIndex, ( OpaqueObjectHandle_t ) xHandle, NULL, KERNEL_OBJECT_TYPE_QUEUE ) + #define MPU_GetQueueSetHandleAtIndex( lIndex ) ( QueueSetHandle_t ) MPU_GetHandleAtIndex( lIndex, KERNEL_OBJECT_TYPE_QUEUE ) + #define MPU_StoreQueueSetMemberHandleAtIndex( lIndex, xHandle ) MPU_StoreHandleAndDataAtIndex( lIndex, ( OpaqueObjectHandle_t ) xHandle, NULL, KERNEL_OBJECT_TYPE_QUEUE ) + #define MPU_GetQueueSetMemberHandleAtIndex( lIndex ) ( QueueSetMemberHandle_t ) MPU_GetHandleAtIndex( lIndex, KERNEL_OBJECT_TYPE_QUEUE ) + #define MPU_GetIndexForQueueSetMemberHandle( xHandle ) MPU_GetIndexForHandle( ( OpaqueObjectHandle_t ) xHandle, KERNEL_OBJECT_TYPE_QUEUE ) + #endif + +/* + * Wrappers to keep all the casting in one place for Task APIs. + */ + #define MPU_StoreTaskHandleAtIndex( lIndex, xHandle ) MPU_StoreHandleAndDataAtIndex( lIndex, ( OpaqueObjectHandle_t ) xHandle, NULL, KERNEL_OBJECT_TYPE_TASK ) + #define MPU_GetTaskHandleAtIndex( lIndex ) ( TaskHandle_t ) MPU_GetHandleAtIndex( lIndex, KERNEL_OBJECT_TYPE_TASK ) + #define MPU_GetIndexForTaskHandle( xHandle ) MPU_GetIndexForHandle( ( OpaqueObjectHandle_t ) xHandle, KERNEL_OBJECT_TYPE_TASK ) + +/* + * Wrappers to keep all the casting in one place for Event Group APIs. + */ + #define MPU_StoreEventGroupHandleAtIndex( lIndex, xHandle ) MPU_StoreHandleAndDataAtIndex( lIndex, ( OpaqueObjectHandle_t ) xHandle, NULL, KERNEL_OBJECT_TYPE_EVENT_GROUP ) + #define MPU_GetEventGroupHandleAtIndex( lIndex ) ( EventGroupHandle_t ) MPU_GetHandleAtIndex( lIndex, KERNEL_OBJECT_TYPE_EVENT_GROUP ) + #define MPU_GetIndexForEventGroupHandle( xHandle ) MPU_GetIndexForHandle( ( OpaqueObjectHandle_t ) xHandle, KERNEL_OBJECT_TYPE_EVENT_GROUP ) + +/* + * Wrappers to keep all the casting in one place for Stream Buffer APIs. + */ + #define MPU_StoreStreamBufferHandleAtIndex( lIndex, xHandle ) MPU_StoreHandleAndDataAtIndex( lIndex, ( OpaqueObjectHandle_t ) xHandle, NULL, KERNEL_OBJECT_TYPE_STREAM_BUFFER ) + #define MPU_GetStreamBufferHandleAtIndex( lIndex ) ( StreamBufferHandle_t ) MPU_GetHandleAtIndex( lIndex, KERNEL_OBJECT_TYPE_STREAM_BUFFER ) + #define MPU_GetIndexForStreamBufferHandle( xHandle ) MPU_GetIndexForHandle( ( OpaqueObjectHandle_t ) xHandle, KERNEL_OBJECT_TYPE_STREAM_BUFFER ) + + #if ( configUSE_TIMERS == 1 ) + +/* + * Wrappers to keep all the casting in one place for Timer APIs. + */ + #define MPU_StoreTimerHandleAtIndex( lIndex, xHandle, pxApplicationCallback ) MPU_StoreHandleAndDataAtIndex( lIndex, ( OpaqueObjectHandle_t ) xHandle, ( void * ) pxApplicationCallback, KERNEL_OBJECT_TYPE_TIMER ) + #define MPU_GetTimerHandleAtIndex( lIndex ) ( TimerHandle_t ) MPU_GetHandleAtIndex( lIndex, KERNEL_OBJECT_TYPE_TIMER ) + #define MPU_GetIndexForTimerHandle( xHandle ) MPU_GetIndexForHandle( ( OpaqueObjectHandle_t ) xHandle, KERNEL_OBJECT_TYPE_TIMER ) + + #endif /* #if ( configUSE_TIMERS == 1 ) */ + +/*-----------------------------------------------------------*/ + +/** + * @brief Kernel object pool. + */ + PRIVILEGED_DATA static KernelObject_t xKernelObjectPool[ configPROTECTED_KERNEL_OBJECT_POOL_SIZE ] = { NULL }; +/*-----------------------------------------------------------*/ + + static int32_t MPU_GetFreeIndexInKernelObjectPool( void ) /* PRIVILEGED_FUNCTION */ + { + int32_t i, lFreeIndex = -1; + + /* This function is called only from resource create APIs + * which are not supposed to be called from ISRs. Therefore, + * we only need to suspend the scheduler and do not require + * critical section. */ + vTaskSuspendAll(); + { + for( i = 0; i < configPROTECTED_KERNEL_OBJECT_POOL_SIZE; i++ ) + { + if( xKernelObjectPool[ i ].xInternalObjectHandle == NULL ) + { + /* Mark this index as not free. */ + xKernelObjectPool[ i ].xInternalObjectHandle = ( OpaqueObjectHandle_t ) ( ~0 ); + lFreeIndex = i; + break; + } + } + } + xTaskResumeAll(); + + return lFreeIndex; + } +/*-----------------------------------------------------------*/ + + static void MPU_SetIndexFreeInKernelObjectPool( int32_t lIndex ) /* PRIVILEGED_FUNCTION */ + { + configASSERT( IS_INTERNAL_INDEX_VALID( lIndex ) != pdFALSE ); + + taskENTER_CRITICAL(); + { + xKernelObjectPool[ lIndex ].xInternalObjectHandle = NULL; + xKernelObjectPool[ lIndex ].ulKernelObjectType = KERNEL_OBJECT_TYPE_INVALID; + xKernelObjectPool[ lIndex ].pvKernelObjectData = NULL; + } + taskEXIT_CRITICAL(); + } +/*-----------------------------------------------------------*/ + + static int32_t MPU_GetIndexForHandle( OpaqueObjectHandle_t xHandle, + uint32_t ulKernelObjectType ) /* PRIVILEGED_FUNCTION */ + { + int32_t i, lIndex = -1; + + configASSERT( xHandle != NULL ); + + for( i = 0; i < configPROTECTED_KERNEL_OBJECT_POOL_SIZE; i++ ) + { + if( ( xKernelObjectPool[ i ].xInternalObjectHandle == xHandle ) && + ( xKernelObjectPool[ i ].ulKernelObjectType == ulKernelObjectType ) ) + { + lIndex = i; + break; + } + } + + return lIndex; + } +/*-----------------------------------------------------------*/ + + static void MPU_StoreHandleAndDataAtIndex( int32_t lIndex, + OpaqueObjectHandle_t xHandle, + void * pvKernelObjectData, + uint32_t ulKernelObjectType ) /* PRIVILEGED_FUNCTION */ + { + configASSERT( IS_INTERNAL_INDEX_VALID( lIndex ) != pdFALSE ); + xKernelObjectPool[ lIndex ].xInternalObjectHandle = xHandle; + xKernelObjectPool[ lIndex ].ulKernelObjectType = ulKernelObjectType; + xKernelObjectPool[ lIndex ].pvKernelObjectData = pvKernelObjectData; + } +/*-----------------------------------------------------------*/ + + static OpaqueObjectHandle_t MPU_GetHandleAtIndex( int32_t lIndex, + uint32_t ulKernelObjectType ) /* PRIVILEGED_FUNCTION */ + { + configASSERT( IS_INTERNAL_INDEX_VALID( lIndex ) != pdFALSE ); + configASSERT( xKernelObjectPool[ lIndex ].ulKernelObjectType == ulKernelObjectType ); + return xKernelObjectPool[ lIndex ].xInternalObjectHandle; + } +/*-----------------------------------------------------------*/ + + #if ( configUSE_TIMERS == 1 ) + + static void MPU_TimerCallback( TimerHandle_t xInternalHandle ) /* PRIVILEGED_FUNCTION */ + { + int32_t i, lIndex = -1; + TimerHandle_t xExternalHandle = NULL; + TimerCallbackFunction_t pxApplicationCallBack = NULL; + + /* Coming from the timer task and therefore, should be valid. */ + configASSERT( xInternalHandle != NULL ); + + for( i = 0; i < configPROTECTED_KERNEL_OBJECT_POOL_SIZE; i++ ) + { + if( ( ( TimerHandle_t ) xKernelObjectPool[ i ].xInternalObjectHandle == xInternalHandle ) && + ( xKernelObjectPool[ i ].ulKernelObjectType == KERNEL_OBJECT_TYPE_TIMER ) ) + { + lIndex = i; + break; + } + } + + configASSERT( lIndex != -1 ); + xExternalHandle = ( TimerHandle_t ) CONVERT_TO_EXTERNAL_INDEX( lIndex ); + + pxApplicationCallBack = ( TimerCallbackFunction_t ) xKernelObjectPool[ lIndex ].pvKernelObjectData; + pxApplicationCallBack( xExternalHandle ); + } + + #endif /* #if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +/*-----------------------------------------------------------*/ +/* MPU wrappers for tasks APIs. */ +/*-----------------------------------------------------------*/ + + #if ( INCLUDE_xTaskDelayUntil == 1 ) + + BaseType_t MPU_xTaskDelayUntilImpl( TickType_t * const pxPreviousWakeTime, + TickType_t xTimeIncrement ) PRIVILEGED_FUNCTION; + + BaseType_t MPU_xTaskDelayUntilImpl( TickType_t * const pxPreviousWakeTime, + TickType_t xTimeIncrement ) /* PRIVILEGED_FUNCTION */ + { + BaseType_t xReturn = pdFAIL; + BaseType_t xIsPreviousWakeTimeAccessible = pdFALSE; + + xIsPreviousWakeTimeAccessible = xPortIsAuthorizedToAccessBuffer( pxPreviousWakeTime, + sizeof( TickType_t ), + ( tskMPU_WRITE_PERMISSION | tskMPU_READ_PERMISSION ) ); + + if( xIsPreviousWakeTimeAccessible == pdTRUE ) + { + xReturn = xTaskDelayUntil( pxPreviousWakeTime, xTimeIncrement ); + } + + return xReturn; + } + + #endif /* if ( INCLUDE_xTaskDelayUntil == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( INCLUDE_xTaskAbortDelay == 1 ) + + BaseType_t MPU_xTaskAbortDelayImpl( TaskHandle_t xTask ) PRIVILEGED_FUNCTION; + + BaseType_t MPU_xTaskAbortDelayImpl( TaskHandle_t xTask ) /* PRIVILEGED_FUNCTION */ + { + BaseType_t xReturn = pdFAIL; + TaskHandle_t xInternalTaskHandle = NULL; + int32_t lIndex; + + if( xTask == NULL ) + { + xReturn = xTaskAbortDelay( xTask ); + } + else + { + lIndex = ( int32_t ) xTask; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalTaskHandle = MPU_GetTaskHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalTaskHandle != NULL ) + { + xReturn = xTaskAbortDelay( xInternalTaskHandle ); + } + } + } + + return xReturn; + } + + #endif /* if ( INCLUDE_xTaskAbortDelay == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( INCLUDE_vTaskDelay == 1 ) + + void MPU_vTaskDelayImpl( TickType_t xTicksToDelay ) PRIVILEGED_FUNCTION; + + void MPU_vTaskDelayImpl( TickType_t xTicksToDelay ) /* PRIVILEGED_FUNCTION */ + { + vTaskDelay( xTicksToDelay ); + } + + #endif /* if ( INCLUDE_vTaskDelay == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( INCLUDE_uxTaskPriorityGet == 1 ) + + UBaseType_t MPU_uxTaskPriorityGetImpl( const TaskHandle_t pxTask ) PRIVILEGED_FUNCTION; + + UBaseType_t MPU_uxTaskPriorityGetImpl( const TaskHandle_t pxTask ) /* PRIVILEGED_FUNCTION */ + { + UBaseType_t uxReturn = configMAX_PRIORITIES; + int32_t lIndex; + TaskHandle_t xInternalTaskHandle = NULL; + + if( pxTask == NULL ) + { + uxReturn = uxTaskPriorityGet( pxTask ); + } + else + { + lIndex = ( int32_t ) pxTask; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalTaskHandle = MPU_GetTaskHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalTaskHandle != NULL ) + { + uxReturn = uxTaskPriorityGet( xInternalTaskHandle ); + } + } + } + + return uxReturn; + } + + #endif /* if ( INCLUDE_uxTaskPriorityGet == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( INCLUDE_eTaskGetState == 1 ) + + eTaskState MPU_eTaskGetStateImpl( TaskHandle_t pxTask ) PRIVILEGED_FUNCTION; + + eTaskState MPU_eTaskGetStateImpl( TaskHandle_t pxTask ) /* PRIVILEGED_FUNCTION */ + { + eTaskState eReturn = eInvalid; + TaskHandle_t xInternalTaskHandle = NULL; + int32_t lIndex; + + if( pxTask == NULL ) + { + eReturn = eTaskGetState( pxTask ); + } + else + { + lIndex = ( int32_t ) pxTask; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalTaskHandle = MPU_GetTaskHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalTaskHandle != NULL ) + { + eReturn = eTaskGetState( xInternalTaskHandle ); + } + } + } + + return eReturn; + } + + #endif /* if ( INCLUDE_eTaskGetState == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( configUSE_TRACE_FACILITY == 1 ) + + void MPU_vTaskGetInfoImpl( TaskHandle_t xTask, + TaskStatus_t * pxTaskStatus, + BaseType_t xGetFreeStackSpace, + eTaskState eState ) PRIVILEGED_FUNCTION; + + void MPU_vTaskGetInfoImpl( TaskHandle_t xTask, + TaskStatus_t * pxTaskStatus, + BaseType_t xGetFreeStackSpace, + eTaskState eState ) /* PRIVILEGED_FUNCTION */ + { + int32_t lIndex; + TaskHandle_t xInternalTaskHandle = NULL; + BaseType_t xIsTaskStatusWriteable = pdFALSE; + + xIsTaskStatusWriteable = xPortIsAuthorizedToAccessBuffer( pxTaskStatus, + sizeof( TaskStatus_t ), + tskMPU_WRITE_PERMISSION ); + + if( xIsTaskStatusWriteable == pdTRUE ) + { + if( xTask == NULL ) + { + vTaskGetInfo( xTask, pxTaskStatus, xGetFreeStackSpace, eState ); + } + else + { + lIndex = ( int32_t ) xTask; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalTaskHandle = MPU_GetTaskHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalTaskHandle != NULL ) + { + vTaskGetInfo( xInternalTaskHandle, pxTaskStatus, xGetFreeStackSpace, eState ); + } + } + } + } + } + + #endif /* if ( configUSE_TRACE_FACILITY == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) + + TaskHandle_t MPU_xTaskGetIdleTaskHandleImpl( void ) PRIVILEGED_FUNCTION; + + TaskHandle_t MPU_xTaskGetIdleTaskHandleImpl( void ) /* PRIVILEGED_FUNCTION */ + { + TaskHandle_t xIdleTaskHandle = NULL; + + xIdleTaskHandle = xTaskGetIdleTaskHandle(); + + return xIdleTaskHandle; + } + + #endif /* if ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( INCLUDE_vTaskSuspend == 1 ) + + void MPU_vTaskSuspendImpl( TaskHandle_t pxTaskToSuspend ) PRIVILEGED_FUNCTION; + + void MPU_vTaskSuspendImpl( TaskHandle_t pxTaskToSuspend ) /* PRIVILEGED_FUNCTION */ + { + int32_t lIndex; + TaskHandle_t xInternalTaskHandle = NULL; + + if( pxTaskToSuspend == NULL ) + { + vTaskSuspend( pxTaskToSuspend ); + } + else + { + /* After the scheduler starts, only privileged tasks are allowed + * to suspend other tasks. */ + if( ( xTaskGetSchedulerState() == taskSCHEDULER_NOT_STARTED ) || ( portIS_TASK_PRIVILEGED() == pdTRUE ) ) + { + lIndex = ( int32_t ) pxTaskToSuspend; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalTaskHandle = MPU_GetTaskHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalTaskHandle != NULL ) + { + vTaskSuspend( xInternalTaskHandle ); + } + } + } + } + } + + #endif /* if ( INCLUDE_vTaskSuspend == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( INCLUDE_vTaskSuspend == 1 ) + + void MPU_vTaskResumeImpl( TaskHandle_t pxTaskToResume ) PRIVILEGED_FUNCTION; + + void MPU_vTaskResumeImpl( TaskHandle_t pxTaskToResume ) /* PRIVILEGED_FUNCTION */ + { + int32_t lIndex; + TaskHandle_t xInternalTaskHandle = NULL; + + lIndex = ( int32_t ) pxTaskToResume; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalTaskHandle = MPU_GetTaskHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalTaskHandle != NULL ) + { + vTaskResume( xInternalTaskHandle ); + } + } + } + + #endif /* if ( INCLUDE_vTaskSuspend == 1 ) */ +/*-----------------------------------------------------------*/ + + TickType_t MPU_xTaskGetTickCountImpl( void ) PRIVILEGED_FUNCTION; + + TickType_t MPU_xTaskGetTickCountImpl( void ) /* PRIVILEGED_FUNCTION */ + { + TickType_t xReturn; + + xReturn = xTaskGetTickCount(); + + return xReturn; + } +/*-----------------------------------------------------------*/ + + UBaseType_t MPU_uxTaskGetNumberOfTasksImpl( void ) PRIVILEGED_FUNCTION; + + UBaseType_t MPU_uxTaskGetNumberOfTasksImpl( void ) /* PRIVILEGED_FUNCTION */ + { + UBaseType_t uxReturn; + + uxReturn = uxTaskGetNumberOfTasks(); + + return uxReturn; + } +/*-----------------------------------------------------------*/ + + char * MPU_pcTaskGetNameImpl( TaskHandle_t xTaskToQuery ) PRIVILEGED_FUNCTION; + + char * MPU_pcTaskGetNameImpl( TaskHandle_t xTaskToQuery ) /* PRIVILEGED_FUNCTION */ + { + char * pcReturn = NULL; + int32_t lIndex; + TaskHandle_t xInternalTaskHandle = NULL; + + if( xTaskToQuery == NULL ) + { + pcReturn = pcTaskGetName( xTaskToQuery ); + } + else + { + lIndex = ( int32_t ) xTaskToQuery; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalTaskHandle = MPU_GetTaskHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalTaskHandle != NULL ) + { + pcReturn = pcTaskGetName( xInternalTaskHandle ); + } + } + } + + return pcReturn; + } +/*-----------------------------------------------------------*/ + + #if ( configGENERATE_RUN_TIME_STATS == 1 ) + + configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetRunTimeCounterImpl( const TaskHandle_t xTask ) PRIVILEGED_FUNCTION; + + configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetRunTimeCounterImpl( const TaskHandle_t xTask ) /* PRIVILEGED_FUNCTION */ + { + configRUN_TIME_COUNTER_TYPE xReturn = 0; + int32_t lIndex; + TaskHandle_t xInternalTaskHandle = NULL; + + if( xTask == NULL ) + { + xReturn = ulTaskGetRunTimeCounter( xTask ); + } + else + { + lIndex = ( int32_t ) xTask; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalTaskHandle = MPU_GetTaskHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalTaskHandle != NULL ) + { + xReturn = ulTaskGetRunTimeCounter( xInternalTaskHandle ); + } + } + } + + return xReturn; + } + + #endif /* if ( ( configGENERATE_RUN_TIME_STATS == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( configGENERATE_RUN_TIME_STATS == 1 ) + + configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetRunTimePercentImpl( const TaskHandle_t xTask ) PRIVILEGED_FUNCTION; + + configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetRunTimePercentImpl( const TaskHandle_t xTask ) /* PRIVILEGED_FUNCTION */ + { + configRUN_TIME_COUNTER_TYPE xReturn = 0; + int32_t lIndex; + TaskHandle_t xInternalTaskHandle = NULL; + + if( xTask == NULL ) + { + xReturn = ulTaskGetRunTimePercent( xTask ); + } + else + { + lIndex = ( int32_t ) xTask; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalTaskHandle = MPU_GetTaskHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalTaskHandle != NULL ) + { + xReturn = ulTaskGetRunTimePercent( xInternalTaskHandle ); + } + } + } + + return xReturn; + } + + #endif /* if ( ( configGENERATE_RUN_TIME_STATS == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) + + configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimePercentImpl( void ) PRIVILEGED_FUNCTION; + + configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimePercentImpl( void ) /* PRIVILEGED_FUNCTION */ + { + configRUN_TIME_COUNTER_TYPE xReturn; + + xReturn = ulTaskGetIdleRunTimePercent(); + + return xReturn; + } + + #endif /* if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) */ +/*-----------------------------------------------------------*/ + + #if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) + + configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimeCounterImpl( void ) PRIVILEGED_FUNCTION; + + configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimeCounterImpl( void ) /* PRIVILEGED_FUNCTION */ + { + configRUN_TIME_COUNTER_TYPE xReturn; + + xReturn = ulTaskGetIdleRunTimeCounter(); + + return xReturn; + } + + #endif /* if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) */ +/*-----------------------------------------------------------*/ + + #if ( configUSE_APPLICATION_TASK_TAG == 1 ) + + void MPU_vTaskSetApplicationTaskTagImpl( TaskHandle_t xTask, + TaskHookFunction_t pxTagValue ) PRIVILEGED_FUNCTION; + + void MPU_vTaskSetApplicationTaskTagImpl( TaskHandle_t xTask, + TaskHookFunction_t pxTagValue ) /* PRIVILEGED_FUNCTION */ + { + TaskHandle_t xInternalTaskHandle = NULL; + int32_t lIndex; + + if( xTask == NULL ) + { + vTaskSetApplicationTaskTag( xTask, pxTagValue ); + } + else + { + lIndex = ( int32_t ) xTask; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalTaskHandle = MPU_GetTaskHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalTaskHandle != NULL ) + { + vTaskSetApplicationTaskTag( xInternalTaskHandle, pxTagValue ); + } + } + } + } + + #endif /* if ( configUSE_APPLICATION_TASK_TAG == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( configUSE_APPLICATION_TASK_TAG == 1 ) + + TaskHookFunction_t MPU_xTaskGetApplicationTaskTagImpl( TaskHandle_t xTask ) PRIVILEGED_FUNCTION; + + TaskHookFunction_t MPU_xTaskGetApplicationTaskTagImpl( TaskHandle_t xTask ) /* PRIVILEGED_FUNCTION */ + { + TaskHookFunction_t xReturn = NULL; + int32_t lIndex; + TaskHandle_t xInternalTaskHandle = NULL; + + if( xTask == NULL ) + { + xReturn = xTaskGetApplicationTaskTag( xTask ); + } + else + { + lIndex = ( int32_t ) xTask; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalTaskHandle = MPU_GetTaskHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalTaskHandle != NULL ) + { + xReturn = xTaskGetApplicationTaskTag( xInternalTaskHandle ); + } + } + } + + return xReturn; + } + + #endif /* if ( configUSE_APPLICATION_TASK_TAG == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) + + void MPU_vTaskSetThreadLocalStoragePointerImpl( TaskHandle_t xTaskToSet, + BaseType_t xIndex, + void * pvValue ) PRIVILEGED_FUNCTION; + + void MPU_vTaskSetThreadLocalStoragePointerImpl( TaskHandle_t xTaskToSet, + BaseType_t xIndex, + void * pvValue ) /* PRIVILEGED_FUNCTION */ + { + int32_t lIndex; + TaskHandle_t xInternalTaskHandle = NULL; + + if( xTaskToSet == NULL ) + { + vTaskSetThreadLocalStoragePointer( xTaskToSet, xIndex, pvValue ); + } + else + { + lIndex = ( int32_t ) xTaskToSet; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalTaskHandle = MPU_GetTaskHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalTaskHandle != NULL ) + { + vTaskSetThreadLocalStoragePointer( xInternalTaskHandle, xIndex, pvValue ); + } + } + } + } + + #endif /* if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) */ +/*-----------------------------------------------------------*/ + + #if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) + + void * MPU_pvTaskGetThreadLocalStoragePointerImpl( TaskHandle_t xTaskToQuery, + BaseType_t xIndex ) PRIVILEGED_FUNCTION; + + void * MPU_pvTaskGetThreadLocalStoragePointerImpl( TaskHandle_t xTaskToQuery, + BaseType_t xIndex ) /* PRIVILEGED_FUNCTION */ + { + void * pvReturn = NULL; + int32_t lIndex; + TaskHandle_t xInternalTaskHandle = NULL; + + if( xTaskToQuery == NULL ) + { + pvReturn = pvTaskGetThreadLocalStoragePointer( xTaskToQuery, xIndex ); + } + else + { + lIndex = ( int32_t ) xTaskToQuery; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalTaskHandle = MPU_GetTaskHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalTaskHandle != NULL ) + { + pvReturn = pvTaskGetThreadLocalStoragePointer( xInternalTaskHandle, xIndex ); + } + } + } + + return pvReturn; + } + + #endif /* if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) */ +/*-----------------------------------------------------------*/ + + #if ( configUSE_TRACE_FACILITY == 1 ) + + UBaseType_t MPU_uxTaskGetSystemStateImpl( TaskStatus_t * pxTaskStatusArray, + UBaseType_t uxArraySize, + configRUN_TIME_COUNTER_TYPE * pulTotalRunTime ) PRIVILEGED_FUNCTION; + + UBaseType_t MPU_uxTaskGetSystemStateImpl( TaskStatus_t * pxTaskStatusArray, + UBaseType_t uxArraySize, + configRUN_TIME_COUNTER_TYPE * pulTotalRunTime ) /* PRIVILEGED_FUNCTION */ + { + UBaseType_t uxReturn = pdFALSE; + UBaseType_t xIsTaskStatusArrayWriteable = pdFALSE; + UBaseType_t xIsTotalRunTimeWriteable = pdFALSE; + + xIsTaskStatusArrayWriteable = xPortIsAuthorizedToAccessBuffer( pxTaskStatusArray, + sizeof( TaskStatus_t ) * uxArraySize, + tskMPU_WRITE_PERMISSION ); + + if( pulTotalRunTime != NULL ) + { + xIsTotalRunTimeWriteable = xPortIsAuthorizedToAccessBuffer( pulTotalRunTime, + sizeof( configRUN_TIME_COUNTER_TYPE ), + tskMPU_WRITE_PERMISSION ); + } + + if( ( xIsTaskStatusArrayWriteable == pdTRUE ) && + ( ( pulTotalRunTime == NULL ) || ( xIsTotalRunTimeWriteable == pdTRUE ) ) ) + { + uxReturn = uxTaskGetSystemState( pxTaskStatusArray, uxArraySize, pulTotalRunTime ); + } + + return uxReturn; + } + + #endif /* if ( configUSE_TRACE_FACILITY == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) + + UBaseType_t MPU_uxTaskGetStackHighWaterMarkImpl( TaskHandle_t xTask ) PRIVILEGED_FUNCTION; + + UBaseType_t MPU_uxTaskGetStackHighWaterMarkImpl( TaskHandle_t xTask ) /* PRIVILEGED_FUNCTION */ + { + UBaseType_t uxReturn = 0; + int32_t lIndex; + TaskHandle_t xInternalTaskHandle = NULL; + + if( xTask == NULL ) + { + uxReturn = uxTaskGetStackHighWaterMark( xTask ); + } + else + { + lIndex = ( int32_t ) xTask; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalTaskHandle = MPU_GetTaskHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalTaskHandle != NULL ) + { + uxReturn = uxTaskGetStackHighWaterMark( xInternalTaskHandle ); + } + } + } + + return uxReturn; + } + + #endif /* if ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) + + configSTACK_DEPTH_TYPE MPU_uxTaskGetStackHighWaterMark2Impl( TaskHandle_t xTask ) PRIVILEGED_FUNCTION; + + configSTACK_DEPTH_TYPE MPU_uxTaskGetStackHighWaterMark2Impl( TaskHandle_t xTask ) /* PRIVILEGED_FUNCTION */ + { + configSTACK_DEPTH_TYPE uxReturn = 0; + int32_t lIndex; + TaskHandle_t xInternalTaskHandle = NULL; + + if( xTask == NULL ) + { + uxReturn = uxTaskGetStackHighWaterMark2( xTask ); + } + else + { + lIndex = ( int32_t ) xTask; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalTaskHandle = MPU_GetTaskHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalTaskHandle != NULL ) + { + uxReturn = uxTaskGetStackHighWaterMark2( xInternalTaskHandle ); + } + } + } + + return uxReturn; + } + + #endif /* if ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) ) + + TaskHandle_t MPU_xTaskGetCurrentTaskHandleImpl( void ) PRIVILEGED_FUNCTION; + + TaskHandle_t MPU_xTaskGetCurrentTaskHandleImpl( void ) /* PRIVILEGED_FUNCTION */ + { + TaskHandle_t xInternalTaskHandle = NULL; + TaskHandle_t xExternalTaskHandle = NULL; + int32_t lIndex; + + xInternalTaskHandle = xTaskGetCurrentTaskHandle(); + + if( xInternalTaskHandle != NULL ) + { + lIndex = MPU_GetIndexForTaskHandle( xInternalTaskHandle ); + + if( lIndex != -1 ) + { + xExternalTaskHandle = ( TaskHandle_t ) CONVERT_TO_EXTERNAL_INDEX( lIndex ); + } + } + + return xExternalTaskHandle; + } + + #endif /* if ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) ) */ +/*-----------------------------------------------------------*/ + + #if ( INCLUDE_xTaskGetSchedulerState == 1 ) + + BaseType_t MPU_xTaskGetSchedulerStateImpl( void ) PRIVILEGED_FUNCTION; + + BaseType_t MPU_xTaskGetSchedulerStateImpl( void ) /* PRIVILEGED_FUNCTION */ + { + BaseType_t xReturn = taskSCHEDULER_NOT_STARTED; + + xReturn = xTaskGetSchedulerState(); + + return xReturn; + } + + #endif /* if ( INCLUDE_xTaskGetSchedulerState == 1 ) */ +/*-----------------------------------------------------------*/ + + void MPU_vTaskSetTimeOutStateImpl( TimeOut_t * const pxTimeOut ) PRIVILEGED_FUNCTION; + + void MPU_vTaskSetTimeOutStateImpl( TimeOut_t * const pxTimeOut ) /* PRIVILEGED_FUNCTION */ + { + BaseType_t xIsTimeOutWriteable = pdFALSE; + + xIsTimeOutWriteable = xPortIsAuthorizedToAccessBuffer( pxTimeOut, + sizeof( TimeOut_t ), + tskMPU_WRITE_PERMISSION ); + + if( xIsTimeOutWriteable == pdTRUE ) + { + vTaskSetTimeOutState( pxTimeOut ); + } + } +/*-----------------------------------------------------------*/ + + BaseType_t MPU_xTaskCheckForTimeOutImpl( TimeOut_t * const pxTimeOut, + TickType_t * const pxTicksToWait ) PRIVILEGED_FUNCTION; + + BaseType_t MPU_xTaskCheckForTimeOutImpl( TimeOut_t * const pxTimeOut, + TickType_t * const pxTicksToWait ) /* PRIVILEGED_FUNCTION */ + { + BaseType_t xReturn = pdFALSE; + BaseType_t xIsTimeOutWriteable = pdFALSE; + BaseType_t xIsTicksToWaitWriteable = pdFALSE; + + xIsTimeOutWriteable = xPortIsAuthorizedToAccessBuffer( pxTimeOut, + sizeof( TimeOut_t ), + tskMPU_WRITE_PERMISSION ); + xIsTicksToWaitWriteable = xPortIsAuthorizedToAccessBuffer( pxTicksToWait, + sizeof( TickType_t ), + tskMPU_WRITE_PERMISSION ); + + if( ( xIsTimeOutWriteable == pdTRUE ) && ( xIsTicksToWaitWriteable == pdTRUE ) ) + { + xReturn = xTaskCheckForTimeOut( pxTimeOut, pxTicksToWait ); + } + + return xReturn; + } +/*-----------------------------------------------------------*/ + + #if ( configUSE_TASK_NOTIFICATIONS == 1 ) + + BaseType_t MPU_xTaskGenericNotifyImpl( TaskHandle_t xTaskToNotify, + UBaseType_t uxIndexToNotify, + uint32_t ulValue, + eNotifyAction eAction, + uint32_t * pulPreviousNotificationValue ) PRIVILEGED_FUNCTION; + + BaseType_t MPU_xTaskGenericNotifyImpl( TaskHandle_t xTaskToNotify, + UBaseType_t uxIndexToNotify, + uint32_t ulValue, + eNotifyAction eAction, + uint32_t * pulPreviousNotificationValue ) /* PRIVILEGED_FUNCTION */ + { + BaseType_t xReturn = pdFAIL; + int32_t lIndex; + TaskHandle_t xInternalTaskHandle = NULL; + BaseType_t xIsPreviousNotificationValueWriteable = pdFALSE; + + if( pulPreviousNotificationValue != NULL ) + { + xIsPreviousNotificationValueWriteable = xPortIsAuthorizedToAccessBuffer( pulPreviousNotificationValue, + sizeof( uint32_t ), + tskMPU_WRITE_PERMISSION ); + } + + if( ( pulPreviousNotificationValue == NULL ) || ( xIsPreviousNotificationValueWriteable == pdTRUE ) ) + { + lIndex = ( int32_t ) xTaskToNotify; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalTaskHandle = MPU_GetTaskHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalTaskHandle != NULL ) + { + xReturn = xTaskGenericNotify( xInternalTaskHandle, uxIndexToNotify, ulValue, eAction, pulPreviousNotificationValue ); + } + } + } + + return xReturn; + } + + #endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( configUSE_TASK_NOTIFICATIONS == 1 ) + + BaseType_t MPU_xTaskGenericNotifyWaitImpl( UBaseType_t uxIndexToWaitOn, + uint32_t ulBitsToClearOnEntry, + uint32_t ulBitsToClearOnExit, + uint32_t * pulNotificationValue, + TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; + + BaseType_t MPU_xTaskGenericNotifyWaitImpl( UBaseType_t uxIndexToWaitOn, + uint32_t ulBitsToClearOnEntry, + uint32_t ulBitsToClearOnExit, + uint32_t * pulNotificationValue, + TickType_t xTicksToWait ) /* PRIVILEGED_FUNCTION */ + { + BaseType_t xReturn = pdFAIL; + BaseType_t xIsNotificationValueWritable = pdFALSE; + + if( pulNotificationValue != NULL ) + { + xIsNotificationValueWritable = xPortIsAuthorizedToAccessBuffer( pulNotificationValue, + sizeof( uint32_t ), + tskMPU_WRITE_PERMISSION ); + } + + if( ( pulNotificationValue == NULL ) || ( xIsNotificationValueWritable == pdTRUE ) ) + { + xReturn = xTaskGenericNotifyWait( uxIndexToWaitOn, ulBitsToClearOnEntry, ulBitsToClearOnExit, pulNotificationValue, xTicksToWait ); + } + + return xReturn; + } + + #endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( configUSE_TASK_NOTIFICATIONS == 1 ) + + uint32_t MPU_ulTaskGenericNotifyTakeImpl( UBaseType_t uxIndexToWaitOn, + BaseType_t xClearCountOnExit, + TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; + + uint32_t MPU_ulTaskGenericNotifyTakeImpl( UBaseType_t uxIndexToWaitOn, + BaseType_t xClearCountOnExit, + TickType_t xTicksToWait ) /* PRIVILEGED_FUNCTION */ + { + uint32_t ulReturn; + + ulReturn = ulTaskGenericNotifyTake( uxIndexToWaitOn, xClearCountOnExit, xTicksToWait ); + + return ulReturn; + } + + #endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( configUSE_TASK_NOTIFICATIONS == 1 ) + + BaseType_t MPU_xTaskGenericNotifyStateClearImpl( TaskHandle_t xTask, + UBaseType_t uxIndexToClear ) PRIVILEGED_FUNCTION; + + BaseType_t MPU_xTaskGenericNotifyStateClearImpl( TaskHandle_t xTask, + UBaseType_t uxIndexToClear ) /* PRIVILEGED_FUNCTION */ + { + BaseType_t xReturn = pdFAIL; + int32_t lIndex; + TaskHandle_t xInternalTaskHandle = NULL; + + if( xTask == NULL ) + { + xReturn = xTaskGenericNotifyStateClear( xTask, uxIndexToClear ); + } + else + { + lIndex = ( int32_t ) xTask; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalTaskHandle = MPU_GetTaskHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalTaskHandle != NULL ) + { + xReturn = xTaskGenericNotifyStateClear( xInternalTaskHandle, uxIndexToClear ); + } + } + } + + return xReturn; + } + + #endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( configUSE_TASK_NOTIFICATIONS == 1 ) + + uint32_t MPU_ulTaskGenericNotifyValueClearImpl( TaskHandle_t xTask, + UBaseType_t uxIndexToClear, + uint32_t ulBitsToClear ) PRIVILEGED_FUNCTION; + + uint32_t MPU_ulTaskGenericNotifyValueClearImpl( TaskHandle_t xTask, + UBaseType_t uxIndexToClear, + uint32_t ulBitsToClear ) /* PRIVILEGED_FUNCTION */ + { + uint32_t ulReturn = 0; + int32_t lIndex; + TaskHandle_t xInternalTaskHandle = NULL; + + if( xTask == NULL ) + { + ulReturn = ulTaskGenericNotifyValueClear( xTask, uxIndexToClear, ulBitsToClear ); + } + else + { + lIndex = ( int32_t ) xTask; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalTaskHandle = MPU_GetTaskHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalTaskHandle != NULL ) + { + ulReturn = ulTaskGenericNotifyValueClear( xInternalTaskHandle, uxIndexToClear, ulBitsToClear ); + } + } + } + + return ulReturn; + } + + #endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ +/*-----------------------------------------------------------*/ + +/* Privileged only wrappers for Task APIs. These are needed so that + * the application can use opaque handles maintained in mpu_wrappers.c + * with all the APIs. */ +/*-----------------------------------------------------------*/ + + #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + + BaseType_t MPU_xTaskCreate( TaskFunction_t pvTaskCode, + const char * const pcName, + uint16_t usStackDepth, + void * pvParameters, + UBaseType_t uxPriority, + TaskHandle_t * pxCreatedTask ) /* PRIVILEGED_FUNCTION */ + { + BaseType_t xReturn = pdFAIL; + int32_t lIndex; + TaskHandle_t xInternalTaskHandle = NULL; + + lIndex = MPU_GetFreeIndexInKernelObjectPool(); + + if( lIndex != -1 ) + { + /* xTaskCreate() can only be used to create privileged tasks in MPU port. */ + if( ( uxPriority & portPRIVILEGE_BIT ) != 0 ) + { + xReturn = xTaskCreate( pvTaskCode, pcName, usStackDepth, pvParameters, uxPriority, &( xInternalTaskHandle ) ); + + if( ( xReturn == pdPASS ) && ( xInternalTaskHandle != NULL ) ) + { + MPU_StoreTaskHandleAtIndex( lIndex, xInternalTaskHandle ); + + if( pxCreatedTask != NULL ) + { + *pxCreatedTask = ( TaskHandle_t ) CONVERT_TO_EXTERNAL_INDEX( lIndex ); + } + } + else + { + MPU_SetIndexFreeInKernelObjectPool( lIndex ); + } + } + } + + return xReturn; + } + + #endif /* configSUPPORT_DYNAMIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + + #if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + + TaskHandle_t MPU_xTaskCreateStatic( TaskFunction_t pxTaskCode, + const char * const pcName, + const uint32_t ulStackDepth, + void * const pvParameters, + UBaseType_t uxPriority, + StackType_t * const puxStackBuffer, + StaticTask_t * const pxTaskBuffer ) /* PRIVILEGED_FUNCTION */ + { + TaskHandle_t xExternalTaskHandle = NULL; + TaskHandle_t xInternalTaskHandle = NULL; + int32_t lIndex; + + lIndex = MPU_GetFreeIndexInKernelObjectPool(); + + if( lIndex != -1 ) + { + xInternalTaskHandle = xTaskCreateStatic( pxTaskCode, pcName, ulStackDepth, pvParameters, uxPriority, puxStackBuffer, pxTaskBuffer ); + + if( xInternalTaskHandle != NULL ) + { + MPU_StoreTaskHandleAtIndex( lIndex, xInternalTaskHandle ); + xExternalTaskHandle = ( TaskHandle_t ) CONVERT_TO_EXTERNAL_INDEX( lIndex ); + } + else + { + MPU_SetIndexFreeInKernelObjectPool( lIndex ); + } + } + + return xExternalTaskHandle; + } + + #endif /* configSUPPORT_STATIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + + #if ( INCLUDE_vTaskDelete == 1 ) + + void MPU_vTaskDelete( TaskHandle_t pxTaskToDelete ) /* PRIVILEGED_FUNCTION */ + { + TaskHandle_t xInternalTaskHandle = NULL; + int32_t lIndex; + + if( pxTaskToDelete == NULL ) + { + xInternalTaskHandle = xTaskGetCurrentTaskHandle(); + lIndex = MPU_GetIndexForTaskHandle( xInternalTaskHandle ); + + vTaskDelete( xInternalTaskHandle ); + + if( lIndex != -1 ) + { + MPU_SetIndexFreeInKernelObjectPool( lIndex ); + } + } + else + { + lIndex = ( int32_t ) pxTaskToDelete; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalTaskHandle = MPU_GetTaskHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalTaskHandle != NULL ) + { + vTaskDelete( xInternalTaskHandle ); + MPU_SetIndexFreeInKernelObjectPool( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + } + } + } + } + + #endif /* #if ( INCLUDE_vTaskDelete == 1 ) */ +/*-----------------------------------------------------------*/ + + + #if ( INCLUDE_vTaskPrioritySet == 1 ) + + void MPU_vTaskPrioritySet( TaskHandle_t pxTask, + UBaseType_t uxNewPriority ) /* PRIVILEGED_FUNCTION */ + { + TaskHandle_t xInternalTaskHandle = NULL; + int32_t lIndex; + + if( pxTask == NULL ) + { + vTaskPrioritySet( pxTask, uxNewPriority ); + } + else + { + lIndex = ( int32_t ) pxTask; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalTaskHandle = MPU_GetTaskHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalTaskHandle != NULL ) + { + vTaskPrioritySet( xInternalTaskHandle, uxNewPriority ); + } + } + } + } + + #endif /* if ( INCLUDE_vTaskPrioritySet == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( INCLUDE_xTaskGetHandle == 1 ) + + TaskHandle_t MPU_xTaskGetHandle( const char * pcNameToQuery ) /* PRIVILEGED_FUNCTION */ + { + TaskHandle_t xInternalTaskHandle = NULL; + TaskHandle_t xExternalTaskHandle = NULL; + int32_t lIndex; + + xInternalTaskHandle = xTaskGetHandle( pcNameToQuery ); + + if( xInternalTaskHandle != NULL ) + { + lIndex = MPU_GetIndexForTaskHandle( xInternalTaskHandle ); + + if( lIndex != -1 ) + { + xExternalTaskHandle = ( TaskHandle_t ) CONVERT_TO_EXTERNAL_INDEX( lIndex ); + } + } + + return xExternalTaskHandle; + } + + #endif /* if ( INCLUDE_xTaskGetHandle == 1 ) */ +/*-----------------------------------------------------------*/ + + + #if ( configUSE_APPLICATION_TASK_TAG == 1 ) + + BaseType_t MPU_xTaskCallApplicationTaskHook( TaskHandle_t xTask, + void * pvParameter ) /* PRIVILEGED_FUNCTION */ + { + BaseType_t xReturn = pdFAIL; + int32_t lIndex; + TaskHandle_t xInternalTaskHandle = NULL; + + if( xTask == NULL ) + { + xReturn = xTaskCallApplicationTaskHook( xTask, pvParameter ); + } + else + { + lIndex = ( int32_t ) xTask; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalTaskHandle = MPU_GetTaskHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalTaskHandle != NULL ) + { + xReturn = xTaskCallApplicationTaskHook( xInternalTaskHandle, pvParameter ); + } + } + } + + return xReturn; + } + + #endif /* if ( configUSE_APPLICATION_TASK_TAG == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + + BaseType_t MPU_xTaskCreateRestricted( const TaskParameters_t * const pxTaskDefinition, + TaskHandle_t * pxCreatedTask ) /* PRIVILEGED_FUNCTION */ + { + BaseType_t xReturn = pdFAIL; + int32_t lIndex; + TaskHandle_t xInternalTaskHandle = NULL; + + lIndex = MPU_GetFreeIndexInKernelObjectPool(); + + if( lIndex != -1 ) + { + xReturn = xTaskCreateRestricted( pxTaskDefinition, &( xInternalTaskHandle ) ); + + if( ( xReturn == pdPASS ) && ( xInternalTaskHandle != NULL ) ) + { + MPU_StoreTaskHandleAtIndex( lIndex, xInternalTaskHandle ); + + if( pxCreatedTask != NULL ) + { + *pxCreatedTask = ( TaskHandle_t ) CONVERT_TO_EXTERNAL_INDEX( lIndex ); + } + } + else + { + MPU_SetIndexFreeInKernelObjectPool( lIndex ); + } + } + + return xReturn; + } + + #endif /* configSUPPORT_DYNAMIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + + #if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + + BaseType_t MPU_xTaskCreateRestrictedStatic( const TaskParameters_t * const pxTaskDefinition, + TaskHandle_t * pxCreatedTask ) /* PRIVILEGED_FUNCTION */ + { + BaseType_t xReturn = pdFAIL; + int32_t lIndex; + TaskHandle_t xInternalTaskHandle = NULL; + + lIndex = MPU_GetFreeIndexInKernelObjectPool(); + + if( lIndex != -1 ) + { + xReturn = xTaskCreateRestrictedStatic( pxTaskDefinition, &( xInternalTaskHandle ) ); + + if( ( xReturn == pdPASS ) && ( xInternalTaskHandle != NULL ) ) + { + MPU_StoreTaskHandleAtIndex( lIndex, xInternalTaskHandle ); + + if( pxCreatedTask != NULL ) + { + *pxCreatedTask = ( TaskHandle_t ) CONVERT_TO_EXTERNAL_INDEX( lIndex ); + } + } + else + { + MPU_SetIndexFreeInKernelObjectPool( lIndex ); + } + } + + return xReturn; + } + + #endif /* configSUPPORT_STATIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + + void MPU_vTaskAllocateMPURegions( TaskHandle_t xTaskToModify, + const MemoryRegion_t * const xRegions ) /* PRIVILEGED_FUNCTION */ + { + TaskHandle_t xInternalTaskHandle = NULL; + int32_t lIndex; + + if( xTaskToModify == NULL ) + { + vTaskAllocateMPURegions( xTaskToModify, xRegions ); + } + else + { + lIndex = ( int32_t ) xTaskToModify; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalTaskHandle = MPU_GetTaskHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalTaskHandle != NULL ) + { + vTaskAllocateMPURegions( xInternalTaskHandle, xRegions ); + } + } + } + } +/*-----------------------------------------------------------*/ + + #if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + + BaseType_t MPU_xTaskGetStaticBuffers( TaskHandle_t xTask, + StackType_t ** ppuxStackBuffer, + StaticTask_t ** ppxTaskBuffer ) /* PRIVILEGED_FUNCTION */ + { + TaskHandle_t xInternalTaskHandle = NULL; + int32_t lIndex; + BaseType_t xReturn = pdFALSE; + + if( xTask == NULL ) + { + xInternalTaskHandle = xTaskGetCurrentTaskHandle(); + xReturn = xTaskGetStaticBuffers( xInternalTaskHandle, ppuxStackBuffer, ppxTaskBuffer ); + } + else + { + lIndex = ( int32_t ) xTask; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalTaskHandle = MPU_GetTaskHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalTaskHandle != NULL ) + { + xReturn = xTaskGetStaticBuffers( xInternalTaskHandle, ppuxStackBuffer, ppxTaskBuffer ); + } + } + } + + return xReturn; + } + + #endif /* if ( configSUPPORT_STATIC_ALLOCATION == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( INCLUDE_uxTaskPriorityGet == 1 ) + + UBaseType_t MPU_uxTaskPriorityGetFromISR( const TaskHandle_t xTask ) /* PRIVILEGED_FUNCTION */ + { + UBaseType_t uxReturn = configMAX_PRIORITIES; + int32_t lIndex; + TaskHandle_t xInternalTaskHandle = NULL; + + if( xTask == NULL ) + { + uxReturn = uxTaskPriorityGetFromISR( xTask ); + } + else + { + lIndex = ( int32_t ) xTask; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalTaskHandle = MPU_GetTaskHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalTaskHandle != NULL ) + { + uxReturn = uxTaskPriorityGetFromISR( xInternalTaskHandle ); + } + } + } + + return uxReturn; + } + + #endif /* #if ( INCLUDE_uxTaskPriorityGet == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( ( INCLUDE_xTaskResumeFromISR == 1 ) && ( INCLUDE_vTaskSuspend == 1 ) ) + + BaseType_t MPU_xTaskResumeFromISR( TaskHandle_t xTaskToResume ) /* PRIVILEGED_FUNCTION */ + { + BaseType_t xReturn = pdFAIL; + int32_t lIndex; + TaskHandle_t xInternalTaskHandle = NULL; + + lIndex = ( int32_t ) xTaskToResume; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalTaskHandle = MPU_GetTaskHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalTaskHandle != NULL ) + { + xReturn = xTaskResumeFromISR( xInternalTaskHandle ); + } + } + + return xReturn; + } + + #endif /* #if ( ( INCLUDE_xTaskResumeFromISR == 1 ) && ( INCLUDE_vTaskSuspend == 1 ) )*/ +/*---------------------------------------------------------------------------------------*/ + + #if ( configUSE_APPLICATION_TASK_TAG == 1 ) + + TaskHookFunction_t MPU_xTaskGetApplicationTaskTagFromISR( TaskHandle_t xTask ) /* PRIVILEGED_FUNCTION */ + { + TaskHookFunction_t xReturn = NULL; + int32_t lIndex; + TaskHandle_t xInternalTaskHandle = NULL; + + if( xTask == NULL ) + { + xReturn = xTaskGetApplicationTaskTagFromISR( xTask ); + } + else + { + lIndex = ( int32_t ) xTask; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalTaskHandle = MPU_GetTaskHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalTaskHandle != NULL ) + { + xReturn = xTaskGetApplicationTaskTagFromISR( xInternalTaskHandle ); + } + } + } + + return xReturn; + } + + #endif /* #if ( configUSE_APPLICATION_TASK_TAG == 1 ) */ +/*---------------------------------------------------------------------------------------*/ + + #if ( configUSE_TASK_NOTIFICATIONS == 1 ) + + BaseType_t MPU_xTaskGenericNotifyFromISR( TaskHandle_t xTaskToNotify, + UBaseType_t uxIndexToNotify, + uint32_t ulValue, + eNotifyAction eAction, + uint32_t * pulPreviousNotificationValue, + BaseType_t * pxHigherPriorityTaskWoken ) /* PRIVILEGED_FUNCTION */ + { + BaseType_t xReturn = pdFAIL; + int32_t lIndex; + TaskHandle_t xInternalTaskHandle = NULL; + + lIndex = ( int32_t ) xTaskToNotify; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalTaskHandle = MPU_GetTaskHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalTaskHandle != NULL ) + { + xReturn = xTaskGenericNotifyFromISR( xInternalTaskHandle, uxIndexToNotify, ulValue, eAction, pulPreviousNotificationValue, pxHigherPriorityTaskWoken ); + } + } + + return xReturn; + } + + #endif /* #if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ +/*---------------------------------------------------------------------------------------*/ + + #if ( configUSE_TASK_NOTIFICATIONS == 1 ) + + void MPU_vTaskGenericNotifyGiveFromISR( TaskHandle_t xTaskToNotify, + UBaseType_t uxIndexToNotify, + BaseType_t * pxHigherPriorityTaskWoken ) /* PRIVILEGED_FUNCTION */ + { + int32_t lIndex; + TaskHandle_t xInternalTaskHandle = NULL; + + lIndex = ( int32_t ) xTaskToNotify; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalTaskHandle = MPU_GetTaskHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalTaskHandle != NULL ) + { + vTaskGenericNotifyGiveFromISR( xInternalTaskHandle, uxIndexToNotify, pxHigherPriorityTaskWoken ); + } + } + } + #endif /*#if ( configUSE_TASK_NOTIFICATIONS == 1 )*/ +/*-----------------------------------------------------------*/ + +/*-----------------------------------------------------------*/ +/* MPU wrappers for queue APIs. */ +/*-----------------------------------------------------------*/ + + BaseType_t MPU_xQueueGenericSendImpl( QueueHandle_t xQueue, + const void * const pvItemToQueue, + TickType_t xTicksToWait, + BaseType_t xCopyPosition ) PRIVILEGED_FUNCTION; + + BaseType_t MPU_xQueueGenericSendImpl( QueueHandle_t xQueue, + const void * const pvItemToQueue, + TickType_t xTicksToWait, + BaseType_t xCopyPosition ) /* PRIVILEGED_FUNCTION */ + { + int32_t lIndex; + QueueHandle_t xInternalQueueHandle = NULL; + BaseType_t xReturn = pdFAIL; + BaseType_t xIsItemToQueueReadable = pdFALSE; + + lIndex = ( int32_t ) xQueue; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalQueueHandle = MPU_GetQueueHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalQueueHandle != NULL ) + { + if( pvItemToQueue != NULL ) + { + xIsItemToQueueReadable = xPortIsAuthorizedToAccessBuffer( pvItemToQueue, + uxQueueGetQueueItemSize( xInternalQueueHandle ), + tskMPU_READ_PERMISSION ); + } + + if( ( pvItemToQueue == NULL ) || ( xIsItemToQueueReadable == pdTRUE ) ) + { + xReturn = xQueueGenericSend( xInternalQueueHandle, pvItemToQueue, xTicksToWait, xCopyPosition ); + } + } + } + + return xReturn; + } +/*-----------------------------------------------------------*/ + + UBaseType_t MPU_uxQueueMessagesWaitingImpl( const QueueHandle_t pxQueue ) PRIVILEGED_FUNCTION; + + UBaseType_t MPU_uxQueueMessagesWaitingImpl( const QueueHandle_t pxQueue ) /* PRIVILEGED_FUNCTION */ + { + int32_t lIndex; + QueueHandle_t xInternalQueueHandle = NULL; + UBaseType_t uxReturn = 0; + + lIndex = ( int32_t ) pxQueue; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalQueueHandle = MPU_GetQueueHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalQueueHandle != NULL ) + { + uxReturn = uxQueueMessagesWaiting( xInternalQueueHandle ); + } + } + + return uxReturn; + } +/*-----------------------------------------------------------*/ + + UBaseType_t MPU_uxQueueSpacesAvailableImpl( const QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; + + UBaseType_t MPU_uxQueueSpacesAvailableImpl( const QueueHandle_t xQueue ) /* PRIVILEGED_FUNCTION */ + { + int32_t lIndex; + QueueHandle_t xInternalQueueHandle = NULL; + UBaseType_t uxReturn = 0; + + lIndex = ( int32_t ) xQueue; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalQueueHandle = MPU_GetQueueHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalQueueHandle != NULL ) + { + uxReturn = uxQueueSpacesAvailable( xInternalQueueHandle ); + } + } + + return uxReturn; + } +/*-----------------------------------------------------------*/ + + BaseType_t MPU_xQueueReceiveImpl( QueueHandle_t pxQueue, + void * const pvBuffer, + TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; + + BaseType_t MPU_xQueueReceiveImpl( QueueHandle_t pxQueue, + void * const pvBuffer, + TickType_t xTicksToWait ) /* PRIVILEGED_FUNCTION */ + { + int32_t lIndex; + QueueHandle_t xInternalQueueHandle = NULL; + BaseType_t xReturn = pdFAIL; + BaseType_t xIsReceiveBufferWritable = pdFALSE; + + lIndex = ( int32_t ) pxQueue; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalQueueHandle = MPU_GetQueueHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalQueueHandle != NULL ) + { + xIsReceiveBufferWritable = xPortIsAuthorizedToAccessBuffer( pvBuffer, + uxQueueGetQueueItemSize( xInternalQueueHandle ), + tskMPU_WRITE_PERMISSION ); + + if( xIsReceiveBufferWritable == pdTRUE ) + { + xReturn = xQueueReceive( xInternalQueueHandle, pvBuffer, xTicksToWait ); + } + } + } + + return xReturn; + } +/*-----------------------------------------------------------*/ + + BaseType_t MPU_xQueuePeekImpl( QueueHandle_t xQueue, + void * const pvBuffer, + TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; + + BaseType_t MPU_xQueuePeekImpl( QueueHandle_t xQueue, + void * const pvBuffer, + TickType_t xTicksToWait ) /* PRIVILEGED_FUNCTION */ + { + int32_t lIndex; + QueueHandle_t xInternalQueueHandle = NULL; + BaseType_t xReturn = pdFAIL; + BaseType_t xIsReceiveBufferWritable = pdFALSE; + + lIndex = ( int32_t ) xQueue; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalQueueHandle = MPU_GetQueueHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalQueueHandle != NULL ) + { + xIsReceiveBufferWritable = xPortIsAuthorizedToAccessBuffer( pvBuffer, + uxQueueGetQueueItemSize( xInternalQueueHandle ), + tskMPU_WRITE_PERMISSION ); + + if( xIsReceiveBufferWritable == pdTRUE ) + { + xReturn = xQueuePeek( xInternalQueueHandle, pvBuffer, xTicksToWait ); + } + } + } + + return xReturn; + } +/*-----------------------------------------------------------*/ + + BaseType_t MPU_xQueueSemaphoreTakeImpl( QueueHandle_t xQueue, + TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; + + BaseType_t MPU_xQueueSemaphoreTakeImpl( QueueHandle_t xQueue, + TickType_t xTicksToWait ) /* PRIVILEGED_FUNCTION */ + { + int32_t lIndex; + QueueHandle_t xInternalQueueHandle = NULL; + BaseType_t xReturn = pdFAIL; + + lIndex = ( int32_t ) xQueue; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalQueueHandle = MPU_GetQueueHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalQueueHandle != NULL ) + { + xReturn = xQueueSemaphoreTake( xInternalQueueHandle, xTicksToWait ); + } + } + + return xReturn; + } +/*-----------------------------------------------------------*/ + + #if ( ( configUSE_MUTEXES == 1 ) && ( INCLUDE_xSemaphoreGetMutexHolder == 1 ) ) + + TaskHandle_t MPU_xQueueGetMutexHolderImpl( QueueHandle_t xSemaphore ) PRIVILEGED_FUNCTION; + + TaskHandle_t MPU_xQueueGetMutexHolderImpl( QueueHandle_t xSemaphore ) /* PRIVILEGED_FUNCTION */ + { + TaskHandle_t xMutexHolderTaskInternalHandle = NULL; + TaskHandle_t xMutexHolderTaskExternalHandle = NULL; + int32_t lIndex, lMutexHolderTaskIndex; + QueueHandle_t xInternalQueueHandle = NULL; + + + lIndex = ( int32_t ) xSemaphore; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalQueueHandle = MPU_GetQueueHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalQueueHandle != NULL ) + { + xMutexHolderTaskInternalHandle = xQueueGetMutexHolder( xInternalQueueHandle ); + + if( xMutexHolderTaskInternalHandle != NULL ) + { + lMutexHolderTaskIndex = MPU_GetIndexForTaskHandle( xMutexHolderTaskInternalHandle ); + + if( lMutexHolderTaskIndex != -1 ) + { + xMutexHolderTaskExternalHandle = ( TaskHandle_t ) ( CONVERT_TO_EXTERNAL_INDEX( lMutexHolderTaskIndex ) ); + } + } + } + } + + return xMutexHolderTaskExternalHandle; + } + + #endif /* if ( ( configUSE_MUTEXES == 1 ) && ( INCLUDE_xSemaphoreGetMutexHolder == 1 ) ) */ +/*-----------------------------------------------------------*/ + + #if ( configUSE_RECURSIVE_MUTEXES == 1 ) + + BaseType_t MPU_xQueueTakeMutexRecursiveImpl( QueueHandle_t xMutex, + TickType_t xBlockTime ) PRIVILEGED_FUNCTION; + + BaseType_t MPU_xQueueTakeMutexRecursiveImpl( QueueHandle_t xMutex, + TickType_t xBlockTime ) /* PRIVILEGED_FUNCTION */ + { + BaseType_t xReturn = pdFAIL; + int32_t lIndex; + QueueHandle_t xInternalQueueHandle = NULL; + + lIndex = ( int32_t ) xMutex; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalQueueHandle = MPU_GetQueueHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalQueueHandle != NULL ) + { + xReturn = xQueueTakeMutexRecursive( xInternalQueueHandle, xBlockTime ); + } + } + + return xReturn; + } + + #endif /* if ( configUSE_RECURSIVE_MUTEXES == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( configUSE_RECURSIVE_MUTEXES == 1 ) + + BaseType_t MPU_xQueueGiveMutexRecursiveImpl( QueueHandle_t xMutex ) PRIVILEGED_FUNCTION; + + BaseType_t MPU_xQueueGiveMutexRecursiveImpl( QueueHandle_t xMutex ) /* PRIVILEGED_FUNCTION */ + { + BaseType_t xReturn = pdFAIL; + int32_t lIndex; + QueueHandle_t xInternalQueueHandle = NULL; + + lIndex = ( int32_t ) xMutex; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalQueueHandle = MPU_GetQueueHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalQueueHandle != NULL ) + { + xReturn = xQueueGiveMutexRecursive( xInternalQueueHandle ); + } + } + + return xReturn; + } + + #endif /* if ( configUSE_RECURSIVE_MUTEXES == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( configUSE_QUEUE_SETS == 1 ) + + QueueSetMemberHandle_t MPU_xQueueSelectFromSetImpl( QueueSetHandle_t xQueueSet, + TickType_t xBlockTimeTicks ) PRIVILEGED_FUNCTION; + + QueueSetMemberHandle_t MPU_xQueueSelectFromSetImpl( QueueSetHandle_t xQueueSet, + TickType_t xBlockTimeTicks ) /* PRIVILEGED_FUNCTION */ + { + QueueSetHandle_t xInternalQueueSetHandle = NULL; + QueueSetMemberHandle_t xSelectedMemberInternal = NULL; + QueueSetMemberHandle_t xSelectedMemberExternal = NULL; + int32_t lIndexQueueSet, lIndexSelectedMember; + + lIndexQueueSet = ( int32_t ) xQueueSet; + + if( IS_EXTERNAL_INDEX_VALID( lIndexQueueSet ) != pdFALSE ) + { + xInternalQueueSetHandle = MPU_GetQueueSetHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndexQueueSet ) ); + + if( xInternalQueueSetHandle != NULL ) + { + xSelectedMemberInternal = xQueueSelectFromSet( xInternalQueueSetHandle, xBlockTimeTicks ); + + if( xSelectedMemberInternal != NULL ) + { + lIndexSelectedMember = MPU_GetIndexForQueueSetMemberHandle( xSelectedMemberInternal ); + + if( lIndexSelectedMember != -1 ) + { + xSelectedMemberExternal = ( QueueSetMemberHandle_t ) ( CONVERT_TO_EXTERNAL_INDEX( lIndexSelectedMember ) ); + } + } + } + } + + return xSelectedMemberExternal; + } + + #endif /* if ( configUSE_QUEUE_SETS == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( configUSE_QUEUE_SETS == 1 ) + + BaseType_t MPU_xQueueAddToSetImpl( QueueSetMemberHandle_t xQueueOrSemaphore, + QueueSetHandle_t xQueueSet ) PRIVILEGED_FUNCTION; + + BaseType_t MPU_xQueueAddToSetImpl( QueueSetMemberHandle_t xQueueOrSemaphore, + QueueSetHandle_t xQueueSet ) /* PRIVILEGED_FUNCTION */ + { + BaseType_t xReturn = pdFAIL; + QueueSetMemberHandle_t xInternalQueueSetMemberHandle = NULL; + QueueSetHandle_t xInternalQueueSetHandle; + int32_t lIndexQueueSet, lIndexQueueSetMember; + + lIndexQueueSet = ( int32_t ) xQueueSet; + lIndexQueueSetMember = ( int32_t ) xQueueOrSemaphore; + + if( ( IS_EXTERNAL_INDEX_VALID( lIndexQueueSet ) != pdFALSE ) && + ( IS_EXTERNAL_INDEX_VALID( lIndexQueueSetMember ) != pdFALSE ) ) + { + xInternalQueueSetHandle = MPU_GetQueueSetHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndexQueueSet ) ); + xInternalQueueSetMemberHandle = MPU_GetQueueSetMemberHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndexQueueSetMember ) ); + + if( ( xInternalQueueSetHandle != NULL ) && ( xInternalQueueSetMemberHandle != NULL ) ) + { + xReturn = xQueueAddToSet( xInternalQueueSetMemberHandle, xInternalQueueSetHandle ); + } + } + + return xReturn; + } + + #endif /* if ( configUSE_QUEUE_SETS == 1 ) */ +/*-----------------------------------------------------------*/ + + #if configQUEUE_REGISTRY_SIZE > 0 + + void MPU_vQueueAddToRegistryImpl( QueueHandle_t xQueue, + const char * pcName ) PRIVILEGED_FUNCTION; + + void MPU_vQueueAddToRegistryImpl( QueueHandle_t xQueue, + const char * pcName ) /* PRIVILEGED_FUNCTION */ + { + int32_t lIndex; + QueueHandle_t xInternalQueueHandle = NULL; + + lIndex = ( int32_t ) xQueue; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalQueueHandle = MPU_GetQueueHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalQueueHandle != NULL ) + { + vQueueAddToRegistry( xInternalQueueHandle, pcName ); + } + } + } + + #endif /* if configQUEUE_REGISTRY_SIZE > 0 */ +/*-----------------------------------------------------------*/ + + #if configQUEUE_REGISTRY_SIZE > 0 + + void MPU_vQueueUnregisterQueueImpl( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; + + void MPU_vQueueUnregisterQueueImpl( QueueHandle_t xQueue ) /* PRIVILEGED_FUNCTION */ + { + int32_t lIndex; + QueueHandle_t xInternalQueueHandle = NULL; + + lIndex = ( int32_t ) xQueue; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalQueueHandle = MPU_GetQueueHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalQueueHandle != NULL ) + { + vQueueUnregisterQueue( xInternalQueueHandle ); + } + } + } + + #endif /* if configQUEUE_REGISTRY_SIZE > 0 */ +/*-----------------------------------------------------------*/ + + #if configQUEUE_REGISTRY_SIZE > 0 + + const char * MPU_pcQueueGetNameImpl( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; + + const char * MPU_pcQueueGetNameImpl( QueueHandle_t xQueue ) /* PRIVILEGED_FUNCTION */ + { + const char * pcReturn; + QueueHandle_t xInternalQueueHandle = NULL; + int32_t lIndex; + + lIndex = ( int32_t ) xQueue; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalQueueHandle = MPU_GetQueueHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalQueueHandle != NULL ) + { + pcReturn = pcQueueGetName( xInternalQueueHandle ); + } + } + + return pcReturn; + } + + #endif /* if configQUEUE_REGISTRY_SIZE > 0 */ +/*-----------------------------------------------------------*/ + +/* Privileged only wrappers for Queue APIs. These are needed so that + * the application can use opaque handles maintained in mpu_wrappers.c + * with all the APIs. */ +/*-----------------------------------------------------------*/ + + void MPU_vQueueDelete( QueueHandle_t xQueue ) /* PRIVILEGED_FUNCTION */ + { + QueueHandle_t xInternalQueueHandle = NULL; + int32_t lIndex; + + lIndex = ( int32_t ) xQueue; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalQueueHandle = MPU_GetQueueHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalQueueHandle != NULL ) + { + vQueueDelete( xInternalQueueHandle ); + MPU_SetIndexFreeInKernelObjectPool( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + } + } + } +/*-----------------------------------------------------------*/ + + #if ( ( configUSE_MUTEXES == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) + + QueueHandle_t MPU_xQueueCreateMutex( const uint8_t ucQueueType ) /* PRIVILEGED_FUNCTION */ + { + QueueHandle_t xInternalQueueHandle = NULL; + QueueHandle_t xExternalQueueHandle = NULL; + int32_t lIndex; + + lIndex = MPU_GetFreeIndexInKernelObjectPool(); + + if( lIndex != -1 ) + { + xInternalQueueHandle = xQueueCreateMutex( ucQueueType ); + + if( xInternalQueueHandle != NULL ) + { + MPU_StoreQueueHandleAtIndex( lIndex, xInternalQueueHandle ); + xExternalQueueHandle = ( QueueHandle_t ) CONVERT_TO_EXTERNAL_INDEX( lIndex ); + } + else + { + MPU_SetIndexFreeInKernelObjectPool( lIndex ); + } + } + + return xExternalQueueHandle; + } + + #endif /* if ( ( configUSE_MUTEXES == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) */ +/*-----------------------------------------------------------*/ + + #if ( ( configUSE_MUTEXES == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) + + QueueHandle_t MPU_xQueueCreateMutexStatic( const uint8_t ucQueueType, + StaticQueue_t * pxStaticQueue ) /* PRIVILEGED_FUNCTION */ + { + QueueHandle_t xInternalQueueHandle = NULL; + QueueHandle_t xExternalQueueHandle = NULL; + int32_t lIndex; + + lIndex = MPU_GetFreeIndexInKernelObjectPool(); + + if( lIndex != -1 ) + { + xInternalQueueHandle = xQueueCreateMutexStatic( ucQueueType, pxStaticQueue ); + + if( xInternalQueueHandle != NULL ) + { + MPU_StoreQueueHandleAtIndex( lIndex, xInternalQueueHandle ); + xExternalQueueHandle = ( QueueHandle_t ) CONVERT_TO_EXTERNAL_INDEX( lIndex ); + } + else + { + MPU_SetIndexFreeInKernelObjectPool( lIndex ); + } + } + + return xExternalQueueHandle; + } + + #endif /* if ( ( configUSE_MUTEXES == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) */ +/*-----------------------------------------------------------*/ + + #if ( ( configUSE_COUNTING_SEMAPHORES == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) + + QueueHandle_t MPU_xQueueCreateCountingSemaphore( UBaseType_t uxCountValue, + UBaseType_t uxInitialCount ) /* PRIVILEGED_FUNCTION */ + { + QueueHandle_t xInternalQueueHandle = NULL; + QueueHandle_t xExternalQueueHandle = NULL; + int32_t lIndex; + + lIndex = MPU_GetFreeIndexInKernelObjectPool(); + + if( lIndex != -1 ) + { + xInternalQueueHandle = xQueueCreateCountingSemaphore( uxCountValue, uxInitialCount ); + + if( xInternalQueueHandle != NULL ) + { + MPU_StoreQueueHandleAtIndex( lIndex, xInternalQueueHandle ); + xExternalQueueHandle = ( QueueHandle_t ) CONVERT_TO_EXTERNAL_INDEX( lIndex ); + } + else + { + MPU_SetIndexFreeInKernelObjectPool( lIndex ); + } + } + + return xExternalQueueHandle; + } + + #endif /* if ( ( configUSE_COUNTING_SEMAPHORES == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) */ +/*-----------------------------------------------------------*/ + + #if ( ( configUSE_COUNTING_SEMAPHORES == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) + + QueueHandle_t MPU_xQueueCreateCountingSemaphoreStatic( const UBaseType_t uxMaxCount, + const UBaseType_t uxInitialCount, + StaticQueue_t * pxStaticQueue ) /* PRIVILEGED_FUNCTION */ + { + QueueHandle_t xInternalQueueHandle = NULL; + QueueHandle_t xExternalQueueHandle = NULL; + int32_t lIndex; + + lIndex = MPU_GetFreeIndexInKernelObjectPool(); + + if( lIndex != -1 ) + { + xInternalQueueHandle = xQueueCreateCountingSemaphoreStatic( uxMaxCount, uxInitialCount, pxStaticQueue ); + + if( xInternalQueueHandle != NULL ) + { + MPU_StoreQueueHandleAtIndex( lIndex, xInternalQueueHandle ); + xExternalQueueHandle = ( QueueHandle_t ) CONVERT_TO_EXTERNAL_INDEX( lIndex ); + } + else + { + MPU_SetIndexFreeInKernelObjectPool( lIndex ); + } + } + + return xExternalQueueHandle; + } + + #endif /* if ( ( configUSE_COUNTING_SEMAPHORES == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) */ +/*-----------------------------------------------------------*/ + + #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + + QueueHandle_t MPU_xQueueGenericCreate( UBaseType_t uxQueueLength, + UBaseType_t uxItemSize, + uint8_t ucQueueType ) /* PRIVILEGED_FUNCTION */ + { + QueueHandle_t xInternalQueueHandle = NULL; + QueueHandle_t xExternalQueueHandle = NULL; + int32_t lIndex; + + lIndex = MPU_GetFreeIndexInKernelObjectPool(); + + if( lIndex != -1 ) + { + xInternalQueueHandle = xQueueGenericCreate( uxQueueLength, uxItemSize, ucQueueType ); + + if( xInternalQueueHandle != NULL ) + { + MPU_StoreQueueHandleAtIndex( lIndex, xInternalQueueHandle ); + xExternalQueueHandle = ( QueueHandle_t ) CONVERT_TO_EXTERNAL_INDEX( lIndex ); + } + else + { + MPU_SetIndexFreeInKernelObjectPool( lIndex ); + } + } + + return xExternalQueueHandle; + } + + #endif /* if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + + QueueHandle_t MPU_xQueueGenericCreateStatic( const UBaseType_t uxQueueLength, + const UBaseType_t uxItemSize, + uint8_t * pucQueueStorage, + StaticQueue_t * pxStaticQueue, + const uint8_t ucQueueType ) /* PRIVILEGED_FUNCTION */ + { + QueueHandle_t xInternalQueueHandle = NULL; + QueueHandle_t xExternalQueueHandle = NULL; + int32_t lIndex; + + lIndex = MPU_GetFreeIndexInKernelObjectPool(); + + if( lIndex != -1 ) + { + xInternalQueueHandle = xQueueGenericCreateStatic( uxQueueLength, uxItemSize, pucQueueStorage, pxStaticQueue, ucQueueType ); + + if( xInternalQueueHandle != NULL ) + { + MPU_StoreQueueHandleAtIndex( lIndex, xInternalQueueHandle ); + xExternalQueueHandle = ( QueueHandle_t ) CONVERT_TO_EXTERNAL_INDEX( lIndex ); + } + else + { + MPU_SetIndexFreeInKernelObjectPool( lIndex ); + } + } + + return xExternalQueueHandle; + } + + #endif /* if ( configSUPPORT_STATIC_ALLOCATION == 1 ) */ +/*-----------------------------------------------------------*/ + + BaseType_t MPU_xQueueGenericReset( QueueHandle_t xQueue, + BaseType_t xNewQueue ) /* PRIVILEGED_FUNCTION */ + { + int32_t lIndex; + QueueHandle_t xInternalQueueHandle = NULL; + BaseType_t xReturn = pdFAIL; + + lIndex = ( uint32_t ) xQueue; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalQueueHandle = MPU_GetQueueHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalQueueHandle != NULL ) + { + xReturn = xQueueGenericReset( xInternalQueueHandle, xNewQueue ); + } + } + + return xReturn; + } +/*-----------------------------------------------------------*/ + + #if ( ( configUSE_QUEUE_SETS == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) + + QueueSetHandle_t MPU_xQueueCreateSet( UBaseType_t uxEventQueueLength ) /* PRIVILEGED_FUNCTION */ + { + QueueSetHandle_t xInternalQueueSetHandle = NULL; + QueueSetHandle_t xExternalQueueSetHandle = NULL; + int32_t lIndex; + + lIndex = MPU_GetFreeIndexInKernelObjectPool(); + + if( lIndex != -1 ) + { + xInternalQueueSetHandle = xQueueCreateSet( uxEventQueueLength ); + + if( xInternalQueueSetHandle != NULL ) + { + MPU_StoreQueueSetHandleAtIndex( lIndex, xInternalQueueSetHandle ); + xExternalQueueSetHandle = ( QueueSetHandle_t ) CONVERT_TO_EXTERNAL_INDEX( lIndex ); + } + else + { + MPU_SetIndexFreeInKernelObjectPool( lIndex ); + } + } + + return xExternalQueueSetHandle; + } + + #endif /* if ( ( configUSE_QUEUE_SETS == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) */ +/*-----------------------------------------------------------*/ + + #if ( configUSE_QUEUE_SETS == 1 ) + + BaseType_t MPU_xQueueRemoveFromSet( QueueSetMemberHandle_t xQueueOrSemaphore, + QueueSetHandle_t xQueueSet ) /* PRIVILEGED_FUNCTION */ + { + BaseType_t xReturn = pdFAIL; + QueueSetMemberHandle_t xInternalQueueSetMemberHandle = NULL; + QueueSetHandle_t xInternalQueueSetHandle; + int32_t lIndexQueueSet, lIndexQueueSetMember; + + lIndexQueueSet = ( int32_t ) xQueueSet; + lIndexQueueSetMember = ( int32_t ) xQueueOrSemaphore; + + if( ( IS_EXTERNAL_INDEX_VALID( lIndexQueueSet ) != pdFALSE ) && + ( IS_EXTERNAL_INDEX_VALID( lIndexQueueSetMember ) != pdFALSE ) ) + { + xInternalQueueSetHandle = MPU_GetQueueSetHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndexQueueSet ) ); + xInternalQueueSetMemberHandle = MPU_GetQueueSetMemberHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndexQueueSetMember ) ); + + if( ( xInternalQueueSetHandle != NULL ) && ( xInternalQueueSetMemberHandle != NULL ) ) + { + xReturn = xQueueRemoveFromSet( xInternalQueueSetMemberHandle, xInternalQueueSetHandle ); + } + } + + return xReturn; + } + + #endif /* if ( configUSE_QUEUE_SETS == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + + BaseType_t MPU_xQueueGenericGetStaticBuffers( QueueHandle_t xQueue, + uint8_t ** ppucQueueStorage, + StaticQueue_t ** ppxStaticQueue ) /* PRIVILEGED_FUNCTION */ + { + int32_t lIndex; + QueueHandle_t xInternalQueueHandle = NULL; + BaseType_t xReturn = pdFALSE; + + lIndex = ( int32_t ) xQueue; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalQueueHandle = MPU_GetQueueHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalQueueHandle != NULL ) + { + xReturn = xQueueGenericGetStaticBuffers( xInternalQueueHandle, ppucQueueStorage, ppxStaticQueue ); + } + } + + return xReturn; + } + + #endif /*if ( configSUPPORT_STATIC_ALLOCATION == 1 )*/ +/*-----------------------------------------------------------*/ + + BaseType_t MPU_xQueueGenericSendFromISR( QueueHandle_t xQueue, + const void * const pvItemToQueue, + BaseType_t * const pxHigherPriorityTaskWoken, + const BaseType_t xCopyPosition ) /* PRIVILEGED_FUNCTION */ + { + BaseType_t xReturn = pdFAIL; + int32_t lIndex; + QueueHandle_t xInternalQueueHandle = NULL; + + lIndex = ( int32_t ) xQueue; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalQueueHandle = MPU_GetQueueHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalQueueHandle != NULL ) + { + xReturn = xQueueGenericSendFromISR( xInternalQueueHandle, pvItemToQueue, pxHigherPriorityTaskWoken, xCopyPosition ); + } + } + + return xReturn; + } + +/*-----------------------------------------------------------*/ + + BaseType_t MPU_xQueueGiveFromISR( QueueHandle_t xQueue, + BaseType_t * const pxHigherPriorityTaskWoken ) /* PRIVILEGED_FUNCTION */ + { + BaseType_t xReturn = pdFAIL; + int32_t lIndex; + QueueHandle_t xInternalQueueHandle = NULL; + + lIndex = ( int32_t ) xQueue; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalQueueHandle = MPU_GetQueueHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalQueueHandle != NULL ) + { + xReturn = xQueueGiveFromISR( xInternalQueueHandle, pxHigherPriorityTaskWoken ); + } + } + + return xReturn; + } + +/*-----------------------------------------------------------*/ + + BaseType_t MPU_xQueuePeekFromISR( QueueHandle_t xQueue, + void * const pvBuffer ) /* PRIVILEGED_FUNCTION */ + { + BaseType_t xReturn = pdFAIL; + int32_t lIndex; + QueueHandle_t xInternalQueueHandle = NULL; + + lIndex = ( int32_t ) xQueue; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalQueueHandle = MPU_GetQueueHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalQueueHandle != NULL ) + { + xReturn = xQueuePeekFromISR( xInternalQueueHandle, pvBuffer ); + } + } + + return xReturn; + } + +/*-----------------------------------------------------------*/ + + BaseType_t MPU_xQueueReceiveFromISR( QueueHandle_t xQueue, + void * const pvBuffer, + BaseType_t * const pxHigherPriorityTaskWoken ) /* PRIVILEGED_FUNCTION */ + { + BaseType_t xReturn = pdFAIL; + int32_t lIndex; + QueueHandle_t xInternalQueueHandle = NULL; + + lIndex = ( int32_t ) xQueue; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalQueueHandle = MPU_GetQueueHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalQueueHandle != NULL ) + { + xReturn = xQueueReceiveFromISR( xInternalQueueHandle, pvBuffer, pxHigherPriorityTaskWoken ); + } + } + + return xReturn; + } + +/*-----------------------------------------------------------*/ + + BaseType_t MPU_xQueueIsQueueEmptyFromISR( const QueueHandle_t xQueue ) /* PRIVILEGED_FUNCTION */ + { + BaseType_t xReturn = pdFAIL; + int32_t lIndex; + QueueHandle_t xInternalQueueHandle = NULL; + + lIndex = ( int32_t ) xQueue; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalQueueHandle = MPU_GetQueueHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalQueueHandle != NULL ) + { + xReturn = xQueueIsQueueEmptyFromISR( xInternalQueueHandle ); + } + } + + return xReturn; + } +/*-----------------------------------------------------------*/ + + BaseType_t MPU_xQueueIsQueueFullFromISR( const QueueHandle_t xQueue ) /* PRIVILEGED_FUNCTION */ + { + BaseType_t xReturn = pdFAIL; + int32_t lIndex; + QueueHandle_t xInternalQueueHandle = NULL; + + lIndex = ( int32_t ) xQueue; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalQueueHandle = MPU_GetQueueHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalQueueHandle != NULL ) + { + xReturn = xQueueIsQueueFullFromISR( xInternalQueueHandle ); + } + } + + return xReturn; + } + +/*-----------------------------------------------------------*/ + + UBaseType_t MPU_uxQueueMessagesWaitingFromISR( const QueueHandle_t xQueue ) /* PRIVILEGED_FUNCTION */ + { + UBaseType_t uxReturn = 0; + int32_t lIndex; + QueueHandle_t xInternalQueueHandle = NULL; + + lIndex = ( int32_t ) xQueue; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalQueueHandle = MPU_GetQueueHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalQueueHandle != NULL ) + { + uxReturn = uxQueueMessagesWaitingFromISR( xInternalQueueHandle ); + } + } + + return uxReturn; + } + +/*-----------------------------------------------------------*/ + + #if ( ( configUSE_MUTEXES == 1 ) && ( INCLUDE_xSemaphoreGetMutexHolder == 1 ) ) + + TaskHandle_t MPU_xQueueGetMutexHolderFromISR( QueueHandle_t xSemaphore ) /* PRIVILEGED_FUNCTION */ + { + TaskHandle_t xMutexHolderTaskInternalHandle = NULL; + TaskHandle_t xMutexHolderTaskExternalHandle = NULL; + int32_t lIndex, lMutexHolderTaskIndex; + QueueHandle_t xInternalSemaphoreHandle = NULL; + + lIndex = ( int32_t ) xSemaphore; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalSemaphoreHandle = MPU_GetQueueHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalSemaphoreHandle != NULL ) + { + xMutexHolderTaskInternalHandle = xQueueGetMutexHolder( xInternalSemaphoreHandle ); + + if( xMutexHolderTaskInternalHandle != NULL ) + { + lMutexHolderTaskIndex = MPU_GetIndexForTaskHandle( xMutexHolderTaskInternalHandle ); + + if( lMutexHolderTaskIndex != -1 ) + { + xMutexHolderTaskExternalHandle = ( TaskHandle_t ) ( CONVERT_TO_EXTERNAL_INDEX( lMutexHolderTaskIndex ) ); + } + } + } + } + + return xMutexHolderTaskExternalHandle; + } + + #endif /* #if ( ( configUSE_MUTEXES == 1 ) && ( INCLUDE_xSemaphoreGetMutexHolder == 1 ) ) */ +/*-----------------------------------------------------------*/ + + #if ( configUSE_QUEUE_SETS == 1 ) + + QueueSetMemberHandle_t MPU_xQueueSelectFromSetFromISR( QueueSetHandle_t xQueueSet ) /* PRIVILEGED_FUNCTION */ + { + QueueSetHandle_t xInternalQueueSetHandle = NULL; + QueueSetMemberHandle_t xSelectedMemberInternal = NULL; + QueueSetMemberHandle_t xSelectedMemberExternal = NULL; + int32_t lIndexQueueSet, lIndexSelectedMember; + + lIndexQueueSet = ( int32_t ) xQueueSet; + + if( IS_EXTERNAL_INDEX_VALID( lIndexQueueSet ) != pdFALSE ) + { + xInternalQueueSetHandle = MPU_GetQueueSetHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndexQueueSet ) ); + + if( xInternalQueueSetHandle != NULL ) + { + xSelectedMemberInternal = xQueueSelectFromSetFromISR( xInternalQueueSetHandle ); + + if( xSelectedMemberInternal != NULL ) + { + lIndexSelectedMember = MPU_GetIndexForQueueSetMemberHandle( xSelectedMemberInternal ); + + if( lIndexSelectedMember != -1 ) + { + xSelectedMemberExternal = ( QueueSetMemberHandle_t ) ( CONVERT_TO_EXTERNAL_INDEX( lIndexSelectedMember ) ); + } + } + } + } + + return xSelectedMemberExternal; + } + + #endif /* if ( configUSE_QUEUE_SETS == 1 ) */ +/*-----------------------------------------------------------*/ + +/*-----------------------------------------------------------*/ +/* MPU wrappers for timers APIs. */ +/*-----------------------------------------------------------*/ + + #if ( configUSE_TIMERS == 1 ) + + void * MPU_pvTimerGetTimerIDImpl( const TimerHandle_t xTimer ) PRIVILEGED_FUNCTION; + + void * MPU_pvTimerGetTimerIDImpl( const TimerHandle_t xTimer ) /* PRIVILEGED_FUNCTION */ + { + void * pvReturn = NULL; + TimerHandle_t xInternalTimerHandle = NULL; + int32_t lIndex; + + lIndex = ( int32_t ) xTimer; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalTimerHandle = MPU_GetTimerHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalTimerHandle != NULL ) + { + pvReturn = pvTimerGetTimerID( xInternalTimerHandle ); + } + } + + return pvReturn; + } + + #endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( configUSE_TIMERS == 1 ) + + void MPU_vTimerSetTimerIDImpl( TimerHandle_t xTimer, + void * pvNewID ) PRIVILEGED_FUNCTION; + + void MPU_vTimerSetTimerIDImpl( TimerHandle_t xTimer, + void * pvNewID ) /* PRIVILEGED_FUNCTION */ + { + TimerHandle_t xInternalTimerHandle = NULL; + int32_t lIndex; + + lIndex = ( int32_t ) xTimer; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalTimerHandle = MPU_GetTimerHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalTimerHandle != NULL ) + { + vTimerSetTimerID( xInternalTimerHandle, pvNewID ); + } + } + } + + #endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( configUSE_TIMERS == 1 ) + + BaseType_t MPU_xTimerIsTimerActiveImpl( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION; + + BaseType_t MPU_xTimerIsTimerActiveImpl( TimerHandle_t xTimer ) /* PRIVILEGED_FUNCTION */ + { + BaseType_t xReturn = pdFALSE; + TimerHandle_t xInternalTimerHandle = NULL; + int32_t lIndex; + + lIndex = ( int32_t ) xTimer; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalTimerHandle = MPU_GetTimerHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalTimerHandle != NULL ) + { + xReturn = xTimerIsTimerActive( xInternalTimerHandle ); + } + } + + return xReturn; + } + + #endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( configUSE_TIMERS == 1 ) + + TaskHandle_t MPU_xTimerGetTimerDaemonTaskHandleImpl( void ) PRIVILEGED_FUNCTION; + + TaskHandle_t MPU_xTimerGetTimerDaemonTaskHandleImpl( void ) /* PRIVILEGED_FUNCTION */ + { + TaskHandle_t xReturn; + + xReturn = xTimerGetTimerDaemonTaskHandle(); + + return xReturn; + } + + #endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( configUSE_TIMERS == 1 ) + + BaseType_t MPU_xTimerGenericCommandImpl( TimerHandle_t xTimer, + const BaseType_t xCommandID, + const TickType_t xOptionalValue, + BaseType_t * const pxHigherPriorityTaskWoken, + const TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; + + BaseType_t MPU_xTimerGenericCommandImpl( TimerHandle_t xTimer, + const BaseType_t xCommandID, + const TickType_t xOptionalValue, + BaseType_t * const pxHigherPriorityTaskWoken, + const TickType_t xTicksToWait ) /* PRIVILEGED_FUNCTION */ + { + BaseType_t xReturn = pdFALSE; + TimerHandle_t xInternalTimerHandle = NULL; + int32_t lIndex; + BaseType_t xIsHigherPriorityTaskWokenWriteable = pdFALSE; + + if( pxHigherPriorityTaskWoken != NULL ) + { + xIsHigherPriorityTaskWokenWriteable = xPortIsAuthorizedToAccessBuffer( pxHigherPriorityTaskWoken, + sizeof( BaseType_t ), + tskMPU_WRITE_PERMISSION ); + } + + if( ( pxHigherPriorityTaskWoken == NULL ) || ( xIsHigherPriorityTaskWokenWriteable == pdTRUE ) ) + { + lIndex = ( int32_t ) xTimer; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalTimerHandle = MPU_GetTimerHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalTimerHandle != NULL ) + { + xReturn = xTimerGenericCommand( xInternalTimerHandle, xCommandID, xOptionalValue, pxHigherPriorityTaskWoken, xTicksToWait ); + } + } + } + + return xReturn; + } + + #endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( configUSE_TIMERS == 1 ) + + const char * MPU_pcTimerGetNameImpl( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION; + + const char * MPU_pcTimerGetNameImpl( TimerHandle_t xTimer ) /* PRIVILEGED_FUNCTION */ + { + const char * pcReturn = NULL; + TimerHandle_t xInternalTimerHandle = NULL; + int32_t lIndex; + + lIndex = ( int32_t ) xTimer; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalTimerHandle = MPU_GetTimerHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalTimerHandle != NULL ) + { + pcReturn = pcTimerGetName( xInternalTimerHandle ); + } + } + + return pcReturn; + } + + #endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( configUSE_TIMERS == 1 ) + + void MPU_vTimerSetReloadModeImpl( TimerHandle_t xTimer, + const UBaseType_t uxAutoReload ) PRIVILEGED_FUNCTION; + + void MPU_vTimerSetReloadModeImpl( TimerHandle_t xTimer, + const UBaseType_t uxAutoReload ) /* PRIVILEGED_FUNCTION */ + { + TimerHandle_t xInternalTimerHandle = NULL; + int32_t lIndex; + + lIndex = ( int32_t ) xTimer; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalTimerHandle = MPU_GetTimerHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalTimerHandle != NULL ) + { + vTimerSetReloadMode( xInternalTimerHandle, uxAutoReload ); + } + } + } + + #endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( configUSE_TIMERS == 1 ) + + BaseType_t MPU_xTimerGetReloadModeImpl( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION; + + BaseType_t MPU_xTimerGetReloadModeImpl( TimerHandle_t xTimer ) /* PRIVILEGED_FUNCTION */ + { + BaseType_t xReturn = pdFALSE; + TimerHandle_t xInternalTimerHandle = NULL; + int32_t lIndex; + + lIndex = ( int32_t ) xTimer; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalTimerHandle = MPU_GetTimerHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalTimerHandle != NULL ) + { + xReturn = xTimerGetReloadMode( xInternalTimerHandle ); + } + } + + return xReturn; + } + + #endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( configUSE_TIMERS == 1 ) + + UBaseType_t MPU_uxTimerGetReloadModeImpl( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION; + + UBaseType_t MPU_uxTimerGetReloadModeImpl( TimerHandle_t xTimer ) /* PRIVILEGED_FUNCTION */ + { + UBaseType_t uxReturn = 0; + TimerHandle_t xInternalTimerHandle = NULL; + int32_t lIndex; + + lIndex = ( int32_t ) xTimer; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalTimerHandle = MPU_GetTimerHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalTimerHandle != NULL ) + { + uxReturn = uxTimerGetReloadMode( xInternalTimerHandle ); + } + } + + return uxReturn; + } + + #endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( configUSE_TIMERS == 1 ) + + TickType_t MPU_xTimerGetPeriodImpl( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION; + + TickType_t MPU_xTimerGetPeriodImpl( TimerHandle_t xTimer ) /* PRIVILEGED_FUNCTION */ + { + TickType_t xReturn = 0; + TimerHandle_t xInternalTimerHandle = NULL; + int32_t lIndex; + + lIndex = ( int32_t ) xTimer; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalTimerHandle = MPU_GetTimerHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalTimerHandle != NULL ) + { + xReturn = xTimerGetPeriod( xInternalTimerHandle ); + } + } + + return xReturn; + } + + #endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( configUSE_TIMERS == 1 ) + + TickType_t MPU_xTimerGetExpiryTimeImpl( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION; + + TickType_t MPU_xTimerGetExpiryTimeImpl( TimerHandle_t xTimer ) /* PRIVILEGED_FUNCTION */ + { + TickType_t xReturn = 0; + TimerHandle_t xInternalTimerHandle = NULL; + int32_t lIndex; + + lIndex = ( int32_t ) xTimer; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalTimerHandle = MPU_GetTimerHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalTimerHandle != NULL ) + { + xReturn = xTimerGetExpiryTime( xInternalTimerHandle ); + } + } + + return xReturn; + } + + #endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +/* Privileged only wrappers for Timer APIs. These are needed so that + * the application can use opaque handles maintained in mpu_wrappers.c + * with all the APIs. */ +/*-----------------------------------------------------------*/ + + #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configUSE_TIMERS == 1 ) + + TimerHandle_t MPU_xTimerCreate( const char * const pcTimerName, + const TickType_t xTimerPeriodInTicks, + const UBaseType_t uxAutoReload, + void * const pvTimerID, + TimerCallbackFunction_t pxCallbackFunction ) /* PRIVILEGED_FUNCTION */ + { + TimerHandle_t xInternalTimerHandle = NULL; + TimerHandle_t xExternalTimerHandle = NULL; + int32_t lIndex; + + lIndex = MPU_GetFreeIndexInKernelObjectPool(); + + if( lIndex != -1 ) + { + xInternalTimerHandle = xTimerCreate( pcTimerName, xTimerPeriodInTicks, uxAutoReload, pvTimerID, MPU_TimerCallback ); + + if( xInternalTimerHandle != NULL ) + { + MPU_StoreTimerHandleAtIndex( lIndex, xInternalTimerHandle, pxCallbackFunction ); + xExternalTimerHandle = ( TimerHandle_t ) CONVERT_TO_EXTERNAL_INDEX( lIndex ); + } + else + { + MPU_SetIndexFreeInKernelObjectPool( lIndex ); + } + } + + return xExternalTimerHandle; + } + + #endif /* if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configUSE_TIMERS == 1 ) + + TimerHandle_t MPU_xTimerCreateStatic( const char * const pcTimerName, + const TickType_t xTimerPeriodInTicks, + const UBaseType_t uxAutoReload, + void * const pvTimerID, + TimerCallbackFunction_t pxCallbackFunction, + StaticTimer_t * pxTimerBuffer ) /* PRIVILEGED_FUNCTION */ + { + TimerHandle_t xInternalTimerHandle = NULL; + TimerHandle_t xExternalTimerHandle = NULL; + int32_t lIndex; + + lIndex = MPU_GetFreeIndexInKernelObjectPool(); + + if( lIndex != -1 ) + { + xInternalTimerHandle = xTimerCreateStatic( pcTimerName, xTimerPeriodInTicks, uxAutoReload, pvTimerID, MPU_TimerCallback, pxTimerBuffer ); + + if( xInternalTimerHandle != NULL ) + { + MPU_StoreTimerHandleAtIndex( lIndex, xInternalTimerHandle, pxCallbackFunction ); + xExternalTimerHandle = ( TimerHandle_t ) CONVERT_TO_EXTERNAL_INDEX( lIndex ); + } + else + { + MPU_SetIndexFreeInKernelObjectPool( lIndex ); + } + } + + return xExternalTimerHandle; + } + + #endif /* if ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configUSE_TIMERS == 1 ) + + BaseType_t MPU_xTimerGetStaticBuffer( TimerHandle_t xTimer, + StaticTimer_t ** ppxTimerBuffer ) /* PRIVILEGED_FUNCTION */ + { + TimerHandle_t xInternalTimerHandle = NULL; + int32_t lIndex; + BaseType_t xReturn = pdFALSE; + + lIndex = ( int32_t ) xTimer; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalTimerHandle = MPU_GetTimerHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalTimerHandle != NULL ) + { + xReturn = xTimerGetStaticBuffer( xInternalTimerHandle, ppxTimerBuffer ); + } + } + + return xReturn; + } + + #endif /* if ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +/*-----------------------------------------------------------*/ +/* MPU wrappers for event group APIs. */ +/*-----------------------------------------------------------*/ + + EventBits_t MPU_xEventGroupWaitBitsImpl( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToWaitFor, + const BaseType_t xClearOnExit, + const BaseType_t xWaitForAllBits, + TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; + + EventBits_t MPU_xEventGroupWaitBitsImpl( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToWaitFor, + const BaseType_t xClearOnExit, + const BaseType_t xWaitForAllBits, + TickType_t xTicksToWait ) /* PRIVILEGED_FUNCTION */ + { + EventBits_t xReturn = 0; + EventGroupHandle_t xInternalEventGroupHandle = NULL; + int32_t lIndex; + + lIndex = ( int32_t ) xEventGroup; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalEventGroupHandle = MPU_GetEventGroupHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalEventGroupHandle != NULL ) + { + xReturn = xEventGroupWaitBits( xInternalEventGroupHandle, uxBitsToWaitFor, xClearOnExit, xWaitForAllBits, xTicksToWait ); + } + } + + return xReturn; + } +/*-----------------------------------------------------------*/ + + EventBits_t MPU_xEventGroupClearBitsImpl( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToClear ) PRIVILEGED_FUNCTION; + + EventBits_t MPU_xEventGroupClearBitsImpl( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToClear ) /* PRIVILEGED_FUNCTION */ + { + EventBits_t xReturn = 0; + EventGroupHandle_t xInternalEventGroupHandle = NULL; + int32_t lIndex; + + lIndex = ( int32_t ) xEventGroup; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalEventGroupHandle = MPU_GetEventGroupHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalEventGroupHandle != NULL ) + { + xReturn = xEventGroupClearBits( xInternalEventGroupHandle, uxBitsToClear ); + } + } + + return xReturn; + } +/*-----------------------------------------------------------*/ + + EventBits_t MPU_xEventGroupSetBitsImpl( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet ) PRIVILEGED_FUNCTION; + + EventBits_t MPU_xEventGroupSetBitsImpl( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet ) /* PRIVILEGED_FUNCTION */ + { + EventBits_t xReturn = 0; + EventGroupHandle_t xInternalEventGroupHandle = NULL; + int32_t lIndex; + + lIndex = ( int32_t ) xEventGroup; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalEventGroupHandle = MPU_GetEventGroupHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalEventGroupHandle != NULL ) + { + xReturn = xEventGroupSetBits( xInternalEventGroupHandle, uxBitsToSet ); + } + } + + return xReturn; + } +/*-----------------------------------------------------------*/ + + EventBits_t MPU_xEventGroupSyncImpl( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet, + const EventBits_t uxBitsToWaitFor, + TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; + + EventBits_t MPU_xEventGroupSyncImpl( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet, + const EventBits_t uxBitsToWaitFor, + TickType_t xTicksToWait ) /* PRIVILEGED_FUNCTION */ + { + EventBits_t xReturn; + EventGroupHandle_t xInternalEventGroupHandle = NULL; + int32_t lIndex; + + lIndex = ( int32_t ) xEventGroup; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalEventGroupHandle = MPU_GetEventGroupHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalEventGroupHandle != NULL ) + { + xReturn = xEventGroupSync( xInternalEventGroupHandle, uxBitsToSet, uxBitsToWaitFor, xTicksToWait ); + } + } + + return xReturn; + } +/*-----------------------------------------------------------*/ + + #if ( configUSE_TRACE_FACILITY == 1 ) + + UBaseType_t MPU_uxEventGroupGetNumberImpl( void * xEventGroup ) PRIVILEGED_FUNCTION; + + UBaseType_t MPU_uxEventGroupGetNumberImpl( void * xEventGroup ) /* PRIVILEGED_FUNCTION */ + { + UBaseType_t xReturn = 0; + EventGroupHandle_t xInternalEventGroupHandle = NULL; + int32_t lIndex; + + lIndex = ( int32_t ) xEventGroup; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalEventGroupHandle = MPU_GetEventGroupHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalEventGroupHandle != NULL ) + { + xReturn = uxEventGroupGetNumber( xInternalEventGroupHandle ); + } + } + + return xReturn; + } + + #endif /*( configUSE_TRACE_FACILITY == 1 )*/ +/*-----------------------------------------------------------*/ + + #if ( configUSE_TRACE_FACILITY == 1 ) + + void MPU_vEventGroupSetNumberImpl( void * xEventGroup, + UBaseType_t uxEventGroupNumber ) PRIVILEGED_FUNCTION; + + void MPU_vEventGroupSetNumberImpl( void * xEventGroup, + UBaseType_t uxEventGroupNumber ) /* PRIVILEGED_FUNCTION */ + { + EventGroupHandle_t xInternalEventGroupHandle = NULL; + int32_t lIndex; + + lIndex = ( int32_t ) xEventGroup; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalEventGroupHandle = MPU_GetEventGroupHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalEventGroupHandle != NULL ) + { + vEventGroupSetNumber( xInternalEventGroupHandle, uxEventGroupNumber ); + } + } + } + + #endif /*( configUSE_TRACE_FACILITY == 1 )*/ +/*-----------------------------------------------------------*/ + +/* Privileged only wrappers for Event Group APIs. These are needed so that + * the application can use opaque handles maintained in mpu_wrappers.c + * with all the APIs. */ +/*-----------------------------------------------------------*/ + + #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + + EventGroupHandle_t MPU_xEventGroupCreate( void ) /* PRIVILEGED_FUNCTION */ + { + EventGroupHandle_t xInternalEventGroupHandle = NULL; + EventGroupHandle_t xExternalEventGroupHandle = NULL; + int32_t lIndex; + + lIndex = MPU_GetFreeIndexInKernelObjectPool(); + + if( lIndex != -1 ) + { + xInternalEventGroupHandle = xEventGroupCreate(); + + if( xInternalEventGroupHandle != NULL ) + { + MPU_StoreEventGroupHandleAtIndex( lIndex, xInternalEventGroupHandle ); + xExternalEventGroupHandle = ( EventGroupHandle_t ) CONVERT_TO_EXTERNAL_INDEX( lIndex ); + } + else + { + MPU_SetIndexFreeInKernelObjectPool( lIndex ); + } + } + + return xExternalEventGroupHandle; + } + + #endif /* if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + + EventGroupHandle_t MPU_xEventGroupCreateStatic( StaticEventGroup_t * pxEventGroupBuffer ) /* PRIVILEGED_FUNCTION */ + { + EventGroupHandle_t xInternalEventGroupHandle = NULL; + EventGroupHandle_t xExternalEventGroupHandle = NULL; + int32_t lIndex; + + lIndex = MPU_GetFreeIndexInKernelObjectPool(); + + if( lIndex != -1 ) + { + xInternalEventGroupHandle = xEventGroupCreateStatic( pxEventGroupBuffer ); + + if( xInternalEventGroupHandle != NULL ) + { + MPU_StoreEventGroupHandleAtIndex( lIndex, xInternalEventGroupHandle ); + xExternalEventGroupHandle = ( EventGroupHandle_t ) CONVERT_TO_EXTERNAL_INDEX( lIndex ); + } + else + { + MPU_SetIndexFreeInKernelObjectPool( lIndex ); + } + } + + return xExternalEventGroupHandle; + } + + #endif /* if ( configSUPPORT_STATIC_ALLOCATION == 1 ) */ +/*-----------------------------------------------------------*/ + + void MPU_vEventGroupDelete( EventGroupHandle_t xEventGroup ) /* PRIVILEGED_FUNCTION */ + { + EventGroupHandle_t xInternalEventGroupHandle = NULL; + int32_t lIndex; + + lIndex = ( int32_t ) xEventGroup; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalEventGroupHandle = MPU_GetEventGroupHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalEventGroupHandle != NULL ) + { + vEventGroupDelete( xInternalEventGroupHandle ); + MPU_SetIndexFreeInKernelObjectPool( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + } + } + } +/*-----------------------------------------------------------*/ + + #if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + + BaseType_t MPU_xEventGroupGetStaticBuffer( EventGroupHandle_t xEventGroup, + StaticEventGroup_t ** ppxEventGroupBuffer ) /* PRIVILEGED_FUNCTION */ + { + BaseType_t xReturn = pdFALSE; + EventGroupHandle_t xInternalEventGroupHandle = NULL; + int32_t lIndex; + + lIndex = ( int32_t ) xEventGroup; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalEventGroupHandle = MPU_GetEventGroupHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalEventGroupHandle != NULL ) + { + xReturn = xEventGroupGetStaticBuffer( xInternalEventGroupHandle, ppxEventGroupBuffer ); + } + } + + return xReturn; + } + + #endif /* if ( configSUPPORT_STATIC_ALLOCATION == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( ( configUSE_TRACE_FACILITY == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) ) + + BaseType_t MPU_xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToClear ) /* PRIVILEGED_FUNCTION */ + { + BaseType_t xReturn = pdFALSE; + EventGroupHandle_t xInternalEventGroupHandle = NULL; + int32_t lIndex; + + lIndex = ( int32_t ) xEventGroup; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalEventGroupHandle = MPU_GetEventGroupHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalEventGroupHandle != NULL ) + { + xReturn = xEventGroupClearBitsFromISR( xInternalEventGroupHandle, uxBitsToClear ); + } + } + + return xReturn; + } + + #endif /* #if ( ( configUSE_TRACE_FACILITY == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) ) */ +/*-----------------------------------------------------------*/ + + #if ( ( configUSE_TRACE_FACILITY == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) ) + + BaseType_t MPU_xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet, + BaseType_t * pxHigherPriorityTaskWoken ) /* PRIVILEGED_FUNCTION */ + { + BaseType_t xReturn = pdFALSE; + EventGroupHandle_t xInternalEventGroupHandle = NULL; + int32_t lIndex; + + lIndex = ( int32_t ) xEventGroup; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalEventGroupHandle = MPU_GetEventGroupHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalEventGroupHandle != NULL ) + { + xReturn = xEventGroupSetBitsFromISR( xInternalEventGroupHandle, uxBitsToSet, pxHigherPriorityTaskWoken ); + } + } + + return xReturn; + } + + #endif /* #if ( ( configUSE_TRACE_FACILITY == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) ) */ +/*-----------------------------------------------------------*/ + + EventBits_t MPU_xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup ) /* PRIVILEGED_FUNCTION */ + { + EventBits_t xReturn = 0; + EventGroupHandle_t xInternalEventGroupHandle = NULL; + int32_t lIndex; + + lIndex = ( int32_t ) xEventGroup; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalEventGroupHandle = MPU_GetEventGroupHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalEventGroupHandle != NULL ) + { + xReturn = xEventGroupGetBitsFromISR( xInternalEventGroupHandle ); + } + } + + return xReturn; + } +/*-----------------------------------------------------------*/ + +/*-----------------------------------------------------------*/ +/* MPU wrappers for stream buffer APIs. */ +/*-----------------------------------------------------------*/ + + size_t MPU_xStreamBufferSendImpl( StreamBufferHandle_t xStreamBuffer, + const void * pvTxData, + size_t xDataLengthBytes, + TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; + + size_t MPU_xStreamBufferSendImpl( StreamBufferHandle_t xStreamBuffer, + const void * pvTxData, + size_t xDataLengthBytes, + TickType_t xTicksToWait ) /* PRIVILEGED_FUNCTION */ + { + size_t xReturn = 0; + StreamBufferHandle_t xInternalStreamBufferHandle = NULL; + int32_t lIndex; + BaseType_t xIsTxDataBufferReadable = pdFALSE; + + xIsTxDataBufferReadable = xPortIsAuthorizedToAccessBuffer( pvTxData, + xDataLengthBytes, + tskMPU_READ_PERMISSION ); + + if( xIsTxDataBufferReadable == pdTRUE ) + { + lIndex = ( int32_t ) xStreamBuffer; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalStreamBufferHandle = MPU_GetStreamBufferHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalStreamBufferHandle != NULL ) + { + xReturn = xStreamBufferSend( xInternalStreamBufferHandle, pvTxData, xDataLengthBytes, xTicksToWait ); + } + } + } + + return xReturn; + } +/*-----------------------------------------------------------*/ + + size_t MPU_xStreamBufferReceiveImpl( StreamBufferHandle_t xStreamBuffer, + void * pvRxData, + size_t xBufferLengthBytes, + TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; + + size_t MPU_xStreamBufferReceiveImpl( StreamBufferHandle_t xStreamBuffer, + void * pvRxData, + size_t xBufferLengthBytes, + TickType_t xTicksToWait ) /* PRIVILEGED_FUNCTION */ + { + size_t xReturn = 0; + StreamBufferHandle_t xInternalStreamBufferHandle = NULL; + int32_t lIndex; + BaseType_t xIsRxDataBufferWriteable = pdFALSE; + + xIsRxDataBufferWriteable = xPortIsAuthorizedToAccessBuffer( pvRxData, + xBufferLengthBytes, + tskMPU_WRITE_PERMISSION ); + + if( xIsRxDataBufferWriteable == pdTRUE ) + { + lIndex = ( int32_t ) xStreamBuffer; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalStreamBufferHandle = MPU_GetStreamBufferHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalStreamBufferHandle != NULL ) + { + xReturn = xStreamBufferReceive( xInternalStreamBufferHandle, pvRxData, xBufferLengthBytes, xTicksToWait ); + } + } + } + + return xReturn; + } +/*-----------------------------------------------------------*/ + + BaseType_t MPU_xStreamBufferIsFullImpl( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; + + BaseType_t MPU_xStreamBufferIsFullImpl( StreamBufferHandle_t xStreamBuffer ) /* PRIVILEGED_FUNCTION */ + { + BaseType_t xReturn = pdFALSE; + StreamBufferHandle_t xInternalStreamBufferHandle = NULL; + int32_t lIndex; + + lIndex = ( int32_t ) xStreamBuffer; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalStreamBufferHandle = MPU_GetStreamBufferHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalStreamBufferHandle != NULL ) + { + xReturn = xStreamBufferIsFull( xInternalStreamBufferHandle ); + } + } + + return xReturn; + } +/*-----------------------------------------------------------*/ + + BaseType_t MPU_xStreamBufferIsEmptyImpl( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; + + BaseType_t MPU_xStreamBufferIsEmptyImpl( StreamBufferHandle_t xStreamBuffer ) /* PRIVILEGED_FUNCTION */ + { + BaseType_t xReturn = pdFALSE; + StreamBufferHandle_t xInternalStreamBufferHandle = NULL; + int32_t lIndex; + + lIndex = ( int32_t ) xStreamBuffer; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalStreamBufferHandle = MPU_GetStreamBufferHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalStreamBufferHandle != NULL ) + { + xReturn = xStreamBufferIsEmpty( xInternalStreamBufferHandle ); + } + } + + return xReturn; + } +/*-----------------------------------------------------------*/ + + size_t MPU_xStreamBufferSpacesAvailableImpl( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; + + size_t MPU_xStreamBufferSpacesAvailableImpl( StreamBufferHandle_t xStreamBuffer ) /* PRIVILEGED_FUNCTION */ + { + size_t xReturn = 0; + StreamBufferHandle_t xInternalStreamBufferHandle = NULL; + int32_t lIndex; + + lIndex = ( int32_t ) xStreamBuffer; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalStreamBufferHandle = MPU_GetStreamBufferHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalStreamBufferHandle != NULL ) + { + xReturn = xStreamBufferSpacesAvailable( xInternalStreamBufferHandle ); + } + } + + return xReturn; + } +/*-----------------------------------------------------------*/ + + size_t MPU_xStreamBufferBytesAvailableImpl( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; + + size_t MPU_xStreamBufferBytesAvailableImpl( StreamBufferHandle_t xStreamBuffer ) /* PRIVILEGED_FUNCTION */ + { + size_t xReturn = 0; + StreamBufferHandle_t xInternalStreamBufferHandle = NULL; + int32_t lIndex; + + lIndex = ( int32_t ) xStreamBuffer; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalStreamBufferHandle = MPU_GetStreamBufferHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalStreamBufferHandle != NULL ) + { + xReturn = xStreamBufferBytesAvailable( xInternalStreamBufferHandle ); + } + } + + return xReturn; + } +/*-----------------------------------------------------------*/ + + BaseType_t MPU_xStreamBufferSetTriggerLevelImpl( StreamBufferHandle_t xStreamBuffer, + size_t xTriggerLevel ) PRIVILEGED_FUNCTION; + + BaseType_t MPU_xStreamBufferSetTriggerLevelImpl( StreamBufferHandle_t xStreamBuffer, + size_t xTriggerLevel ) /* PRIVILEGED_FUNCTION */ + { + BaseType_t xReturn = pdFALSE; + StreamBufferHandle_t xInternalStreamBufferHandle = NULL; + int32_t lIndex; + + lIndex = ( int32_t ) xStreamBuffer; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalStreamBufferHandle = MPU_GetStreamBufferHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalStreamBufferHandle != NULL ) + { + xReturn = xStreamBufferSetTriggerLevel( xInternalStreamBufferHandle, xTriggerLevel ); + } + } + + return xReturn; + } +/*-----------------------------------------------------------*/ + + size_t MPU_xStreamBufferNextMessageLengthBytesImpl( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; + + size_t MPU_xStreamBufferNextMessageLengthBytesImpl( StreamBufferHandle_t xStreamBuffer ) /* PRIVILEGED_FUNCTION */ + { + size_t xReturn = 0; + StreamBufferHandle_t xInternalStreamBufferHandle = NULL; + int32_t lIndex; + + lIndex = ( int32_t ) xStreamBuffer; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalStreamBufferHandle = MPU_GetStreamBufferHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalStreamBufferHandle != NULL ) + { + xReturn = xStreamBufferNextMessageLengthBytes( xInternalStreamBufferHandle ); + } + } + + return xReturn; + } +/*-----------------------------------------------------------*/ + +/* Privileged only wrappers for Stream Buffer APIs. These are needed so that + * the application can use opaque handles maintained in mpu_wrappers.c + * with all the APIs. */ +/*-----------------------------------------------------------*/ + + #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + + StreamBufferHandle_t MPU_xStreamBufferGenericCreate( size_t xBufferSizeBytes, + size_t xTriggerLevelBytes, + BaseType_t xIsMessageBuffer, + StreamBufferCallbackFunction_t pxSendCompletedCallback, + StreamBufferCallbackFunction_t pxReceiveCompletedCallback ) /* PRIVILEGED_FUNCTION */ + { + StreamBufferHandle_t xInternalStreamBufferHandle = NULL; + StreamBufferHandle_t xExternalStreamBufferHandle = NULL; + int32_t lIndex; + + /** + * Stream buffer application level callback functionality is disabled for MPU + * enabled ports. + */ + configASSERT( ( pxSendCompletedCallback == NULL ) && + ( pxReceiveCompletedCallback == NULL ) ); + + if( ( pxSendCompletedCallback == NULL ) && + ( pxReceiveCompletedCallback == NULL ) ) + { + lIndex = MPU_GetFreeIndexInKernelObjectPool(); + + if( lIndex != -1 ) + { + xInternalStreamBufferHandle = xStreamBufferGenericCreate( xBufferSizeBytes, + xTriggerLevelBytes, + xIsMessageBuffer, + NULL, + NULL ); + + if( xInternalStreamBufferHandle != NULL ) + { + MPU_StoreStreamBufferHandleAtIndex( lIndex, xInternalStreamBufferHandle ); + xExternalStreamBufferHandle = ( StreamBufferHandle_t ) CONVERT_TO_EXTERNAL_INDEX( lIndex ); + } + else + { + MPU_SetIndexFreeInKernelObjectPool( lIndex ); + } + } + } + else + { + traceSTREAM_BUFFER_CREATE_FAILED( xIsMessageBuffer ); + xExternalStreamBufferHandle = NULL; + } + + return xExternalStreamBufferHandle; + } + + #endif /* configSUPPORT_DYNAMIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + + #if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + + StreamBufferHandle_t MPU_xStreamBufferGenericCreateStatic( size_t xBufferSizeBytes, + size_t xTriggerLevelBytes, + BaseType_t xIsMessageBuffer, + uint8_t * const pucStreamBufferStorageArea, + StaticStreamBuffer_t * const pxStaticStreamBuffer, + StreamBufferCallbackFunction_t pxSendCompletedCallback, + StreamBufferCallbackFunction_t pxReceiveCompletedCallback ) /* PRIVILEGED_FUNCTION */ + { + StreamBufferHandle_t xInternalStreamBufferHandle = NULL; + StreamBufferHandle_t xExternalStreamBufferHandle = NULL; + int32_t lIndex; + + /** + * Stream buffer application level callback functionality is disabled for MPU + * enabled ports. + */ + configASSERT( ( pxSendCompletedCallback == NULL ) && + ( pxReceiveCompletedCallback == NULL ) ); + + if( ( pxSendCompletedCallback == NULL ) && + ( pxReceiveCompletedCallback == NULL ) ) + { + lIndex = MPU_GetFreeIndexInKernelObjectPool(); + + if( lIndex != -1 ) + { + xInternalStreamBufferHandle = xStreamBufferGenericCreateStatic( xBufferSizeBytes, + xTriggerLevelBytes, + xIsMessageBuffer, + pucStreamBufferStorageArea, + pxStaticStreamBuffer, + NULL, + NULL ); + + if( xInternalStreamBufferHandle != NULL ) + { + MPU_StoreStreamBufferHandleAtIndex( lIndex, xInternalStreamBufferHandle ); + xExternalStreamBufferHandle = ( StreamBufferHandle_t ) CONVERT_TO_EXTERNAL_INDEX( lIndex ); + } + else + { + MPU_SetIndexFreeInKernelObjectPool( lIndex ); + } + } + } + else + { + traceSTREAM_BUFFER_CREATE_STATIC_FAILED( xReturn, xIsMessageBuffer ); + xExternalStreamBufferHandle = NULL; + } + + return xExternalStreamBufferHandle; + } + + #endif /* configSUPPORT_STATIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + + void MPU_vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer ) /* PRIVILEGED_FUNCTION */ + { + StreamBufferHandle_t xInternalStreamBufferHandle = NULL; + int32_t lIndex; + + lIndex = ( int32_t ) xStreamBuffer; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalStreamBufferHandle = MPU_GetStreamBufferHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalStreamBufferHandle != NULL ) + { + vStreamBufferDelete( xInternalStreamBufferHandle ); + } + + MPU_SetIndexFreeInKernelObjectPool( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + } + } +/*-----------------------------------------------------------*/ + + BaseType_t MPU_xStreamBufferReset( StreamBufferHandle_t xStreamBuffer ) /* PRIVILEGED_FUNCTION */ + { + BaseType_t xReturn = pdFALSE; + StreamBufferHandle_t xInternalStreamBufferHandle = NULL; + int32_t lIndex; + + lIndex = ( int32_t ) xStreamBuffer; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalStreamBufferHandle = MPU_GetStreamBufferHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalStreamBufferHandle != NULL ) + { + xReturn = xStreamBufferReset( xInternalStreamBufferHandle ); + } + } + + return xReturn; + } +/*-----------------------------------------------------------*/ + + #if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + + BaseType_t MPU_xStreamBufferGetStaticBuffers( StreamBufferHandle_t xStreamBuffers, + uint8_t * ppucStreamBufferStorageArea, + StaticStreamBuffer_t * ppxStaticStreamBuffer ) /* PRIVILEGED_FUNCTION */ + { + BaseType_t xReturn = pdFALSE; + StreamBufferHandle_t xInternalStreamBufferHandle = NULL; + int32_t lIndex; + + lIndex = ( int32_t ) xStreamBuffers; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalStreamBufferHandle = MPU_GetStreamBufferHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalStreamBufferHandle != NULL ) + { + xReturn = MPU_xStreamBufferGetStaticBuffers( xInternalStreamBufferHandle, ppucStreamBufferStorageArea, ppxStaticStreamBuffer ); + } + } + + return xReturn; + } + + #endif /* if ( configSUPPORT_STATIC_ALLOCATION == 1 ) */ +/*-----------------------------------------------------------*/ + + size_t MPU_xStreamBufferSendFromISR( StreamBufferHandle_t xStreamBuffer, + const void * pvTxData, + size_t xDataLengthBytes, + BaseType_t * const pxHigherPriorityTaskWoken ) /* PRIVILEGED_FUNCTION */ + { + size_t xReturn = 0; + StreamBufferHandle_t xInternalStreamBufferHandle = NULL; + int32_t lIndex; + + lIndex = ( int32_t ) xStreamBuffer; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalStreamBufferHandle = MPU_GetStreamBufferHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalStreamBufferHandle != NULL ) + { + xReturn = xStreamBufferSendFromISR( xInternalStreamBufferHandle, pvTxData, xDataLengthBytes, pxHigherPriorityTaskWoken ); + } + } + + return xReturn; + } +/*-----------------------------------------------------------*/ + + size_t MPU_xStreamBufferReceiveFromISR( StreamBufferHandle_t xStreamBuffer, + void * pvRxData, + size_t xBufferLengthBytes, + BaseType_t * const pxHigherPriorityTaskWoken ) /* PRIVILEGED_FUNCTION */ + { + size_t xReturn = 0; + StreamBufferHandle_t xInternalStreamBufferHandle = NULL; + int32_t lIndex; + + lIndex = ( int32_t ) xStreamBuffer; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalStreamBufferHandle = MPU_GetStreamBufferHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalStreamBufferHandle != NULL ) + { + xReturn = xStreamBufferReceiveFromISR( xInternalStreamBufferHandle, pvRxData, xBufferLengthBytes, pxHigherPriorityTaskWoken ); + } + } + + return xReturn; + } +/*-----------------------------------------------------------*/ + + BaseType_t MPU_xStreamBufferSendCompletedFromISR( StreamBufferHandle_t xStreamBuffer, + BaseType_t * pxHigherPriorityTaskWoken ) /* PRIVILEGED_FUNCTION */ + { + BaseType_t xReturn = pdFALSE; + StreamBufferHandle_t xInternalStreamBufferHandle = NULL; + int32_t lIndex; + + lIndex = ( int32_t ) xStreamBuffer; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalStreamBufferHandle = MPU_GetStreamBufferHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalStreamBufferHandle != NULL ) + { + xReturn = xStreamBufferSendCompletedFromISR( xInternalStreamBufferHandle, pxHigherPriorityTaskWoken ); + } + } + + return xReturn; + } +/*-----------------------------------------------------------*/ + + BaseType_t MPU_xStreamBufferReceiveCompletedFromISR( StreamBufferHandle_t xStreamBuffer, + BaseType_t * pxHigherPriorityTaskWoken ) /*PRIVILEGED_FUNCTION */ + { + BaseType_t xReturn = pdFALSE; + StreamBufferHandle_t xInternalStreamBufferHandle = NULL; + int32_t lIndex; + + lIndex = ( int32_t ) xStreamBuffer; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalStreamBufferHandle = MPU_GetStreamBufferHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalStreamBufferHandle != NULL ) + { + xReturn = xStreamBufferReceiveCompletedFromISR( xInternalStreamBufferHandle, pxHigherPriorityTaskWoken ); + } + } + + return xReturn; + } + +/*-----------------------------------------------------------*/ + +/* Functions that the application writer wants to execute in privileged mode + * can be defined in application_defined_privileged_functions.h. */ + + #if configINCLUDE_APPLICATION_DEFINED_PRIVILEGED_FUNCTIONS == 1 + #include "application_defined_privileged_functions.h" + #endif +/*-----------------------------------------------------------*/ + +#endif /* #if ( ( portUSING_MPU_WRAPPERS == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ +/*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM7_AT91SAM7S/port.c b/portable/GCC/ARM7_AT91SAM7S/port.c index 335f9852626..a9d78bb138b 100644 --- a/portable/GCC/ARM7_AT91SAM7S/port.c +++ b/portable/GCC/ARM7_AT91SAM7S/port.c @@ -204,7 +204,7 @@ AT91PS_PITC pxPIT = AT91C_BASE_PITC; /* Configure the PIT period. */ pxPIT->PITC_PIMR = portPIT_ENABLE | portPIT_INT_ENABLE | portPIT_COUNTER_VALUE; - /* Enable the interrupt. Global interrupts are disables at this point so + /* Enable the interrupt. Global interrupts are disabled at this point so this is safe. */ AT91C_BASE_AIC->AIC_IECR = 0x1 << AT91C_ID_SYS; } diff --git a/portable/GCC/ARM_CM0/portmacro.h b/portable/GCC/ARM_CM0/portmacro.h index dc7f54578e2..14375bf9581 100644 --- a/portable/GCC/ARM_CM0/portmacro.h +++ b/portable/GCC/ARM_CM0/portmacro.h @@ -79,7 +79,6 @@ typedef unsigned long UBaseType_t; #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) #define portBYTE_ALIGNMENT 8 #define portDONT_DISCARD __attribute__( ( used ) ) -#define portNORETURN __attribute__( ( noreturn ) ) /*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM23/non_secure/mpu_wrappers_v2_asm.c b/portable/GCC/ARM_CM23/non_secure/mpu_wrappers_v2_asm.c new file mode 100644 index 00000000000..a1e5ce0828f --- /dev/null +++ b/portable/GCC/ARM_CM23/non_secure/mpu_wrappers_v2_asm.c @@ -0,0 +1,2419 @@ +/* + * FreeRTOS Kernel + * Copyright (C) 2021 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 + * + */ + +/* 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. */ +#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +/* Scheduler includes. */ +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" +#include "timers.h" +#include "event_groups.h" +#include "stream_buffer.h" + +#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + +#if ( INCLUDE_xTaskDelayUntil == 1 ) + +BaseType_t MPU_xTaskDelayUntil( TickType_t * const pxPreviousWakeTime, + const TickType_t xTimeIncrement ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskDelayUntil( TickType_t * const pxPreviousWakeTime, + const TickType_t xTimeIncrement ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskDelayUntilImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xTaskDelayUntil_Unpriv \n" + " MPU_xTaskDelayUntil_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xTaskDelayUntilImpl \n" + " MPU_xTaskDelayUntil_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xTaskDelayUntilImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_xTaskDelayUntil == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_xTaskAbortDelay == 1 ) + +BaseType_t MPU_xTaskAbortDelay( TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskAbortDelay( TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskAbortDelayImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xTaskAbortDelay_Unpriv \n" + " MPU_xTaskAbortDelay_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xTaskAbortDelayImpl \n" + " MPU_xTaskAbortDelay_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xTaskAbortDelayImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_xTaskAbortDelay == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskDelay == 1 ) + +void MPU_vTaskDelay( const TickType_t xTicksToDelay ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskDelay( const TickType_t xTicksToDelay ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskDelayImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_vTaskDelay_Unpriv \n" + " MPU_vTaskDelay_Priv: \n" + " pop {r0, r1} \n" + " b MPU_vTaskDelayImpl \n" + " MPU_vTaskDelay_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_vTaskDelayImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_vTaskDelay == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_uxTaskPriorityGet == 1 ) + +UBaseType_t MPU_uxTaskPriorityGet( const TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxTaskPriorityGet( const TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxTaskPriorityGetImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_uxTaskPriorityGet_Unpriv \n" + " MPU_uxTaskPriorityGet_Priv: \n" + " pop {r0, r1} \n" + " b MPU_uxTaskPriorityGetImpl \n" + " MPU_uxTaskPriorityGet_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_uxTaskPriorityGetImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_uxTaskPriorityGet == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_eTaskGetState == 1 ) + +eTaskState MPU_eTaskGetState( TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +eTaskState MPU_eTaskGetState( TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_eTaskGetStateImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_eTaskGetState_Unpriv \n" + " MPU_eTaskGetState_Priv: \n" + " pop {r0, r1} \n" + " b MPU_eTaskGetStateImpl \n" + " MPU_eTaskGetState_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_eTaskGetStateImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_eTaskGetState == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + +void MPU_vTaskGetInfo( TaskHandle_t xTask, + TaskStatus_t * pxTaskStatus, + BaseType_t xGetFreeStackSpace, + eTaskState eState ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskGetInfo( TaskHandle_t xTask, + TaskStatus_t * pxTaskStatus, + BaseType_t xGetFreeStackSpace, + eTaskState eState ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskGetInfoImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_vTaskGetInfo_Unpriv \n" + " MPU_vTaskGetInfo_Priv: \n" + " pop {r0, r1} \n" + " b MPU_vTaskGetInfoImpl \n" + " MPU_vTaskGetInfo_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_vTaskGetInfoImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TRACE_FACILITY == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) + +TaskHandle_t MPU_xTaskGetIdleTaskHandle( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TaskHandle_t MPU_xTaskGetIdleTaskHandle( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGetIdleTaskHandleImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xTaskGetIdleTaskHandle_Unpriv \n" + " MPU_xTaskGetIdleTaskHandle_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xTaskGetIdleTaskHandleImpl \n" + " MPU_xTaskGetIdleTaskHandle_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xTaskGetIdleTaskHandleImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskSuspend == 1 ) + +void MPU_vTaskSuspend( TaskHandle_t xTaskToSuspend ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskSuspend( TaskHandle_t xTaskToSuspend ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskSuspendImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_vTaskSuspend_Unpriv \n" + " MPU_vTaskSuspend_Priv: \n" + " pop {r0, r1} \n" + " b MPU_vTaskSuspendImpl \n" + " MPU_vTaskSuspend_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_vTaskSuspendImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_vTaskSuspend == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskSuspend == 1 ) + +void MPU_vTaskResume( TaskHandle_t xTaskToResume ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskResume( TaskHandle_t xTaskToResume ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskResumeImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_vTaskResume_Unpriv \n" + " MPU_vTaskResume_Priv: \n" + " pop {r0, r1} \n" + " b MPU_vTaskResumeImpl \n" + " MPU_vTaskResume_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_vTaskResumeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_vTaskSuspend == 1 ) */ +/*-----------------------------------------------------------*/ + +TickType_t MPU_xTaskGetTickCount( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TickType_t MPU_xTaskGetTickCount( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGetTickCountImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xTaskGetTickCount_Unpriv \n" + " MPU_xTaskGetTickCount_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xTaskGetTickCountImpl \n" + " MPU_xTaskGetTickCount_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xTaskGetTickCountImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +UBaseType_t MPU_uxTaskGetNumberOfTasks( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxTaskGetNumberOfTasks( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxTaskGetNumberOfTasksImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_uxTaskGetNumberOfTasks_Unpriv \n" + " MPU_uxTaskGetNumberOfTasks_Priv: \n" + " pop {r0, r1} \n" + " b MPU_uxTaskGetNumberOfTasksImpl \n" + " MPU_uxTaskGetNumberOfTasks_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_uxTaskGetNumberOfTasksImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +char * MPU_pcTaskGetName( TaskHandle_t xTaskToQuery ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +char * MPU_pcTaskGetName( TaskHandle_t xTaskToQuery ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_pcTaskGetNameImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_pcTaskGetName_Unpriv \n" + " MPU_pcTaskGetName_Priv: \n" + " pop {r0, r1} \n" + " b MPU_pcTaskGetNameImpl \n" + " MPU_pcTaskGetName_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_pcTaskGetNameImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +#if ( configGENERATE_RUN_TIME_STATS == 1 ) + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetRunTimeCounter( const TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetRunTimeCounter( const TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_ulTaskGetRunTimeCounterImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_ulTaskGetRunTimeCounter_Unpriv \n" + " MPU_ulTaskGetRunTimeCounter_Priv: \n" + " pop {r0, r1} \n" + " b MPU_ulTaskGetRunTimeCounterImpl \n" + " MPU_ulTaskGetRunTimeCounter_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_ulTaskGetRunTimeCounterImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( ( configGENERATE_RUN_TIME_STATS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configGENERATE_RUN_TIME_STATS == 1 ) + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetRunTimePercent( const TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetRunTimePercent( const TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_ulTaskGetRunTimePercentImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_ulTaskGetRunTimePercent_Unpriv \n" + " MPU_ulTaskGetRunTimePercent_Priv: \n" + " pop {r0, r1} \n" + " b MPU_ulTaskGetRunTimePercentImpl \n" + " MPU_ulTaskGetRunTimePercent_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_ulTaskGetRunTimePercentImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( ( configGENERATE_RUN_TIME_STATS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimePercent( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimePercent( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_ulTaskGetIdleRunTimePercentImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_ulTaskGetIdleRunTimePercent_Unpriv \n" + " MPU_ulTaskGetIdleRunTimePercent_Priv: \n" + " pop {r0, r1} \n" + " b MPU_ulTaskGetIdleRunTimePercentImpl \n" + " MPU_ulTaskGetIdleRunTimePercent_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_ulTaskGetIdleRunTimePercentImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimeCounter( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimeCounter( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_ulTaskGetIdleRunTimeCounterImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_ulTaskGetIdleRunTimeCounter_Unpriv \n" + " MPU_ulTaskGetIdleRunTimeCounter_Priv: \n" + " pop {r0, r1} \n" + " b MPU_ulTaskGetIdleRunTimeCounterImpl \n" + " MPU_ulTaskGetIdleRunTimeCounter_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_ulTaskGetIdleRunTimeCounterImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_APPLICATION_TASK_TAG == 1 ) + +void MPU_vTaskSetApplicationTaskTag( TaskHandle_t xTask, + TaskHookFunction_t pxHookFunction ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskSetApplicationTaskTag( TaskHandle_t xTask, + TaskHookFunction_t pxHookFunction ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskSetApplicationTaskTagImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_vTaskSetApplicationTaskTag_Unpriv \n" + " MPU_vTaskSetApplicationTaskTag_Priv: \n" + " pop {r0, r1} \n" + " b MPU_vTaskSetApplicationTaskTagImpl \n" + " MPU_vTaskSetApplicationTaskTag_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_vTaskSetApplicationTaskTagImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_APPLICATION_TASK_TAG == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_APPLICATION_TASK_TAG == 1 ) + +TaskHookFunction_t MPU_xTaskGetApplicationTaskTag( TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TaskHookFunction_t MPU_xTaskGetApplicationTaskTag( TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGetApplicationTaskTagImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xTaskGetApplicationTaskTag_Unpriv \n" + " MPU_xTaskGetApplicationTaskTag_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xTaskGetApplicationTaskTagImpl \n" + " MPU_xTaskGetApplicationTaskTag_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xTaskGetApplicationTaskTagImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_APPLICATION_TASK_TAG == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) + +void MPU_vTaskSetThreadLocalStoragePointer( TaskHandle_t xTaskToSet, + BaseType_t xIndex, + void * pvValue ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskSetThreadLocalStoragePointer( TaskHandle_t xTaskToSet, + BaseType_t xIndex, + void * pvValue ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskSetThreadLocalStoragePointerImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_vTaskSetThreadLocalStoragePointer_Unpriv \n" + " MPU_vTaskSetThreadLocalStoragePointer_Priv: \n" + " pop {r0, r1} \n" + " b MPU_vTaskSetThreadLocalStoragePointerImpl \n" + " MPU_vTaskSetThreadLocalStoragePointer_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_vTaskSetThreadLocalStoragePointerImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) + +void * MPU_pvTaskGetThreadLocalStoragePointer( TaskHandle_t xTaskToQuery, + BaseType_t xIndex ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void * MPU_pvTaskGetThreadLocalStoragePointer( TaskHandle_t xTaskToQuery, + BaseType_t xIndex ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_pvTaskGetThreadLocalStoragePointerImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_pvTaskGetThreadLocalStoragePointer_Unpriv \n" + " MPU_pvTaskGetThreadLocalStoragePointer_Priv: \n" + " pop {r0, r1} \n" + " b MPU_pvTaskGetThreadLocalStoragePointerImpl \n" + " MPU_pvTaskGetThreadLocalStoragePointer_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_pvTaskGetThreadLocalStoragePointerImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + +UBaseType_t MPU_uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray, + const UBaseType_t uxArraySize, + configRUN_TIME_COUNTER_TYPE * const pulTotalRunTime ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray, + const UBaseType_t uxArraySize, + configRUN_TIME_COUNTER_TYPE * const pulTotalRunTime ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxTaskGetSystemStateImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_uxTaskGetSystemState_Unpriv \n" + " MPU_uxTaskGetSystemState_Priv: \n" + " pop {r0, r1} \n" + " b MPU_uxTaskGetSystemStateImpl \n" + " MPU_uxTaskGetSystemState_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_uxTaskGetSystemStateImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TRACE_FACILITY == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) + +UBaseType_t MPU_uxTaskGetStackHighWaterMark( TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxTaskGetStackHighWaterMark( TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxTaskGetStackHighWaterMarkImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_uxTaskGetStackHighWaterMark_Unpriv \n" + " MPU_uxTaskGetStackHighWaterMark_Priv: \n" + " pop {r0, r1} \n" + " b MPU_uxTaskGetStackHighWaterMarkImpl \n" + " MPU_uxTaskGetStackHighWaterMark_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_uxTaskGetStackHighWaterMarkImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) + +configSTACK_DEPTH_TYPE MPU_uxTaskGetStackHighWaterMark2( TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +configSTACK_DEPTH_TYPE MPU_uxTaskGetStackHighWaterMark2( TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxTaskGetStackHighWaterMark2Impl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_uxTaskGetStackHighWaterMark2_Unpriv \n" + " MPU_uxTaskGetStackHighWaterMark2_Priv: \n" + " pop {r0, r1} \n" + " b MPU_uxTaskGetStackHighWaterMark2Impl \n" + " MPU_uxTaskGetStackHighWaterMark2_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_uxTaskGetStackHighWaterMark2Impl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) ) + +TaskHandle_t MPU_xTaskGetCurrentTaskHandle( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TaskHandle_t MPU_xTaskGetCurrentTaskHandle( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGetCurrentTaskHandleImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xTaskGetCurrentTaskHandle_Unpriv \n" + " MPU_xTaskGetCurrentTaskHandle_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xTaskGetCurrentTaskHandleImpl \n" + " MPU_xTaskGetCurrentTaskHandle_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xTaskGetCurrentTaskHandleImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_xTaskGetSchedulerState == 1 ) + +BaseType_t MPU_xTaskGetSchedulerState( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskGetSchedulerState( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGetSchedulerStateImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xTaskGetSchedulerState_Unpriv \n" + " MPU_xTaskGetSchedulerState_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xTaskGetSchedulerStateImpl \n" + " MPU_xTaskGetSchedulerState_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xTaskGetSchedulerStateImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_xTaskGetSchedulerState == 1 ) */ +/*-----------------------------------------------------------*/ + +void MPU_vTaskSetTimeOutState( TimeOut_t * const pxTimeOut ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskSetTimeOutState( TimeOut_t * const pxTimeOut ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskSetTimeOutStateImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_vTaskSetTimeOutState_Unpriv \n" + " MPU_vTaskSetTimeOutState_Priv: \n" + " pop {r0, r1} \n" + " b MPU_vTaskSetTimeOutStateImpl \n" + " MPU_vTaskSetTimeOutState_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_vTaskSetTimeOutStateImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut, + TickType_t * const pxTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut, + TickType_t * const pxTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskCheckForTimeOutImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xTaskCheckForTimeOut_Unpriv \n" + " MPU_xTaskCheckForTimeOut_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xTaskCheckForTimeOutImpl \n" + " MPU_xTaskCheckForTimeOut_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xTaskCheckForTimeOutImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +#if ( configUSE_TASK_NOTIFICATIONS == 1 ) + +BaseType_t MPU_xTaskGenericNotify( TaskHandle_t xTaskToNotify, + UBaseType_t uxIndexToNotify, + uint32_t ulValue, + eNotifyAction eAction, + uint32_t * pulPreviousNotificationValue ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskGenericNotify( TaskHandle_t xTaskToNotify, + UBaseType_t uxIndexToNotify, + uint32_t ulValue, + eNotifyAction eAction, + uint32_t * pulPreviousNotificationValue ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGenericNotifyImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xTaskGenericNotify_Unpriv \n" + " MPU_xTaskGenericNotify_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xTaskGenericNotifyImpl \n" + " MPU_xTaskGenericNotify_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xTaskGenericNotifyImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER_1 ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TASK_NOTIFICATIONS == 1 ) + +BaseType_t MPU_xTaskGenericNotifyWait( UBaseType_t uxIndexToWaitOn, + uint32_t ulBitsToClearOnEntry, + uint32_t ulBitsToClearOnExit, + uint32_t * pulNotificationValue, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskGenericNotifyWait( UBaseType_t uxIndexToWaitOn, + uint32_t ulBitsToClearOnEntry, + uint32_t ulBitsToClearOnExit, + uint32_t * pulNotificationValue, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGenericNotifyWaitImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xTaskGenericNotifyWait_Unpriv \n" + " MPU_xTaskGenericNotifyWait_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xTaskGenericNotifyWaitImpl \n" + " MPU_xTaskGenericNotifyWait_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xTaskGenericNotifyWaitImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER_1 ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TASK_NOTIFICATIONS == 1 ) + +uint32_t MPU_ulTaskGenericNotifyTake( UBaseType_t uxIndexToWaitOn, + BaseType_t xClearCountOnExit, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +uint32_t MPU_ulTaskGenericNotifyTake( UBaseType_t uxIndexToWaitOn, + BaseType_t xClearCountOnExit, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_ulTaskGenericNotifyTakeImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_ulTaskGenericNotifyTake_Unpriv \n" + " MPU_ulTaskGenericNotifyTake_Priv: \n" + " pop {r0, r1} \n" + " b MPU_ulTaskGenericNotifyTakeImpl \n" + " MPU_ulTaskGenericNotifyTake_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_ulTaskGenericNotifyTakeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TASK_NOTIFICATIONS == 1 ) + +BaseType_t MPU_xTaskGenericNotifyStateClear( TaskHandle_t xTask, + UBaseType_t uxIndexToClear ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskGenericNotifyStateClear( TaskHandle_t xTask, + UBaseType_t uxIndexToClear ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGenericNotifyStateClearImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xTaskGenericNotifyStateClear_Unpriv \n" + " MPU_xTaskGenericNotifyStateClear_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xTaskGenericNotifyStateClearImpl \n" + " MPU_xTaskGenericNotifyStateClear_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xTaskGenericNotifyStateClearImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TASK_NOTIFICATIONS == 1 ) + +uint32_t MPU_ulTaskGenericNotifyValueClear( TaskHandle_t xTask, + UBaseType_t uxIndexToClear, + uint32_t ulBitsToClear ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +uint32_t MPU_ulTaskGenericNotifyValueClear( TaskHandle_t xTask, + UBaseType_t uxIndexToClear, + uint32_t ulBitsToClear ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_ulTaskGenericNotifyValueClearImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_ulTaskGenericNotifyValueClear_Unpriv \n" + " MPU_ulTaskGenericNotifyValueClear_Priv: \n" + " pop {r0, r1} \n" + " b MPU_ulTaskGenericNotifyValueClearImpl \n" + " MPU_ulTaskGenericNotifyValueClear_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_ulTaskGenericNotifyValueClearImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xQueueGenericSend( QueueHandle_t xQueue, + const void * const pvItemToQueue, + TickType_t xTicksToWait, + const BaseType_t xCopyPosition ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueueGenericSend( QueueHandle_t xQueue, + const void * const pvItemToQueue, + TickType_t xTicksToWait, + const BaseType_t xCopyPosition ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueGenericSendImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xQueueGenericSend_Unpriv \n" + " MPU_xQueueGenericSend_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xQueueGenericSendImpl \n" + " MPU_xQueueGenericSend_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xQueueGenericSendImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +UBaseType_t MPU_uxQueueMessagesWaiting( const QueueHandle_t xQueue ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxQueueMessagesWaiting( const QueueHandle_t xQueue ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxQueueMessagesWaitingImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_uxQueueMessagesWaiting_Unpriv \n" + " MPU_uxQueueMessagesWaiting_Priv: \n" + " pop {r0, r1} \n" + " b MPU_uxQueueMessagesWaitingImpl \n" + " MPU_uxQueueMessagesWaiting_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_uxQueueMessagesWaitingImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +UBaseType_t MPU_uxQueueSpacesAvailable( const QueueHandle_t xQueue ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxQueueSpacesAvailable( const QueueHandle_t xQueue ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxQueueSpacesAvailableImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_uxQueueSpacesAvailable_Unpriv \n" + " MPU_uxQueueSpacesAvailable_Priv: \n" + " pop {r0, r1} \n" + " b MPU_uxQueueSpacesAvailableImpl \n" + " MPU_uxQueueSpacesAvailable_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_uxQueueSpacesAvailableImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xQueueReceive( QueueHandle_t xQueue, + void * const pvBuffer, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueueReceive( QueueHandle_t xQueue, + void * const pvBuffer, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueReceiveImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xQueueReceive_Unpriv \n" + " MPU_xQueueReceive_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xQueueReceiveImpl \n" + " MPU_xQueueReceive_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xQueueReceiveImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xQueuePeek( QueueHandle_t xQueue, + void * const pvBuffer, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueuePeek( QueueHandle_t xQueue, + void * const pvBuffer, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueuePeekImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xQueuePeek_Unpriv \n" + " MPU_xQueuePeek_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xQueuePeekImpl \n" + " MPU_xQueuePeek_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xQueuePeekImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xQueueSemaphoreTake( QueueHandle_t xQueue, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueueSemaphoreTake( QueueHandle_t xQueue, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueSemaphoreTakeImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xQueueSemaphoreTake_Unpriv \n" + " MPU_xQueueSemaphoreTake_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xQueueSemaphoreTakeImpl \n" + " MPU_xQueueSemaphoreTake_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xQueueSemaphoreTakeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +#if ( ( configUSE_MUTEXES == 1 ) && ( INCLUDE_xSemaphoreGetMutexHolder == 1 ) ) + +TaskHandle_t MPU_xQueueGetMutexHolder( QueueHandle_t xSemaphore ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TaskHandle_t MPU_xQueueGetMutexHolder( QueueHandle_t xSemaphore ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueGetMutexHolderImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xQueueGetMutexHolder_Unpriv \n" + " MPU_xQueueGetMutexHolder_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xQueueGetMutexHolderImpl \n" + " MPU_xQueueGetMutexHolder_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xQueueGetMutexHolderImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( ( configUSE_MUTEXES == 1 ) && ( INCLUDE_xSemaphoreGetMutexHolder == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_RECURSIVE_MUTEXES == 1 ) + +BaseType_t MPU_xQueueTakeMutexRecursive( QueueHandle_t xMutex, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueueTakeMutexRecursive( QueueHandle_t xMutex, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueTakeMutexRecursiveImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xQueueTakeMutexRecursive_Unpriv \n" + " MPU_xQueueTakeMutexRecursive_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xQueueTakeMutexRecursiveImpl \n" + " MPU_xQueueTakeMutexRecursive_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xQueueTakeMutexRecursiveImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_RECURSIVE_MUTEXES == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_RECURSIVE_MUTEXES == 1 ) + +BaseType_t MPU_xQueueGiveMutexRecursive( QueueHandle_t pxMutex ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueueGiveMutexRecursive( QueueHandle_t pxMutex ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueGiveMutexRecursiveImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xQueueGiveMutexRecursive_Unpriv \n" + " MPU_xQueueGiveMutexRecursive_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xQueueGiveMutexRecursiveImpl \n" + " MPU_xQueueGiveMutexRecursive_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xQueueGiveMutexRecursiveImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_RECURSIVE_MUTEXES == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_QUEUE_SETS == 1 ) + +QueueSetMemberHandle_t MPU_xQueueSelectFromSet( QueueSetHandle_t xQueueSet, + const TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +QueueSetMemberHandle_t MPU_xQueueSelectFromSet( QueueSetHandle_t xQueueSet, + const TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueSelectFromSetImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xQueueSelectFromSet_Unpriv \n" + " MPU_xQueueSelectFromSet_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xQueueSelectFromSetImpl \n" + " MPU_xQueueSelectFromSet_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xQueueSelectFromSetImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_QUEUE_SETS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_QUEUE_SETS == 1 ) + +BaseType_t MPU_xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore, + QueueSetHandle_t xQueueSet ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore, + QueueSetHandle_t xQueueSet ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueAddToSetImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xQueueAddToSet_Unpriv \n" + " MPU_xQueueAddToSet_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xQueueAddToSetImpl \n" + " MPU_xQueueAddToSet_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xQueueAddToSetImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_QUEUE_SETS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configQUEUE_REGISTRY_SIZE > 0 ) + +void MPU_vQueueAddToRegistry( QueueHandle_t xQueue, + const char * pcName ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vQueueAddToRegistry( QueueHandle_t xQueue, + const char * pcName ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vQueueAddToRegistryImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_vQueueAddToRegistry_Unpriv \n" + " MPU_vQueueAddToRegistry_Priv: \n" + " pop {r0, r1} \n" + " b MPU_vQueueAddToRegistryImpl \n" + " MPU_vQueueAddToRegistry_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_vQueueAddToRegistryImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configQUEUE_REGISTRY_SIZE > 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configQUEUE_REGISTRY_SIZE > 0 ) + +void MPU_vQueueUnregisterQueue( QueueHandle_t xQueue ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vQueueUnregisterQueue( QueueHandle_t xQueue ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vQueueUnregisterQueueImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_vQueueUnregisterQueue_Unpriv \n" + " MPU_vQueueUnregisterQueue_Priv: \n" + " pop {r0, r1} \n" + " b MPU_vQueueUnregisterQueueImpl \n" + " MPU_vQueueUnregisterQueue_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_vQueueUnregisterQueueImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configQUEUE_REGISTRY_SIZE > 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configQUEUE_REGISTRY_SIZE > 0 ) + +const char * MPU_pcQueueGetName( QueueHandle_t xQueue ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +const char * MPU_pcQueueGetName( QueueHandle_t xQueue ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_pcQueueGetNameImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_pcQueueGetName_Unpriv \n" + " MPU_pcQueueGetName_Priv: \n" + " pop {r0, r1} \n" + " b MPU_pcQueueGetNameImpl \n" + " MPU_pcQueueGetName_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_pcQueueGetNameImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configQUEUE_REGISTRY_SIZE > 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +void * MPU_pvTimerGetTimerID( const TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void * MPU_pvTimerGetTimerID( const TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_pvTimerGetTimerIDImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_pvTimerGetTimerID_Unpriv \n" + " MPU_pvTimerGetTimerID_Priv: \n" + " pop {r0, r1} \n" + " b MPU_pvTimerGetTimerIDImpl \n" + " MPU_pvTimerGetTimerID_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_pvTimerGetTimerIDImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +void MPU_vTimerSetTimerID( TimerHandle_t xTimer, + void * pvNewID ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTimerSetTimerID( TimerHandle_t xTimer, + void * pvNewID ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTimerSetTimerIDImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_vTimerSetTimerID_Unpriv \n" + " MPU_vTimerSetTimerID_Priv: \n" + " pop {r0, r1} \n" + " b MPU_vTimerSetTimerIDImpl \n" + " MPU_vTimerSetTimerID_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_vTimerSetTimerIDImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +BaseType_t MPU_xTimerIsTimerActive( TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTimerIsTimerActive( TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTimerIsTimerActiveImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xTimerIsTimerActive_Unpriv \n" + " MPU_xTimerIsTimerActive_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xTimerIsTimerActiveImpl \n" + " MPU_xTimerIsTimerActive_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xTimerIsTimerActiveImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +TaskHandle_t MPU_xTimerGetTimerDaemonTaskHandle( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TaskHandle_t MPU_xTimerGetTimerDaemonTaskHandle( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTimerGetTimerDaemonTaskHandleImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xTimerGetTimerDaemonTaskHandle_Unpriv \n" + " MPU_xTimerGetTimerDaemonTaskHandle_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xTimerGetTimerDaemonTaskHandleImpl \n" + " MPU_xTimerGetTimerDaemonTaskHandle_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xTimerGetTimerDaemonTaskHandleImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +BaseType_t MPU_xTimerGenericCommand( TimerHandle_t xTimer, + const BaseType_t xCommandID, + const TickType_t xOptionalValue, + BaseType_t * const pxHigherPriorityTaskWoken, + const TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTimerGenericCommand( TimerHandle_t xTimer, + const BaseType_t xCommandID, + const TickType_t xOptionalValue, + BaseType_t * const pxHigherPriorityTaskWoken, + const TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTimerGenericCommandImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, ipsr \n" + " cmp r0, #0 \n" + " bne MPU_xTimerGenericCommand_Priv \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " beq MPU_xTimerGenericCommand_Priv \n" + " MPU_xTimerGenericCommand_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xTimerGenericCommandImpl \n" + " svc %1 \n" + " bx lr \n" + " MPU_xTimerGenericCommand_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xTimerGenericCommandImpl \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER_1 ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +const char * MPU_pcTimerGetName( TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +const char * MPU_pcTimerGetName( TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_pcTimerGetNameImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_pcTimerGetName_Unpriv \n" + " MPU_pcTimerGetName_Priv: \n" + " pop {r0, r1} \n" + " b MPU_pcTimerGetNameImpl \n" + " MPU_pcTimerGetName_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_pcTimerGetNameImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, + const BaseType_t uxAutoReload ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, + const BaseType_t uxAutoReload ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTimerSetReloadModeImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_vTimerSetReloadMode_Unpriv \n" + " MPU_vTimerSetReloadMode_Priv: \n" + " pop {r0, r1} \n" + " b MPU_vTimerSetReloadModeImpl \n" + " MPU_vTimerSetReloadMode_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_vTimerSetReloadModeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +BaseType_t MPU_xTimerGetReloadMode( TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTimerGetReloadMode( TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTimerGetReloadModeImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xTimerGetReloadMode_Unpriv \n" + " MPU_xTimerGetReloadMode_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xTimerGetReloadModeImpl \n" + " MPU_xTimerGetReloadMode_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xTimerGetReloadModeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +UBaseType_t MPU_uxTimerGetReloadMode( TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxTimerGetReloadMode( TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxTimerGetReloadModeImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_uxTimerGetReloadMode_Unpriv \n" + " MPU_uxTimerGetReloadMode_Priv: \n" + " pop {r0, r1} \n" + " b MPU_uxTimerGetReloadModeImpl \n" + " MPU_uxTimerGetReloadMode_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_uxTimerGetReloadModeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +TickType_t MPU_xTimerGetPeriod( TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TickType_t MPU_xTimerGetPeriod( TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTimerGetPeriodImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xTimerGetPeriod_Unpriv \n" + " MPU_xTimerGetPeriod_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xTimerGetPeriodImpl \n" + " MPU_xTimerGetPeriod_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xTimerGetPeriodImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +TickType_t MPU_xTimerGetExpiryTime( TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TickType_t MPU_xTimerGetExpiryTime( TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTimerGetExpiryTimeImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xTimerGetExpiryTime_Unpriv \n" + " MPU_xTimerGetExpiryTime_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xTimerGetExpiryTimeImpl \n" + " MPU_xTimerGetExpiryTime_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xTimerGetExpiryTimeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +EventBits_t MPU_xEventGroupWaitBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToWaitFor, + const BaseType_t xClearOnExit, + const BaseType_t xWaitForAllBits, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +EventBits_t MPU_xEventGroupWaitBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToWaitFor, + const BaseType_t xClearOnExit, + const BaseType_t xWaitForAllBits, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupWaitBitsImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xEventGroupWaitBits_Unpriv \n" + " MPU_xEventGroupWaitBits_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xEventGroupWaitBitsImpl \n" + " MPU_xEventGroupWaitBits_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xEventGroupWaitBitsImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER_1 ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToClear ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToClear ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupClearBitsImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xEventGroupClearBits_Unpriv \n" + " MPU_xEventGroupClearBits_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xEventGroupClearBitsImpl \n" + " MPU_xEventGroupClearBits_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xEventGroupClearBitsImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupSetBitsImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xEventGroupSetBits_Unpriv \n" + " MPU_xEventGroupSetBits_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xEventGroupSetBitsImpl \n" + " MPU_xEventGroupSetBits_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xEventGroupSetBitsImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet, + const EventBits_t uxBitsToWaitFor, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet, + const EventBits_t uxBitsToWaitFor, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupSyncImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xEventGroupSync_Unpriv \n" + " MPU_xEventGroupSync_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xEventGroupSyncImpl \n" + " MPU_xEventGroupSync_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xEventGroupSyncImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + +UBaseType_t MPU_uxEventGroupGetNumber( void * xEventGroup ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxEventGroupGetNumber( void * xEventGroup ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxEventGroupGetNumberImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_uxEventGroupGetNumber_Unpriv \n" + " MPU_uxEventGroupGetNumber_Priv: \n" + " pop {r0, r1} \n" + " b MPU_uxEventGroupGetNumberImpl \n" + " MPU_uxEventGroupGetNumber_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_uxEventGroupGetNumberImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /*( configUSE_TRACE_FACILITY == 1 )*/ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + +void MPU_vEventGroupSetNumber( void * xEventGroup, + UBaseType_t uxEventGroupNumber ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vEventGroupSetNumber( void * xEventGroup, + UBaseType_t uxEventGroupNumber ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vEventGroupSetNumberImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_vEventGroupSetNumber_Unpriv \n" + " MPU_vEventGroupSetNumber_Priv: \n" + " pop {r0, r1} \n" + " b MPU_vEventGroupSetNumberImpl \n" + " MPU_vEventGroupSetNumber_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_vEventGroupSetNumberImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /*( configUSE_TRACE_FACILITY == 1 )*/ +/*-----------------------------------------------------------*/ + +size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, + const void * pvTxData, + size_t xDataLengthBytes, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, + const void * pvTxData, + size_t xDataLengthBytes, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferSendImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xStreamBufferSend_Unpriv \n" + " MPU_xStreamBufferSend_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xStreamBufferSendImpl \n" + " MPU_xStreamBufferSend_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xStreamBufferSendImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, + void * pvRxData, + size_t xBufferLengthBytes, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, + void * pvRxData, + size_t xBufferLengthBytes, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferReceiveImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xStreamBufferReceive_Unpriv \n" + " MPU_xStreamBufferReceive_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xStreamBufferReceiveImpl \n" + " MPU_xStreamBufferReceive_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xStreamBufferReceiveImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferIsFullImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xStreamBufferIsFull_Unpriv \n" + " MPU_xStreamBufferIsFull_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xStreamBufferIsFullImpl \n" + " MPU_xStreamBufferIsFull_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xStreamBufferIsFullImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferIsEmptyImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xStreamBufferIsEmpty_Unpriv \n" + " MPU_xStreamBufferIsEmpty_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xStreamBufferIsEmptyImpl \n" + " MPU_xStreamBufferIsEmpty_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xStreamBufferIsEmptyImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferSpacesAvailableImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xStreamBufferSpacesAvailable_Unpriv \n" + " MPU_xStreamBufferSpacesAvailable_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xStreamBufferSpacesAvailableImpl \n" + " MPU_xStreamBufferSpacesAvailable_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xStreamBufferSpacesAvailableImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferBytesAvailableImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xStreamBufferBytesAvailable_Unpriv \n" + " MPU_xStreamBufferBytesAvailable_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xStreamBufferBytesAvailableImpl \n" + " MPU_xStreamBufferBytesAvailable_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xStreamBufferBytesAvailableImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, + size_t xTriggerLevel ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, + size_t xTriggerLevel ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferSetTriggerLevelImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xStreamBufferSetTriggerLevel_Unpriv \n" + " MPU_xStreamBufferSetTriggerLevel_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xStreamBufferSetTriggerLevelImpl \n" + " MPU_xStreamBufferSetTriggerLevel_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xStreamBufferSetTriggerLevelImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferNextMessageLengthBytesImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xStreamBufferNextMessageLengthBytes_Unpriv \n" + " MPU_xStreamBufferNextMessageLengthBytes_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xStreamBufferNextMessageLengthBytesImpl \n" + " MPU_xStreamBufferNextMessageLengthBytes_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xStreamBufferNextMessageLengthBytesImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ diff --git a/portable/GCC/ARM_CM23/non_secure/port.c b/portable/GCC/ARM_CM23/non_secure/port.c index 7bbe1b7bc53..cab1b3668bf 100644 --- a/portable/GCC/ARM_CM23/non_secure/port.c +++ b/portable/GCC/ARM_CM23/non_secure/port.c @@ -107,6 +107,13 @@ #define portPRIGROUP_SHIFT ( 8UL ) /*-----------------------------------------------------------*/ +/** + * @brief Constants used during system call enter and exit. + */ +#define portPSR_STACK_PADDING_MASK ( 1UL << 9UL ) +#define portEXC_RETURN_STACK_FRAME_TYPE_MASK ( 1UL << 4UL ) +/*-----------------------------------------------------------*/ + /** * @brief Constants required to manipulate the FPU. */ @@ -123,6 +130,14 @@ #define portFPCCR_LSPEN_MASK ( 1UL << portFPCCR_LSPEN_POS ) /*-----------------------------------------------------------*/ +/** + * @brief Offsets in the stack to the parameters when inside the SVC handler. + */ +#define portOFFSET_TO_LR ( 5 ) +#define portOFFSET_TO_PC ( 6 ) +#define portOFFSET_TO_PSR ( 7 ) +/*-----------------------------------------------------------*/ + /** * @brief Constants required to manipulate the MPU. */ @@ -148,6 +163,8 @@ #define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ #define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ +#define portMPU_RBAR_ACCESS_PERMISSIONS_MASK ( 3UL << 1UL ) + #define portMPU_MAIR_ATTR0_POS ( 0UL ) #define portMPU_MAIR_ATTR0_MASK ( 0x000000ff ) @@ -191,6 +208,30 @@ /* Expected value of the portMPU_TYPE register. */ #define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) + +/* Extract first address of the MPU region as encoded in the + * RBAR (Region Base Address Register) value. */ +#define portEXTRACT_FIRST_ADDRESS_FROM_RBAR( rbar ) \ + ( ( rbar ) & portMPU_RBAR_ADDRESS_MASK ) + +/* Extract last address of the MPU region as encoded in the + * RLAR (Region Limit Address Register) value. */ +#define portEXTRACT_LAST_ADDRESS_FROM_RLAR( rlar ) \ + ( ( ( rlar ) & portMPU_RLAR_ADDRESS_MASK ) | ~portMPU_RLAR_ADDRESS_MASK ) + +/* Does addr lies within [start, end] address range? */ +#define portIS_ADDRESS_WITHIN_RANGE( addr, start, end ) \ + ( ( ( addr ) >= ( start ) ) && ( ( addr ) <= ( end ) ) ) + +/* Is the access request satisfied by the available permissions? */ +#define portIS_AUTHORIZED( accessRequest, permissions ) \ + ( ( ( permissions ) & ( accessRequest ) ) == accessRequest ) + +/* 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 ) ) ) /*-----------------------------------------------------------*/ /** @@ -311,6 +352,19 @@ static void prvTaskExitError( void ); #if ( configENABLE_MPU == 1 ) +/** + * @brief Extract MPU region's access permissions from the Region Base Address + * Register (RBAR) value. + * + * @param ulRBARValue RBAR value for the MPU region. + * + * @return uint32_t Access permissions. + */ + static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) PRIVILEGED_FUNCTION; +#endif /* configENABLE_MPU */ + +#if ( configENABLE_MPU == 1 ) + /** * @brief Setup the Memory Protection Unit (MPU). */ @@ -365,6 +419,60 @@ void SysTick_Handler( void ) PRIVILEGED_FUNCTION; * @brief C part of SVC handler. */ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIVILEGED_FUNCTION; + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + + /** + * @brief Sets up the system call stack so that upon returning from + * SVC, the system call stack is used. + * + * It is used for the system calls with up to 4 parameters. + * + * @param pulTaskStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + */ + void vSystemCallEnter( uint32_t * pulTaskStack, uint32_t ulLR ) PRIVILEGED_FUNCTION; + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + + /** + * @brief Sets up the system call stack so that upon returning from + * SVC, the system call stack is used. + * + * It is used for the system calls with 5 parameters. + * + * @param pulTaskStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + */ + void vSystemCallEnter_1( uint32_t * pulTaskStack, uint32_t ulLR ) PRIVILEGED_FUNCTION; + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + + /** + * @brief Sets up the task stack so that upon returning from + * SVC, the task stack is used again. + * + * @param pulSystemCallStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + */ + void vSystemCallExit( uint32_t * pulSystemCallStack, uint32_t ulLR ) PRIVILEGED_FUNCTION; + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + +#if ( configENABLE_MPU == 1 ) + + /** + * @brief Checks whether or not the calling task is privileged. + * + * @return pdTRUE if the calling task is privileged, pdFALSE otherwise. + */ + BaseType_t xPortIsTaskPrivileged( void ) PRIVILEGED_FUNCTION; + +#endif /* configENABLE_MPU == 1 */ /*-----------------------------------------------------------*/ /** @@ -681,6 +789,26 @@ static void prvTaskExitError( void ) } /*-----------------------------------------------------------*/ +#if ( configENABLE_MPU == 1 ) + static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) /* PRIVILEGED_FUNCTION */ + { + uint32_t ulAccessPermissions = 0; + + if( ( ulRBARValue & portMPU_RBAR_ACCESS_PERMISSIONS_MASK ) == portMPU_REGION_READ_ONLY ) + { + ulAccessPermissions = tskMPU_READ_PERMISSION; + } + + if( ( ulRBARValue & portMPU_RBAR_ACCESS_PERMISSIONS_MASK ) == portMPU_REGION_READ_WRITE ) + { + ulAccessPermissions = ( tskMPU_READ_PERMISSION | tskMPU_WRITE_PERMISSION ); + } + + return ulAccessPermissions; + } +#endif /* configENABLE_MPU */ +/*-----------------------------------------------------------*/ + #if ( configENABLE_MPU == 1 ) static void prvSetupMPU( void ) /* PRIVILEGED_FUNCTION */ { @@ -853,7 +981,7 @@ void SysTick_Handler( void ) /* PRIVILEGED_FUNCTION */ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTION portDONT_DISCARD */ { - #if ( configENABLE_MPU == 1 ) + #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) ) #if defined( __ARMCC_VERSION ) /* Declaration when these variable are defined in code instead of being @@ -865,7 +993,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO extern uint32_t __syscalls_flash_start__[]; extern uint32_t __syscalls_flash_end__[]; #endif /* defined( __ARMCC_VERSION ) */ - #endif /* configENABLE_MPU */ + #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */ uint32_t ulPC; @@ -880,7 +1008,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO /* Register are stored on the stack in the following order - R0, R1, R2, R3, * R12, LR, PC, xPSR. */ - ulPC = pulCallerStackAddress[ 6 ]; + ulPC = pulCallerStackAddress[ portOFFSET_TO_PC ]; ucSVCNumber = ( ( uint8_t * ) ulPC )[ -2 ]; switch( ucSVCNumber ) @@ -951,18 +1079,18 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO vRestoreContextOfFirstTask(); break; - #if ( configENABLE_MPU == 1 ) - case portSVC_RAISE_PRIVILEGE: + #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) ) + case portSVC_RAISE_PRIVILEGE: - /* Only raise the privilege, if the svc was raised from any of - * the system calls. */ - if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) && - ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ) - { - vRaisePrivilege(); - } - break; - #endif /* configENABLE_MPU */ + /* Only raise the privilege, if the svc was raised from any of + * the system calls. */ + if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ) + { + vRaisePrivilege(); + } + break; + #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */ default: /* Incorrect SVC call. */ @@ -971,51 +1099,455 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } /*-----------------------------------------------------------*/ -/* *INDENT-OFF* */ -#if ( configENABLE_MPU == 1 ) - StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, - StackType_t * pxEndOfStack, - TaskFunction_t pxCode, - void * pvParameters, - BaseType_t xRunPrivileged ) /* PRIVILEGED_FUNCTION */ -#else - StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, - StackType_t * pxEndOfStack, - TaskFunction_t pxCode, - void * pvParameters ) /* PRIVILEGED_FUNCTION */ -#endif /* configENABLE_MPU */ -/* *INDENT-ON* */ +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + +void vSystemCallEnter( uint32_t * pulTaskStack, uint32_t ulLR ) /* PRIVILEGED_FUNCTION */ { - /* Simulate the stack frame as it would be created by a context switch - * interrupt. */ - #if ( portPRELOAD_REGISTERS == 0 ) + extern TaskHandle_t pxCurrentTCB; + xMPU_SETTINGS * pxMpuSettings; + uint32_t * pulSystemCallStack; + uint32_t ulStackFrameSize, ulSystemCallLocation, i; + #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being + * exported from linker scripts. */ + extern uint32_t * __syscalls_flash_start__; + extern uint32_t * __syscalls_flash_end__; + #else + /* Declaration when these variable are exported from linker scripts. */ + extern uint32_t __syscalls_flash_start__[]; + extern uint32_t __syscalls_flash_end__[]; + #endif /* #if defined( __ARMCC_VERSION ) */ + + ulSystemCallLocation = pulTaskStack[ portOFFSET_TO_PC ]; + + /* If the request did not come from the system call section, do nothing. */ + if( ( ulSystemCallLocation >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulSystemCallLocation <= ( uint32_t ) __syscalls_flash_end__ ) ) { - pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ - *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ - pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pxCode; /* PC */ - pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR */ - pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ - *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ - pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */ - *pxTopOfStack = portINITIAL_EXC_RETURN; + pxMpuSettings = xTaskGetMPUSettings( pxCurrentTCB ); + pulSystemCallStack = pxMpuSettings->xSystemCallStackInfo.pulSystemCallStack; - #if ( configENABLE_MPU == 1 ) + /* This is not NULL only for the duration of the system call. */ + configASSERT( pxMpuSettings->xSystemCallStackInfo.pulTaskStack == NULL ); + + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) { - pxTopOfStack--; + if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) + { + /* Extended frame i.e. FPU in use. */ + ulStackFrameSize = 26; + __asm volatile ( + " vpush {s0} \n" /* Trigger lazy stacking. */ + " vpop {s0} \n" /* Nullify the affect of the above instruction. */ + ::: "memory" + ); + } + else + { + /* Standard frame i.e. FPU not in use. */ + ulStackFrameSize = 8; + } + } + #else + { + ulStackFrameSize = 8; + } + #endif /* configENABLE_FPU || configENABLE_MVE */ + + /* Make space on the system call stack for the stack frame. */ + pulSystemCallStack = pulSystemCallStack - ulStackFrameSize; + + /* Copy the stack frame. */ + for( i = 0; i < ulStackFrameSize; i++ ) + { + pulSystemCallStack[ i ] = pulTaskStack[ i ]; + } + + /* Store the value of the LR and PSPLIM registers before the SVC was raised. We need to + * restore it when we exit from the system call. */ + pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; + __asm volatile ( "mrs %0, psplim" : "=r" ( pxMpuSettings->xSystemCallStackInfo.ulStackLimitRegisterAtSystemCallEntry ) ); + + /* Use the pulSystemCallStack in thread mode. */ + __asm volatile ( "msr psp, %0" : : "r" ( pulSystemCallStack ) ); + __asm volatile ( "msr psplim, %0" : : "r" ( pxMpuSettings->xSystemCallStackInfo.pulSystemCallStackLimit ) ); + + /* Remember the location where we should copy the stack frame when we exit from + * the system call. */ + pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulStackFrameSize; + + /* Record if the hardware used padding to force the stack pointer + * to be double word aligned. */ + if( ( pulTaskStack[ portOFFSET_TO_PSR ] & portPSR_STACK_PADDING_MASK ) == portPSR_STACK_PADDING_MASK ) + { + pxMpuSettings->ulTaskFlags |= portSTACK_FRAME_HAS_PADDING_FLAG; + } + else + { + pxMpuSettings->ulTaskFlags &= ( ~portSTACK_FRAME_HAS_PADDING_FLAG ); + } + + /* We ensure in pxPortInitialiseStack that the system call stack is + * double word aligned and therefore, there is no need of padding. + * Clear the bit[9] of stacked xPSR. */ + pulSystemCallStack[ portOFFSET_TO_PSR ] &= ( ~portPSR_STACK_PADDING_MASK ); + + /* Raise the privilege for the duration of the system call. */ + __asm volatile ( + " mrs r0, control \n" /* Obtain current control value. */ + " movs r1, #1 \n" /* r1 = 1. */ + " bics r0, r1 \n" /* Clear nPRIV bit. */ + " msr control, r0 \n" /* Write back new control value. */ + ::: "r0", "r1", "memory" + ); + } +} - if( xRunPrivileged == pdTRUE ) +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + +void vSystemCallEnter_1( uint32_t * pulTaskStack, uint32_t ulLR ) /* PRIVILEGED_FUNCTION */ +{ + extern TaskHandle_t pxCurrentTCB; + xMPU_SETTINGS * pxMpuSettings; + uint32_t * pulSystemCallStack; + uint32_t ulStackFrameSize, ulSystemCallLocation, i; + #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being + * exported from linker scripts. */ + extern uint32_t * __syscalls_flash_start__; + extern uint32_t * __syscalls_flash_end__; + #else + /* Declaration when these variable are exported from linker scripts. */ + extern uint32_t __syscalls_flash_start__[]; + extern uint32_t __syscalls_flash_end__[]; + #endif /* #if defined( __ARMCC_VERSION ) */ + + ulSystemCallLocation = pulTaskStack[ portOFFSET_TO_PC ]; + + /* If the request did not come from the system call section, do nothing. */ + if( ( ulSystemCallLocation >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulSystemCallLocation <= ( uint32_t ) __syscalls_flash_end__ ) ) + { + pxMpuSettings = xTaskGetMPUSettings( pxCurrentTCB ); + pulSystemCallStack = pxMpuSettings->xSystemCallStackInfo.pulSystemCallStack; + + /* This is not NULL only for the duration of the system call. */ + configASSERT( pxMpuSettings->xSystemCallStackInfo.pulTaskStack == NULL ); + + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + { + if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) { - *pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */ + /* Extended frame i.e. FPU in use. */ + ulStackFrameSize = 26; + __asm volatile ( + " vpush {s0} \n" /* Trigger lazy stacking. */ + " vpop {s0} \n" /* Nullify the affect of the above instruction. */ + ::: "memory" + ); } else { - *pxTopOfStack = portINITIAL_CONTROL_UNPRIVILEGED; /* Slot used to hold this task's CONTROL value. */ + /* Standard frame i.e. FPU not in use. */ + ulStackFrameSize = 8; } } - #endif /* configENABLE_MPU */ + #else + { + ulStackFrameSize = 8; + } + #endif /* configENABLE_FPU || configENABLE_MVE */ + + /* Make space on the system call stack for the stack frame and + * the parameter passed on the stack. We only need to copy one + * parameter but we still reserve 2 spaces to keep the stack + * double word aligned. */ + pulSystemCallStack = pulSystemCallStack - ulStackFrameSize - 2UL; + + /* Copy the stack frame. */ + for( i = 0; i < ulStackFrameSize; i++ ) + { + pulSystemCallStack[ i ] = pulTaskStack[ i ]; + } + + /* Copy the parameter which is passed the stack. */ + if( ( pulTaskStack[ portOFFSET_TO_PSR ] & portPSR_STACK_PADDING_MASK ) == portPSR_STACK_PADDING_MASK ) + { + pulSystemCallStack[ ulStackFrameSize ] = pulTaskStack[ ulStackFrameSize + 1 ]; + /* Record if the hardware used padding to force the stack pointer + * to be double word aligned. */ + pxMpuSettings->ulTaskFlags |= portSTACK_FRAME_HAS_PADDING_FLAG; + } + else + { + pulSystemCallStack[ ulStackFrameSize ] = pulTaskStack[ ulStackFrameSize ]; + /* Record if the hardware used padding to force the stack pointer + * to be double word aligned. */ + pxMpuSettings->ulTaskFlags &= ( ~portSTACK_FRAME_HAS_PADDING_FLAG ); + } + + /* Store the value of the LR and PSPLIM registers before the SVC was raised. + * We need to restore it when we exit from the system call. */ + pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; + __asm volatile ( "mrs %0, psplim" : "=r" ( pxMpuSettings->xSystemCallStackInfo.ulStackLimitRegisterAtSystemCallEntry ) ); + + /* Use the pulSystemCallStack in thread mode. */ + __asm volatile ( "msr psp, %0" : : "r" ( pulSystemCallStack ) ); + __asm volatile ( "msr psplim, %0" : : "r" ( pxMpuSettings->xSystemCallStackInfo.pulSystemCallStackLimit ) ); + + /* Remember the location where we should copy the stack frame when we exit from + * the system call. */ + pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulStackFrameSize; + + /* We ensure in pxPortInitialiseStack that the system call stack is + * double word aligned and therefore, there is no need of padding. + * Clear the bit[9] of stacked xPSR. */ + pulSystemCallStack[ portOFFSET_TO_PSR ] &= ( ~portPSR_STACK_PADDING_MASK ); + + /* Raise the privilege for the duration of the system call. */ + __asm volatile ( + " mrs r0, control \n" /* Obtain current control value. */ + " movs r1, #1 \n" /* r1 = 1. */ + " bics r0, r1 \n" /* Clear nPRIV bit. */ + " msr control, r0 \n" /* Write back new control value. */ + ::: "r0", "r1", "memory" + ); + } +} + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) +void vSystemCallExit( uint32_t * pulSystemCallStack, uint32_t ulLR ) /* PRIVILEGED_FUNCTION */ +{ + extern TaskHandle_t pxCurrentTCB; + xMPU_SETTINGS * pxMpuSettings; + uint32_t * pulTaskStack; + uint32_t ulStackFrameSize, ulSystemCallLocation, i; + #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being + * exported from linker scripts. */ + extern uint32_t * __syscalls_flash_start__; + extern uint32_t * __syscalls_flash_end__; + #else + /* Declaration when these variable are exported from linker scripts. */ + extern uint32_t __syscalls_flash_start__[]; + extern uint32_t __syscalls_flash_end__[]; + #endif /* #if defined( __ARMCC_VERSION ) */ + + ulSystemCallLocation = pulSystemCallStack[ portOFFSET_TO_PC ]; + + /* If the request did not come from the system call section, do nothing. */ + if( ( ulSystemCallLocation >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulSystemCallLocation <= ( uint32_t ) __syscalls_flash_end__ ) ) + { + pxMpuSettings = xTaskGetMPUSettings( pxCurrentTCB ); + pulTaskStack = pxMpuSettings->xSystemCallStackInfo.pulTaskStack; + + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + { + if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) + { + /* Extended frame i.e. FPU in use. */ + ulStackFrameSize = 26; + __asm volatile ( + " vpush {s0} \n" /* Trigger lazy stacking. */ + " vpop {s0} \n" /* Nullify the affect of the above instruction. */ + ::: "memory" + ); + } + else + { + /* Standard frame i.e. FPU not in use. */ + ulStackFrameSize = 8; + } + } + #else + { + ulStackFrameSize = 8; + } + #endif /* configENABLE_FPU || configENABLE_MVE */ + + /* Make space on the task stack for the stack frame. */ + pulTaskStack = pulTaskStack - ulStackFrameSize; + + /* Copy the stack frame. */ + for( i = 0; i < ulStackFrameSize; i++ ) + { + pulTaskStack[ i ] = pulSystemCallStack[ i ]; + } + + /* Use the pulTaskStack in thread mode. */ + __asm volatile ( "msr psp, %0" : : "r" ( pulTaskStack ) ); + + /* Restore the LR and PSPLIM to what they were at the time of + * system call entry. */ + pulTaskStack[ portOFFSET_TO_LR ] = pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry; + __asm volatile ( "msr psplim, %0" : : "r" ( pxMpuSettings->xSystemCallStackInfo.ulStackLimitRegisterAtSystemCallEntry ) ); + + /* If the hardware used padding to force the stack pointer + * to be double word aligned, set the stacked xPSR bit[9], + * otherwise clear it. */ + if( ( pxMpuSettings->ulTaskFlags & portSTACK_FRAME_HAS_PADDING_FLAG ) == portSTACK_FRAME_HAS_PADDING_FLAG ) + { + pulTaskStack[ portOFFSET_TO_PSR ] |= portPSR_STACK_PADDING_MASK; + } + else + { + pulTaskStack[ portOFFSET_TO_PSR ] &= ( ~portPSR_STACK_PADDING_MASK ); + } + + /* This is not NULL only for the duration of the system call. */ + pxMpuSettings->xSystemCallStackInfo.pulTaskStack = NULL; + + /* Drop the privilege before returning to the thread mode. */ + __asm volatile ( + " mrs r0, control \n" /* Obtain current control value. */ + " movs r1, #1 \n" /* r1 = 1. */ + " orrs r0, r1 \n" /* Set nPRIV bit. */ + " msr control, r0 \n" /* Write back new control value. */ + ::: "r0", "r1", "memory" + ); + } +} + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configENABLE_MPU == 1 ) + +BaseType_t xPortIsTaskPrivileged( void ) /* PRIVILEGED_FUNCTION */ +{ + BaseType_t xTaskIsPrivileged = pdFALSE; + const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */ + + if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) + { + xTaskIsPrivileged = pdTRUE; + } + + return xTaskIsPrivileged; +} + +#endif /* configENABLE_MPU == 1 */ +/*-----------------------------------------------------------*/ + +#if( configENABLE_MPU == 1 ) + +StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, + StackType_t * pxEndOfStack, + TaskFunction_t pxCode, + void * pvParameters, + BaseType_t xRunPrivileged, + xMPU_SETTINGS * xMPUSettings ) /* PRIVILEGED_FUNCTION */ +{ + uint32_t ulIndex = 0; + + xMPUSettings->ulContext[ ulIndex ] = 0x04040404; /* r4. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x05050505; /* r5. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x06060606; /* r6. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x07070707; /* r7. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x08080808; /* r8. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x09090909; /* r9. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x10101010; /* r10. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x11111111; /* r11. */ + ulIndex++; + + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pvParameters; /* r0. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x01010101; /* r1. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x02020202; /* r2. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x03030303; /* r3. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x12121212; /* r12. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portTASK_RETURN_ADDRESS; /* LR. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxCode; /* PC. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = portINITIAL_XPSR; /* xPSR. */ + ulIndex++; + + #if ( configENABLE_TRUSTZONE == 1 ) + { + xMPUSettings->ulContext[ ulIndex ] = portNO_SECURE_CONTEXT; /* xSecureContext. */ + ulIndex++; + } + #endif /* configENABLE_TRUSTZONE */ + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) ( pxTopOfStack - 8 ); /* PSP with the hardware saved stack. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */ + ulIndex++; + if( xRunPrivileged == pdTRUE ) + { + xMPUSettings->ulTaskFlags |= portTASK_IS_PRIVILEGED_FLAG; + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_PRIVILEGED; /* CONTROL. */ + ulIndex++; + } + else + { + xMPUSettings->ulTaskFlags &= ( ~portTASK_IS_PRIVILEGED_FLAG ); + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_UNPRIVILEGED; /* CONTROL. */ + ulIndex++; + } + xMPUSettings->ulContext[ ulIndex ] = portINITIAL_EXC_RETURN; /* LR (EXC_RETURN). */ + ulIndex++; + + #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + { + /* Ensure that the system call stack is double word aligned. */ + xMPUSettings->xSystemCallStackInfo.pulSystemCallStack = &( xMPUSettings->xSystemCallStackInfo.ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE - 1 ] ); + xMPUSettings->xSystemCallStackInfo.pulSystemCallStack = ( uint32_t * ) ( ( uint32_t ) ( xMPUSettings->xSystemCallStackInfo.pulSystemCallStack ) & + ( uint32_t ) ( ~( portBYTE_ALIGNMENT_MASK ) ) ); + + xMPUSettings->xSystemCallStackInfo.pulSystemCallStackLimit = &( xMPUSettings->xSystemCallStackInfo.ulSystemCallStackBuffer[ 0 ] ); + xMPUSettings->xSystemCallStackInfo.pulSystemCallStackLimit = ( uint32_t * ) ( ( ( uint32_t ) ( xMPUSettings->xSystemCallStackInfo.pulSystemCallStackLimit ) + + ( uint32_t ) ( portBYTE_ALIGNMENT - 1 ) ) & + ( uint32_t ) ( ~( portBYTE_ALIGNMENT_MASK ) ) ); + + /* This is not NULL only for the duration of a system call. */ + xMPUSettings->xSystemCallStackInfo.pulTaskStack = NULL; + } + #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + + return &( xMPUSettings->ulContext[ ulIndex ] ); +} + +#else /* configENABLE_MPU */ + +StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, + StackType_t * pxEndOfStack, + TaskFunction_t pxCode, + void * pvParameters ) /* PRIVILEGED_FUNCTION */ +{ + /* Simulate the stack frame as it would be created by a context switch + * interrupt. */ + #if ( portPRELOAD_REGISTERS == 0 ) + { + pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ + *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR. */ + pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ + pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */ + *pxTopOfStack = portINITIAL_EXC_RETURN; pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ @@ -1029,55 +1561,39 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO #else /* portPRELOAD_REGISTERS */ { pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ - *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ + *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pxCode; /* PC */ + *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR */ + *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x12121212UL; /* R12 */ + *pxTopOfStack = ( StackType_t ) 0x12121212UL; /* R12. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x03030303UL; /* R3 */ + *pxTopOfStack = ( StackType_t ) 0x03030303UL; /* R3. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x02020202UL; /* R2 */ + *pxTopOfStack = ( StackType_t ) 0x02020202UL; /* R2. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x01010101UL; /* R1 */ + *pxTopOfStack = ( StackType_t ) 0x01010101UL; /* R1. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x11111111UL; /* R11 */ + *pxTopOfStack = ( StackType_t ) 0x11111111UL; /* R11. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x10101010UL; /* R10 */ + *pxTopOfStack = ( StackType_t ) 0x10101010UL; /* R10. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x09090909UL; /* R09 */ + *pxTopOfStack = ( StackType_t ) 0x09090909UL; /* R09. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x08080808UL; /* R08 */ + *pxTopOfStack = ( StackType_t ) 0x08080808UL; /* R08. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x07070707UL; /* R07 */ + *pxTopOfStack = ( StackType_t ) 0x07070707UL; /* R07. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x06060606UL; /* R06 */ + *pxTopOfStack = ( StackType_t ) 0x06060606UL; /* R06. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x05050505UL; /* R05 */ + *pxTopOfStack = ( StackType_t ) 0x05050505UL; /* R05. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x04040404UL; /* R04 */ + *pxTopOfStack = ( StackType_t ) 0x04040404UL; /* R04. */ pxTopOfStack--; - *pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN */ - - #if ( configENABLE_MPU == 1 ) - { - pxTopOfStack--; - - if( xRunPrivileged == pdTRUE ) - { - *pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */ - } - else - { - *pxTopOfStack = portINITIAL_CONTROL_UNPRIVILEGED; /* Slot used to hold this task's CONTROL value. */ - } - } - #endif /* configENABLE_MPU */ - + *pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN. */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ @@ -1092,6 +1608,8 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO return pxTopOfStack; } + +#endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ @@ -1128,6 +1646,10 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ configASSERT( ucMaxSysCallPriority ); + /* Check that the bits not implemented in hardware are zero in + * configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & ( ~ucMaxPriorityValue ) ) == 0U ); + /* Calculate the maximum acceptable priority group value for the number * of bits read back. */ @@ -1164,35 +1686,6 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulImplementedPrioBits; } - /* The interrupt priority bits are not modelled in QEMU and the assert that - * checks the number of implemented bits and __NVIC_PRIO_BITS will always fail. - * Therefore, this assert is not adding any value for QEMU targets. The config - * option `configDISABLE_INTERRUPT_PRIO_BITS_CHECK` should be defined in the - * `FreeRTOSConfig.h` for QEMU targets. */ - #ifndef configDISABLE_INTERRUPT_PRIO_BITS_CHECK - { - #ifdef __NVIC_PRIO_BITS - { - /* - * Check that the number of implemented priority bits queried from - * hardware is equal to the CMSIS __NVIC_PRIO_BITS configuration macro. - */ - configASSERT( ulImplementedPrioBits == __NVIC_PRIO_BITS ); - } - #endif /* __NVIC_PRIO_BITS */ - - #ifdef configPRIO_BITS - { - /* - * Check that the number of implemented priority bits queried from - * hardware is equal to the FreeRTOS configPRIO_BITS configuration macro. - */ - configASSERT( ulImplementedPrioBits == configPRIO_BITS ); - } - #endif /* configPRIO_BITS */ - } - #endif /* #ifndef configDISABLE_INTERRUPT_PRIO_BITS_CHECK */ - /* Shift the priority group value back to its position within the AIRCR * register. */ ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT; @@ -1372,6 +1865,54 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ +#if ( configENABLE_MPU == 1 ) + BaseType_t xPortIsAuthorizedToAccessBuffer( const void * pvBuffer, + uint32_t ulBufferLength, + uint32_t ulAccessRequested ) /* PRIVILEGED_FUNCTION */ + + { + uint32_t i, ulBufferStartAddress, ulBufferEndAddress; + BaseType_t xAccessGranted = pdFALSE; + const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */ + + if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) + { + xAccessGranted = pdTRUE; + } + else + { + if( portADD_UINT32_WILL_OVERFLOW( ( ( uint32_t ) pvBuffer ), ( ulBufferLength - 1UL ) ) == pdFALSE ) + { + ulBufferStartAddress = ( uint32_t ) pvBuffer; + ulBufferEndAddress = ( ( ( uint32_t ) pvBuffer ) + ulBufferLength - 1UL ); + + for( i = 0; i < portTOTAL_NUM_REGIONS; i++ ) + { + /* Is the MPU region enabled? */ + if( ( xTaskMpuSettings->xRegionsSettings[ i ].ulRLAR & portMPU_RLAR_REGION_ENABLE ) == portMPU_RLAR_REGION_ENABLE ) + { + if( portIS_ADDRESS_WITHIN_RANGE( ulBufferStartAddress, + portEXTRACT_FIRST_ADDRESS_FROM_RBAR( xTaskMpuSettings->xRegionsSettings[ i ].ulRBAR ), + portEXTRACT_LAST_ADDRESS_FROM_RLAR( xTaskMpuSettings->xRegionsSettings[ i ].ulRLAR ) ) && + portIS_ADDRESS_WITHIN_RANGE( ulBufferEndAddress, + portEXTRACT_FIRST_ADDRESS_FROM_RBAR( xTaskMpuSettings->xRegionsSettings[ i ].ulRBAR ), + portEXTRACT_LAST_ADDRESS_FROM_RLAR( xTaskMpuSettings->xRegionsSettings[ i ].ulRLAR ) ) && + portIS_AUTHORIZED( ulAccessRequested, + prvGetRegionAccessPermissions( xTaskMpuSettings->xRegionsSettings[ i ].ulRBAR ) ) ) + { + xAccessGranted = pdTRUE; + break; + } + } + } + } + } + + return xAccessGranted; + } +#endif /* configENABLE_MPU */ +/*-----------------------------------------------------------*/ + BaseType_t xPortIsInsideInterrupt( void ) { uint32_t ulCurrentInterrupt; diff --git a/portable/GCC/ARM_CM23/non_secure/portasm.c b/portable/GCC/ARM_CM23/non_secure/portasm.c index 44f159af1fa..64a24f527ff 100644 --- a/portable/GCC/ARM_CM23/non_secure/portasm.c +++ b/portable/GCC/ARM_CM23/non_secure/portasm.c @@ -44,6 +44,109 @@ #error Cortex-M23 does not have a Floating Point Unit (FPU) and therefore configENABLE_FPU must be set to 0. #endif +#if ( configENABLE_MPU == 1 ) + +void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ +{ + __asm volatile + ( + " .syntax unified \n" + " \n" + " program_mpu_first_task: \n" + " ldr r3, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r0, [r3] \n" /* r0 = pxCurrentTCB.*/ + " \n" + " dmb \n" /* Complete outstanding transfers before disabling MPU. */ + " ldr r1, xMPUCTRLConst2 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ + " movs r3, #1 \n" /* r3 = 1. */ + " bics r2, r3 \n" /* r2 = r2 & ~r3 i.e. Clear the bit 0 in r2. */ + " str r2, [r1] \n" /* Disable MPU. */ + " \n" + " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */ + " ldr r1, [r0] \n" /* r1 = *r0 i.e. r1 = MAIR0. */ + " ldr r2, xMAIR0Const2 \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */ + " str r1, [r2] \n" /* Program MAIR0. */ + " \n" + " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */ + " ldr r1, xRNRConst2 \n" /* r1 = 0xe000ed98 [Location of RNR]. */ + " \n" + " movs r3, #4 \n" /* r3 = 4. */ + " str r3, [r1] \n" /* Program RNR = 4. */ + " ldmia r0!, {r4-r5} \n" /* Read first set of RBAR/RLAR registers from TCB. */ + " ldr r2, xRBARConst2 \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ + " stmia r2!, {r4-r5} \n" /* Write first set of RBAR/RLAR registers. */ + " movs r3, #5 \n" /* r3 = 5. */ + " str r3, [r1] \n" /* Program RNR = 5. */ + " ldmia r0!, {r4-r5} \n" /* Read second set of RBAR/RLAR registers from TCB. */ + " ldr r2, xRBARConst2 \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ + " stmia r2!, {r4-r5} \n" /* Write second set of RBAR/RLAR registers. */ + " movs r3, #6 \n" /* r3 = 6. */ + " str r3, [r1] \n" /* Program RNR = 6. */ + " ldmia r0!, {r4-r5} \n" /* Read third set of RBAR/RLAR registers from TCB. */ + " ldr r2, xRBARConst2 \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ + " stmia r2!, {r4-r5} \n" /* Write third set of RBAR/RLAR registers. */ + " movs r3, #7 \n" /* r3 = 6. */ + " str r3, [r1] \n" /* Program RNR = 7. */ + " ldmia r0!, {r4-r5} \n" /* Read fourth set of RBAR/RLAR registers from TCB. */ + " ldr r2, xRBARConst2 \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ + " stmia r2!, {r4-r5} \n" /* Write fourth set of RBAR/RLAR registers. */ + " \n" + " ldr r1, xMPUCTRLConst2 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ + " movs r3, #1 \n" /* r3 = 1. */ + " orrs r2, r3 \n" /* r2 = r2 | r3 i.e. Set the bit 0 in r2. */ + " str r2, [r1] \n" /* Enable MPU. */ + " dsb \n" /* Force memory writes before continuing. */ + " \n" + " restore_context_first_task: \n" + " ldr r3, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r1, [r3] \n" /* r1 = pxCurrentTCB.*/ + " ldr r2, [r1] \n" /* r2 = Location of saved context in TCB. */ + " \n" + " restore_special_regs_first_task: \n" + " subs r2, #20 \n" + " ldmia r2!, {r0, r3-r6} \n" /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, r6 = LR. */ + " subs r2, #20 \n" + " msr psp, r3 \n" + " msr psplim, r4 \n" + " msr control, r5 \n" + " mov lr, r6 \n" + " ldr r4, xSecureContextConst2 \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ + " str r0, [r4] \n" /* Restore xSecureContext. */ + " \n" + " restore_general_regs_first_task: \n" + " subs r2, #32 \n" + " ldmia r2!, {r4-r7} \n" /* r4-r7 contain half of the hardware saved context. */ + " stmia r3!, {r4-r7} \n" /* Copy half of the the hardware saved context on the task stack. */ + " ldmia r2!, {r4-r7} \n" /* r4-r7 contain rest half of the hardware saved context. */ + " stmia r3!, {r4-r7} \n" /* Copy rest half of the the hardware saved context on the task stack. */ + " subs r2, #48 \n" + " ldmia r2!, {r4-r7} \n" /* Restore r8-r11. */ + " mov r8, r4 \n" /* r8 = r4. */ + " mov r9, r5 \n" /* r9 = r5. */ + " mov r10, r6 \n" /* r10 = r6. */ + " mov r11, r7 \n" /* r11 = r7. */ + " subs r2, #32 \n" + " ldmia r2!, {r4-r7} \n" /* Restore r4-r7. */ + " subs r2, #16 \n" + " \n" + " restore_context_done_first_task: \n" + " str r2, [r1] \n" /* Save the location where the context should be saved next as the first member of TCB. */ + " bx lr \n" + " \n" + " .align 4 \n" + " pxCurrentTCBConst2: .word pxCurrentTCB \n" + " xSecureContextConst2: .word xSecureContext \n" + " xMPUCTRLConst2: .word 0xe000ed94 \n" + " xMAIR0Const2: .word 0xe000edc0 \n" + " xRNRConst2: .word 0xe000ed98 \n" + " xRBARConst2: .word 0xe000ed9c \n" + ); +} + +#else /* configENABLE_MPU */ + void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ { __asm volatile @@ -54,83 +157,24 @@ void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_ " ldr r3, [r2] \n"/* Read pxCurrentTCB. */ " ldr r0, [r3] \n"/* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ " \n" - #if ( configENABLE_MPU == 1 ) - " dmb \n"/* Complete outstanding transfers before disabling MPU. */ - " ldr r2, xMPUCTRLConst2 \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ - " ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */ - " movs r5, #1 \n"/* r5 = 1. */ - " bics r4, r5 \n"/* r4 = r4 & ~r5 i.e. Clear the bit 0 in r4. */ - " str r4, [r2] \n"/* Disable MPU. */ - " \n" - " adds r3, #4 \n"/* r3 = r3 + 4. r3 now points to MAIR0 in TCB. */ - " ldr r4, [r3] \n"/* r4 = *r3 i.e. r4 = MAIR0. */ - " ldr r2, xMAIR0Const2 \n"/* r2 = 0xe000edc0 [Location of MAIR0]. */ - " str r4, [r2] \n"/* Program MAIR0. */ - " ldr r2, xRNRConst2 \n"/* r2 = 0xe000ed98 [Location of RNR]. */ - " adds r3, #4 \n"/* r3 = r3 + 4. r3 now points to first RBAR in TCB. */ - " movs r5, #4 \n"/* r5 = 4. */ - " str r5, [r2] \n"/* Program RNR = 4. */ - " ldmia r3!, {r6,r7} \n"/* Read first set of RBAR/RLAR from TCB. */ - " ldr r4, xRBARConst2 \n"/* r4 = 0xe000ed9c [Location of RBAR]. */ - " stmia r4!, {r6,r7} \n"/* Write first set of RBAR/RLAR registers. */ - " movs r5, #5 \n"/* r5 = 5. */ - " str r5, [r2] \n"/* Program RNR = 5. */ - " ldmia r3!, {r6,r7} \n"/* Read second set of RBAR/RLAR from TCB. */ - " ldr r4, xRBARConst2 \n"/* r4 = 0xe000ed9c [Location of RBAR]. */ - " stmia r4!, {r6,r7} \n"/* Write second set of RBAR/RLAR registers. */ - " movs r5, #6 \n"/* r5 = 6. */ - " str r5, [r2] \n"/* Program RNR = 6. */ - " ldmia r3!, {r6,r7} \n"/* Read third set of RBAR/RLAR from TCB. */ - " ldr r4, xRBARConst2 \n"/* r4 = 0xe000ed9c [Location of RBAR]. */ - " stmia r4!, {r6,r7} \n"/* Write third set of RBAR/RLAR registers. */ - " movs r5, #7 \n"/* r5 = 7. */ - " str r5, [r2] \n"/* Program RNR = 7. */ - " ldmia r3!, {r6,r7} \n"/* Read fourth set of RBAR/RLAR from TCB. */ - " ldr r4, xRBARConst2 \n"/* r4 = 0xe000ed9c [Location of RBAR]. */ - " stmia r4!, {r6,r7} \n"/* Write fourth set of RBAR/RLAR registers. */ - " \n" - " ldr r2, xMPUCTRLConst2 \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ - " ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */ - " movs r5, #1 \n"/* r5 = 1. */ - " orrs r4, r5 \n"/* r4 = r4 | r5 i.e. Set the bit 0 in r4. */ - " str r4, [r2] \n"/* Enable MPU. */ - " dsb \n"/* Force memory writes before continuing. */ - #endif /* configENABLE_MPU */ - " \n" - #if ( configENABLE_MPU == 1 ) - " ldm r0!, {r1-r4} \n"/* Read from stack - r1 = xSecureContext, r2 = PSPLIM, r3 = CONTROL and r4 = EXC_RETURN. */ - " ldr r5, xSecureContextConst2 \n" - " str r1, [r5] \n"/* Set xSecureContext to this task's value for the same. */ - " msr psplim, r2 \n"/* Set this task's PSPLIM value. */ - " msr control, r3 \n"/* Set this task's CONTROL value. */ - " adds r0, #32 \n"/* Discard everything up to r0. */ - " msr psp, r0 \n"/* This is now the new top of stack to use in the task. */ - " isb \n" - " bx r4 \n"/* Finally, branch to EXC_RETURN. */ - #else /* configENABLE_MPU */ - " ldm r0!, {r1-r3} \n"/* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */ - " ldr r4, xSecureContextConst2 \n" - " str r1, [r4] \n"/* Set xSecureContext to this task's value for the same. */ - " msr psplim, r2 \n"/* Set this task's PSPLIM value. */ - " movs r1, #2 \n"/* r1 = 2. */ - " msr CONTROL, r1 \n"/* Switch to use PSP in the thread mode. */ - " adds r0, #32 \n"/* Discard everything up to r0. */ - " msr psp, r0 \n"/* This is now the new top of stack to use in the task. */ - " isb \n" - " bx r3 \n"/* Finally, branch to EXC_RETURN. */ - #endif /* configENABLE_MPU */ + " ldm r0!, {r1-r3} \n"/* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */ + " ldr r4, xSecureContextConst2 \n" + " str r1, [r4] \n"/* Set xSecureContext to this task's value for the same. */ + " msr psplim, r2 \n"/* Set this task's PSPLIM value. */ + " movs r1, #2 \n"/* r1 = 2. */ + " msr CONTROL, r1 \n"/* Switch to use PSP in the thread mode. */ + " adds r0, #32 \n"/* Discard everything up to r0. */ + " msr psp, r0 \n"/* This is now the new top of stack to use in the task. */ + " isb \n" + " bx r3 \n"/* Finally, branch to EXC_RETURN. */ " \n" " .align 4 \n" "pxCurrentTCBConst2: .word pxCurrentTCB \n" "xSecureContextConst2: .word xSecureContext \n" - #if ( configENABLE_MPU == 1 ) - "xMPUCTRLConst2: .word 0xe000ed94 \n" - "xMAIR0Const2: .word 0xe000edc0 \n" - "xRNRConst2: .word 0xe000ed98 \n" - "xRBARConst2: .word 0xe000ed9c \n" - #endif /* configENABLE_MPU */ ); } + +#endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */ @@ -237,6 +281,167 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att } /*-----------------------------------------------------------*/ +#if ( configENABLE_MPU == 1 ) + +void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern SecureContext_SaveContext \n" + " .extern SecureContext_LoadContext \n" + " \n" + " ldr r3, xSecureContextConst \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ + " ldr r0, [r3] \n" /* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */ + " ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r1, [r3] \n" /* Read pxCurrentTCB - Value of pxCurrentTCB must be in r1 as it is used as a parameter later.*/ + " ldr r2, [r1] \n" /* r2 = Location in TCB where the context should be saved. */ + " \n" + " cbz r0, save_ns_context \n" /* No secure context to save. */ + " save_s_context: \n" + " push {r0-r2, lr} \n" + " bl SecureContext_SaveContext \n" /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ + " pop {r0-r3} \n" /* LR is now in r3. */ + " mov lr, r3 \n" /* Restore LR. */ + " \n" + " save_ns_context: \n" + " mov r3, lr \n" /* r3 = LR (EXC_RETURN). */ + " lsls r3, r3, #25 \n" /* r3 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ + " bmi save_special_regs \n" /* r3 < 0 ==> Bit[6] in EXC_RETURN is 1 ==> secure stack was used to store the stack frame. */ + " \n" + " save_general_regs: \n" + " mrs r3, psp \n" + " stmia r2!, {r4-r7} \n" /* Store r4-r7. */ + " mov r4, r8 \n" /* r4 = r8. */ + " mov r5, r9 \n" /* r5 = r9. */ + " mov r6, r10 \n" /* r6 = r10. */ + " mov r7, r11 \n" /* r7 = r11. */ + " stmia r2!, {r4-r7} \n" /* Store r8-r11. */ + " ldmia r3!, {r4-r7} \n" /* Copy half of the hardware saved context into r4-r7. */ + " stmia r2!, {r4-r7} \n" /* Store the hardware saved context. */ + " ldmia r3!, {r4-r7} \n" /* Copy rest half of the hardware saved context into r4-r7. */ + " stmia r2!, {r4-r7} \n" /* Store the hardware saved context. */ + " \n" + " save_special_regs: \n" + " mrs r3, psp \n" /* r3 = PSP. */ + " mrs r4, psplim \n" /* r4 = PSPLIM. */ + " mrs r5, control \n" /* r5 = CONTROL. */ + " mov r6, lr \n" /* r6 = LR. */ + " stmia r2!, {r0, r3-r6} \n" /* Store xSecureContext, original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */ + " str r2, [r1] \n" /* Save the location from where the context should be restored as the first member of TCB. */ + " \n" + " select_next_task: \n" + " cpsid i \n" + " bl vTaskSwitchContext \n" + " cpsie i \n" + " \n" + " program_mpu: \n" + " ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r0, [r3] \n" /* r0 = pxCurrentTCB.*/ + " \n" + " dmb \n" /* Complete outstanding transfers before disabling MPU. */ + " ldr r1, xMPUCTRLConst \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ + " movs r3, #1 \n" /* r3 = 1. */ + " bics r2, r3 \n" /* r2 = r2 & ~r3 i.e. Clear the bit 0 in r2. */ + " str r2, [r1] \n" /* Disable MPU. */ + " \n" + " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */ + " ldr r1, [r0] \n" /* r1 = *r0 i.e. r1 = MAIR0. */ + " ldr r2, xMAIR0Const \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */ + " str r1, [r2] \n" /* Program MAIR0. */ + " \n" + " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */ + " ldr r1, xRNRConst \n" /* r1 = 0xe000ed98 [Location of RNR]. */ + " \n" + " movs r3, #4 \n" /* r3 = 4. */ + " str r3, [r1] \n" /* Program RNR = 4. */ + " ldmia r0!, {r4-r5} \n" /* Read first set of RBAR/RLAR registers from TCB. */ + " ldr r2, xRBARConst \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ + " stmia r2!, {r4-r5} \n" /* Write first set of RBAR/RLAR registers. */ + " movs r3, #5 \n" /* r3 = 5. */ + " str r3, [r1] \n" /* Program RNR = 5. */ + " ldmia r0!, {r4-r5} \n" /* Read second set of RBAR/RLAR registers from TCB. */ + " ldr r2, xRBARConst \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ + " stmia r2!, {r4-r5} \n" /* Write second set of RBAR/RLAR registers. */ + " movs r3, #6 \n" /* r3 = 6. */ + " str r3, [r1] \n" /* Program RNR = 6. */ + " ldmia r0!, {r4-r5} \n" /* Read third set of RBAR/RLAR registers from TCB. */ + " ldr r2, xRBARConst \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ + " stmia r2!, {r4-r5} \n" /* Write third set of RBAR/RLAR registers. */ + " movs r3, #7 \n" /* r3 = 6. */ + " str r3, [r1] \n" /* Program RNR = 7. */ + " ldmia r0!, {r4-r5} \n" /* Read fourth set of RBAR/RLAR registers from TCB. */ + " ldr r2, xRBARConst \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ + " stmia r2!, {r4-r5} \n" /* Write fourth set of RBAR/RLAR registers. */ + " \n" + " ldr r1, xMPUCTRLConst \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ + " movs r3, #1 \n" /* r3 = 1. */ + " orrs r2, r3 \n" /* r2 = r2 | r3 i.e. Set the bit 0 in r2. */ + " str r2, [r1] \n" /* Enable MPU. */ + " dsb \n" /* Force memory writes before continuing. */ + " \n" + " restore_context: \n" + " ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r1, [r3] \n" /* r1 = pxCurrentTCB.*/ + " ldr r2, [r1] \n" /* r2 = Location of saved context in TCB. */ + " \n" + " restore_special_regs: \n" + " subs r2, #20 \n" + " ldmia r2!, {r0, r3-r6} \n" /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, r6 = LR. */ + " subs r2, #20 \n" + " msr psp, r3 \n" + " msr psplim, r4 \n" + " msr control, r5 \n" + " mov lr, r6 \n" + " ldr r4, xSecureContextConst \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ + " str r0, [r4] \n" /* Restore xSecureContext. */ + " cbz r0, restore_ns_context \n" /* No secure context to restore. */ + " \n" + " restore_s_context: \n" + " push {r1-r3, lr} \n" + " bl SecureContext_LoadContext \n" /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ + " pop {r1-r4} \n" /* LR is now in r4. */ + " mov lr, r4 \n" + " \n" + " restore_ns_context: \n" + " mov r0, lr \n" /* r0 = LR (EXC_RETURN). */ + " lsls r0, r0, #25 \n" /* r0 = r0 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ + " bmi restore_context_done \n" /* r0 < 0 ==> Bit[6] in EXC_RETURN is 1 ==> secure stack was used to store the stack frame. */ + " \n" + " restore_general_regs: \n" + " subs r2, #32 \n" + " ldmia r2!, {r4-r7} \n" /* r4-r7 contain half of the hardware saved context. */ + " stmia r3!, {r4-r7} \n" /* Copy half of the the hardware saved context on the task stack. */ + " ldmia r2!, {r4-r7} \n" /* r4-r7 contain rest half of the hardware saved context. */ + " stmia r3!, {r4-r7} \n" /* Copy rest half of the the hardware saved context on the task stack. */ + " subs r2, #48 \n" + " ldmia r2!, {r4-r7} \n" /* Restore r8-r11. */ + " mov r8, r4 \n" /* r8 = r4. */ + " mov r9, r5 \n" /* r9 = r5. */ + " mov r10, r6 \n" /* r10 = r6. */ + " mov r11, r7 \n" /* r11 = r7. */ + " subs r2, #32 \n" + " ldmia r2!, {r4-r7} \n" /* Restore r4-r7. */ + " subs r2, #16 \n" + " \n" + " restore_context_done: \n" + " str r2, [r1] \n" /* Save the location where the context should be saved next as the first member of TCB. */ + " bx lr \n" + " \n" + " .align 4 \n" + " pxCurrentTCBConst: .word pxCurrentTCB \n" + " xSecureContextConst: .word xSecureContext \n" + " xMPUCTRLConst: .word 0xe000ed94 \n" + " xMAIR0Const: .word 0xe000edc0 \n" + " xRNRConst: .word 0xe000ed98 \n" + " xRBARConst: .word 0xe000ed9c \n" + ); +} + +#else /* configENABLE_MPU */ + void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ { __asm volatile @@ -260,52 +465,26 @@ void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ " bpl save_ns_context \n"/* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ " ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r3] \n"/* Read pxCurrentTCB. */ - #if ( configENABLE_MPU == 1 ) - " subs r2, r2, #16 \n"/* Make space for xSecureContext, PSPLIM, CONTROL and LR on the stack. */ - " str r2, [r1] \n"/* Save the new top of stack in TCB. */ - " mrs r1, psplim \n"/* r1 = PSPLIM. */ - " mrs r3, control \n"/* r3 = CONTROL. */ - " mov r4, lr \n"/* r4 = LR/EXC_RETURN. */ - " stmia r2!, {r0, r1, r3, r4} \n"/* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */ - #else /* configENABLE_MPU */ - " subs r2, r2, #12 \n"/* Make space for xSecureContext, PSPLIM and LR on the stack. */ - " str r2, [r1] \n"/* Save the new top of stack in TCB. */ - " mrs r1, psplim \n"/* r1 = PSPLIM. */ - " mov r3, lr \n"/* r3 = LR/EXC_RETURN. */ - " stmia r2!, {r0, r1, r3} \n"/* Store xSecureContext, PSPLIM and LR on the stack. */ - #endif /* configENABLE_MPU */ + " subs r2, r2, #12 \n"/* Make space for xSecureContext, PSPLIM and LR on the stack. */ + " str r2, [r1] \n"/* Save the new top of stack in TCB. */ + " mrs r1, psplim \n"/* r1 = PSPLIM. */ + " mov r3, lr \n"/* r3 = LR/EXC_RETURN. */ + " stmia r2!, {r0, r1, r3} \n"/* Store xSecureContext, PSPLIM and LR on the stack. */ " b select_next_task \n" " \n" " save_ns_context: \n" " ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r3] \n"/* Read pxCurrentTCB. */ - #if ( configENABLE_MPU == 1 ) - " subs r2, r2, #48 \n"/* Make space for xSecureContext, PSPLIM, CONTROL, LR and the remaining registers on the stack. */ - " str r2, [r1] \n"/* Save the new top of stack in TCB. */ - " adds r2, r2, #16 \n"/* r2 = r2 + 16. */ - " stmia r2!, {r4-r7} \n"/* Store the low registers that are not saved automatically. */ - " mov r4, r8 \n"/* r4 = r8. */ - " mov r5, r9 \n"/* r5 = r9. */ - " mov r6, r10 \n"/* r6 = r10. */ - " mov r7, r11 \n"/* r7 = r11. */ - " stmia r2!, {r4-r7} \n"/* Store the high registers that are not saved automatically. */ - " mrs r1, psplim \n"/* r1 = PSPLIM. */ - " mrs r3, control \n"/* r3 = CONTROL. */ - " mov r4, lr \n"/* r4 = LR/EXC_RETURN. */ - " subs r2, r2, #48 \n"/* r2 = r2 - 48. */ - " stmia r2!, {r0, r1, r3, r4} \n"/* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */ - #else /* configENABLE_MPU */ - " subs r2, r2, #44 \n"/* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */ - " str r2, [r1] \n"/* Save the new top of stack in TCB. */ - " mrs r1, psplim \n"/* r1 = PSPLIM. */ - " mov r3, lr \n"/* r3 = LR/EXC_RETURN. */ - " stmia r2!, {r0, r1, r3-r7} \n"/* Store xSecureContext, PSPLIM, LR and the low registers that are not saved automatically. */ - " mov r4, r8 \n"/* r4 = r8. */ - " mov r5, r9 \n"/* r5 = r9. */ - " mov r6, r10 \n"/* r6 = r10. */ - " mov r7, r11 \n"/* r7 = r11. */ - " stmia r2!, {r4-r7} \n"/* Store the high registers that are not saved automatically. */ - #endif /* configENABLE_MPU */ + " subs r2, r2, #44 \n"/* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */ + " str r2, [r1] \n"/* Save the new top of stack in TCB. */ + " mrs r1, psplim \n"/* r1 = PSPLIM. */ + " mov r3, lr \n"/* r3 = LR/EXC_RETURN. */ + " stmia r2!, {r0, r1, r3-r7} \n"/* Store xSecureContext, PSPLIM, LR and the low registers that are not saved automatically. */ + " mov r4, r8 \n"/* r4 = r8. */ + " mov r5, r9 \n"/* r5 = r9. */ + " mov r6, r10 \n"/* r6 = r10. */ + " mov r7, r11 \n"/* r7 = r11. */ + " stmia r2!, {r4-r7} \n"/* Store the high registers that are not saved automatically. */ " \n" " select_next_task: \n" " cpsid i \n" @@ -316,85 +495,22 @@ void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ " ldr r1, [r3] \n"/* Read pxCurrentTCB. */ " ldr r2, [r1] \n"/* The first item in pxCurrentTCB is the task top of stack. r2 now points to the top of stack. */ " \n" - #if ( configENABLE_MPU == 1 ) - " dmb \n"/* Complete outstanding transfers before disabling MPU. */ - " ldr r3, xMPUCTRLConst \n"/* r3 = 0xe000ed94 [Location of MPU_CTRL]. */ - " ldr r4, [r3] \n"/* Read the value of MPU_CTRL. */ - " movs r5, #1 \n"/* r5 = 1. */ - " bics r4, r5 \n"/* r4 = r4 & ~r5 i.e. Clear the bit 0 in r4. */ - " str r4, [r3] \n"/* Disable MPU. */ - " \n" - " adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */ - " ldr r4, [r1] \n"/* r4 = *r1 i.e. r4 = MAIR0. */ - " ldr r3, xMAIR0Const \n"/* r3 = 0xe000edc0 [Location of MAIR0]. */ - " str r4, [r3] \n"/* Program MAIR0. */ - " ldr r4, xRNRConst \n"/* r4 = 0xe000ed98 [Location of RNR]. */ - " adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to first RBAR in TCB. */ - " movs r5, #4 \n"/* r5 = 4. */ - " str r5, [r4] \n"/* Program RNR = 4. */ - " ldmia r1!, {r6,r7} \n"/* Read first set of RBAR/RLAR from TCB. */ - " ldr r3, xRBARConst \n"/* r3 = 0xe000ed9c [Location of RBAR]. */ - " stmia r3!, {r6,r7} \n"/* Write first set of RBAR/RLAR registers. */ - " movs r5, #5 \n"/* r5 = 5. */ - " str r5, [r4] \n"/* Program RNR = 5. */ - " ldmia r1!, {r6,r7} \n"/* Read second set of RBAR/RLAR from TCB. */ - " ldr r3, xRBARConst \n"/* r3 = 0xe000ed9c [Location of RBAR]. */ - " stmia r3!, {r6,r7} \n"/* Write second set of RBAR/RLAR registers. */ - " movs r5, #6 \n"/* r5 = 6. */ - " str r5, [r4] \n"/* Program RNR = 6. */ - " ldmia r1!, {r6,r7} \n"/* Read third set of RBAR/RLAR from TCB. */ - " ldr r3, xRBARConst \n"/* r3 = 0xe000ed9c [Location of RBAR]. */ - " stmia r3!, {r6,r7} \n"/* Write third set of RBAR/RLAR registers. */ - " movs r5, #7 \n"/* r5 = 7. */ - " str r5, [r4] \n"/* Program RNR = 7. */ - " ldmia r1!, {r6,r7} \n"/* Read fourth set of RBAR/RLAR from TCB. */ - " ldr r3, xRBARConst \n"/* r3 = 0xe000ed9c [Location of RBAR]. */ - " stmia r3!, {r6,r7} \n"/* Write fourth set of RBAR/RLAR registers. */ - " \n" - " ldr r3, xMPUCTRLConst \n"/* r3 = 0xe000ed94 [Location of MPU_CTRL]. */ - " ldr r4, [r3] \n"/* Read the value of MPU_CTRL. */ - " movs r5, #1 \n"/* r5 = 1. */ - " orrs r4, r5 \n"/* r4 = r4 | r5 i.e. Set the bit 0 in r4. */ - " str r4, [r3] \n"/* Enable MPU. */ - " dsb \n"/* Force memory writes before continuing. */ - #endif /* configENABLE_MPU */ - " \n" - #if ( configENABLE_MPU == 1 ) - " ldmia r2!, {r0, r1, r3, r4} \n"/* Read from stack - r0 = xSecureContext, r1 = PSPLIM, r3 = CONTROL and r4 = LR. */ - " msr psplim, r1 \n"/* Restore the PSPLIM register value for the task. */ - " msr control, r3 \n"/* Restore the CONTROL register value for the task. */ - " mov lr, r4 \n"/* LR = r4. */ - " ldr r3, xSecureContextConst \n"/* Read the location of xSecureContext i.e. &( xSecureContext ). */ - " str r0, [r3] \n"/* Restore the task's xSecureContext. */ - " cbz r0, restore_ns_context \n"/* If there is no secure context for the task, restore the non-secure context. */ - " ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - " ldr r1, [r3] \n"/* Read pxCurrentTCB. */ - " push {r2, r4} \n" - " bl SecureContext_LoadContext \n"/* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ - " pop {r2, r4} \n" - " mov lr, r4 \n"/* LR = r4. */ - " lsls r1, r4, #25 \n"/* r1 = r4 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ - " bpl restore_ns_context \n"/* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ - " msr psp, r2 \n"/* Remember the new top of stack for the task. */ - " bx lr \n" - #else /* configENABLE_MPU */ - " ldmia r2!, {r0, r1, r4} \n"/* Read from stack - r0 = xSecureContext, r1 = PSPLIM and r4 = LR. */ - " msr psplim, r1 \n"/* Restore the PSPLIM register value for the task. */ - " mov lr, r4 \n"/* LR = r4. */ - " ldr r3, xSecureContextConst \n"/* Read the location of xSecureContext i.e. &( xSecureContext ). */ - " str r0, [r3] \n"/* Restore the task's xSecureContext. */ - " cbz r0, restore_ns_context \n"/* If there is no secure context for the task, restore the non-secure context. */ - " ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - " ldr r1, [r3] \n"/* Read pxCurrentTCB. */ - " push {r2, r4} \n" - " bl SecureContext_LoadContext \n"/* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ - " pop {r2, r4} \n" - " mov lr, r4 \n"/* LR = r4. */ - " lsls r1, r4, #25 \n"/* r1 = r4 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ - " bpl restore_ns_context \n"/* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ - " msr psp, r2 \n"/* Remember the new top of stack for the task. */ - " bx lr \n" - #endif /* configENABLE_MPU */ + " ldmia r2!, {r0, r1, r4} \n"/* Read from stack - r0 = xSecureContext, r1 = PSPLIM and r4 = LR. */ + " msr psplim, r1 \n"/* Restore the PSPLIM register value for the task. */ + " mov lr, r4 \n"/* LR = r4. */ + " ldr r3, xSecureContextConst \n"/* Read the location of xSecureContext i.e. &( xSecureContext ). */ + " str r0, [r3] \n"/* Restore the task's xSecureContext. */ + " cbz r0, restore_ns_context \n"/* If there is no secure context for the task, restore the non-secure context. */ + " ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r1, [r3] \n"/* Read pxCurrentTCB. */ + " push {r2, r4} \n" + " bl SecureContext_LoadContext \n"/* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ + " pop {r2, r4} \n" + " mov lr, r4 \n"/* LR = r4. */ + " lsls r1, r4, #25 \n"/* r1 = r4 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ + " bpl restore_ns_context \n"/* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ + " msr psp, r2 \n"/* Remember the new top of stack for the task. */ + " bx lr \n" " \n" " restore_ns_context: \n" " adds r2, r2, #16 \n"/* Move to the high registers. */ @@ -411,16 +527,62 @@ void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ " .align 4 \n" "pxCurrentTCBConst: .word pxCurrentTCB \n" "xSecureContextConst: .word xSecureContext \n" - #if ( configENABLE_MPU == 1 ) - "xMPUCTRLConst: .word 0xe000ed94 \n" - "xMAIR0Const: .word 0xe000edc0 \n" - "xRNRConst: .word 0xe000ed98 \n" - "xRBARConst: .word 0xe000ed9c \n" - #endif /* configENABLE_MPU */ ); } + +#endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + +void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ +{ + __asm volatile + ( + ".syntax unified \n" + ".extern vPortSVCHandler_C \n" + ".extern vSystemCallEnter \n" + ".extern vSystemCallEnter_1 \n" + ".extern vSystemCallExit \n" + " \n" + "movs r0, #4 \n" + "mov r1, lr \n" + "tst r0, r1 \n" + "beq stack_on_msp \n" + "stack_on_psp: \n" + " mrs r0, psp \n" + " b route_svc \n" + "stack_on_msp: \n" + " mrs r0, msp \n" + " b route_svc \n" + " \n" + "route_svc: \n" + " ldr r2, [r0, #24] \n" + " subs r2, #2 \n" + " ldrb r3, [r2, #0] \n" + " cmp r3, %0 \n" + " beq system_call_enter \n" + " cmp r3, %1 \n" + " beq system_call_enter_1 \n" + " cmp r3, %2 \n" + " beq system_call_exit \n" + " b vPortSVCHandler_C \n" + " \n" + "system_call_enter: \n" + " b vSystemCallEnter \n" + "system_call_enter_1: \n" + " b vSystemCallEnter_1 \n" + "system_call_exit: \n" + " b vSystemCallExit \n" + " \n" + : /* No outputs. */ + :"i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_ENTER_1 ), "i" ( portSVC_SYSTEM_CALL_EXIT ) + : "r0", "r1", "r2", "r3", "memory" + ); +} + +#else /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ { __asm volatile @@ -443,6 +605,8 @@ void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ "svchandler_address_const: .word vPortSVCHandler_C \n" ); } + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ /*-----------------------------------------------------------*/ void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) /* __attribute__ (( naked )) */ diff --git a/portable/GCC/ARM_CM23/non_secure/portmacro.h b/portable/GCC/ARM_CM23/non_secure/portmacro.h index 746f734b8ac..5fd94c1c371 100644 --- a/portable/GCC/ARM_CM23/non_secure/portmacro.h +++ b/portable/GCC/ARM_CM23/non_secure/portmacro.h @@ -51,7 +51,6 @@ #define portARCH_NAME "Cortex-M23" #define portHAS_BASEPRI 0 #define portDONT_DISCARD __attribute__( ( used ) ) -#define portNORETURN __attribute__( ( noreturn ) ) /*-----------------------------------------------------------*/ /* ARMv8-M common port configurations. */ diff --git a/portable/GCC/ARM_CM23/non_secure/portmacrocommon.h b/portable/GCC/ARM_CM23/non_secure/portmacrocommon.h index c2ca5fa7730..65ac109c802 100644 --- a/portable/GCC/ARM_CM23/non_secure/portmacrocommon.h +++ b/portable/GCC/ARM_CM23/non_secure/portmacrocommon.h @@ -186,23 +186,120 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #define portMPU_REGION_EXECUTE_NEVER ( 1UL ) /*-----------------------------------------------------------*/ -/** - * @brief Settings to define an MPU region. - */ -typedef struct MPURegionSettings -{ - uint32_t ulRBAR; /**< RBAR for the region. */ - uint32_t ulRLAR; /**< RLAR for the region. */ -} MPURegionSettings_t; +#if ( configENABLE_MPU == 1 ) -/** - * @brief MPU settings as stored in the TCB. - */ -typedef struct MPU_SETTINGS -{ - uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ - MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */ -} xMPU_SETTINGS; + /** + * @brief Settings to define an MPU region. + */ + typedef struct MPURegionSettings + { + uint32_t ulRBAR; /**< RBAR for the region. */ + uint32_t ulRLAR; /**< RLAR for the region. */ + } MPURegionSettings_t; + + #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + + #ifndef configSYSTEM_CALL_STACK_SIZE + #error configSYSTEM_CALL_STACK_SIZE must be defined to the desired size of the system call stack in words for using MPU wrappers v2. + #endif + + /** + * @brief System call stack. + */ + typedef struct SYSTEM_CALL_STACK_INFO + { + uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ]; + uint32_t * pulSystemCallStack; + uint32_t * pulSystemCallStackLimit; + uint32_t * pulTaskStack; + uint32_t ulLinkRegisterAtSystemCallEntry; + uint32_t ulStackLimitRegisterAtSystemCallEntry; + } xSYSTEM_CALL_STACK_INFO; + + #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + + /** + * @brief MPU settings as stored in the TCB. + */ + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + + #if( configENABLE_TRUSTZONE == 1 ) + + /* + * +-----------+---------------+----------+-----------------+------------------------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | + * | | | | PC, xPSR | CONTROL, EXC_RETURN | | + * +-----------+---------------+----------+-----------------+------------------------------+-----+ + * + * <-----------><--------------><---------><----------------><-----------------------------><----> + * 16 16 8 8 5 1 + */ + #define MAX_CONTEXT_SIZE 54 + + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ + + /* + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | + * | | | | PC, xPSR | EXC_RETURN | | + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * + * <-----------><--------------><---------><----------------><---------------------><----> + * 16 16 8 8 4 1 + */ + #define MAX_CONTEXT_SIZE 53 + + #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + + #else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ + + #if( configENABLE_TRUSTZONE == 1 ) + + /* + * +----------+-----------------+------------------------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | + * | | PC, xPSR | CONTROL, EXC_RETURN | | + * +----------+-----------------+------------------------------+-----+ + * + * <---------><----------------><------------------------------><----> + * 8 8 5 1 + */ + #define MAX_CONTEXT_SIZE 22 + + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ + + /* + * +----------+-----------------+----------------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | + * | | PC, xPSR | EXC_RETURN | | + * +----------+-----------------+----------------------+-----+ + * + * <---------><----------------><----------------------><----> + * 8 8 4 1 + */ + #define MAX_CONTEXT_SIZE 21 + + #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + + #endif /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ + + /* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ + #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) + #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) + + typedef struct MPU_SETTINGS + { + uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ + MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */ + uint32_t ulContext[ MAX_CONTEXT_SIZE ]; + uint32_t ulTaskFlags; + + #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo; + #endif + } xMPU_SETTINGS; + +#endif /* configENABLE_MPU == 1 */ /*-----------------------------------------------------------*/ /** @@ -223,6 +320,9 @@ typedef struct MPU_SETTINGS #define portSVC_FREE_SECURE_CONTEXT 1 #define portSVC_START_SCHEDULER 2 #define portSVC_RAISE_PRIVILEGE 3 +#define portSVC_SYSTEM_CALL_ENTER 4 /* System calls with upto 4 parameters. */ +#define portSVC_SYSTEM_CALL_ENTER_1 5 /* System calls with 5 parameters. */ +#define portSVC_SYSTEM_CALL_EXIT 6 /*-----------------------------------------------------------*/ /** @@ -315,6 +415,20 @@ typedef struct MPU_SETTINGS #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ +#if ( configENABLE_MPU == 1 ) + + extern BaseType_t xPortIsTaskPrivileged( void ); + + /** + * @brief Checks whether or not the calling task is privileged. + * + * @return pdTRUE if the calling task is privileged, pdFALSE otherwise. + */ + #define portIS_TASK_PRIVILEGED() xPortIsTaskPrivileged() + +#endif /* configENABLE_MPU == 1 */ +/*-----------------------------------------------------------*/ + /** * @brief Barriers. */ diff --git a/portable/GCC/ARM_CM23_NTZ/non_secure/mpu_wrappers_v2_asm.c b/portable/GCC/ARM_CM23_NTZ/non_secure/mpu_wrappers_v2_asm.c new file mode 100644 index 00000000000..a1e5ce0828f --- /dev/null +++ b/portable/GCC/ARM_CM23_NTZ/non_secure/mpu_wrappers_v2_asm.c @@ -0,0 +1,2419 @@ +/* + * FreeRTOS Kernel + * Copyright (C) 2021 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 + * + */ + +/* 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. */ +#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +/* Scheduler includes. */ +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" +#include "timers.h" +#include "event_groups.h" +#include "stream_buffer.h" + +#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + +#if ( INCLUDE_xTaskDelayUntil == 1 ) + +BaseType_t MPU_xTaskDelayUntil( TickType_t * const pxPreviousWakeTime, + const TickType_t xTimeIncrement ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskDelayUntil( TickType_t * const pxPreviousWakeTime, + const TickType_t xTimeIncrement ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskDelayUntilImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xTaskDelayUntil_Unpriv \n" + " MPU_xTaskDelayUntil_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xTaskDelayUntilImpl \n" + " MPU_xTaskDelayUntil_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xTaskDelayUntilImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_xTaskDelayUntil == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_xTaskAbortDelay == 1 ) + +BaseType_t MPU_xTaskAbortDelay( TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskAbortDelay( TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskAbortDelayImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xTaskAbortDelay_Unpriv \n" + " MPU_xTaskAbortDelay_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xTaskAbortDelayImpl \n" + " MPU_xTaskAbortDelay_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xTaskAbortDelayImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_xTaskAbortDelay == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskDelay == 1 ) + +void MPU_vTaskDelay( const TickType_t xTicksToDelay ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskDelay( const TickType_t xTicksToDelay ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskDelayImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_vTaskDelay_Unpriv \n" + " MPU_vTaskDelay_Priv: \n" + " pop {r0, r1} \n" + " b MPU_vTaskDelayImpl \n" + " MPU_vTaskDelay_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_vTaskDelayImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_vTaskDelay == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_uxTaskPriorityGet == 1 ) + +UBaseType_t MPU_uxTaskPriorityGet( const TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxTaskPriorityGet( const TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxTaskPriorityGetImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_uxTaskPriorityGet_Unpriv \n" + " MPU_uxTaskPriorityGet_Priv: \n" + " pop {r0, r1} \n" + " b MPU_uxTaskPriorityGetImpl \n" + " MPU_uxTaskPriorityGet_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_uxTaskPriorityGetImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_uxTaskPriorityGet == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_eTaskGetState == 1 ) + +eTaskState MPU_eTaskGetState( TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +eTaskState MPU_eTaskGetState( TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_eTaskGetStateImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_eTaskGetState_Unpriv \n" + " MPU_eTaskGetState_Priv: \n" + " pop {r0, r1} \n" + " b MPU_eTaskGetStateImpl \n" + " MPU_eTaskGetState_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_eTaskGetStateImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_eTaskGetState == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + +void MPU_vTaskGetInfo( TaskHandle_t xTask, + TaskStatus_t * pxTaskStatus, + BaseType_t xGetFreeStackSpace, + eTaskState eState ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskGetInfo( TaskHandle_t xTask, + TaskStatus_t * pxTaskStatus, + BaseType_t xGetFreeStackSpace, + eTaskState eState ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskGetInfoImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_vTaskGetInfo_Unpriv \n" + " MPU_vTaskGetInfo_Priv: \n" + " pop {r0, r1} \n" + " b MPU_vTaskGetInfoImpl \n" + " MPU_vTaskGetInfo_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_vTaskGetInfoImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TRACE_FACILITY == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) + +TaskHandle_t MPU_xTaskGetIdleTaskHandle( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TaskHandle_t MPU_xTaskGetIdleTaskHandle( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGetIdleTaskHandleImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xTaskGetIdleTaskHandle_Unpriv \n" + " MPU_xTaskGetIdleTaskHandle_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xTaskGetIdleTaskHandleImpl \n" + " MPU_xTaskGetIdleTaskHandle_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xTaskGetIdleTaskHandleImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskSuspend == 1 ) + +void MPU_vTaskSuspend( TaskHandle_t xTaskToSuspend ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskSuspend( TaskHandle_t xTaskToSuspend ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskSuspendImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_vTaskSuspend_Unpriv \n" + " MPU_vTaskSuspend_Priv: \n" + " pop {r0, r1} \n" + " b MPU_vTaskSuspendImpl \n" + " MPU_vTaskSuspend_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_vTaskSuspendImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_vTaskSuspend == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskSuspend == 1 ) + +void MPU_vTaskResume( TaskHandle_t xTaskToResume ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskResume( TaskHandle_t xTaskToResume ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskResumeImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_vTaskResume_Unpriv \n" + " MPU_vTaskResume_Priv: \n" + " pop {r0, r1} \n" + " b MPU_vTaskResumeImpl \n" + " MPU_vTaskResume_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_vTaskResumeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_vTaskSuspend == 1 ) */ +/*-----------------------------------------------------------*/ + +TickType_t MPU_xTaskGetTickCount( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TickType_t MPU_xTaskGetTickCount( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGetTickCountImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xTaskGetTickCount_Unpriv \n" + " MPU_xTaskGetTickCount_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xTaskGetTickCountImpl \n" + " MPU_xTaskGetTickCount_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xTaskGetTickCountImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +UBaseType_t MPU_uxTaskGetNumberOfTasks( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxTaskGetNumberOfTasks( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxTaskGetNumberOfTasksImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_uxTaskGetNumberOfTasks_Unpriv \n" + " MPU_uxTaskGetNumberOfTasks_Priv: \n" + " pop {r0, r1} \n" + " b MPU_uxTaskGetNumberOfTasksImpl \n" + " MPU_uxTaskGetNumberOfTasks_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_uxTaskGetNumberOfTasksImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +char * MPU_pcTaskGetName( TaskHandle_t xTaskToQuery ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +char * MPU_pcTaskGetName( TaskHandle_t xTaskToQuery ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_pcTaskGetNameImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_pcTaskGetName_Unpriv \n" + " MPU_pcTaskGetName_Priv: \n" + " pop {r0, r1} \n" + " b MPU_pcTaskGetNameImpl \n" + " MPU_pcTaskGetName_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_pcTaskGetNameImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +#if ( configGENERATE_RUN_TIME_STATS == 1 ) + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetRunTimeCounter( const TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetRunTimeCounter( const TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_ulTaskGetRunTimeCounterImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_ulTaskGetRunTimeCounter_Unpriv \n" + " MPU_ulTaskGetRunTimeCounter_Priv: \n" + " pop {r0, r1} \n" + " b MPU_ulTaskGetRunTimeCounterImpl \n" + " MPU_ulTaskGetRunTimeCounter_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_ulTaskGetRunTimeCounterImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( ( configGENERATE_RUN_TIME_STATS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configGENERATE_RUN_TIME_STATS == 1 ) + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetRunTimePercent( const TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetRunTimePercent( const TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_ulTaskGetRunTimePercentImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_ulTaskGetRunTimePercent_Unpriv \n" + " MPU_ulTaskGetRunTimePercent_Priv: \n" + " pop {r0, r1} \n" + " b MPU_ulTaskGetRunTimePercentImpl \n" + " MPU_ulTaskGetRunTimePercent_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_ulTaskGetRunTimePercentImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( ( configGENERATE_RUN_TIME_STATS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimePercent( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimePercent( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_ulTaskGetIdleRunTimePercentImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_ulTaskGetIdleRunTimePercent_Unpriv \n" + " MPU_ulTaskGetIdleRunTimePercent_Priv: \n" + " pop {r0, r1} \n" + " b MPU_ulTaskGetIdleRunTimePercentImpl \n" + " MPU_ulTaskGetIdleRunTimePercent_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_ulTaskGetIdleRunTimePercentImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimeCounter( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimeCounter( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_ulTaskGetIdleRunTimeCounterImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_ulTaskGetIdleRunTimeCounter_Unpriv \n" + " MPU_ulTaskGetIdleRunTimeCounter_Priv: \n" + " pop {r0, r1} \n" + " b MPU_ulTaskGetIdleRunTimeCounterImpl \n" + " MPU_ulTaskGetIdleRunTimeCounter_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_ulTaskGetIdleRunTimeCounterImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_APPLICATION_TASK_TAG == 1 ) + +void MPU_vTaskSetApplicationTaskTag( TaskHandle_t xTask, + TaskHookFunction_t pxHookFunction ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskSetApplicationTaskTag( TaskHandle_t xTask, + TaskHookFunction_t pxHookFunction ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskSetApplicationTaskTagImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_vTaskSetApplicationTaskTag_Unpriv \n" + " MPU_vTaskSetApplicationTaskTag_Priv: \n" + " pop {r0, r1} \n" + " b MPU_vTaskSetApplicationTaskTagImpl \n" + " MPU_vTaskSetApplicationTaskTag_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_vTaskSetApplicationTaskTagImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_APPLICATION_TASK_TAG == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_APPLICATION_TASK_TAG == 1 ) + +TaskHookFunction_t MPU_xTaskGetApplicationTaskTag( TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TaskHookFunction_t MPU_xTaskGetApplicationTaskTag( TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGetApplicationTaskTagImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xTaskGetApplicationTaskTag_Unpriv \n" + " MPU_xTaskGetApplicationTaskTag_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xTaskGetApplicationTaskTagImpl \n" + " MPU_xTaskGetApplicationTaskTag_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xTaskGetApplicationTaskTagImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_APPLICATION_TASK_TAG == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) + +void MPU_vTaskSetThreadLocalStoragePointer( TaskHandle_t xTaskToSet, + BaseType_t xIndex, + void * pvValue ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskSetThreadLocalStoragePointer( TaskHandle_t xTaskToSet, + BaseType_t xIndex, + void * pvValue ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskSetThreadLocalStoragePointerImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_vTaskSetThreadLocalStoragePointer_Unpriv \n" + " MPU_vTaskSetThreadLocalStoragePointer_Priv: \n" + " pop {r0, r1} \n" + " b MPU_vTaskSetThreadLocalStoragePointerImpl \n" + " MPU_vTaskSetThreadLocalStoragePointer_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_vTaskSetThreadLocalStoragePointerImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) + +void * MPU_pvTaskGetThreadLocalStoragePointer( TaskHandle_t xTaskToQuery, + BaseType_t xIndex ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void * MPU_pvTaskGetThreadLocalStoragePointer( TaskHandle_t xTaskToQuery, + BaseType_t xIndex ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_pvTaskGetThreadLocalStoragePointerImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_pvTaskGetThreadLocalStoragePointer_Unpriv \n" + " MPU_pvTaskGetThreadLocalStoragePointer_Priv: \n" + " pop {r0, r1} \n" + " b MPU_pvTaskGetThreadLocalStoragePointerImpl \n" + " MPU_pvTaskGetThreadLocalStoragePointer_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_pvTaskGetThreadLocalStoragePointerImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + +UBaseType_t MPU_uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray, + const UBaseType_t uxArraySize, + configRUN_TIME_COUNTER_TYPE * const pulTotalRunTime ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray, + const UBaseType_t uxArraySize, + configRUN_TIME_COUNTER_TYPE * const pulTotalRunTime ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxTaskGetSystemStateImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_uxTaskGetSystemState_Unpriv \n" + " MPU_uxTaskGetSystemState_Priv: \n" + " pop {r0, r1} \n" + " b MPU_uxTaskGetSystemStateImpl \n" + " MPU_uxTaskGetSystemState_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_uxTaskGetSystemStateImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TRACE_FACILITY == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) + +UBaseType_t MPU_uxTaskGetStackHighWaterMark( TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxTaskGetStackHighWaterMark( TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxTaskGetStackHighWaterMarkImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_uxTaskGetStackHighWaterMark_Unpriv \n" + " MPU_uxTaskGetStackHighWaterMark_Priv: \n" + " pop {r0, r1} \n" + " b MPU_uxTaskGetStackHighWaterMarkImpl \n" + " MPU_uxTaskGetStackHighWaterMark_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_uxTaskGetStackHighWaterMarkImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) + +configSTACK_DEPTH_TYPE MPU_uxTaskGetStackHighWaterMark2( TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +configSTACK_DEPTH_TYPE MPU_uxTaskGetStackHighWaterMark2( TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxTaskGetStackHighWaterMark2Impl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_uxTaskGetStackHighWaterMark2_Unpriv \n" + " MPU_uxTaskGetStackHighWaterMark2_Priv: \n" + " pop {r0, r1} \n" + " b MPU_uxTaskGetStackHighWaterMark2Impl \n" + " MPU_uxTaskGetStackHighWaterMark2_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_uxTaskGetStackHighWaterMark2Impl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) ) + +TaskHandle_t MPU_xTaskGetCurrentTaskHandle( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TaskHandle_t MPU_xTaskGetCurrentTaskHandle( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGetCurrentTaskHandleImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xTaskGetCurrentTaskHandle_Unpriv \n" + " MPU_xTaskGetCurrentTaskHandle_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xTaskGetCurrentTaskHandleImpl \n" + " MPU_xTaskGetCurrentTaskHandle_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xTaskGetCurrentTaskHandleImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_xTaskGetSchedulerState == 1 ) + +BaseType_t MPU_xTaskGetSchedulerState( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskGetSchedulerState( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGetSchedulerStateImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xTaskGetSchedulerState_Unpriv \n" + " MPU_xTaskGetSchedulerState_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xTaskGetSchedulerStateImpl \n" + " MPU_xTaskGetSchedulerState_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xTaskGetSchedulerStateImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_xTaskGetSchedulerState == 1 ) */ +/*-----------------------------------------------------------*/ + +void MPU_vTaskSetTimeOutState( TimeOut_t * const pxTimeOut ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskSetTimeOutState( TimeOut_t * const pxTimeOut ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskSetTimeOutStateImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_vTaskSetTimeOutState_Unpriv \n" + " MPU_vTaskSetTimeOutState_Priv: \n" + " pop {r0, r1} \n" + " b MPU_vTaskSetTimeOutStateImpl \n" + " MPU_vTaskSetTimeOutState_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_vTaskSetTimeOutStateImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut, + TickType_t * const pxTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut, + TickType_t * const pxTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskCheckForTimeOutImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xTaskCheckForTimeOut_Unpriv \n" + " MPU_xTaskCheckForTimeOut_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xTaskCheckForTimeOutImpl \n" + " MPU_xTaskCheckForTimeOut_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xTaskCheckForTimeOutImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +#if ( configUSE_TASK_NOTIFICATIONS == 1 ) + +BaseType_t MPU_xTaskGenericNotify( TaskHandle_t xTaskToNotify, + UBaseType_t uxIndexToNotify, + uint32_t ulValue, + eNotifyAction eAction, + uint32_t * pulPreviousNotificationValue ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskGenericNotify( TaskHandle_t xTaskToNotify, + UBaseType_t uxIndexToNotify, + uint32_t ulValue, + eNotifyAction eAction, + uint32_t * pulPreviousNotificationValue ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGenericNotifyImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xTaskGenericNotify_Unpriv \n" + " MPU_xTaskGenericNotify_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xTaskGenericNotifyImpl \n" + " MPU_xTaskGenericNotify_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xTaskGenericNotifyImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER_1 ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TASK_NOTIFICATIONS == 1 ) + +BaseType_t MPU_xTaskGenericNotifyWait( UBaseType_t uxIndexToWaitOn, + uint32_t ulBitsToClearOnEntry, + uint32_t ulBitsToClearOnExit, + uint32_t * pulNotificationValue, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskGenericNotifyWait( UBaseType_t uxIndexToWaitOn, + uint32_t ulBitsToClearOnEntry, + uint32_t ulBitsToClearOnExit, + uint32_t * pulNotificationValue, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGenericNotifyWaitImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xTaskGenericNotifyWait_Unpriv \n" + " MPU_xTaskGenericNotifyWait_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xTaskGenericNotifyWaitImpl \n" + " MPU_xTaskGenericNotifyWait_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xTaskGenericNotifyWaitImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER_1 ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TASK_NOTIFICATIONS == 1 ) + +uint32_t MPU_ulTaskGenericNotifyTake( UBaseType_t uxIndexToWaitOn, + BaseType_t xClearCountOnExit, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +uint32_t MPU_ulTaskGenericNotifyTake( UBaseType_t uxIndexToWaitOn, + BaseType_t xClearCountOnExit, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_ulTaskGenericNotifyTakeImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_ulTaskGenericNotifyTake_Unpriv \n" + " MPU_ulTaskGenericNotifyTake_Priv: \n" + " pop {r0, r1} \n" + " b MPU_ulTaskGenericNotifyTakeImpl \n" + " MPU_ulTaskGenericNotifyTake_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_ulTaskGenericNotifyTakeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TASK_NOTIFICATIONS == 1 ) + +BaseType_t MPU_xTaskGenericNotifyStateClear( TaskHandle_t xTask, + UBaseType_t uxIndexToClear ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskGenericNotifyStateClear( TaskHandle_t xTask, + UBaseType_t uxIndexToClear ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGenericNotifyStateClearImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xTaskGenericNotifyStateClear_Unpriv \n" + " MPU_xTaskGenericNotifyStateClear_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xTaskGenericNotifyStateClearImpl \n" + " MPU_xTaskGenericNotifyStateClear_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xTaskGenericNotifyStateClearImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TASK_NOTIFICATIONS == 1 ) + +uint32_t MPU_ulTaskGenericNotifyValueClear( TaskHandle_t xTask, + UBaseType_t uxIndexToClear, + uint32_t ulBitsToClear ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +uint32_t MPU_ulTaskGenericNotifyValueClear( TaskHandle_t xTask, + UBaseType_t uxIndexToClear, + uint32_t ulBitsToClear ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_ulTaskGenericNotifyValueClearImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_ulTaskGenericNotifyValueClear_Unpriv \n" + " MPU_ulTaskGenericNotifyValueClear_Priv: \n" + " pop {r0, r1} \n" + " b MPU_ulTaskGenericNotifyValueClearImpl \n" + " MPU_ulTaskGenericNotifyValueClear_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_ulTaskGenericNotifyValueClearImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xQueueGenericSend( QueueHandle_t xQueue, + const void * const pvItemToQueue, + TickType_t xTicksToWait, + const BaseType_t xCopyPosition ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueueGenericSend( QueueHandle_t xQueue, + const void * const pvItemToQueue, + TickType_t xTicksToWait, + const BaseType_t xCopyPosition ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueGenericSendImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xQueueGenericSend_Unpriv \n" + " MPU_xQueueGenericSend_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xQueueGenericSendImpl \n" + " MPU_xQueueGenericSend_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xQueueGenericSendImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +UBaseType_t MPU_uxQueueMessagesWaiting( const QueueHandle_t xQueue ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxQueueMessagesWaiting( const QueueHandle_t xQueue ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxQueueMessagesWaitingImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_uxQueueMessagesWaiting_Unpriv \n" + " MPU_uxQueueMessagesWaiting_Priv: \n" + " pop {r0, r1} \n" + " b MPU_uxQueueMessagesWaitingImpl \n" + " MPU_uxQueueMessagesWaiting_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_uxQueueMessagesWaitingImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +UBaseType_t MPU_uxQueueSpacesAvailable( const QueueHandle_t xQueue ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxQueueSpacesAvailable( const QueueHandle_t xQueue ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxQueueSpacesAvailableImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_uxQueueSpacesAvailable_Unpriv \n" + " MPU_uxQueueSpacesAvailable_Priv: \n" + " pop {r0, r1} \n" + " b MPU_uxQueueSpacesAvailableImpl \n" + " MPU_uxQueueSpacesAvailable_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_uxQueueSpacesAvailableImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xQueueReceive( QueueHandle_t xQueue, + void * const pvBuffer, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueueReceive( QueueHandle_t xQueue, + void * const pvBuffer, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueReceiveImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xQueueReceive_Unpriv \n" + " MPU_xQueueReceive_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xQueueReceiveImpl \n" + " MPU_xQueueReceive_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xQueueReceiveImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xQueuePeek( QueueHandle_t xQueue, + void * const pvBuffer, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueuePeek( QueueHandle_t xQueue, + void * const pvBuffer, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueuePeekImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xQueuePeek_Unpriv \n" + " MPU_xQueuePeek_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xQueuePeekImpl \n" + " MPU_xQueuePeek_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xQueuePeekImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xQueueSemaphoreTake( QueueHandle_t xQueue, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueueSemaphoreTake( QueueHandle_t xQueue, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueSemaphoreTakeImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xQueueSemaphoreTake_Unpriv \n" + " MPU_xQueueSemaphoreTake_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xQueueSemaphoreTakeImpl \n" + " MPU_xQueueSemaphoreTake_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xQueueSemaphoreTakeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +#if ( ( configUSE_MUTEXES == 1 ) && ( INCLUDE_xSemaphoreGetMutexHolder == 1 ) ) + +TaskHandle_t MPU_xQueueGetMutexHolder( QueueHandle_t xSemaphore ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TaskHandle_t MPU_xQueueGetMutexHolder( QueueHandle_t xSemaphore ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueGetMutexHolderImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xQueueGetMutexHolder_Unpriv \n" + " MPU_xQueueGetMutexHolder_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xQueueGetMutexHolderImpl \n" + " MPU_xQueueGetMutexHolder_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xQueueGetMutexHolderImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( ( configUSE_MUTEXES == 1 ) && ( INCLUDE_xSemaphoreGetMutexHolder == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_RECURSIVE_MUTEXES == 1 ) + +BaseType_t MPU_xQueueTakeMutexRecursive( QueueHandle_t xMutex, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueueTakeMutexRecursive( QueueHandle_t xMutex, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueTakeMutexRecursiveImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xQueueTakeMutexRecursive_Unpriv \n" + " MPU_xQueueTakeMutexRecursive_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xQueueTakeMutexRecursiveImpl \n" + " MPU_xQueueTakeMutexRecursive_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xQueueTakeMutexRecursiveImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_RECURSIVE_MUTEXES == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_RECURSIVE_MUTEXES == 1 ) + +BaseType_t MPU_xQueueGiveMutexRecursive( QueueHandle_t pxMutex ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueueGiveMutexRecursive( QueueHandle_t pxMutex ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueGiveMutexRecursiveImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xQueueGiveMutexRecursive_Unpriv \n" + " MPU_xQueueGiveMutexRecursive_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xQueueGiveMutexRecursiveImpl \n" + " MPU_xQueueGiveMutexRecursive_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xQueueGiveMutexRecursiveImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_RECURSIVE_MUTEXES == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_QUEUE_SETS == 1 ) + +QueueSetMemberHandle_t MPU_xQueueSelectFromSet( QueueSetHandle_t xQueueSet, + const TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +QueueSetMemberHandle_t MPU_xQueueSelectFromSet( QueueSetHandle_t xQueueSet, + const TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueSelectFromSetImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xQueueSelectFromSet_Unpriv \n" + " MPU_xQueueSelectFromSet_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xQueueSelectFromSetImpl \n" + " MPU_xQueueSelectFromSet_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xQueueSelectFromSetImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_QUEUE_SETS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_QUEUE_SETS == 1 ) + +BaseType_t MPU_xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore, + QueueSetHandle_t xQueueSet ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore, + QueueSetHandle_t xQueueSet ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueAddToSetImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xQueueAddToSet_Unpriv \n" + " MPU_xQueueAddToSet_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xQueueAddToSetImpl \n" + " MPU_xQueueAddToSet_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xQueueAddToSetImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_QUEUE_SETS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configQUEUE_REGISTRY_SIZE > 0 ) + +void MPU_vQueueAddToRegistry( QueueHandle_t xQueue, + const char * pcName ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vQueueAddToRegistry( QueueHandle_t xQueue, + const char * pcName ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vQueueAddToRegistryImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_vQueueAddToRegistry_Unpriv \n" + " MPU_vQueueAddToRegistry_Priv: \n" + " pop {r0, r1} \n" + " b MPU_vQueueAddToRegistryImpl \n" + " MPU_vQueueAddToRegistry_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_vQueueAddToRegistryImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configQUEUE_REGISTRY_SIZE > 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configQUEUE_REGISTRY_SIZE > 0 ) + +void MPU_vQueueUnregisterQueue( QueueHandle_t xQueue ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vQueueUnregisterQueue( QueueHandle_t xQueue ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vQueueUnregisterQueueImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_vQueueUnregisterQueue_Unpriv \n" + " MPU_vQueueUnregisterQueue_Priv: \n" + " pop {r0, r1} \n" + " b MPU_vQueueUnregisterQueueImpl \n" + " MPU_vQueueUnregisterQueue_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_vQueueUnregisterQueueImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configQUEUE_REGISTRY_SIZE > 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configQUEUE_REGISTRY_SIZE > 0 ) + +const char * MPU_pcQueueGetName( QueueHandle_t xQueue ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +const char * MPU_pcQueueGetName( QueueHandle_t xQueue ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_pcQueueGetNameImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_pcQueueGetName_Unpriv \n" + " MPU_pcQueueGetName_Priv: \n" + " pop {r0, r1} \n" + " b MPU_pcQueueGetNameImpl \n" + " MPU_pcQueueGetName_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_pcQueueGetNameImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configQUEUE_REGISTRY_SIZE > 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +void * MPU_pvTimerGetTimerID( const TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void * MPU_pvTimerGetTimerID( const TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_pvTimerGetTimerIDImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_pvTimerGetTimerID_Unpriv \n" + " MPU_pvTimerGetTimerID_Priv: \n" + " pop {r0, r1} \n" + " b MPU_pvTimerGetTimerIDImpl \n" + " MPU_pvTimerGetTimerID_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_pvTimerGetTimerIDImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +void MPU_vTimerSetTimerID( TimerHandle_t xTimer, + void * pvNewID ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTimerSetTimerID( TimerHandle_t xTimer, + void * pvNewID ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTimerSetTimerIDImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_vTimerSetTimerID_Unpriv \n" + " MPU_vTimerSetTimerID_Priv: \n" + " pop {r0, r1} \n" + " b MPU_vTimerSetTimerIDImpl \n" + " MPU_vTimerSetTimerID_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_vTimerSetTimerIDImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +BaseType_t MPU_xTimerIsTimerActive( TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTimerIsTimerActive( TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTimerIsTimerActiveImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xTimerIsTimerActive_Unpriv \n" + " MPU_xTimerIsTimerActive_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xTimerIsTimerActiveImpl \n" + " MPU_xTimerIsTimerActive_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xTimerIsTimerActiveImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +TaskHandle_t MPU_xTimerGetTimerDaemonTaskHandle( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TaskHandle_t MPU_xTimerGetTimerDaemonTaskHandle( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTimerGetTimerDaemonTaskHandleImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xTimerGetTimerDaemonTaskHandle_Unpriv \n" + " MPU_xTimerGetTimerDaemonTaskHandle_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xTimerGetTimerDaemonTaskHandleImpl \n" + " MPU_xTimerGetTimerDaemonTaskHandle_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xTimerGetTimerDaemonTaskHandleImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +BaseType_t MPU_xTimerGenericCommand( TimerHandle_t xTimer, + const BaseType_t xCommandID, + const TickType_t xOptionalValue, + BaseType_t * const pxHigherPriorityTaskWoken, + const TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTimerGenericCommand( TimerHandle_t xTimer, + const BaseType_t xCommandID, + const TickType_t xOptionalValue, + BaseType_t * const pxHigherPriorityTaskWoken, + const TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTimerGenericCommandImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, ipsr \n" + " cmp r0, #0 \n" + " bne MPU_xTimerGenericCommand_Priv \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " beq MPU_xTimerGenericCommand_Priv \n" + " MPU_xTimerGenericCommand_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xTimerGenericCommandImpl \n" + " svc %1 \n" + " bx lr \n" + " MPU_xTimerGenericCommand_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xTimerGenericCommandImpl \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER_1 ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +const char * MPU_pcTimerGetName( TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +const char * MPU_pcTimerGetName( TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_pcTimerGetNameImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_pcTimerGetName_Unpriv \n" + " MPU_pcTimerGetName_Priv: \n" + " pop {r0, r1} \n" + " b MPU_pcTimerGetNameImpl \n" + " MPU_pcTimerGetName_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_pcTimerGetNameImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, + const BaseType_t uxAutoReload ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, + const BaseType_t uxAutoReload ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTimerSetReloadModeImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_vTimerSetReloadMode_Unpriv \n" + " MPU_vTimerSetReloadMode_Priv: \n" + " pop {r0, r1} \n" + " b MPU_vTimerSetReloadModeImpl \n" + " MPU_vTimerSetReloadMode_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_vTimerSetReloadModeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +BaseType_t MPU_xTimerGetReloadMode( TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTimerGetReloadMode( TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTimerGetReloadModeImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xTimerGetReloadMode_Unpriv \n" + " MPU_xTimerGetReloadMode_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xTimerGetReloadModeImpl \n" + " MPU_xTimerGetReloadMode_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xTimerGetReloadModeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +UBaseType_t MPU_uxTimerGetReloadMode( TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxTimerGetReloadMode( TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxTimerGetReloadModeImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_uxTimerGetReloadMode_Unpriv \n" + " MPU_uxTimerGetReloadMode_Priv: \n" + " pop {r0, r1} \n" + " b MPU_uxTimerGetReloadModeImpl \n" + " MPU_uxTimerGetReloadMode_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_uxTimerGetReloadModeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +TickType_t MPU_xTimerGetPeriod( TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TickType_t MPU_xTimerGetPeriod( TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTimerGetPeriodImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xTimerGetPeriod_Unpriv \n" + " MPU_xTimerGetPeriod_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xTimerGetPeriodImpl \n" + " MPU_xTimerGetPeriod_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xTimerGetPeriodImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +TickType_t MPU_xTimerGetExpiryTime( TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TickType_t MPU_xTimerGetExpiryTime( TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTimerGetExpiryTimeImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xTimerGetExpiryTime_Unpriv \n" + " MPU_xTimerGetExpiryTime_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xTimerGetExpiryTimeImpl \n" + " MPU_xTimerGetExpiryTime_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xTimerGetExpiryTimeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +EventBits_t MPU_xEventGroupWaitBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToWaitFor, + const BaseType_t xClearOnExit, + const BaseType_t xWaitForAllBits, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +EventBits_t MPU_xEventGroupWaitBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToWaitFor, + const BaseType_t xClearOnExit, + const BaseType_t xWaitForAllBits, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupWaitBitsImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xEventGroupWaitBits_Unpriv \n" + " MPU_xEventGroupWaitBits_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xEventGroupWaitBitsImpl \n" + " MPU_xEventGroupWaitBits_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xEventGroupWaitBitsImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER_1 ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToClear ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToClear ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupClearBitsImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xEventGroupClearBits_Unpriv \n" + " MPU_xEventGroupClearBits_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xEventGroupClearBitsImpl \n" + " MPU_xEventGroupClearBits_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xEventGroupClearBitsImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupSetBitsImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xEventGroupSetBits_Unpriv \n" + " MPU_xEventGroupSetBits_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xEventGroupSetBitsImpl \n" + " MPU_xEventGroupSetBits_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xEventGroupSetBitsImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet, + const EventBits_t uxBitsToWaitFor, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet, + const EventBits_t uxBitsToWaitFor, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupSyncImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xEventGroupSync_Unpriv \n" + " MPU_xEventGroupSync_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xEventGroupSyncImpl \n" + " MPU_xEventGroupSync_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xEventGroupSyncImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + +UBaseType_t MPU_uxEventGroupGetNumber( void * xEventGroup ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxEventGroupGetNumber( void * xEventGroup ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxEventGroupGetNumberImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_uxEventGroupGetNumber_Unpriv \n" + " MPU_uxEventGroupGetNumber_Priv: \n" + " pop {r0, r1} \n" + " b MPU_uxEventGroupGetNumberImpl \n" + " MPU_uxEventGroupGetNumber_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_uxEventGroupGetNumberImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /*( configUSE_TRACE_FACILITY == 1 )*/ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + +void MPU_vEventGroupSetNumber( void * xEventGroup, + UBaseType_t uxEventGroupNumber ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vEventGroupSetNumber( void * xEventGroup, + UBaseType_t uxEventGroupNumber ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vEventGroupSetNumberImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_vEventGroupSetNumber_Unpriv \n" + " MPU_vEventGroupSetNumber_Priv: \n" + " pop {r0, r1} \n" + " b MPU_vEventGroupSetNumberImpl \n" + " MPU_vEventGroupSetNumber_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_vEventGroupSetNumberImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /*( configUSE_TRACE_FACILITY == 1 )*/ +/*-----------------------------------------------------------*/ + +size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, + const void * pvTxData, + size_t xDataLengthBytes, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, + const void * pvTxData, + size_t xDataLengthBytes, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferSendImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xStreamBufferSend_Unpriv \n" + " MPU_xStreamBufferSend_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xStreamBufferSendImpl \n" + " MPU_xStreamBufferSend_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xStreamBufferSendImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, + void * pvRxData, + size_t xBufferLengthBytes, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, + void * pvRxData, + size_t xBufferLengthBytes, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferReceiveImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xStreamBufferReceive_Unpriv \n" + " MPU_xStreamBufferReceive_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xStreamBufferReceiveImpl \n" + " MPU_xStreamBufferReceive_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xStreamBufferReceiveImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferIsFullImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xStreamBufferIsFull_Unpriv \n" + " MPU_xStreamBufferIsFull_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xStreamBufferIsFullImpl \n" + " MPU_xStreamBufferIsFull_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xStreamBufferIsFullImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferIsEmptyImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xStreamBufferIsEmpty_Unpriv \n" + " MPU_xStreamBufferIsEmpty_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xStreamBufferIsEmptyImpl \n" + " MPU_xStreamBufferIsEmpty_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xStreamBufferIsEmptyImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferSpacesAvailableImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xStreamBufferSpacesAvailable_Unpriv \n" + " MPU_xStreamBufferSpacesAvailable_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xStreamBufferSpacesAvailableImpl \n" + " MPU_xStreamBufferSpacesAvailable_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xStreamBufferSpacesAvailableImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferBytesAvailableImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xStreamBufferBytesAvailable_Unpriv \n" + " MPU_xStreamBufferBytesAvailable_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xStreamBufferBytesAvailableImpl \n" + " MPU_xStreamBufferBytesAvailable_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xStreamBufferBytesAvailableImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, + size_t xTriggerLevel ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, + size_t xTriggerLevel ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferSetTriggerLevelImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xStreamBufferSetTriggerLevel_Unpriv \n" + " MPU_xStreamBufferSetTriggerLevel_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xStreamBufferSetTriggerLevelImpl \n" + " MPU_xStreamBufferSetTriggerLevel_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xStreamBufferSetTriggerLevelImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferNextMessageLengthBytesImpl \n" + " \n" + " push {r0, r1} \n" + " mrs r0, control \n" + " movs r1, #1 \n" + " tst r0, r1 \n" + " bne MPU_xStreamBufferNextMessageLengthBytes_Unpriv \n" + " MPU_xStreamBufferNextMessageLengthBytes_Priv: \n" + " pop {r0, r1} \n" + " b MPU_xStreamBufferNextMessageLengthBytesImpl \n" + " MPU_xStreamBufferNextMessageLengthBytes_Unpriv: \n" + " pop {r0, r1} \n" + " svc %0 \n" + " bl MPU_xStreamBufferNextMessageLengthBytesImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ diff --git a/portable/GCC/ARM_CM23_NTZ/non_secure/port.c b/portable/GCC/ARM_CM23_NTZ/non_secure/port.c index 7bbe1b7bc53..cab1b3668bf 100644 --- a/portable/GCC/ARM_CM23_NTZ/non_secure/port.c +++ b/portable/GCC/ARM_CM23_NTZ/non_secure/port.c @@ -107,6 +107,13 @@ #define portPRIGROUP_SHIFT ( 8UL ) /*-----------------------------------------------------------*/ +/** + * @brief Constants used during system call enter and exit. + */ +#define portPSR_STACK_PADDING_MASK ( 1UL << 9UL ) +#define portEXC_RETURN_STACK_FRAME_TYPE_MASK ( 1UL << 4UL ) +/*-----------------------------------------------------------*/ + /** * @brief Constants required to manipulate the FPU. */ @@ -123,6 +130,14 @@ #define portFPCCR_LSPEN_MASK ( 1UL << portFPCCR_LSPEN_POS ) /*-----------------------------------------------------------*/ +/** + * @brief Offsets in the stack to the parameters when inside the SVC handler. + */ +#define portOFFSET_TO_LR ( 5 ) +#define portOFFSET_TO_PC ( 6 ) +#define portOFFSET_TO_PSR ( 7 ) +/*-----------------------------------------------------------*/ + /** * @brief Constants required to manipulate the MPU. */ @@ -148,6 +163,8 @@ #define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ #define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ +#define portMPU_RBAR_ACCESS_PERMISSIONS_MASK ( 3UL << 1UL ) + #define portMPU_MAIR_ATTR0_POS ( 0UL ) #define portMPU_MAIR_ATTR0_MASK ( 0x000000ff ) @@ -191,6 +208,30 @@ /* Expected value of the portMPU_TYPE register. */ #define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) + +/* Extract first address of the MPU region as encoded in the + * RBAR (Region Base Address Register) value. */ +#define portEXTRACT_FIRST_ADDRESS_FROM_RBAR( rbar ) \ + ( ( rbar ) & portMPU_RBAR_ADDRESS_MASK ) + +/* Extract last address of the MPU region as encoded in the + * RLAR (Region Limit Address Register) value. */ +#define portEXTRACT_LAST_ADDRESS_FROM_RLAR( rlar ) \ + ( ( ( rlar ) & portMPU_RLAR_ADDRESS_MASK ) | ~portMPU_RLAR_ADDRESS_MASK ) + +/* Does addr lies within [start, end] address range? */ +#define portIS_ADDRESS_WITHIN_RANGE( addr, start, end ) \ + ( ( ( addr ) >= ( start ) ) && ( ( addr ) <= ( end ) ) ) + +/* Is the access request satisfied by the available permissions? */ +#define portIS_AUTHORIZED( accessRequest, permissions ) \ + ( ( ( permissions ) & ( accessRequest ) ) == accessRequest ) + +/* 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 ) ) ) /*-----------------------------------------------------------*/ /** @@ -311,6 +352,19 @@ static void prvTaskExitError( void ); #if ( configENABLE_MPU == 1 ) +/** + * @brief Extract MPU region's access permissions from the Region Base Address + * Register (RBAR) value. + * + * @param ulRBARValue RBAR value for the MPU region. + * + * @return uint32_t Access permissions. + */ + static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) PRIVILEGED_FUNCTION; +#endif /* configENABLE_MPU */ + +#if ( configENABLE_MPU == 1 ) + /** * @brief Setup the Memory Protection Unit (MPU). */ @@ -365,6 +419,60 @@ void SysTick_Handler( void ) PRIVILEGED_FUNCTION; * @brief C part of SVC handler. */ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIVILEGED_FUNCTION; + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + + /** + * @brief Sets up the system call stack so that upon returning from + * SVC, the system call stack is used. + * + * It is used for the system calls with up to 4 parameters. + * + * @param pulTaskStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + */ + void vSystemCallEnter( uint32_t * pulTaskStack, uint32_t ulLR ) PRIVILEGED_FUNCTION; + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + + /** + * @brief Sets up the system call stack so that upon returning from + * SVC, the system call stack is used. + * + * It is used for the system calls with 5 parameters. + * + * @param pulTaskStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + */ + void vSystemCallEnter_1( uint32_t * pulTaskStack, uint32_t ulLR ) PRIVILEGED_FUNCTION; + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + + /** + * @brief Sets up the task stack so that upon returning from + * SVC, the task stack is used again. + * + * @param pulSystemCallStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + */ + void vSystemCallExit( uint32_t * pulSystemCallStack, uint32_t ulLR ) PRIVILEGED_FUNCTION; + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + +#if ( configENABLE_MPU == 1 ) + + /** + * @brief Checks whether or not the calling task is privileged. + * + * @return pdTRUE if the calling task is privileged, pdFALSE otherwise. + */ + BaseType_t xPortIsTaskPrivileged( void ) PRIVILEGED_FUNCTION; + +#endif /* configENABLE_MPU == 1 */ /*-----------------------------------------------------------*/ /** @@ -681,6 +789,26 @@ static void prvTaskExitError( void ) } /*-----------------------------------------------------------*/ +#if ( configENABLE_MPU == 1 ) + static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) /* PRIVILEGED_FUNCTION */ + { + uint32_t ulAccessPermissions = 0; + + if( ( ulRBARValue & portMPU_RBAR_ACCESS_PERMISSIONS_MASK ) == portMPU_REGION_READ_ONLY ) + { + ulAccessPermissions = tskMPU_READ_PERMISSION; + } + + if( ( ulRBARValue & portMPU_RBAR_ACCESS_PERMISSIONS_MASK ) == portMPU_REGION_READ_WRITE ) + { + ulAccessPermissions = ( tskMPU_READ_PERMISSION | tskMPU_WRITE_PERMISSION ); + } + + return ulAccessPermissions; + } +#endif /* configENABLE_MPU */ +/*-----------------------------------------------------------*/ + #if ( configENABLE_MPU == 1 ) static void prvSetupMPU( void ) /* PRIVILEGED_FUNCTION */ { @@ -853,7 +981,7 @@ void SysTick_Handler( void ) /* PRIVILEGED_FUNCTION */ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTION portDONT_DISCARD */ { - #if ( configENABLE_MPU == 1 ) + #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) ) #if defined( __ARMCC_VERSION ) /* Declaration when these variable are defined in code instead of being @@ -865,7 +993,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO extern uint32_t __syscalls_flash_start__[]; extern uint32_t __syscalls_flash_end__[]; #endif /* defined( __ARMCC_VERSION ) */ - #endif /* configENABLE_MPU */ + #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */ uint32_t ulPC; @@ -880,7 +1008,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO /* Register are stored on the stack in the following order - R0, R1, R2, R3, * R12, LR, PC, xPSR. */ - ulPC = pulCallerStackAddress[ 6 ]; + ulPC = pulCallerStackAddress[ portOFFSET_TO_PC ]; ucSVCNumber = ( ( uint8_t * ) ulPC )[ -2 ]; switch( ucSVCNumber ) @@ -951,18 +1079,18 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO vRestoreContextOfFirstTask(); break; - #if ( configENABLE_MPU == 1 ) - case portSVC_RAISE_PRIVILEGE: + #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) ) + case portSVC_RAISE_PRIVILEGE: - /* Only raise the privilege, if the svc was raised from any of - * the system calls. */ - if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) && - ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ) - { - vRaisePrivilege(); - } - break; - #endif /* configENABLE_MPU */ + /* Only raise the privilege, if the svc was raised from any of + * the system calls. */ + if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ) + { + vRaisePrivilege(); + } + break; + #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */ default: /* Incorrect SVC call. */ @@ -971,51 +1099,455 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } /*-----------------------------------------------------------*/ -/* *INDENT-OFF* */ -#if ( configENABLE_MPU == 1 ) - StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, - StackType_t * pxEndOfStack, - TaskFunction_t pxCode, - void * pvParameters, - BaseType_t xRunPrivileged ) /* PRIVILEGED_FUNCTION */ -#else - StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, - StackType_t * pxEndOfStack, - TaskFunction_t pxCode, - void * pvParameters ) /* PRIVILEGED_FUNCTION */ -#endif /* configENABLE_MPU */ -/* *INDENT-ON* */ +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + +void vSystemCallEnter( uint32_t * pulTaskStack, uint32_t ulLR ) /* PRIVILEGED_FUNCTION */ { - /* Simulate the stack frame as it would be created by a context switch - * interrupt. */ - #if ( portPRELOAD_REGISTERS == 0 ) + extern TaskHandle_t pxCurrentTCB; + xMPU_SETTINGS * pxMpuSettings; + uint32_t * pulSystemCallStack; + uint32_t ulStackFrameSize, ulSystemCallLocation, i; + #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being + * exported from linker scripts. */ + extern uint32_t * __syscalls_flash_start__; + extern uint32_t * __syscalls_flash_end__; + #else + /* Declaration when these variable are exported from linker scripts. */ + extern uint32_t __syscalls_flash_start__[]; + extern uint32_t __syscalls_flash_end__[]; + #endif /* #if defined( __ARMCC_VERSION ) */ + + ulSystemCallLocation = pulTaskStack[ portOFFSET_TO_PC ]; + + /* If the request did not come from the system call section, do nothing. */ + if( ( ulSystemCallLocation >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulSystemCallLocation <= ( uint32_t ) __syscalls_flash_end__ ) ) { - pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ - *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ - pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pxCode; /* PC */ - pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR */ - pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ - *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ - pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */ - *pxTopOfStack = portINITIAL_EXC_RETURN; + pxMpuSettings = xTaskGetMPUSettings( pxCurrentTCB ); + pulSystemCallStack = pxMpuSettings->xSystemCallStackInfo.pulSystemCallStack; - #if ( configENABLE_MPU == 1 ) + /* This is not NULL only for the duration of the system call. */ + configASSERT( pxMpuSettings->xSystemCallStackInfo.pulTaskStack == NULL ); + + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) { - pxTopOfStack--; + if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) + { + /* Extended frame i.e. FPU in use. */ + ulStackFrameSize = 26; + __asm volatile ( + " vpush {s0} \n" /* Trigger lazy stacking. */ + " vpop {s0} \n" /* Nullify the affect of the above instruction. */ + ::: "memory" + ); + } + else + { + /* Standard frame i.e. FPU not in use. */ + ulStackFrameSize = 8; + } + } + #else + { + ulStackFrameSize = 8; + } + #endif /* configENABLE_FPU || configENABLE_MVE */ + + /* Make space on the system call stack for the stack frame. */ + pulSystemCallStack = pulSystemCallStack - ulStackFrameSize; + + /* Copy the stack frame. */ + for( i = 0; i < ulStackFrameSize; i++ ) + { + pulSystemCallStack[ i ] = pulTaskStack[ i ]; + } + + /* Store the value of the LR and PSPLIM registers before the SVC was raised. We need to + * restore it when we exit from the system call. */ + pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; + __asm volatile ( "mrs %0, psplim" : "=r" ( pxMpuSettings->xSystemCallStackInfo.ulStackLimitRegisterAtSystemCallEntry ) ); + + /* Use the pulSystemCallStack in thread mode. */ + __asm volatile ( "msr psp, %0" : : "r" ( pulSystemCallStack ) ); + __asm volatile ( "msr psplim, %0" : : "r" ( pxMpuSettings->xSystemCallStackInfo.pulSystemCallStackLimit ) ); + + /* Remember the location where we should copy the stack frame when we exit from + * the system call. */ + pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulStackFrameSize; + + /* Record if the hardware used padding to force the stack pointer + * to be double word aligned. */ + if( ( pulTaskStack[ portOFFSET_TO_PSR ] & portPSR_STACK_PADDING_MASK ) == portPSR_STACK_PADDING_MASK ) + { + pxMpuSettings->ulTaskFlags |= portSTACK_FRAME_HAS_PADDING_FLAG; + } + else + { + pxMpuSettings->ulTaskFlags &= ( ~portSTACK_FRAME_HAS_PADDING_FLAG ); + } + + /* We ensure in pxPortInitialiseStack that the system call stack is + * double word aligned and therefore, there is no need of padding. + * Clear the bit[9] of stacked xPSR. */ + pulSystemCallStack[ portOFFSET_TO_PSR ] &= ( ~portPSR_STACK_PADDING_MASK ); + + /* Raise the privilege for the duration of the system call. */ + __asm volatile ( + " mrs r0, control \n" /* Obtain current control value. */ + " movs r1, #1 \n" /* r1 = 1. */ + " bics r0, r1 \n" /* Clear nPRIV bit. */ + " msr control, r0 \n" /* Write back new control value. */ + ::: "r0", "r1", "memory" + ); + } +} - if( xRunPrivileged == pdTRUE ) +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + +void vSystemCallEnter_1( uint32_t * pulTaskStack, uint32_t ulLR ) /* PRIVILEGED_FUNCTION */ +{ + extern TaskHandle_t pxCurrentTCB; + xMPU_SETTINGS * pxMpuSettings; + uint32_t * pulSystemCallStack; + uint32_t ulStackFrameSize, ulSystemCallLocation, i; + #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being + * exported from linker scripts. */ + extern uint32_t * __syscalls_flash_start__; + extern uint32_t * __syscalls_flash_end__; + #else + /* Declaration when these variable are exported from linker scripts. */ + extern uint32_t __syscalls_flash_start__[]; + extern uint32_t __syscalls_flash_end__[]; + #endif /* #if defined( __ARMCC_VERSION ) */ + + ulSystemCallLocation = pulTaskStack[ portOFFSET_TO_PC ]; + + /* If the request did not come from the system call section, do nothing. */ + if( ( ulSystemCallLocation >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulSystemCallLocation <= ( uint32_t ) __syscalls_flash_end__ ) ) + { + pxMpuSettings = xTaskGetMPUSettings( pxCurrentTCB ); + pulSystemCallStack = pxMpuSettings->xSystemCallStackInfo.pulSystemCallStack; + + /* This is not NULL only for the duration of the system call. */ + configASSERT( pxMpuSettings->xSystemCallStackInfo.pulTaskStack == NULL ); + + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + { + if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) { - *pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */ + /* Extended frame i.e. FPU in use. */ + ulStackFrameSize = 26; + __asm volatile ( + " vpush {s0} \n" /* Trigger lazy stacking. */ + " vpop {s0} \n" /* Nullify the affect of the above instruction. */ + ::: "memory" + ); } else { - *pxTopOfStack = portINITIAL_CONTROL_UNPRIVILEGED; /* Slot used to hold this task's CONTROL value. */ + /* Standard frame i.e. FPU not in use. */ + ulStackFrameSize = 8; } } - #endif /* configENABLE_MPU */ + #else + { + ulStackFrameSize = 8; + } + #endif /* configENABLE_FPU || configENABLE_MVE */ + + /* Make space on the system call stack for the stack frame and + * the parameter passed on the stack. We only need to copy one + * parameter but we still reserve 2 spaces to keep the stack + * double word aligned. */ + pulSystemCallStack = pulSystemCallStack - ulStackFrameSize - 2UL; + + /* Copy the stack frame. */ + for( i = 0; i < ulStackFrameSize; i++ ) + { + pulSystemCallStack[ i ] = pulTaskStack[ i ]; + } + + /* Copy the parameter which is passed the stack. */ + if( ( pulTaskStack[ portOFFSET_TO_PSR ] & portPSR_STACK_PADDING_MASK ) == portPSR_STACK_PADDING_MASK ) + { + pulSystemCallStack[ ulStackFrameSize ] = pulTaskStack[ ulStackFrameSize + 1 ]; + /* Record if the hardware used padding to force the stack pointer + * to be double word aligned. */ + pxMpuSettings->ulTaskFlags |= portSTACK_FRAME_HAS_PADDING_FLAG; + } + else + { + pulSystemCallStack[ ulStackFrameSize ] = pulTaskStack[ ulStackFrameSize ]; + /* Record if the hardware used padding to force the stack pointer + * to be double word aligned. */ + pxMpuSettings->ulTaskFlags &= ( ~portSTACK_FRAME_HAS_PADDING_FLAG ); + } + + /* Store the value of the LR and PSPLIM registers before the SVC was raised. + * We need to restore it when we exit from the system call. */ + pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; + __asm volatile ( "mrs %0, psplim" : "=r" ( pxMpuSettings->xSystemCallStackInfo.ulStackLimitRegisterAtSystemCallEntry ) ); + + /* Use the pulSystemCallStack in thread mode. */ + __asm volatile ( "msr psp, %0" : : "r" ( pulSystemCallStack ) ); + __asm volatile ( "msr psplim, %0" : : "r" ( pxMpuSettings->xSystemCallStackInfo.pulSystemCallStackLimit ) ); + + /* Remember the location where we should copy the stack frame when we exit from + * the system call. */ + pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulStackFrameSize; + + /* We ensure in pxPortInitialiseStack that the system call stack is + * double word aligned and therefore, there is no need of padding. + * Clear the bit[9] of stacked xPSR. */ + pulSystemCallStack[ portOFFSET_TO_PSR ] &= ( ~portPSR_STACK_PADDING_MASK ); + + /* Raise the privilege for the duration of the system call. */ + __asm volatile ( + " mrs r0, control \n" /* Obtain current control value. */ + " movs r1, #1 \n" /* r1 = 1. */ + " bics r0, r1 \n" /* Clear nPRIV bit. */ + " msr control, r0 \n" /* Write back new control value. */ + ::: "r0", "r1", "memory" + ); + } +} + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) +void vSystemCallExit( uint32_t * pulSystemCallStack, uint32_t ulLR ) /* PRIVILEGED_FUNCTION */ +{ + extern TaskHandle_t pxCurrentTCB; + xMPU_SETTINGS * pxMpuSettings; + uint32_t * pulTaskStack; + uint32_t ulStackFrameSize, ulSystemCallLocation, i; + #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being + * exported from linker scripts. */ + extern uint32_t * __syscalls_flash_start__; + extern uint32_t * __syscalls_flash_end__; + #else + /* Declaration when these variable are exported from linker scripts. */ + extern uint32_t __syscalls_flash_start__[]; + extern uint32_t __syscalls_flash_end__[]; + #endif /* #if defined( __ARMCC_VERSION ) */ + + ulSystemCallLocation = pulSystemCallStack[ portOFFSET_TO_PC ]; + + /* If the request did not come from the system call section, do nothing. */ + if( ( ulSystemCallLocation >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulSystemCallLocation <= ( uint32_t ) __syscalls_flash_end__ ) ) + { + pxMpuSettings = xTaskGetMPUSettings( pxCurrentTCB ); + pulTaskStack = pxMpuSettings->xSystemCallStackInfo.pulTaskStack; + + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + { + if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) + { + /* Extended frame i.e. FPU in use. */ + ulStackFrameSize = 26; + __asm volatile ( + " vpush {s0} \n" /* Trigger lazy stacking. */ + " vpop {s0} \n" /* Nullify the affect of the above instruction. */ + ::: "memory" + ); + } + else + { + /* Standard frame i.e. FPU not in use. */ + ulStackFrameSize = 8; + } + } + #else + { + ulStackFrameSize = 8; + } + #endif /* configENABLE_FPU || configENABLE_MVE */ + + /* Make space on the task stack for the stack frame. */ + pulTaskStack = pulTaskStack - ulStackFrameSize; + + /* Copy the stack frame. */ + for( i = 0; i < ulStackFrameSize; i++ ) + { + pulTaskStack[ i ] = pulSystemCallStack[ i ]; + } + + /* Use the pulTaskStack in thread mode. */ + __asm volatile ( "msr psp, %0" : : "r" ( pulTaskStack ) ); + + /* Restore the LR and PSPLIM to what they were at the time of + * system call entry. */ + pulTaskStack[ portOFFSET_TO_LR ] = pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry; + __asm volatile ( "msr psplim, %0" : : "r" ( pxMpuSettings->xSystemCallStackInfo.ulStackLimitRegisterAtSystemCallEntry ) ); + + /* If the hardware used padding to force the stack pointer + * to be double word aligned, set the stacked xPSR bit[9], + * otherwise clear it. */ + if( ( pxMpuSettings->ulTaskFlags & portSTACK_FRAME_HAS_PADDING_FLAG ) == portSTACK_FRAME_HAS_PADDING_FLAG ) + { + pulTaskStack[ portOFFSET_TO_PSR ] |= portPSR_STACK_PADDING_MASK; + } + else + { + pulTaskStack[ portOFFSET_TO_PSR ] &= ( ~portPSR_STACK_PADDING_MASK ); + } + + /* This is not NULL only for the duration of the system call. */ + pxMpuSettings->xSystemCallStackInfo.pulTaskStack = NULL; + + /* Drop the privilege before returning to the thread mode. */ + __asm volatile ( + " mrs r0, control \n" /* Obtain current control value. */ + " movs r1, #1 \n" /* r1 = 1. */ + " orrs r0, r1 \n" /* Set nPRIV bit. */ + " msr control, r0 \n" /* Write back new control value. */ + ::: "r0", "r1", "memory" + ); + } +} + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configENABLE_MPU == 1 ) + +BaseType_t xPortIsTaskPrivileged( void ) /* PRIVILEGED_FUNCTION */ +{ + BaseType_t xTaskIsPrivileged = pdFALSE; + const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */ + + if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) + { + xTaskIsPrivileged = pdTRUE; + } + + return xTaskIsPrivileged; +} + +#endif /* configENABLE_MPU == 1 */ +/*-----------------------------------------------------------*/ + +#if( configENABLE_MPU == 1 ) + +StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, + StackType_t * pxEndOfStack, + TaskFunction_t pxCode, + void * pvParameters, + BaseType_t xRunPrivileged, + xMPU_SETTINGS * xMPUSettings ) /* PRIVILEGED_FUNCTION */ +{ + uint32_t ulIndex = 0; + + xMPUSettings->ulContext[ ulIndex ] = 0x04040404; /* r4. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x05050505; /* r5. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x06060606; /* r6. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x07070707; /* r7. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x08080808; /* r8. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x09090909; /* r9. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x10101010; /* r10. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x11111111; /* r11. */ + ulIndex++; + + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pvParameters; /* r0. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x01010101; /* r1. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x02020202; /* r2. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x03030303; /* r3. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x12121212; /* r12. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portTASK_RETURN_ADDRESS; /* LR. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxCode; /* PC. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = portINITIAL_XPSR; /* xPSR. */ + ulIndex++; + + #if ( configENABLE_TRUSTZONE == 1 ) + { + xMPUSettings->ulContext[ ulIndex ] = portNO_SECURE_CONTEXT; /* xSecureContext. */ + ulIndex++; + } + #endif /* configENABLE_TRUSTZONE */ + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) ( pxTopOfStack - 8 ); /* PSP with the hardware saved stack. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */ + ulIndex++; + if( xRunPrivileged == pdTRUE ) + { + xMPUSettings->ulTaskFlags |= portTASK_IS_PRIVILEGED_FLAG; + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_PRIVILEGED; /* CONTROL. */ + ulIndex++; + } + else + { + xMPUSettings->ulTaskFlags &= ( ~portTASK_IS_PRIVILEGED_FLAG ); + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_UNPRIVILEGED; /* CONTROL. */ + ulIndex++; + } + xMPUSettings->ulContext[ ulIndex ] = portINITIAL_EXC_RETURN; /* LR (EXC_RETURN). */ + ulIndex++; + + #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + { + /* Ensure that the system call stack is double word aligned. */ + xMPUSettings->xSystemCallStackInfo.pulSystemCallStack = &( xMPUSettings->xSystemCallStackInfo.ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE - 1 ] ); + xMPUSettings->xSystemCallStackInfo.pulSystemCallStack = ( uint32_t * ) ( ( uint32_t ) ( xMPUSettings->xSystemCallStackInfo.pulSystemCallStack ) & + ( uint32_t ) ( ~( portBYTE_ALIGNMENT_MASK ) ) ); + + xMPUSettings->xSystemCallStackInfo.pulSystemCallStackLimit = &( xMPUSettings->xSystemCallStackInfo.ulSystemCallStackBuffer[ 0 ] ); + xMPUSettings->xSystemCallStackInfo.pulSystemCallStackLimit = ( uint32_t * ) ( ( ( uint32_t ) ( xMPUSettings->xSystemCallStackInfo.pulSystemCallStackLimit ) + + ( uint32_t ) ( portBYTE_ALIGNMENT - 1 ) ) & + ( uint32_t ) ( ~( portBYTE_ALIGNMENT_MASK ) ) ); + + /* This is not NULL only for the duration of a system call. */ + xMPUSettings->xSystemCallStackInfo.pulTaskStack = NULL; + } + #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + + return &( xMPUSettings->ulContext[ ulIndex ] ); +} + +#else /* configENABLE_MPU */ + +StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, + StackType_t * pxEndOfStack, + TaskFunction_t pxCode, + void * pvParameters ) /* PRIVILEGED_FUNCTION */ +{ + /* Simulate the stack frame as it would be created by a context switch + * interrupt. */ + #if ( portPRELOAD_REGISTERS == 0 ) + { + pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ + *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR. */ + pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ + pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */ + *pxTopOfStack = portINITIAL_EXC_RETURN; pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ @@ -1029,55 +1561,39 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO #else /* portPRELOAD_REGISTERS */ { pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ - *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ + *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pxCode; /* PC */ + *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR */ + *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x12121212UL; /* R12 */ + *pxTopOfStack = ( StackType_t ) 0x12121212UL; /* R12. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x03030303UL; /* R3 */ + *pxTopOfStack = ( StackType_t ) 0x03030303UL; /* R3. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x02020202UL; /* R2 */ + *pxTopOfStack = ( StackType_t ) 0x02020202UL; /* R2. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x01010101UL; /* R1 */ + *pxTopOfStack = ( StackType_t ) 0x01010101UL; /* R1. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x11111111UL; /* R11 */ + *pxTopOfStack = ( StackType_t ) 0x11111111UL; /* R11. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x10101010UL; /* R10 */ + *pxTopOfStack = ( StackType_t ) 0x10101010UL; /* R10. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x09090909UL; /* R09 */ + *pxTopOfStack = ( StackType_t ) 0x09090909UL; /* R09. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x08080808UL; /* R08 */ + *pxTopOfStack = ( StackType_t ) 0x08080808UL; /* R08. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x07070707UL; /* R07 */ + *pxTopOfStack = ( StackType_t ) 0x07070707UL; /* R07. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x06060606UL; /* R06 */ + *pxTopOfStack = ( StackType_t ) 0x06060606UL; /* R06. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x05050505UL; /* R05 */ + *pxTopOfStack = ( StackType_t ) 0x05050505UL; /* R05. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x04040404UL; /* R04 */ + *pxTopOfStack = ( StackType_t ) 0x04040404UL; /* R04. */ pxTopOfStack--; - *pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN */ - - #if ( configENABLE_MPU == 1 ) - { - pxTopOfStack--; - - if( xRunPrivileged == pdTRUE ) - { - *pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */ - } - else - { - *pxTopOfStack = portINITIAL_CONTROL_UNPRIVILEGED; /* Slot used to hold this task's CONTROL value. */ - } - } - #endif /* configENABLE_MPU */ - + *pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN. */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ @@ -1092,6 +1608,8 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO return pxTopOfStack; } + +#endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ @@ -1128,6 +1646,10 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ configASSERT( ucMaxSysCallPriority ); + /* Check that the bits not implemented in hardware are zero in + * configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & ( ~ucMaxPriorityValue ) ) == 0U ); + /* Calculate the maximum acceptable priority group value for the number * of bits read back. */ @@ -1164,35 +1686,6 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulImplementedPrioBits; } - /* The interrupt priority bits are not modelled in QEMU and the assert that - * checks the number of implemented bits and __NVIC_PRIO_BITS will always fail. - * Therefore, this assert is not adding any value for QEMU targets. The config - * option `configDISABLE_INTERRUPT_PRIO_BITS_CHECK` should be defined in the - * `FreeRTOSConfig.h` for QEMU targets. */ - #ifndef configDISABLE_INTERRUPT_PRIO_BITS_CHECK - { - #ifdef __NVIC_PRIO_BITS - { - /* - * Check that the number of implemented priority bits queried from - * hardware is equal to the CMSIS __NVIC_PRIO_BITS configuration macro. - */ - configASSERT( ulImplementedPrioBits == __NVIC_PRIO_BITS ); - } - #endif /* __NVIC_PRIO_BITS */ - - #ifdef configPRIO_BITS - { - /* - * Check that the number of implemented priority bits queried from - * hardware is equal to the FreeRTOS configPRIO_BITS configuration macro. - */ - configASSERT( ulImplementedPrioBits == configPRIO_BITS ); - } - #endif /* configPRIO_BITS */ - } - #endif /* #ifndef configDISABLE_INTERRUPT_PRIO_BITS_CHECK */ - /* Shift the priority group value back to its position within the AIRCR * register. */ ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT; @@ -1372,6 +1865,54 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ +#if ( configENABLE_MPU == 1 ) + BaseType_t xPortIsAuthorizedToAccessBuffer( const void * pvBuffer, + uint32_t ulBufferLength, + uint32_t ulAccessRequested ) /* PRIVILEGED_FUNCTION */ + + { + uint32_t i, ulBufferStartAddress, ulBufferEndAddress; + BaseType_t xAccessGranted = pdFALSE; + const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */ + + if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) + { + xAccessGranted = pdTRUE; + } + else + { + if( portADD_UINT32_WILL_OVERFLOW( ( ( uint32_t ) pvBuffer ), ( ulBufferLength - 1UL ) ) == pdFALSE ) + { + ulBufferStartAddress = ( uint32_t ) pvBuffer; + ulBufferEndAddress = ( ( ( uint32_t ) pvBuffer ) + ulBufferLength - 1UL ); + + for( i = 0; i < portTOTAL_NUM_REGIONS; i++ ) + { + /* Is the MPU region enabled? */ + if( ( xTaskMpuSettings->xRegionsSettings[ i ].ulRLAR & portMPU_RLAR_REGION_ENABLE ) == portMPU_RLAR_REGION_ENABLE ) + { + if( portIS_ADDRESS_WITHIN_RANGE( ulBufferStartAddress, + portEXTRACT_FIRST_ADDRESS_FROM_RBAR( xTaskMpuSettings->xRegionsSettings[ i ].ulRBAR ), + portEXTRACT_LAST_ADDRESS_FROM_RLAR( xTaskMpuSettings->xRegionsSettings[ i ].ulRLAR ) ) && + portIS_ADDRESS_WITHIN_RANGE( ulBufferEndAddress, + portEXTRACT_FIRST_ADDRESS_FROM_RBAR( xTaskMpuSettings->xRegionsSettings[ i ].ulRBAR ), + portEXTRACT_LAST_ADDRESS_FROM_RLAR( xTaskMpuSettings->xRegionsSettings[ i ].ulRLAR ) ) && + portIS_AUTHORIZED( ulAccessRequested, + prvGetRegionAccessPermissions( xTaskMpuSettings->xRegionsSettings[ i ].ulRBAR ) ) ) + { + xAccessGranted = pdTRUE; + break; + } + } + } + } + } + + return xAccessGranted; + } +#endif /* configENABLE_MPU */ +/*-----------------------------------------------------------*/ + BaseType_t xPortIsInsideInterrupt( void ) { uint32_t ulCurrentInterrupt; diff --git a/portable/GCC/ARM_CM23_NTZ/non_secure/portasm.c b/portable/GCC/ARM_CM23_NTZ/non_secure/portasm.c index 7fb7b5ade5d..b11b6e97c5e 100644 --- a/portable/GCC/ARM_CM23_NTZ/non_secure/portasm.c +++ b/portable/GCC/ARM_CM23_NTZ/non_secure/portasm.c @@ -44,6 +44,106 @@ #error Cortex-M23 does not have a Floating Point Unit (FPU) and therefore configENABLE_FPU must be set to 0. #endif +#if ( configENABLE_MPU == 1 ) + +void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ +{ + __asm volatile + ( + " .syntax unified \n" + " \n" + " program_mpu_first_task: \n" + " ldr r3, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r0, [r3] \n" /* r0 = pxCurrentTCB.*/ + " \n" + " dmb \n" /* Complete outstanding transfers before disabling MPU. */ + " ldr r1, xMPUCTRLConst2 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ + " movs r3, #1 \n" /* r3 = 1. */ + " bics r2, r3 \n" /* r2 = r2 & ~r3 i.e. Clear the bit 0 in r2. */ + " str r2, [r1] \n" /* Disable MPU. */ + " \n" + " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */ + " ldr r1, [r0] \n" /* r1 = *r0 i.e. r1 = MAIR0. */ + " ldr r2, xMAIR0Const2 \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */ + " str r1, [r2] \n" /* Program MAIR0. */ + " \n" + " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */ + " ldr r1, xRNRConst2 \n" /* r1 = 0xe000ed98 [Location of RNR]. */ + " \n" + " movs r3, #4 \n" /* r3 = 4. */ + " str r3, [r1] \n" /* Program RNR = 4. */ + " ldmia r0!, {r4-r5} \n" /* Read first set of RBAR/RLAR registers from TCB. */ + " ldr r2, xRBARConst2 \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ + " stmia r2!, {r4-r5} \n" /* Write first set of RBAR/RLAR registers. */ + " movs r3, #5 \n" /* r3 = 5. */ + " str r3, [r1] \n" /* Program RNR = 5. */ + " ldmia r0!, {r4-r5} \n" /* Read second set of RBAR/RLAR registers from TCB. */ + " ldr r2, xRBARConst2 \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ + " stmia r2!, {r4-r5} \n" /* Write second set of RBAR/RLAR registers. */ + " movs r3, #6 \n" /* r3 = 6. */ + " str r3, [r1] \n" /* Program RNR = 6. */ + " ldmia r0!, {r4-r5} \n" /* Read third set of RBAR/RLAR registers from TCB. */ + " ldr r2, xRBARConst2 \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ + " stmia r2!, {r4-r5} \n" /* Write third set of RBAR/RLAR registers. */ + " movs r3, #7 \n" /* r3 = 6. */ + " str r3, [r1] \n" /* Program RNR = 7. */ + " ldmia r0!, {r4-r5} \n" /* Read fourth set of RBAR/RLAR registers from TCB. */ + " ldr r2, xRBARConst2 \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ + " stmia r2!, {r4-r5} \n" /* Write fourth set of RBAR/RLAR registers. */ + " \n" + " ldr r1, xMPUCTRLConst2 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ + " movs r3, #1 \n" /* r3 = 1. */ + " orrs r2, r3 \n" /* r2 = r2 | r3 i.e. Set the bit 0 in r2. */ + " str r2, [r1] \n" /* Enable MPU. */ + " dsb \n" /* Force memory writes before continuing. */ + " \n" + " restore_context_first_task: \n" + " ldr r2, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r0, [r2] \n" /* r0 = pxCurrentTCB.*/ + " ldr r1, [r0] \n" /* r1 = Location of saved context in TCB. */ + " \n" + " restore_special_regs_first_task: \n" + " subs r1, #16 \n" + " ldmia r1!, {r2-r5} \n" /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, r5 = LR. */ + " subs r1, #16 \n" + " msr psp, r2 \n" + " msr psplim, r3 \n" + " msr control, r4 \n" + " mov lr, r5 \n" + " \n" + " restore_general_regs_first_task: \n" + " subs r1, #32 \n" + " ldmia r1!, {r4-r7} \n" /* r4-r7 contain half of the hardware saved context. */ + " stmia r2!, {r4-r7} \n" /* Copy half of the the hardware saved context on the task stack. */ + " ldmia r1!, {r4-r7} \n" /* r4-r7 contain rest half of the hardware saved context. */ + " stmia r2!, {r4-r7} \n" /* Copy rest half of the the hardware saved context on the task stack. */ + " subs r1, #48 \n" + " ldmia r1!, {r4-r7} \n" /* Restore r8-r11. */ + " mov r8, r4 \n" /* r8 = r4. */ + " mov r9, r5 \n" /* r9 = r5. */ + " mov r10, r6 \n" /* r10 = r6. */ + " mov r11, r7 \n" /* r11 = r7. */ + " subs r1, #32 \n" + " ldmia r1!, {r4-r7} \n" /* Restore r4-r7. */ + " subs r1, #16 \n" + " \n" + " restore_context_done_first_task: \n" + " str r1, [r0] \n" /* Save the location where the context should be saved next as the first member of TCB. */ + " bx lr \n" + " \n" + " .align 4 \n" + " pxCurrentTCBConst2: .word pxCurrentTCB \n" + " xMPUCTRLConst2: .word 0xe000ed94 \n" + " xMAIR0Const2: .word 0xe000edc0 \n" + " xRNRConst2: .word 0xe000ed98 \n" + " xRBARConst2: .word 0xe000ed9c \n" + ); +} + +#else /* configENABLE_MPU */ + void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ { __asm volatile @@ -54,78 +154,21 @@ void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_ " ldr r1, [r2] \n"/* Read pxCurrentTCB. */ " ldr r0, [r1] \n"/* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ " \n" - #if ( configENABLE_MPU == 1 ) - " dmb \n"/* Complete outstanding transfers before disabling MPU. */ - " ldr r2, xMPUCTRLConst2 \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ - " ldr r3, [r2] \n"/* Read the value of MPU_CTRL. */ - " movs r4, #1 \n"/* r4 = 1. */ - " bics r3, r4 \n"/* r3 = r3 & ~r4 i.e. Clear the bit 0 in r3. */ - " str r3, [r2] \n"/* Disable MPU. */ - " \n" - " adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */ - " ldr r4, [r1] \n"/* r4 = *r1 i.e. r4 = MAIR0. */ - " ldr r2, xMAIR0Const2 \n"/* r2 = 0xe000edc0 [Location of MAIR0]. */ - " str r4, [r2] \n"/* Program MAIR0. */ - " ldr r2, xRNRConst2 \n"/* r2 = 0xe000ed98 [Location of RNR]. */ - " adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to first RBAR in TCB. */ - " movs r4, #4 \n"/* r4 = 4. */ - " str r4, [r2] \n"/* Program RNR = 4. */ - " ldmia r1!, {r5,r6} \n"/* Read first set of RBAR/RLAR from TCB. */ - " ldr r3, xRBARConst2 \n"/* r3 = 0xe000ed9c [Location of RBAR]. */ - " stmia r3!, {r5,r6} \n"/* Write first set of RBAR/RLAR registers. */ - " movs r4, #5 \n"/* r4 = 5. */ - " str r4, [r2] \n"/* Program RNR = 5. */ - " ldmia r1!, {r5,r6} \n"/* Read second set of RBAR/RLAR from TCB. */ - " ldr r3, xRBARConst2 \n"/* r3 = 0xe000ed9c [Location of RBAR]. */ - " stmia r3!, {r5,r6} \n"/* Write second set of RBAR/RLAR registers. */ - " movs r4, #6 \n"/* r4 = 6. */ - " str r4, [r2] \n"/* Program RNR = 6. */ - " ldmia r1!, {r5,r6} \n"/* Read third set of RBAR/RLAR from TCB. */ - " ldr r3, xRBARConst2 \n"/* r3 = 0xe000ed9c [Location of RBAR]. */ - " stmia r3!, {r5,r6} \n"/* Write third set of RBAR/RLAR registers. */ - " movs r4, #7 \n"/* r4 = 7. */ - " str r4, [r2] \n"/* Program RNR = 7. */ - " ldmia r1!, {r5,r6} \n"/* Read fourth set of RBAR/RLAR from TCB. */ - " ldr r3, xRBARConst2 \n"/* r3 = 0xe000ed9c [Location of RBAR]. */ - " stmia r3!, {r5,r6} \n"/* Write fourth set of RBAR/RLAR registers. */ - " \n" - " ldr r2, xMPUCTRLConst2 \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ - " ldr r3, [r2] \n"/* Read the value of MPU_CTRL. */ - " movs r4, #1 \n"/* r4 = 1. */ - " orrs r3, r4 \n"/* r3 = r3 | r4 i.e. Set the bit 0 in r3. */ - " str r3, [r2] \n"/* Enable MPU. */ - " dsb \n"/* Force memory writes before continuing. */ - #endif /* configENABLE_MPU */ - " \n" - #if ( configENABLE_MPU == 1 ) - " ldm r0!, {r1-r3} \n"/* Read from stack - r1 = PSPLIM, r2 = CONTROL and r3 = EXC_RETURN. */ - " msr psplim, r1 \n"/* Set this task's PSPLIM value. */ - " msr control, r2 \n"/* Set this task's CONTROL value. */ - " adds r0, #32 \n"/* Discard everything up to r0. */ - " msr psp, r0 \n"/* This is now the new top of stack to use in the task. */ - " isb \n" - " bx r3 \n"/* Finally, branch to EXC_RETURN. */ - #else /* configENABLE_MPU */ - " ldm r0!, {r1-r2} \n"/* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */ - " msr psplim, r1 \n"/* Set this task's PSPLIM value. */ - " movs r1, #2 \n"/* r1 = 2. */ - " msr CONTROL, r1 \n"/* Switch to use PSP in the thread mode. */ - " adds r0, #32 \n"/* Discard everything up to r0. */ - " msr psp, r0 \n"/* This is now the new top of stack to use in the task. */ - " isb \n" - " bx r2 \n"/* Finally, branch to EXC_RETURN. */ - #endif /* configENABLE_MPU */ + " ldm r0!, {r1-r2} \n"/* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */ + " msr psplim, r1 \n"/* Set this task's PSPLIM value. */ + " movs r1, #2 \n"/* r1 = 2. */ + " msr CONTROL, r1 \n"/* Switch to use PSP in the thread mode. */ + " adds r0, #32 \n"/* Discard everything up to r0. */ + " msr psp, r0 \n"/* This is now the new top of stack to use in the task. */ + " isb \n" + " bx r2 \n"/* Finally, branch to EXC_RETURN. */ " \n" " .align 4 \n" "pxCurrentTCBConst2: .word pxCurrentTCB \n" - #if ( configENABLE_MPU == 1 ) - "xMPUCTRLConst2: .word 0xe000ed94 \n" - "xMAIR0Const2: .word 0xe000edc0 \n" - "xRNRConst2: .word 0xe000ed98 \n" - "xRBARConst2: .word 0xe000ed9c \n" - #endif /* configENABLE_MPU */ ); } + +#endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */ @@ -232,6 +275,136 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att } /*-----------------------------------------------------------*/ +#if ( configENABLE_MPU == 1 ) + +void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ +{ + __asm volatile + ( + " .syntax unified \n" + " \n" + " ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r0, [r2] \n" /* r0 = pxCurrentTCB. */ + " ldr r1, [r0] \n" /* r1 = Location in TCB where the context should be saved. */ + " mrs r2, psp \n" /* r2 = PSP. */ + " \n" + " save_general_regs: \n" + " stmia r1!, {r4-r7} \n" /* Store r4-r7. */ + " mov r4, r8 \n" /* r4 = r8. */ + " mov r5, r9 \n" /* r5 = r9. */ + " mov r6, r10 \n" /* r6 = r10. */ + " mov r7, r11 \n" /* r7 = r11. */ + " stmia r1!, {r4-r7} \n" /* Store r8-r11. */ + " ldmia r2!, {r4-r7} \n" /* Copy half of the hardware saved context into r4-r7. */ + " stmia r1!, {r4-r7} \n" /* Store the hardware saved context. */ + " ldmia r2!, {r4-r7} \n" /* Copy rest half of the hardware saved context into r4-r7. */ + " stmia r1!, {r4-r7} \n" /* Store the hardware saved context. */ + " \n" + " save_special_regs: \n" + " mrs r2, psp \n" /* r2 = PSP. */ + " mrs r3, psplim \n" /* r3 = PSPLIM. */ + " mrs r4, control \n" /* r4 = CONTROL. */ + " mov r5, lr \n" /* r5 = LR. */ + " stmia r1!, {r2-r5} \n" /* Store original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */ + " str r1, [r0] \n" /* Save the location from where the context should be restored as the first member of TCB. */ + " \n" + " select_next_task: \n" + " cpsid i \n" + " bl vTaskSwitchContext \n" + " cpsie i \n" + " \n" + " program_mpu: \n" + " ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r0, [r3] \n" /* r0 = pxCurrentTCB.*/ + " \n" + " dmb \n" /* Complete outstanding transfers before disabling MPU. */ + " ldr r1, xMPUCTRLConst \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ + " movs r3, #1 \n" /* r3 = 1. */ + " bics r2, r3 \n" /* r2 = r2 & ~r3 i.e. Clear the bit 0 in r2. */ + " str r2, [r1] \n" /* Disable MPU. */ + " \n" + " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */ + " ldr r1, [r0] \n" /* r1 = *r0 i.e. r1 = MAIR0. */ + " ldr r2, xMAIR0Const \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */ + " str r1, [r2] \n" /* Program MAIR0. */ + " \n" + " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */ + " ldr r1, xRNRConst \n" /* r1 = 0xe000ed98 [Location of RNR]. */ + " \n" + " movs r3, #4 \n" /* r3 = 4. */ + " str r3, [r1] \n" /* Program RNR = 4. */ + " ldmia r0!, {r4-r5} \n" /* Read first set of RBAR/RLAR registers from TCB. */ + " ldr r2, xRBARConst \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ + " stmia r2!, {r4-r5} \n" /* Write first set of RBAR/RLAR registers. */ + " movs r3, #5 \n" /* r3 = 5. */ + " str r3, [r1] \n" /* Program RNR = 5. */ + " ldmia r0!, {r4-r5} \n" /* Read second set of RBAR/RLAR registers from TCB. */ + " ldr r2, xRBARConst \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ + " stmia r2!, {r4-r5} \n" /* Write second set of RBAR/RLAR registers. */ + " movs r3, #6 \n" /* r3 = 6. */ + " str r3, [r1] \n" /* Program RNR = 6. */ + " ldmia r0!, {r4-r5} \n" /* Read third set of RBAR/RLAR registers from TCB. */ + " ldr r2, xRBARConst \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ + " stmia r2!, {r4-r5} \n" /* Write third set of RBAR/RLAR registers. */ + " movs r3, #7 \n" /* r3 = 6. */ + " str r3, [r1] \n" /* Program RNR = 7. */ + " ldmia r0!, {r4-r5} \n" /* Read fourth set of RBAR/RLAR registers from TCB. */ + " ldr r2, xRBARConst \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ + " stmia r2!, {r4-r5} \n" /* Write fourth set of RBAR/RLAR registers. */ + " \n" + " ldr r1, xMPUCTRLConst \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ + " movs r3, #1 \n" /* r3 = 1. */ + " orrs r2, r3 \n" /* r2 = r2 | r3 i.e. Set the bit 0 in r2. */ + " str r2, [r1] \n" /* Enable MPU. */ + " dsb \n" /* Force memory writes before continuing. */ + " \n" + " restore_context: \n" + " ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r0, [r2] \n" /* r0 = pxCurrentTCB.*/ + " ldr r1, [r0] \n" /* r1 = Location of saved context in TCB. */ + " \n" + " restore_special_regs: \n" + " subs r1, #16 \n" + " ldmia r1!, {r2-r5} \n" /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, r5 = LR. */ + " subs r1, #16 \n" + " msr psp, r2 \n" + " msr psplim, r3 \n" + " msr control, r4 \n" + " mov lr, r5 \n" + " \n" + " restore_general_regs: \n" + " subs r1, #32 \n" + " ldmia r1!, {r4-r7} \n" /* r4-r7 contain half of the hardware saved context. */ + " stmia r2!, {r4-r7} \n" /* Copy half of the the hardware saved context on the task stack. */ + " ldmia r1!, {r4-r7} \n" /* r4-r7 contain rest half of the hardware saved context. */ + " stmia r2!, {r4-r7} \n" /* Copy rest half of the the hardware saved context on the task stack. */ + " subs r1, #48 \n" + " ldmia r1!, {r4-r7} \n" /* Restore r8-r11. */ + " mov r8, r4 \n" /* r8 = r4. */ + " mov r9, r5 \n" /* r9 = r5. */ + " mov r10, r6 \n" /* r10 = r6. */ + " mov r11, r7 \n" /* r11 = r7. */ + " subs r1, #32 \n" + " ldmia r1!, {r4-r7} \n" /* Restore r4-r7. */ + " subs r1, #16 \n" + " \n" + " restore_context_done: \n" + " str r1, [r0] \n" /* Save the location where the context should be saved next as the first member of TCB. */ + " bx lr \n" + " \n" + " .align 4 \n" + " pxCurrentTCBConst: .word pxCurrentTCB \n" + " xMPUCTRLConst: .word 0xe000ed94 \n" + " xMAIR0Const: .word 0xe000edc0 \n" + " xRNRConst: .word 0xe000ed98 \n" + " xRBARConst: .word 0xe000ed9c \n" + ); +} + +#else /* configENABLE_MPU */ + void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ { __asm volatile @@ -241,30 +414,16 @@ void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ " mrs r0, psp \n"/* Read PSP in r0. */ " ldr r2, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r2] \n"/* Read pxCurrentTCB. */ - #if ( configENABLE_MPU == 1 ) - " subs r0, r0, #44 \n"/* Make space for PSPLIM, CONTROL, LR and the remaining registers on the stack. */ - " str r0, [r1] \n"/* Save the new top of stack in TCB. */ - " mrs r1, psplim \n"/* r1 = PSPLIM. */ - " mrs r2, control \n"/* r2 = CONTROL. */ - " mov r3, lr \n"/* r3 = LR/EXC_RETURN. */ - " stmia r0!, {r1-r7} \n"/* Store on the stack - PSPLIM, CONTROL, LR and low registers that are not automatically saved. */ - " mov r4, r8 \n"/* r4 = r8. */ - " mov r5, r9 \n"/* r5 = r9. */ - " mov r6, r10 \n"/* r6 = r10. */ - " mov r7, r11 \n"/* r7 = r11. */ - " stmia r0!, {r4-r7} \n"/* Store the high registers that are not saved automatically. */ - #else /* configENABLE_MPU */ - " subs r0, r0, #40 \n"/* Make space for PSPLIM, LR and the remaining registers on the stack. */ - " str r0, [r1] \n"/* Save the new top of stack in TCB. */ - " mrs r2, psplim \n"/* r2 = PSPLIM. */ - " mov r3, lr \n"/* r3 = LR/EXC_RETURN. */ - " stmia r0!, {r2-r7} \n"/* Store on the stack - PSPLIM, LR and low registers that are not automatically saved. */ - " mov r4, r8 \n"/* r4 = r8. */ - " mov r5, r9 \n"/* r5 = r9. */ - " mov r6, r10 \n"/* r6 = r10. */ - " mov r7, r11 \n"/* r7 = r11. */ - " stmia r0!, {r4-r7} \n"/* Store the high registers that are not saved automatically. */ - #endif /* configENABLE_MPU */ + " subs r0, r0, #40 \n"/* Make space for PSPLIM, LR and the remaining registers on the stack. */ + " str r0, [r1] \n"/* Save the new top of stack in TCB. */ + " mrs r2, psplim \n"/* r2 = PSPLIM. */ + " mov r3, lr \n"/* r3 = LR/EXC_RETURN. */ + " stmia r0!, {r2-r7} \n"/* Store on the stack - PSPLIM, LR and low registers that are not automatically saved. */ + " mov r4, r8 \n"/* r4 = r8. */ + " mov r5, r9 \n"/* r5 = r9. */ + " mov r6, r10 \n"/* r6 = r10. */ + " mov r7, r11 \n"/* r7 = r11. */ + " stmia r0!, {r4-r7} \n"/* Store the high registers that are not saved automatically. */ " \n" " cpsid i \n" " bl vTaskSwitchContext \n" @@ -274,88 +433,76 @@ void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ " ldr r1, [r2] \n"/* Read pxCurrentTCB. */ " ldr r0, [r1] \n"/* The first item in pxCurrentTCB is the task top of stack. r0 now points to the top of stack. */ " \n" - #if ( configENABLE_MPU == 1 ) - " dmb \n"/* Complete outstanding transfers before disabling MPU. */ - " ldr r2, xMPUCTRLConst \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ - " ldr r3, [r2] \n"/* Read the value of MPU_CTRL. */ - " movs r4, #1 \n"/* r4 = 1. */ - " bics r3, r4 \n"/* r3 = r3 & ~r4 i.e. Clear the bit 0 in r3. */ - " str r3, [r2] \n"/* Disable MPU. */ - " \n" - " adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */ - " ldr r4, [r1] \n"/* r4 = *r1 i.e. r4 = MAIR0. */ - " ldr r2, xMAIR0Const \n"/* r2 = 0xe000edc0 [Location of MAIR0]. */ - " str r4, [r2] \n"/* Program MAIR0. */ - " ldr r2, xRNRConst \n"/* r2 = 0xe000ed98 [Location of RNR]. */ - " adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to first RBAR in TCB. */ - " movs r4, #4 \n"/* r4 = 4. */ - " str r4, [r2] \n"/* Program RNR = 4. */ - " ldmia r1!, {r5,r6} \n"/* Read first set of RBAR/RLAR from TCB. */ - " ldr r3, xRBARConst \n"/* r3 = 0xe000ed9c [Location of RBAR]. */ - " stmia r3!, {r5,r6} \n"/* Write first set of RBAR/RLAR registers. */ - " movs r4, #5 \n"/* r4 = 5. */ - " str r4, [r2] \n"/* Program RNR = 5. */ - " ldmia r1!, {r5,r6} \n"/* Read second set of RBAR/RLAR from TCB. */ - " ldr r3, xRBARConst \n"/* r3 = 0xe000ed9c [Location of RBAR]. */ - " stmia r3!, {r5,r6} \n"/* Write second set of RBAR/RLAR registers. */ - " movs r4, #6 \n"/* r4 = 6. */ - " str r4, [r2] \n"/* Program RNR = 6. */ - " ldmia r1!, {r5,r6} \n"/* Read third set of RBAR/RLAR from TCB. */ - " ldr r3, xRBARConst \n"/* r3 = 0xe000ed9c [Location of RBAR]. */ - " stmia r3!, {r5,r6} \n"/* Write third set of RBAR/RLAR registers. */ - " movs r4, #7 \n"/* r4 = 7. */ - " str r4, [r2] \n"/* Program RNR = 7. */ - " ldmia r1!, {r5,r6} \n"/* Read fourth set of RBAR/RLAR from TCB. */ - " ldr r3, xRBARConst \n"/* r3 = 0xe000ed9c [Location of RBAR]. */ - " stmia r3!, {r5,r6} \n"/* Write fourth set of RBAR/RLAR registers. */ - " \n" - " ldr r2, xMPUCTRLConst \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ - " ldr r3, [r2] \n"/* Read the value of MPU_CTRL. */ - " movs r4, #1 \n"/* r4 = 1. */ - " orrs r3, r4 \n"/* r3 = r3 | r4 i.e. Set the bit 0 in r3. */ - " str r3, [r2] \n"/* Enable MPU. */ - " dsb \n"/* Force memory writes before continuing. */ - #endif /* configENABLE_MPU */ - " \n" - #if ( configENABLE_MPU == 1 ) - " adds r0, r0, #28 \n"/* Move to the high registers. */ - " ldmia r0!, {r4-r7} \n"/* Restore the high registers that are not automatically restored. */ - " mov r8, r4 \n"/* r8 = r4. */ - " mov r9, r5 \n"/* r9 = r5. */ - " mov r10, r6 \n"/* r10 = r6. */ - " mov r11, r7 \n"/* r11 = r7. */ - " msr psp, r0 \n"/* Remember the new top of stack for the task. */ - " subs r0, r0, #44 \n"/* Move to the starting of the saved context. */ - " ldmia r0!, {r1-r7} \n"/* Read from stack - r1 = PSPLIM, r2 = CONTROL, r3 = LR and r4-r7 restored. */ - " msr psplim, r1 \n"/* Restore the PSPLIM register value for the task. */ - " msr control, r2 \n"/* Restore the CONTROL register value for the task. */ - " bx r3 \n" - #else /* configENABLE_MPU */ - " adds r0, r0, #24 \n"/* Move to the high registers. */ - " ldmia r0!, {r4-r7} \n"/* Restore the high registers that are not automatically restored. */ - " mov r8, r4 \n"/* r8 = r4. */ - " mov r9, r5 \n"/* r9 = r5. */ - " mov r10, r6 \n"/* r10 = r6. */ - " mov r11, r7 \n"/* r11 = r7. */ - " msr psp, r0 \n"/* Remember the new top of stack for the task. */ - " subs r0, r0, #40 \n"/* Move to the starting of the saved context. */ - " ldmia r0!, {r2-r7} \n"/* Read from stack - r2 = PSPLIM, r3 = LR and r4-r7 restored. */ - " msr psplim, r2 \n"/* Restore the PSPLIM register value for the task. */ - " bx r3 \n" - #endif /* configENABLE_MPU */ + " adds r0, r0, #24 \n"/* Move to the high registers. */ + " ldmia r0!, {r4-r7} \n"/* Restore the high registers that are not automatically restored. */ + " mov r8, r4 \n"/* r8 = r4. */ + " mov r9, r5 \n"/* r9 = r5. */ + " mov r10, r6 \n"/* r10 = r6. */ + " mov r11, r7 \n"/* r11 = r7. */ + " msr psp, r0 \n"/* Remember the new top of stack for the task. */ + " subs r0, r0, #40 \n"/* Move to the starting of the saved context. */ + " ldmia r0!, {r2-r7} \n"/* Read from stack - r2 = PSPLIM, r3 = LR and r4-r7 restored. */ + " msr psplim, r2 \n"/* Restore the PSPLIM register value for the task. */ + " bx r3 \n" " \n" " .align 4 \n" "pxCurrentTCBConst: .word pxCurrentTCB \n" - #if ( configENABLE_MPU == 1 ) - "xMPUCTRLConst: .word 0xe000ed94 \n" - "xMAIR0Const: .word 0xe000edc0 \n" - "xRNRConst: .word 0xe000ed98 \n" - "xRBARConst: .word 0xe000ed9c \n" - #endif /* configENABLE_MPU */ ); } + +#endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + +void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ +{ + __asm volatile + ( + ".syntax unified \n" + ".extern vPortSVCHandler_C \n" + ".extern vSystemCallEnter \n" + ".extern vSystemCallEnter_1 \n" + ".extern vSystemCallExit \n" + " \n" + "movs r0, #4 \n" + "mov r1, lr \n" + "tst r0, r1 \n" + "beq stack_on_msp \n" + "stack_on_psp: \n" + " mrs r0, psp \n" + " b route_svc \n" + "stack_on_msp: \n" + " mrs r0, msp \n" + " b route_svc \n" + " \n" + "route_svc: \n" + " ldr r2, [r0, #24] \n" + " subs r2, #2 \n" + " ldrb r3, [r2, #0] \n" + " cmp r3, %0 \n" + " beq system_call_enter \n" + " cmp r3, %1 \n" + " beq system_call_enter_1 \n" + " cmp r3, %2 \n" + " beq system_call_exit \n" + " b vPortSVCHandler_C \n" + " \n" + "system_call_enter: \n" + " b vSystemCallEnter \n" + "system_call_enter_1: \n" + " b vSystemCallEnter_1 \n" + "system_call_exit: \n" + " b vSystemCallExit \n" + " \n" + : /* No outputs. */ + :"i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_ENTER_1 ), "i" ( portSVC_SYSTEM_CALL_EXIT ) + : "r0", "r1", "r2", "r3", "memory" + ); +} + +#else /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ { __asm volatile @@ -378,4 +525,6 @@ void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ "svchandler_address_const: .word vPortSVCHandler_C \n" ); } + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ /*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM23_NTZ/non_secure/portmacro.h b/portable/GCC/ARM_CM23_NTZ/non_secure/portmacro.h index 746f734b8ac..5fd94c1c371 100644 --- a/portable/GCC/ARM_CM23_NTZ/non_secure/portmacro.h +++ b/portable/GCC/ARM_CM23_NTZ/non_secure/portmacro.h @@ -51,7 +51,6 @@ #define portARCH_NAME "Cortex-M23" #define portHAS_BASEPRI 0 #define portDONT_DISCARD __attribute__( ( used ) ) -#define portNORETURN __attribute__( ( noreturn ) ) /*-----------------------------------------------------------*/ /* ARMv8-M common port configurations. */ diff --git a/portable/GCC/ARM_CM23_NTZ/non_secure/portmacrocommon.h b/portable/GCC/ARM_CM23_NTZ/non_secure/portmacrocommon.h index c2ca5fa7730..65ac109c802 100644 --- a/portable/GCC/ARM_CM23_NTZ/non_secure/portmacrocommon.h +++ b/portable/GCC/ARM_CM23_NTZ/non_secure/portmacrocommon.h @@ -186,23 +186,120 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #define portMPU_REGION_EXECUTE_NEVER ( 1UL ) /*-----------------------------------------------------------*/ -/** - * @brief Settings to define an MPU region. - */ -typedef struct MPURegionSettings -{ - uint32_t ulRBAR; /**< RBAR for the region. */ - uint32_t ulRLAR; /**< RLAR for the region. */ -} MPURegionSettings_t; +#if ( configENABLE_MPU == 1 ) -/** - * @brief MPU settings as stored in the TCB. - */ -typedef struct MPU_SETTINGS -{ - uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ - MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */ -} xMPU_SETTINGS; + /** + * @brief Settings to define an MPU region. + */ + typedef struct MPURegionSettings + { + uint32_t ulRBAR; /**< RBAR for the region. */ + uint32_t ulRLAR; /**< RLAR for the region. */ + } MPURegionSettings_t; + + #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + + #ifndef configSYSTEM_CALL_STACK_SIZE + #error configSYSTEM_CALL_STACK_SIZE must be defined to the desired size of the system call stack in words for using MPU wrappers v2. + #endif + + /** + * @brief System call stack. + */ + typedef struct SYSTEM_CALL_STACK_INFO + { + uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ]; + uint32_t * pulSystemCallStack; + uint32_t * pulSystemCallStackLimit; + uint32_t * pulTaskStack; + uint32_t ulLinkRegisterAtSystemCallEntry; + uint32_t ulStackLimitRegisterAtSystemCallEntry; + } xSYSTEM_CALL_STACK_INFO; + + #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + + /** + * @brief MPU settings as stored in the TCB. + */ + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + + #if( configENABLE_TRUSTZONE == 1 ) + + /* + * +-----------+---------------+----------+-----------------+------------------------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | + * | | | | PC, xPSR | CONTROL, EXC_RETURN | | + * +-----------+---------------+----------+-----------------+------------------------------+-----+ + * + * <-----------><--------------><---------><----------------><-----------------------------><----> + * 16 16 8 8 5 1 + */ + #define MAX_CONTEXT_SIZE 54 + + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ + + /* + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | + * | | | | PC, xPSR | EXC_RETURN | | + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * + * <-----------><--------------><---------><----------------><---------------------><----> + * 16 16 8 8 4 1 + */ + #define MAX_CONTEXT_SIZE 53 + + #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + + #else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ + + #if( configENABLE_TRUSTZONE == 1 ) + + /* + * +----------+-----------------+------------------------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | + * | | PC, xPSR | CONTROL, EXC_RETURN | | + * +----------+-----------------+------------------------------+-----+ + * + * <---------><----------------><------------------------------><----> + * 8 8 5 1 + */ + #define MAX_CONTEXT_SIZE 22 + + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ + + /* + * +----------+-----------------+----------------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | + * | | PC, xPSR | EXC_RETURN | | + * +----------+-----------------+----------------------+-----+ + * + * <---------><----------------><----------------------><----> + * 8 8 4 1 + */ + #define MAX_CONTEXT_SIZE 21 + + #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + + #endif /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ + + /* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ + #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) + #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) + + typedef struct MPU_SETTINGS + { + uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ + MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */ + uint32_t ulContext[ MAX_CONTEXT_SIZE ]; + uint32_t ulTaskFlags; + + #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo; + #endif + } xMPU_SETTINGS; + +#endif /* configENABLE_MPU == 1 */ /*-----------------------------------------------------------*/ /** @@ -223,6 +320,9 @@ typedef struct MPU_SETTINGS #define portSVC_FREE_SECURE_CONTEXT 1 #define portSVC_START_SCHEDULER 2 #define portSVC_RAISE_PRIVILEGE 3 +#define portSVC_SYSTEM_CALL_ENTER 4 /* System calls with upto 4 parameters. */ +#define portSVC_SYSTEM_CALL_ENTER_1 5 /* System calls with 5 parameters. */ +#define portSVC_SYSTEM_CALL_EXIT 6 /*-----------------------------------------------------------*/ /** @@ -315,6 +415,20 @@ typedef struct MPU_SETTINGS #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ +#if ( configENABLE_MPU == 1 ) + + extern BaseType_t xPortIsTaskPrivileged( void ); + + /** + * @brief Checks whether or not the calling task is privileged. + * + * @return pdTRUE if the calling task is privileged, pdFALSE otherwise. + */ + #define portIS_TASK_PRIVILEGED() xPortIsTaskPrivileged() + +#endif /* configENABLE_MPU == 1 */ +/*-----------------------------------------------------------*/ + /** * @brief Barriers. */ diff --git a/portable/GCC/ARM_CM3/port.c b/portable/GCC/ARM_CM3/port.c old mode 100755 new mode 100644 index 9b42eac5a4e..ac8185f5f73 --- a/portable/GCC/ARM_CM3/port.c +++ b/portable/GCC/ARM_CM3/port.c @@ -292,6 +292,10 @@ BaseType_t xPortStartScheduler( void ) * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ configASSERT( ucMaxSysCallPriority ); + /* Check that the bits not implemented in hardware are zero in + * configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & ( ~ucMaxPriorityValue ) ) == 0U ); + /* Calculate the maximum acceptable priority group value for the number * of bits read back. */ @@ -328,28 +332,6 @@ BaseType_t xPortStartScheduler( void ) ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulImplementedPrioBits; } - #ifdef __NVIC_PRIO_BITS - { - /* - * Check that the number of implemented priority bits queried from - * hardware is at least as many as specified in the CMSIS - * __NVIC_PRIO_BITS configuration macro. - */ - configASSERT( ulImplementedPrioBits >= __NVIC_PRIO_BITS ); - } - #endif - - #ifdef configPRIO_BITS - { - /* - * Check that the number of implemented priority bits queried from - * hardware is at least as many as specified in the FreeRTOS - * configPRIO_BITS configuration macro. - */ - configASSERT( ulImplementedPrioBits >= configPRIO_BITS ); - } - #endif - /* Shift the priority group value back to its position within the AIRCR * register. */ ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT; diff --git a/portable/GCC/ARM_CM3/portmacro.h b/portable/GCC/ARM_CM3/portmacro.h index 36e38f75d21..0ff96b82ae8 100644 --- a/portable/GCC/ARM_CM3/portmacro.h +++ b/portable/GCC/ARM_CM3/portmacro.h @@ -79,7 +79,6 @@ #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) #define portBYTE_ALIGNMENT 8 #define portDONT_DISCARD __attribute__( ( used ) ) - #define portNORETURN __attribute__( ( noreturn ) ) /*-----------------------------------------------------------*/ /* Scheduler utilities. */ diff --git a/portable/GCC/ARM_CM33/non_secure/mpu_wrappers_v2_asm.c b/portable/GCC/ARM_CM33/non_secure/mpu_wrappers_v2_asm.c new file mode 100644 index 00000000000..6e2043427fe --- /dev/null +++ b/portable/GCC/ARM_CM33/non_secure/mpu_wrappers_v2_asm.c @@ -0,0 +1,2349 @@ +/* + * FreeRTOS Kernel + * Copyright (C) 2021 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 + * + */ + +/* 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. */ +#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +/* Scheduler includes. */ +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" +#include "timers.h" +#include "event_groups.h" +#include "stream_buffer.h" + +#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + +#if ( INCLUDE_xTaskDelayUntil == 1 ) + +BaseType_t MPU_xTaskDelayUntil( TickType_t * const pxPreviousWakeTime, + const TickType_t xTimeIncrement ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskDelayUntil( TickType_t * const pxPreviousWakeTime, + const TickType_t xTimeIncrement ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskDelayUntilImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskDelayUntil_Unpriv \n" + " MPU_xTaskDelayUntil_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskDelayUntilImpl \n" + " MPU_xTaskDelayUntil_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskDelayUntilImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_xTaskDelayUntil == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_xTaskAbortDelay == 1 ) + +BaseType_t MPU_xTaskAbortDelay( TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskAbortDelay( TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskAbortDelayImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskAbortDelay_Unpriv \n" + " MPU_xTaskAbortDelay_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskAbortDelayImpl \n" + " MPU_xTaskAbortDelay_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskAbortDelayImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_xTaskAbortDelay == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskDelay == 1 ) + +void MPU_vTaskDelay( const TickType_t xTicksToDelay ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskDelay( const TickType_t xTicksToDelay ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskDelayImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vTaskDelay_Unpriv \n" + " MPU_vTaskDelay_Priv: \n" + " pop {r0} \n" + " b MPU_vTaskDelayImpl \n" + " MPU_vTaskDelay_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vTaskDelayImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_vTaskDelay == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_uxTaskPriorityGet == 1 ) + +UBaseType_t MPU_uxTaskPriorityGet( const TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxTaskPriorityGet( const TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxTaskPriorityGetImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_uxTaskPriorityGet_Unpriv \n" + " MPU_uxTaskPriorityGet_Priv: \n" + " pop {r0} \n" + " b MPU_uxTaskPriorityGetImpl \n" + " MPU_uxTaskPriorityGet_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_uxTaskPriorityGetImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_uxTaskPriorityGet == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_eTaskGetState == 1 ) + +eTaskState MPU_eTaskGetState( TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +eTaskState MPU_eTaskGetState( TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_eTaskGetStateImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_eTaskGetState_Unpriv \n" + " MPU_eTaskGetState_Priv: \n" + " pop {r0} \n" + " b MPU_eTaskGetStateImpl \n" + " MPU_eTaskGetState_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_eTaskGetStateImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_eTaskGetState == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + +void MPU_vTaskGetInfo( TaskHandle_t xTask, + TaskStatus_t * pxTaskStatus, + BaseType_t xGetFreeStackSpace, + eTaskState eState ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskGetInfo( TaskHandle_t xTask, + TaskStatus_t * pxTaskStatus, + BaseType_t xGetFreeStackSpace, + eTaskState eState ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskGetInfoImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vTaskGetInfo_Unpriv \n" + " MPU_vTaskGetInfo_Priv: \n" + " pop {r0} \n" + " b MPU_vTaskGetInfoImpl \n" + " MPU_vTaskGetInfo_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vTaskGetInfoImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TRACE_FACILITY == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) + +TaskHandle_t MPU_xTaskGetIdleTaskHandle( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TaskHandle_t MPU_xTaskGetIdleTaskHandle( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGetIdleTaskHandleImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskGetIdleTaskHandle_Unpriv \n" + " MPU_xTaskGetIdleTaskHandle_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskGetIdleTaskHandleImpl \n" + " MPU_xTaskGetIdleTaskHandle_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskGetIdleTaskHandleImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskSuspend == 1 ) + +void MPU_vTaskSuspend( TaskHandle_t xTaskToSuspend ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskSuspend( TaskHandle_t xTaskToSuspend ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskSuspendImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vTaskSuspend_Unpriv \n" + " MPU_vTaskSuspend_Priv: \n" + " pop {r0} \n" + " b MPU_vTaskSuspendImpl \n" + " MPU_vTaskSuspend_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vTaskSuspendImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_vTaskSuspend == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskSuspend == 1 ) + +void MPU_vTaskResume( TaskHandle_t xTaskToResume ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskResume( TaskHandle_t xTaskToResume ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskResumeImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vTaskResume_Unpriv \n" + " MPU_vTaskResume_Priv: \n" + " pop {r0} \n" + " b MPU_vTaskResumeImpl \n" + " MPU_vTaskResume_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vTaskResumeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_vTaskSuspend == 1 ) */ +/*-----------------------------------------------------------*/ + +TickType_t MPU_xTaskGetTickCount( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TickType_t MPU_xTaskGetTickCount( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGetTickCountImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskGetTickCount_Unpriv \n" + " MPU_xTaskGetTickCount_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskGetTickCountImpl \n" + " MPU_xTaskGetTickCount_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskGetTickCountImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +UBaseType_t MPU_uxTaskGetNumberOfTasks( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxTaskGetNumberOfTasks( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxTaskGetNumberOfTasksImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_uxTaskGetNumberOfTasks_Unpriv \n" + " MPU_uxTaskGetNumberOfTasks_Priv: \n" + " pop {r0} \n" + " b MPU_uxTaskGetNumberOfTasksImpl \n" + " MPU_uxTaskGetNumberOfTasks_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_uxTaskGetNumberOfTasksImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +char * MPU_pcTaskGetName( TaskHandle_t xTaskToQuery ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +char * MPU_pcTaskGetName( TaskHandle_t xTaskToQuery ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_pcTaskGetNameImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_pcTaskGetName_Unpriv \n" + " MPU_pcTaskGetName_Priv: \n" + " pop {r0} \n" + " b MPU_pcTaskGetNameImpl \n" + " MPU_pcTaskGetName_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_pcTaskGetNameImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +#if ( configGENERATE_RUN_TIME_STATS == 1 ) + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetRunTimeCounter( const TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetRunTimeCounter( const TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_ulTaskGetRunTimeCounterImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_ulTaskGetRunTimeCounter_Unpriv \n" + " MPU_ulTaskGetRunTimeCounter_Priv: \n" + " pop {r0} \n" + " b MPU_ulTaskGetRunTimeCounterImpl \n" + " MPU_ulTaskGetRunTimeCounter_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_ulTaskGetRunTimeCounterImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( ( configGENERATE_RUN_TIME_STATS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configGENERATE_RUN_TIME_STATS == 1 ) + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetRunTimePercent( const TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetRunTimePercent( const TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_ulTaskGetRunTimePercentImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_ulTaskGetRunTimePercent_Unpriv \n" + " MPU_ulTaskGetRunTimePercent_Priv: \n" + " pop {r0} \n" + " b MPU_ulTaskGetRunTimePercentImpl \n" + " MPU_ulTaskGetRunTimePercent_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_ulTaskGetRunTimePercentImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( ( configGENERATE_RUN_TIME_STATS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimePercent( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimePercent( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_ulTaskGetIdleRunTimePercentImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_ulTaskGetIdleRunTimePercent_Unpriv \n" + " MPU_ulTaskGetIdleRunTimePercent_Priv: \n" + " pop {r0} \n" + " b MPU_ulTaskGetIdleRunTimePercentImpl \n" + " MPU_ulTaskGetIdleRunTimePercent_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_ulTaskGetIdleRunTimePercentImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimeCounter( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimeCounter( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_ulTaskGetIdleRunTimeCounterImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_ulTaskGetIdleRunTimeCounter_Unpriv \n" + " MPU_ulTaskGetIdleRunTimeCounter_Priv: \n" + " pop {r0} \n" + " b MPU_ulTaskGetIdleRunTimeCounterImpl \n" + " MPU_ulTaskGetIdleRunTimeCounter_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_ulTaskGetIdleRunTimeCounterImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_APPLICATION_TASK_TAG == 1 ) + +void MPU_vTaskSetApplicationTaskTag( TaskHandle_t xTask, + TaskHookFunction_t pxHookFunction ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskSetApplicationTaskTag( TaskHandle_t xTask, + TaskHookFunction_t pxHookFunction ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskSetApplicationTaskTagImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vTaskSetApplicationTaskTag_Unpriv \n" + " MPU_vTaskSetApplicationTaskTag_Priv: \n" + " pop {r0} \n" + " b MPU_vTaskSetApplicationTaskTagImpl \n" + " MPU_vTaskSetApplicationTaskTag_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vTaskSetApplicationTaskTagImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_APPLICATION_TASK_TAG == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_APPLICATION_TASK_TAG == 1 ) + +TaskHookFunction_t MPU_xTaskGetApplicationTaskTag( TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TaskHookFunction_t MPU_xTaskGetApplicationTaskTag( TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGetApplicationTaskTagImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskGetApplicationTaskTag_Unpriv \n" + " MPU_xTaskGetApplicationTaskTag_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskGetApplicationTaskTagImpl \n" + " MPU_xTaskGetApplicationTaskTag_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskGetApplicationTaskTagImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_APPLICATION_TASK_TAG == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) + +void MPU_vTaskSetThreadLocalStoragePointer( TaskHandle_t xTaskToSet, + BaseType_t xIndex, + void * pvValue ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskSetThreadLocalStoragePointer( TaskHandle_t xTaskToSet, + BaseType_t xIndex, + void * pvValue ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskSetThreadLocalStoragePointerImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vTaskSetThreadLocalStoragePointer_Unpriv \n" + " MPU_vTaskSetThreadLocalStoragePointer_Priv: \n" + " pop {r0} \n" + " b MPU_vTaskSetThreadLocalStoragePointerImpl \n" + " MPU_vTaskSetThreadLocalStoragePointer_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vTaskSetThreadLocalStoragePointerImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) + +void * MPU_pvTaskGetThreadLocalStoragePointer( TaskHandle_t xTaskToQuery, + BaseType_t xIndex ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void * MPU_pvTaskGetThreadLocalStoragePointer( TaskHandle_t xTaskToQuery, + BaseType_t xIndex ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_pvTaskGetThreadLocalStoragePointerImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_pvTaskGetThreadLocalStoragePointer_Unpriv \n" + " MPU_pvTaskGetThreadLocalStoragePointer_Priv: \n" + " pop {r0} \n" + " b MPU_pvTaskGetThreadLocalStoragePointerImpl \n" + " MPU_pvTaskGetThreadLocalStoragePointer_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_pvTaskGetThreadLocalStoragePointerImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + +UBaseType_t MPU_uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray, + const UBaseType_t uxArraySize, + configRUN_TIME_COUNTER_TYPE * const pulTotalRunTime ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray, + const UBaseType_t uxArraySize, + configRUN_TIME_COUNTER_TYPE * const pulTotalRunTime ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxTaskGetSystemStateImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_uxTaskGetSystemState_Unpriv \n" + " MPU_uxTaskGetSystemState_Priv: \n" + " pop {r0} \n" + " b MPU_uxTaskGetSystemStateImpl \n" + " MPU_uxTaskGetSystemState_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_uxTaskGetSystemStateImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TRACE_FACILITY == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) + +UBaseType_t MPU_uxTaskGetStackHighWaterMark( TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxTaskGetStackHighWaterMark( TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxTaskGetStackHighWaterMarkImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_uxTaskGetStackHighWaterMark_Unpriv \n" + " MPU_uxTaskGetStackHighWaterMark_Priv: \n" + " pop {r0} \n" + " b MPU_uxTaskGetStackHighWaterMarkImpl \n" + " MPU_uxTaskGetStackHighWaterMark_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_uxTaskGetStackHighWaterMarkImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) + +configSTACK_DEPTH_TYPE MPU_uxTaskGetStackHighWaterMark2( TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +configSTACK_DEPTH_TYPE MPU_uxTaskGetStackHighWaterMark2( TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxTaskGetStackHighWaterMark2Impl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_uxTaskGetStackHighWaterMark2_Unpriv \n" + " MPU_uxTaskGetStackHighWaterMark2_Priv: \n" + " pop {r0} \n" + " b MPU_uxTaskGetStackHighWaterMark2Impl \n" + " MPU_uxTaskGetStackHighWaterMark2_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_uxTaskGetStackHighWaterMark2Impl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) ) + +TaskHandle_t MPU_xTaskGetCurrentTaskHandle( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TaskHandle_t MPU_xTaskGetCurrentTaskHandle( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGetCurrentTaskHandleImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskGetCurrentTaskHandle_Unpriv \n" + " MPU_xTaskGetCurrentTaskHandle_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskGetCurrentTaskHandleImpl \n" + " MPU_xTaskGetCurrentTaskHandle_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskGetCurrentTaskHandleImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_xTaskGetSchedulerState == 1 ) + +BaseType_t MPU_xTaskGetSchedulerState( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskGetSchedulerState( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGetSchedulerStateImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskGetSchedulerState_Unpriv \n" + " MPU_xTaskGetSchedulerState_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskGetSchedulerStateImpl \n" + " MPU_xTaskGetSchedulerState_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskGetSchedulerStateImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_xTaskGetSchedulerState == 1 ) */ +/*-----------------------------------------------------------*/ + +void MPU_vTaskSetTimeOutState( TimeOut_t * const pxTimeOut ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskSetTimeOutState( TimeOut_t * const pxTimeOut ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskSetTimeOutStateImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vTaskSetTimeOutState_Unpriv \n" + " MPU_vTaskSetTimeOutState_Priv: \n" + " pop {r0} \n" + " b MPU_vTaskSetTimeOutStateImpl \n" + " MPU_vTaskSetTimeOutState_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vTaskSetTimeOutStateImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut, + TickType_t * const pxTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut, + TickType_t * const pxTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskCheckForTimeOutImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskCheckForTimeOut_Unpriv \n" + " MPU_xTaskCheckForTimeOut_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskCheckForTimeOutImpl \n" + " MPU_xTaskCheckForTimeOut_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskCheckForTimeOutImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +#if ( configUSE_TASK_NOTIFICATIONS == 1 ) + +BaseType_t MPU_xTaskGenericNotify( TaskHandle_t xTaskToNotify, + UBaseType_t uxIndexToNotify, + uint32_t ulValue, + eNotifyAction eAction, + uint32_t * pulPreviousNotificationValue ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskGenericNotify( TaskHandle_t xTaskToNotify, + UBaseType_t uxIndexToNotify, + uint32_t ulValue, + eNotifyAction eAction, + uint32_t * pulPreviousNotificationValue ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGenericNotifyImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskGenericNotify_Unpriv \n" + " MPU_xTaskGenericNotify_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskGenericNotifyImpl \n" + " MPU_xTaskGenericNotify_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskGenericNotifyImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER_1 ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TASK_NOTIFICATIONS == 1 ) + +BaseType_t MPU_xTaskGenericNotifyWait( UBaseType_t uxIndexToWaitOn, + uint32_t ulBitsToClearOnEntry, + uint32_t ulBitsToClearOnExit, + uint32_t * pulNotificationValue, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskGenericNotifyWait( UBaseType_t uxIndexToWaitOn, + uint32_t ulBitsToClearOnEntry, + uint32_t ulBitsToClearOnExit, + uint32_t * pulNotificationValue, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGenericNotifyWaitImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskGenericNotifyWait_Unpriv \n" + " MPU_xTaskGenericNotifyWait_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskGenericNotifyWaitImpl \n" + " MPU_xTaskGenericNotifyWait_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskGenericNotifyWaitImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER_1 ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TASK_NOTIFICATIONS == 1 ) + +uint32_t MPU_ulTaskGenericNotifyTake( UBaseType_t uxIndexToWaitOn, + BaseType_t xClearCountOnExit, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +uint32_t MPU_ulTaskGenericNotifyTake( UBaseType_t uxIndexToWaitOn, + BaseType_t xClearCountOnExit, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_ulTaskGenericNotifyTakeImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_ulTaskGenericNotifyTake_Unpriv \n" + " MPU_ulTaskGenericNotifyTake_Priv: \n" + " pop {r0} \n" + " b MPU_ulTaskGenericNotifyTakeImpl \n" + " MPU_ulTaskGenericNotifyTake_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_ulTaskGenericNotifyTakeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TASK_NOTIFICATIONS == 1 ) + +BaseType_t MPU_xTaskGenericNotifyStateClear( TaskHandle_t xTask, + UBaseType_t uxIndexToClear ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskGenericNotifyStateClear( TaskHandle_t xTask, + UBaseType_t uxIndexToClear ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGenericNotifyStateClearImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskGenericNotifyStateClear_Unpriv \n" + " MPU_xTaskGenericNotifyStateClear_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskGenericNotifyStateClearImpl \n" + " MPU_xTaskGenericNotifyStateClear_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskGenericNotifyStateClearImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TASK_NOTIFICATIONS == 1 ) + +uint32_t MPU_ulTaskGenericNotifyValueClear( TaskHandle_t xTask, + UBaseType_t uxIndexToClear, + uint32_t ulBitsToClear ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +uint32_t MPU_ulTaskGenericNotifyValueClear( TaskHandle_t xTask, + UBaseType_t uxIndexToClear, + uint32_t ulBitsToClear ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_ulTaskGenericNotifyValueClearImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_ulTaskGenericNotifyValueClear_Unpriv \n" + " MPU_ulTaskGenericNotifyValueClear_Priv: \n" + " pop {r0} \n" + " b MPU_ulTaskGenericNotifyValueClearImpl \n" + " MPU_ulTaskGenericNotifyValueClear_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_ulTaskGenericNotifyValueClearImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xQueueGenericSend( QueueHandle_t xQueue, + const void * const pvItemToQueue, + TickType_t xTicksToWait, + const BaseType_t xCopyPosition ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueueGenericSend( QueueHandle_t xQueue, + const void * const pvItemToQueue, + TickType_t xTicksToWait, + const BaseType_t xCopyPosition ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueGenericSendImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xQueueGenericSend_Unpriv \n" + " MPU_xQueueGenericSend_Priv: \n" + " pop {r0} \n" + " b MPU_xQueueGenericSendImpl \n" + " MPU_xQueueGenericSend_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xQueueGenericSendImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +UBaseType_t MPU_uxQueueMessagesWaiting( const QueueHandle_t xQueue ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxQueueMessagesWaiting( const QueueHandle_t xQueue ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxQueueMessagesWaitingImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_uxQueueMessagesWaiting_Unpriv \n" + " MPU_uxQueueMessagesWaiting_Priv: \n" + " pop {r0} \n" + " b MPU_uxQueueMessagesWaitingImpl \n" + " MPU_uxQueueMessagesWaiting_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_uxQueueMessagesWaitingImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +UBaseType_t MPU_uxQueueSpacesAvailable( const QueueHandle_t xQueue ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxQueueSpacesAvailable( const QueueHandle_t xQueue ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxQueueSpacesAvailableImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_uxQueueSpacesAvailable_Unpriv \n" + " MPU_uxQueueSpacesAvailable_Priv: \n" + " pop {r0} \n" + " b MPU_uxQueueSpacesAvailableImpl \n" + " MPU_uxQueueSpacesAvailable_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_uxQueueSpacesAvailableImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xQueueReceive( QueueHandle_t xQueue, + void * const pvBuffer, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueueReceive( QueueHandle_t xQueue, + void * const pvBuffer, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueReceiveImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xQueueReceive_Unpriv \n" + " MPU_xQueueReceive_Priv: \n" + " pop {r0} \n" + " b MPU_xQueueReceiveImpl \n" + " MPU_xQueueReceive_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xQueueReceiveImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xQueuePeek( QueueHandle_t xQueue, + void * const pvBuffer, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueuePeek( QueueHandle_t xQueue, + void * const pvBuffer, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueuePeekImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xQueuePeek_Unpriv \n" + " MPU_xQueuePeek_Priv: \n" + " pop {r0} \n" + " b MPU_xQueuePeekImpl \n" + " MPU_xQueuePeek_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xQueuePeekImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xQueueSemaphoreTake( QueueHandle_t xQueue, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueueSemaphoreTake( QueueHandle_t xQueue, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueSemaphoreTakeImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xQueueSemaphoreTake_Unpriv \n" + " MPU_xQueueSemaphoreTake_Priv: \n" + " pop {r0} \n" + " b MPU_xQueueSemaphoreTakeImpl \n" + " MPU_xQueueSemaphoreTake_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xQueueSemaphoreTakeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +#if ( ( configUSE_MUTEXES == 1 ) && ( INCLUDE_xSemaphoreGetMutexHolder == 1 ) ) + +TaskHandle_t MPU_xQueueGetMutexHolder( QueueHandle_t xSemaphore ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TaskHandle_t MPU_xQueueGetMutexHolder( QueueHandle_t xSemaphore ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueGetMutexHolderImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xQueueGetMutexHolder_Unpriv \n" + " MPU_xQueueGetMutexHolder_Priv: \n" + " pop {r0} \n" + " b MPU_xQueueGetMutexHolderImpl \n" + " MPU_xQueueGetMutexHolder_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xQueueGetMutexHolderImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( ( configUSE_MUTEXES == 1 ) && ( INCLUDE_xSemaphoreGetMutexHolder == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_RECURSIVE_MUTEXES == 1 ) + +BaseType_t MPU_xQueueTakeMutexRecursive( QueueHandle_t xMutex, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueueTakeMutexRecursive( QueueHandle_t xMutex, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueTakeMutexRecursiveImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xQueueTakeMutexRecursive_Unpriv \n" + " MPU_xQueueTakeMutexRecursive_Priv: \n" + " pop {r0} \n" + " b MPU_xQueueTakeMutexRecursiveImpl \n" + " MPU_xQueueTakeMutexRecursive_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xQueueTakeMutexRecursiveImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_RECURSIVE_MUTEXES == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_RECURSIVE_MUTEXES == 1 ) + +BaseType_t MPU_xQueueGiveMutexRecursive( QueueHandle_t pxMutex ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueueGiveMutexRecursive( QueueHandle_t pxMutex ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueGiveMutexRecursiveImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xQueueGiveMutexRecursive_Unpriv \n" + " MPU_xQueueGiveMutexRecursive_Priv: \n" + " pop {r0} \n" + " b MPU_xQueueGiveMutexRecursiveImpl \n" + " MPU_xQueueGiveMutexRecursive_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xQueueGiveMutexRecursiveImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_RECURSIVE_MUTEXES == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_QUEUE_SETS == 1 ) + +QueueSetMemberHandle_t MPU_xQueueSelectFromSet( QueueSetHandle_t xQueueSet, + const TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +QueueSetMemberHandle_t MPU_xQueueSelectFromSet( QueueSetHandle_t xQueueSet, + const TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueSelectFromSetImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xQueueSelectFromSet_Unpriv \n" + " MPU_xQueueSelectFromSet_Priv: \n" + " pop {r0} \n" + " b MPU_xQueueSelectFromSetImpl \n" + " MPU_xQueueSelectFromSet_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xQueueSelectFromSetImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_QUEUE_SETS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_QUEUE_SETS == 1 ) + +BaseType_t MPU_xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore, + QueueSetHandle_t xQueueSet ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore, + QueueSetHandle_t xQueueSet ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueAddToSetImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xQueueAddToSet_Unpriv \n" + " MPU_xQueueAddToSet_Priv: \n" + " pop {r0} \n" + " b MPU_xQueueAddToSetImpl \n" + " MPU_xQueueAddToSet_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xQueueAddToSetImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_QUEUE_SETS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configQUEUE_REGISTRY_SIZE > 0 ) + +void MPU_vQueueAddToRegistry( QueueHandle_t xQueue, + const char * pcName ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vQueueAddToRegistry( QueueHandle_t xQueue, + const char * pcName ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vQueueAddToRegistryImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vQueueAddToRegistry_Unpriv \n" + " MPU_vQueueAddToRegistry_Priv: \n" + " pop {r0} \n" + " b MPU_vQueueAddToRegistryImpl \n" + " MPU_vQueueAddToRegistry_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vQueueAddToRegistryImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configQUEUE_REGISTRY_SIZE > 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configQUEUE_REGISTRY_SIZE > 0 ) + +void MPU_vQueueUnregisterQueue( QueueHandle_t xQueue ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vQueueUnregisterQueue( QueueHandle_t xQueue ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vQueueUnregisterQueueImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vQueueUnregisterQueue_Unpriv \n" + " MPU_vQueueUnregisterQueue_Priv: \n" + " pop {r0} \n" + " b MPU_vQueueUnregisterQueueImpl \n" + " MPU_vQueueUnregisterQueue_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vQueueUnregisterQueueImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configQUEUE_REGISTRY_SIZE > 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configQUEUE_REGISTRY_SIZE > 0 ) + +const char * MPU_pcQueueGetName( QueueHandle_t xQueue ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +const char * MPU_pcQueueGetName( QueueHandle_t xQueue ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_pcQueueGetNameImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_pcQueueGetName_Unpriv \n" + " MPU_pcQueueGetName_Priv: \n" + " pop {r0} \n" + " b MPU_pcQueueGetNameImpl \n" + " MPU_pcQueueGetName_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_pcQueueGetNameImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configQUEUE_REGISTRY_SIZE > 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +void * MPU_pvTimerGetTimerID( const TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void * MPU_pvTimerGetTimerID( const TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_pvTimerGetTimerIDImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_pvTimerGetTimerID_Unpriv \n" + " MPU_pvTimerGetTimerID_Priv: \n" + " pop {r0} \n" + " b MPU_pvTimerGetTimerIDImpl \n" + " MPU_pvTimerGetTimerID_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_pvTimerGetTimerIDImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +void MPU_vTimerSetTimerID( TimerHandle_t xTimer, + void * pvNewID ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTimerSetTimerID( TimerHandle_t xTimer, + void * pvNewID ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTimerSetTimerIDImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vTimerSetTimerID_Unpriv \n" + " MPU_vTimerSetTimerID_Priv: \n" + " pop {r0} \n" + " b MPU_vTimerSetTimerIDImpl \n" + " MPU_vTimerSetTimerID_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vTimerSetTimerIDImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +BaseType_t MPU_xTimerIsTimerActive( TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTimerIsTimerActive( TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTimerIsTimerActiveImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTimerIsTimerActive_Unpriv \n" + " MPU_xTimerIsTimerActive_Priv: \n" + " pop {r0} \n" + " b MPU_xTimerIsTimerActiveImpl \n" + " MPU_xTimerIsTimerActive_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTimerIsTimerActiveImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +TaskHandle_t MPU_xTimerGetTimerDaemonTaskHandle( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TaskHandle_t MPU_xTimerGetTimerDaemonTaskHandle( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTimerGetTimerDaemonTaskHandleImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTimerGetTimerDaemonTaskHandle_Unpriv \n" + " MPU_xTimerGetTimerDaemonTaskHandle_Priv: \n" + " pop {r0} \n" + " b MPU_xTimerGetTimerDaemonTaskHandleImpl \n" + " MPU_xTimerGetTimerDaemonTaskHandle_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTimerGetTimerDaemonTaskHandleImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +BaseType_t MPU_xTimerGenericCommand( TimerHandle_t xTimer, + const BaseType_t xCommandID, + const TickType_t xOptionalValue, + BaseType_t * const pxHigherPriorityTaskWoken, + const TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTimerGenericCommand( TimerHandle_t xTimer, + const BaseType_t xCommandID, + const TickType_t xOptionalValue, + BaseType_t * const pxHigherPriorityTaskWoken, + const TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTimerGenericCommandImpl \n" + " \n" + " push {r0} \n" + " mrs r0, ipsr \n" + " cmp r0, #0 \n" + " bne MPU_xTimerGenericCommand_Priv \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " beq MPU_xTimerGenericCommand_Priv \n" + " MPU_xTimerGenericCommand_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTimerGenericCommandImpl \n" + " svc %1 \n" + " bx lr \n" + " MPU_xTimerGenericCommand_Priv: \n" + " pop {r0} \n" + " b MPU_xTimerGenericCommandImpl \n" + " \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER_1 ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +const char * MPU_pcTimerGetName( TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +const char * MPU_pcTimerGetName( TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_pcTimerGetNameImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_pcTimerGetName_Unpriv \n" + " MPU_pcTimerGetName_Priv: \n" + " pop {r0} \n" + " b MPU_pcTimerGetNameImpl \n" + " MPU_pcTimerGetName_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_pcTimerGetNameImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, + const BaseType_t uxAutoReload ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, + const BaseType_t uxAutoReload ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTimerSetReloadModeImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vTimerSetReloadMode_Unpriv \n" + " MPU_vTimerSetReloadMode_Priv: \n" + " pop {r0} \n" + " b MPU_vTimerSetReloadModeImpl \n" + " MPU_vTimerSetReloadMode_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vTimerSetReloadModeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +BaseType_t MPU_xTimerGetReloadMode( TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTimerGetReloadMode( TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTimerGetReloadModeImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTimerGetReloadMode_Unpriv \n" + " MPU_xTimerGetReloadMode_Priv: \n" + " pop {r0} \n" + " b MPU_xTimerGetReloadModeImpl \n" + " MPU_xTimerGetReloadMode_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTimerGetReloadModeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +UBaseType_t MPU_uxTimerGetReloadMode( TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxTimerGetReloadMode( TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxTimerGetReloadModeImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_uxTimerGetReloadMode_Unpriv \n" + " MPU_uxTimerGetReloadMode_Priv: \n" + " pop {r0} \n" + " b MPU_uxTimerGetReloadModeImpl \n" + " MPU_uxTimerGetReloadMode_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_uxTimerGetReloadModeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +TickType_t MPU_xTimerGetPeriod( TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TickType_t MPU_xTimerGetPeriod( TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTimerGetPeriodImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTimerGetPeriod_Unpriv \n" + " MPU_xTimerGetPeriod_Priv: \n" + " pop {r0} \n" + " b MPU_xTimerGetPeriodImpl \n" + " MPU_xTimerGetPeriod_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTimerGetPeriodImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +TickType_t MPU_xTimerGetExpiryTime( TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TickType_t MPU_xTimerGetExpiryTime( TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTimerGetExpiryTimeImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTimerGetExpiryTime_Unpriv \n" + " MPU_xTimerGetExpiryTime_Priv: \n" + " pop {r0} \n" + " b MPU_xTimerGetExpiryTimeImpl \n" + " MPU_xTimerGetExpiryTime_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTimerGetExpiryTimeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +EventBits_t MPU_xEventGroupWaitBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToWaitFor, + const BaseType_t xClearOnExit, + const BaseType_t xWaitForAllBits, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +EventBits_t MPU_xEventGroupWaitBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToWaitFor, + const BaseType_t xClearOnExit, + const BaseType_t xWaitForAllBits, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupWaitBitsImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xEventGroupWaitBits_Unpriv \n" + " MPU_xEventGroupWaitBits_Priv: \n" + " pop {r0} \n" + " b MPU_xEventGroupWaitBitsImpl \n" + " MPU_xEventGroupWaitBits_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xEventGroupWaitBitsImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER_1 ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToClear ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToClear ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupClearBitsImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xEventGroupClearBits_Unpriv \n" + " MPU_xEventGroupClearBits_Priv: \n" + " pop {r0} \n" + " b MPU_xEventGroupClearBitsImpl \n" + " MPU_xEventGroupClearBits_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xEventGroupClearBitsImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupSetBitsImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xEventGroupSetBits_Unpriv \n" + " MPU_xEventGroupSetBits_Priv: \n" + " pop {r0} \n" + " b MPU_xEventGroupSetBitsImpl \n" + " MPU_xEventGroupSetBits_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xEventGroupSetBitsImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet, + const EventBits_t uxBitsToWaitFor, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet, + const EventBits_t uxBitsToWaitFor, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupSyncImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xEventGroupSync_Unpriv \n" + " MPU_xEventGroupSync_Priv: \n" + " pop {r0} \n" + " b MPU_xEventGroupSyncImpl \n" + " MPU_xEventGroupSync_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xEventGroupSyncImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + +UBaseType_t MPU_uxEventGroupGetNumber( void * xEventGroup ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxEventGroupGetNumber( void * xEventGroup ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxEventGroupGetNumberImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_uxEventGroupGetNumber_Unpriv \n" + " MPU_uxEventGroupGetNumber_Priv: \n" + " pop {r0} \n" + " b MPU_uxEventGroupGetNumberImpl \n" + " MPU_uxEventGroupGetNumber_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_uxEventGroupGetNumberImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /*( configUSE_TRACE_FACILITY == 1 )*/ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + +void MPU_vEventGroupSetNumber( void * xEventGroup, + UBaseType_t uxEventGroupNumber ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vEventGroupSetNumber( void * xEventGroup, + UBaseType_t uxEventGroupNumber ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vEventGroupSetNumberImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vEventGroupSetNumber_Unpriv \n" + " MPU_vEventGroupSetNumber_Priv: \n" + " pop {r0} \n" + " b MPU_vEventGroupSetNumberImpl \n" + " MPU_vEventGroupSetNumber_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vEventGroupSetNumberImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /*( configUSE_TRACE_FACILITY == 1 )*/ +/*-----------------------------------------------------------*/ + +size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, + const void * pvTxData, + size_t xDataLengthBytes, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, + const void * pvTxData, + size_t xDataLengthBytes, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferSendImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferSend_Unpriv \n" + " MPU_xStreamBufferSend_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferSendImpl \n" + " MPU_xStreamBufferSend_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xStreamBufferSendImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, + void * pvRxData, + size_t xBufferLengthBytes, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, + void * pvRxData, + size_t xBufferLengthBytes, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferReceiveImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferReceive_Unpriv \n" + " MPU_xStreamBufferReceive_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferReceiveImpl \n" + " MPU_xStreamBufferReceive_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xStreamBufferReceiveImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferIsFullImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferIsFull_Unpriv \n" + " MPU_xStreamBufferIsFull_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferIsFullImpl \n" + " MPU_xStreamBufferIsFull_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xStreamBufferIsFullImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferIsEmptyImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferIsEmpty_Unpriv \n" + " MPU_xStreamBufferIsEmpty_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferIsEmptyImpl \n" + " MPU_xStreamBufferIsEmpty_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xStreamBufferIsEmptyImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferSpacesAvailableImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferSpacesAvailable_Unpriv \n" + " MPU_xStreamBufferSpacesAvailable_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferSpacesAvailableImpl \n" + " MPU_xStreamBufferSpacesAvailable_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xStreamBufferSpacesAvailableImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferBytesAvailableImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferBytesAvailable_Unpriv \n" + " MPU_xStreamBufferBytesAvailable_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferBytesAvailableImpl \n" + " MPU_xStreamBufferBytesAvailable_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xStreamBufferBytesAvailableImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, + size_t xTriggerLevel ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, + size_t xTriggerLevel ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferSetTriggerLevelImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferSetTriggerLevel_Unpriv \n" + " MPU_xStreamBufferSetTriggerLevel_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferSetTriggerLevelImpl \n" + " MPU_xStreamBufferSetTriggerLevel_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xStreamBufferSetTriggerLevelImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferNextMessageLengthBytesImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferNextMessageLengthBytes_Unpriv \n" + " MPU_xStreamBufferNextMessageLengthBytes_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferNextMessageLengthBytesImpl \n" + " MPU_xStreamBufferNextMessageLengthBytes_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xStreamBufferNextMessageLengthBytesImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ diff --git a/portable/GCC/ARM_CM33/non_secure/port.c b/portable/GCC/ARM_CM33/non_secure/port.c index 7bbe1b7bc53..cab1b3668bf 100644 --- a/portable/GCC/ARM_CM33/non_secure/port.c +++ b/portable/GCC/ARM_CM33/non_secure/port.c @@ -107,6 +107,13 @@ #define portPRIGROUP_SHIFT ( 8UL ) /*-----------------------------------------------------------*/ +/** + * @brief Constants used during system call enter and exit. + */ +#define portPSR_STACK_PADDING_MASK ( 1UL << 9UL ) +#define portEXC_RETURN_STACK_FRAME_TYPE_MASK ( 1UL << 4UL ) +/*-----------------------------------------------------------*/ + /** * @brief Constants required to manipulate the FPU. */ @@ -123,6 +130,14 @@ #define portFPCCR_LSPEN_MASK ( 1UL << portFPCCR_LSPEN_POS ) /*-----------------------------------------------------------*/ +/** + * @brief Offsets in the stack to the parameters when inside the SVC handler. + */ +#define portOFFSET_TO_LR ( 5 ) +#define portOFFSET_TO_PC ( 6 ) +#define portOFFSET_TO_PSR ( 7 ) +/*-----------------------------------------------------------*/ + /** * @brief Constants required to manipulate the MPU. */ @@ -148,6 +163,8 @@ #define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ #define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ +#define portMPU_RBAR_ACCESS_PERMISSIONS_MASK ( 3UL << 1UL ) + #define portMPU_MAIR_ATTR0_POS ( 0UL ) #define portMPU_MAIR_ATTR0_MASK ( 0x000000ff ) @@ -191,6 +208,30 @@ /* Expected value of the portMPU_TYPE register. */ #define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) + +/* Extract first address of the MPU region as encoded in the + * RBAR (Region Base Address Register) value. */ +#define portEXTRACT_FIRST_ADDRESS_FROM_RBAR( rbar ) \ + ( ( rbar ) & portMPU_RBAR_ADDRESS_MASK ) + +/* Extract last address of the MPU region as encoded in the + * RLAR (Region Limit Address Register) value. */ +#define portEXTRACT_LAST_ADDRESS_FROM_RLAR( rlar ) \ + ( ( ( rlar ) & portMPU_RLAR_ADDRESS_MASK ) | ~portMPU_RLAR_ADDRESS_MASK ) + +/* Does addr lies within [start, end] address range? */ +#define portIS_ADDRESS_WITHIN_RANGE( addr, start, end ) \ + ( ( ( addr ) >= ( start ) ) && ( ( addr ) <= ( end ) ) ) + +/* Is the access request satisfied by the available permissions? */ +#define portIS_AUTHORIZED( accessRequest, permissions ) \ + ( ( ( permissions ) & ( accessRequest ) ) == accessRequest ) + +/* 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 ) ) ) /*-----------------------------------------------------------*/ /** @@ -311,6 +352,19 @@ static void prvTaskExitError( void ); #if ( configENABLE_MPU == 1 ) +/** + * @brief Extract MPU region's access permissions from the Region Base Address + * Register (RBAR) value. + * + * @param ulRBARValue RBAR value for the MPU region. + * + * @return uint32_t Access permissions. + */ + static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) PRIVILEGED_FUNCTION; +#endif /* configENABLE_MPU */ + +#if ( configENABLE_MPU == 1 ) + /** * @brief Setup the Memory Protection Unit (MPU). */ @@ -365,6 +419,60 @@ void SysTick_Handler( void ) PRIVILEGED_FUNCTION; * @brief C part of SVC handler. */ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIVILEGED_FUNCTION; + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + + /** + * @brief Sets up the system call stack so that upon returning from + * SVC, the system call stack is used. + * + * It is used for the system calls with up to 4 parameters. + * + * @param pulTaskStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + */ + void vSystemCallEnter( uint32_t * pulTaskStack, uint32_t ulLR ) PRIVILEGED_FUNCTION; + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + + /** + * @brief Sets up the system call stack so that upon returning from + * SVC, the system call stack is used. + * + * It is used for the system calls with 5 parameters. + * + * @param pulTaskStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + */ + void vSystemCallEnter_1( uint32_t * pulTaskStack, uint32_t ulLR ) PRIVILEGED_FUNCTION; + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + + /** + * @brief Sets up the task stack so that upon returning from + * SVC, the task stack is used again. + * + * @param pulSystemCallStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + */ + void vSystemCallExit( uint32_t * pulSystemCallStack, uint32_t ulLR ) PRIVILEGED_FUNCTION; + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + +#if ( configENABLE_MPU == 1 ) + + /** + * @brief Checks whether or not the calling task is privileged. + * + * @return pdTRUE if the calling task is privileged, pdFALSE otherwise. + */ + BaseType_t xPortIsTaskPrivileged( void ) PRIVILEGED_FUNCTION; + +#endif /* configENABLE_MPU == 1 */ /*-----------------------------------------------------------*/ /** @@ -681,6 +789,26 @@ static void prvTaskExitError( void ) } /*-----------------------------------------------------------*/ +#if ( configENABLE_MPU == 1 ) + static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) /* PRIVILEGED_FUNCTION */ + { + uint32_t ulAccessPermissions = 0; + + if( ( ulRBARValue & portMPU_RBAR_ACCESS_PERMISSIONS_MASK ) == portMPU_REGION_READ_ONLY ) + { + ulAccessPermissions = tskMPU_READ_PERMISSION; + } + + if( ( ulRBARValue & portMPU_RBAR_ACCESS_PERMISSIONS_MASK ) == portMPU_REGION_READ_WRITE ) + { + ulAccessPermissions = ( tskMPU_READ_PERMISSION | tskMPU_WRITE_PERMISSION ); + } + + return ulAccessPermissions; + } +#endif /* configENABLE_MPU */ +/*-----------------------------------------------------------*/ + #if ( configENABLE_MPU == 1 ) static void prvSetupMPU( void ) /* PRIVILEGED_FUNCTION */ { @@ -853,7 +981,7 @@ void SysTick_Handler( void ) /* PRIVILEGED_FUNCTION */ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTION portDONT_DISCARD */ { - #if ( configENABLE_MPU == 1 ) + #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) ) #if defined( __ARMCC_VERSION ) /* Declaration when these variable are defined in code instead of being @@ -865,7 +993,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO extern uint32_t __syscalls_flash_start__[]; extern uint32_t __syscalls_flash_end__[]; #endif /* defined( __ARMCC_VERSION ) */ - #endif /* configENABLE_MPU */ + #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */ uint32_t ulPC; @@ -880,7 +1008,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO /* Register are stored on the stack in the following order - R0, R1, R2, R3, * R12, LR, PC, xPSR. */ - ulPC = pulCallerStackAddress[ 6 ]; + ulPC = pulCallerStackAddress[ portOFFSET_TO_PC ]; ucSVCNumber = ( ( uint8_t * ) ulPC )[ -2 ]; switch( ucSVCNumber ) @@ -951,18 +1079,18 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO vRestoreContextOfFirstTask(); break; - #if ( configENABLE_MPU == 1 ) - case portSVC_RAISE_PRIVILEGE: + #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) ) + case portSVC_RAISE_PRIVILEGE: - /* Only raise the privilege, if the svc was raised from any of - * the system calls. */ - if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) && - ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ) - { - vRaisePrivilege(); - } - break; - #endif /* configENABLE_MPU */ + /* Only raise the privilege, if the svc was raised from any of + * the system calls. */ + if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ) + { + vRaisePrivilege(); + } + break; + #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */ default: /* Incorrect SVC call. */ @@ -971,51 +1099,455 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } /*-----------------------------------------------------------*/ -/* *INDENT-OFF* */ -#if ( configENABLE_MPU == 1 ) - StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, - StackType_t * pxEndOfStack, - TaskFunction_t pxCode, - void * pvParameters, - BaseType_t xRunPrivileged ) /* PRIVILEGED_FUNCTION */ -#else - StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, - StackType_t * pxEndOfStack, - TaskFunction_t pxCode, - void * pvParameters ) /* PRIVILEGED_FUNCTION */ -#endif /* configENABLE_MPU */ -/* *INDENT-ON* */ +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + +void vSystemCallEnter( uint32_t * pulTaskStack, uint32_t ulLR ) /* PRIVILEGED_FUNCTION */ { - /* Simulate the stack frame as it would be created by a context switch - * interrupt. */ - #if ( portPRELOAD_REGISTERS == 0 ) + extern TaskHandle_t pxCurrentTCB; + xMPU_SETTINGS * pxMpuSettings; + uint32_t * pulSystemCallStack; + uint32_t ulStackFrameSize, ulSystemCallLocation, i; + #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being + * exported from linker scripts. */ + extern uint32_t * __syscalls_flash_start__; + extern uint32_t * __syscalls_flash_end__; + #else + /* Declaration when these variable are exported from linker scripts. */ + extern uint32_t __syscalls_flash_start__[]; + extern uint32_t __syscalls_flash_end__[]; + #endif /* #if defined( __ARMCC_VERSION ) */ + + ulSystemCallLocation = pulTaskStack[ portOFFSET_TO_PC ]; + + /* If the request did not come from the system call section, do nothing. */ + if( ( ulSystemCallLocation >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulSystemCallLocation <= ( uint32_t ) __syscalls_flash_end__ ) ) { - pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ - *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ - pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pxCode; /* PC */ - pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR */ - pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ - *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ - pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */ - *pxTopOfStack = portINITIAL_EXC_RETURN; + pxMpuSettings = xTaskGetMPUSettings( pxCurrentTCB ); + pulSystemCallStack = pxMpuSettings->xSystemCallStackInfo.pulSystemCallStack; - #if ( configENABLE_MPU == 1 ) + /* This is not NULL only for the duration of the system call. */ + configASSERT( pxMpuSettings->xSystemCallStackInfo.pulTaskStack == NULL ); + + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) { - pxTopOfStack--; + if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) + { + /* Extended frame i.e. FPU in use. */ + ulStackFrameSize = 26; + __asm volatile ( + " vpush {s0} \n" /* Trigger lazy stacking. */ + " vpop {s0} \n" /* Nullify the affect of the above instruction. */ + ::: "memory" + ); + } + else + { + /* Standard frame i.e. FPU not in use. */ + ulStackFrameSize = 8; + } + } + #else + { + ulStackFrameSize = 8; + } + #endif /* configENABLE_FPU || configENABLE_MVE */ + + /* Make space on the system call stack for the stack frame. */ + pulSystemCallStack = pulSystemCallStack - ulStackFrameSize; + + /* Copy the stack frame. */ + for( i = 0; i < ulStackFrameSize; i++ ) + { + pulSystemCallStack[ i ] = pulTaskStack[ i ]; + } + + /* Store the value of the LR and PSPLIM registers before the SVC was raised. We need to + * restore it when we exit from the system call. */ + pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; + __asm volatile ( "mrs %0, psplim" : "=r" ( pxMpuSettings->xSystemCallStackInfo.ulStackLimitRegisterAtSystemCallEntry ) ); + + /* Use the pulSystemCallStack in thread mode. */ + __asm volatile ( "msr psp, %0" : : "r" ( pulSystemCallStack ) ); + __asm volatile ( "msr psplim, %0" : : "r" ( pxMpuSettings->xSystemCallStackInfo.pulSystemCallStackLimit ) ); + + /* Remember the location where we should copy the stack frame when we exit from + * the system call. */ + pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulStackFrameSize; + + /* Record if the hardware used padding to force the stack pointer + * to be double word aligned. */ + if( ( pulTaskStack[ portOFFSET_TO_PSR ] & portPSR_STACK_PADDING_MASK ) == portPSR_STACK_PADDING_MASK ) + { + pxMpuSettings->ulTaskFlags |= portSTACK_FRAME_HAS_PADDING_FLAG; + } + else + { + pxMpuSettings->ulTaskFlags &= ( ~portSTACK_FRAME_HAS_PADDING_FLAG ); + } + + /* We ensure in pxPortInitialiseStack that the system call stack is + * double word aligned and therefore, there is no need of padding. + * Clear the bit[9] of stacked xPSR. */ + pulSystemCallStack[ portOFFSET_TO_PSR ] &= ( ~portPSR_STACK_PADDING_MASK ); + + /* Raise the privilege for the duration of the system call. */ + __asm volatile ( + " mrs r0, control \n" /* Obtain current control value. */ + " movs r1, #1 \n" /* r1 = 1. */ + " bics r0, r1 \n" /* Clear nPRIV bit. */ + " msr control, r0 \n" /* Write back new control value. */ + ::: "r0", "r1", "memory" + ); + } +} - if( xRunPrivileged == pdTRUE ) +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + +void vSystemCallEnter_1( uint32_t * pulTaskStack, uint32_t ulLR ) /* PRIVILEGED_FUNCTION */ +{ + extern TaskHandle_t pxCurrentTCB; + xMPU_SETTINGS * pxMpuSettings; + uint32_t * pulSystemCallStack; + uint32_t ulStackFrameSize, ulSystemCallLocation, i; + #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being + * exported from linker scripts. */ + extern uint32_t * __syscalls_flash_start__; + extern uint32_t * __syscalls_flash_end__; + #else + /* Declaration when these variable are exported from linker scripts. */ + extern uint32_t __syscalls_flash_start__[]; + extern uint32_t __syscalls_flash_end__[]; + #endif /* #if defined( __ARMCC_VERSION ) */ + + ulSystemCallLocation = pulTaskStack[ portOFFSET_TO_PC ]; + + /* If the request did not come from the system call section, do nothing. */ + if( ( ulSystemCallLocation >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulSystemCallLocation <= ( uint32_t ) __syscalls_flash_end__ ) ) + { + pxMpuSettings = xTaskGetMPUSettings( pxCurrentTCB ); + pulSystemCallStack = pxMpuSettings->xSystemCallStackInfo.pulSystemCallStack; + + /* This is not NULL only for the duration of the system call. */ + configASSERT( pxMpuSettings->xSystemCallStackInfo.pulTaskStack == NULL ); + + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + { + if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) { - *pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */ + /* Extended frame i.e. FPU in use. */ + ulStackFrameSize = 26; + __asm volatile ( + " vpush {s0} \n" /* Trigger lazy stacking. */ + " vpop {s0} \n" /* Nullify the affect of the above instruction. */ + ::: "memory" + ); } else { - *pxTopOfStack = portINITIAL_CONTROL_UNPRIVILEGED; /* Slot used to hold this task's CONTROL value. */ + /* Standard frame i.e. FPU not in use. */ + ulStackFrameSize = 8; } } - #endif /* configENABLE_MPU */ + #else + { + ulStackFrameSize = 8; + } + #endif /* configENABLE_FPU || configENABLE_MVE */ + + /* Make space on the system call stack for the stack frame and + * the parameter passed on the stack. We only need to copy one + * parameter but we still reserve 2 spaces to keep the stack + * double word aligned. */ + pulSystemCallStack = pulSystemCallStack - ulStackFrameSize - 2UL; + + /* Copy the stack frame. */ + for( i = 0; i < ulStackFrameSize; i++ ) + { + pulSystemCallStack[ i ] = pulTaskStack[ i ]; + } + + /* Copy the parameter which is passed the stack. */ + if( ( pulTaskStack[ portOFFSET_TO_PSR ] & portPSR_STACK_PADDING_MASK ) == portPSR_STACK_PADDING_MASK ) + { + pulSystemCallStack[ ulStackFrameSize ] = pulTaskStack[ ulStackFrameSize + 1 ]; + /* Record if the hardware used padding to force the stack pointer + * to be double word aligned. */ + pxMpuSettings->ulTaskFlags |= portSTACK_FRAME_HAS_PADDING_FLAG; + } + else + { + pulSystemCallStack[ ulStackFrameSize ] = pulTaskStack[ ulStackFrameSize ]; + /* Record if the hardware used padding to force the stack pointer + * to be double word aligned. */ + pxMpuSettings->ulTaskFlags &= ( ~portSTACK_FRAME_HAS_PADDING_FLAG ); + } + + /* Store the value of the LR and PSPLIM registers before the SVC was raised. + * We need to restore it when we exit from the system call. */ + pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; + __asm volatile ( "mrs %0, psplim" : "=r" ( pxMpuSettings->xSystemCallStackInfo.ulStackLimitRegisterAtSystemCallEntry ) ); + + /* Use the pulSystemCallStack in thread mode. */ + __asm volatile ( "msr psp, %0" : : "r" ( pulSystemCallStack ) ); + __asm volatile ( "msr psplim, %0" : : "r" ( pxMpuSettings->xSystemCallStackInfo.pulSystemCallStackLimit ) ); + + /* Remember the location where we should copy the stack frame when we exit from + * the system call. */ + pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulStackFrameSize; + + /* We ensure in pxPortInitialiseStack that the system call stack is + * double word aligned and therefore, there is no need of padding. + * Clear the bit[9] of stacked xPSR. */ + pulSystemCallStack[ portOFFSET_TO_PSR ] &= ( ~portPSR_STACK_PADDING_MASK ); + + /* Raise the privilege for the duration of the system call. */ + __asm volatile ( + " mrs r0, control \n" /* Obtain current control value. */ + " movs r1, #1 \n" /* r1 = 1. */ + " bics r0, r1 \n" /* Clear nPRIV bit. */ + " msr control, r0 \n" /* Write back new control value. */ + ::: "r0", "r1", "memory" + ); + } +} + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) +void vSystemCallExit( uint32_t * pulSystemCallStack, uint32_t ulLR ) /* PRIVILEGED_FUNCTION */ +{ + extern TaskHandle_t pxCurrentTCB; + xMPU_SETTINGS * pxMpuSettings; + uint32_t * pulTaskStack; + uint32_t ulStackFrameSize, ulSystemCallLocation, i; + #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being + * exported from linker scripts. */ + extern uint32_t * __syscalls_flash_start__; + extern uint32_t * __syscalls_flash_end__; + #else + /* Declaration when these variable are exported from linker scripts. */ + extern uint32_t __syscalls_flash_start__[]; + extern uint32_t __syscalls_flash_end__[]; + #endif /* #if defined( __ARMCC_VERSION ) */ + + ulSystemCallLocation = pulSystemCallStack[ portOFFSET_TO_PC ]; + + /* If the request did not come from the system call section, do nothing. */ + if( ( ulSystemCallLocation >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulSystemCallLocation <= ( uint32_t ) __syscalls_flash_end__ ) ) + { + pxMpuSettings = xTaskGetMPUSettings( pxCurrentTCB ); + pulTaskStack = pxMpuSettings->xSystemCallStackInfo.pulTaskStack; + + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + { + if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) + { + /* Extended frame i.e. FPU in use. */ + ulStackFrameSize = 26; + __asm volatile ( + " vpush {s0} \n" /* Trigger lazy stacking. */ + " vpop {s0} \n" /* Nullify the affect of the above instruction. */ + ::: "memory" + ); + } + else + { + /* Standard frame i.e. FPU not in use. */ + ulStackFrameSize = 8; + } + } + #else + { + ulStackFrameSize = 8; + } + #endif /* configENABLE_FPU || configENABLE_MVE */ + + /* Make space on the task stack for the stack frame. */ + pulTaskStack = pulTaskStack - ulStackFrameSize; + + /* Copy the stack frame. */ + for( i = 0; i < ulStackFrameSize; i++ ) + { + pulTaskStack[ i ] = pulSystemCallStack[ i ]; + } + + /* Use the pulTaskStack in thread mode. */ + __asm volatile ( "msr psp, %0" : : "r" ( pulTaskStack ) ); + + /* Restore the LR and PSPLIM to what they were at the time of + * system call entry. */ + pulTaskStack[ portOFFSET_TO_LR ] = pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry; + __asm volatile ( "msr psplim, %0" : : "r" ( pxMpuSettings->xSystemCallStackInfo.ulStackLimitRegisterAtSystemCallEntry ) ); + + /* If the hardware used padding to force the stack pointer + * to be double word aligned, set the stacked xPSR bit[9], + * otherwise clear it. */ + if( ( pxMpuSettings->ulTaskFlags & portSTACK_FRAME_HAS_PADDING_FLAG ) == portSTACK_FRAME_HAS_PADDING_FLAG ) + { + pulTaskStack[ portOFFSET_TO_PSR ] |= portPSR_STACK_PADDING_MASK; + } + else + { + pulTaskStack[ portOFFSET_TO_PSR ] &= ( ~portPSR_STACK_PADDING_MASK ); + } + + /* This is not NULL only for the duration of the system call. */ + pxMpuSettings->xSystemCallStackInfo.pulTaskStack = NULL; + + /* Drop the privilege before returning to the thread mode. */ + __asm volatile ( + " mrs r0, control \n" /* Obtain current control value. */ + " movs r1, #1 \n" /* r1 = 1. */ + " orrs r0, r1 \n" /* Set nPRIV bit. */ + " msr control, r0 \n" /* Write back new control value. */ + ::: "r0", "r1", "memory" + ); + } +} + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configENABLE_MPU == 1 ) + +BaseType_t xPortIsTaskPrivileged( void ) /* PRIVILEGED_FUNCTION */ +{ + BaseType_t xTaskIsPrivileged = pdFALSE; + const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */ + + if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) + { + xTaskIsPrivileged = pdTRUE; + } + + return xTaskIsPrivileged; +} + +#endif /* configENABLE_MPU == 1 */ +/*-----------------------------------------------------------*/ + +#if( configENABLE_MPU == 1 ) + +StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, + StackType_t * pxEndOfStack, + TaskFunction_t pxCode, + void * pvParameters, + BaseType_t xRunPrivileged, + xMPU_SETTINGS * xMPUSettings ) /* PRIVILEGED_FUNCTION */ +{ + uint32_t ulIndex = 0; + + xMPUSettings->ulContext[ ulIndex ] = 0x04040404; /* r4. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x05050505; /* r5. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x06060606; /* r6. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x07070707; /* r7. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x08080808; /* r8. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x09090909; /* r9. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x10101010; /* r10. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x11111111; /* r11. */ + ulIndex++; + + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pvParameters; /* r0. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x01010101; /* r1. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x02020202; /* r2. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x03030303; /* r3. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x12121212; /* r12. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portTASK_RETURN_ADDRESS; /* LR. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxCode; /* PC. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = portINITIAL_XPSR; /* xPSR. */ + ulIndex++; + + #if ( configENABLE_TRUSTZONE == 1 ) + { + xMPUSettings->ulContext[ ulIndex ] = portNO_SECURE_CONTEXT; /* xSecureContext. */ + ulIndex++; + } + #endif /* configENABLE_TRUSTZONE */ + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) ( pxTopOfStack - 8 ); /* PSP with the hardware saved stack. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */ + ulIndex++; + if( xRunPrivileged == pdTRUE ) + { + xMPUSettings->ulTaskFlags |= portTASK_IS_PRIVILEGED_FLAG; + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_PRIVILEGED; /* CONTROL. */ + ulIndex++; + } + else + { + xMPUSettings->ulTaskFlags &= ( ~portTASK_IS_PRIVILEGED_FLAG ); + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_UNPRIVILEGED; /* CONTROL. */ + ulIndex++; + } + xMPUSettings->ulContext[ ulIndex ] = portINITIAL_EXC_RETURN; /* LR (EXC_RETURN). */ + ulIndex++; + + #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + { + /* Ensure that the system call stack is double word aligned. */ + xMPUSettings->xSystemCallStackInfo.pulSystemCallStack = &( xMPUSettings->xSystemCallStackInfo.ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE - 1 ] ); + xMPUSettings->xSystemCallStackInfo.pulSystemCallStack = ( uint32_t * ) ( ( uint32_t ) ( xMPUSettings->xSystemCallStackInfo.pulSystemCallStack ) & + ( uint32_t ) ( ~( portBYTE_ALIGNMENT_MASK ) ) ); + + xMPUSettings->xSystemCallStackInfo.pulSystemCallStackLimit = &( xMPUSettings->xSystemCallStackInfo.ulSystemCallStackBuffer[ 0 ] ); + xMPUSettings->xSystemCallStackInfo.pulSystemCallStackLimit = ( uint32_t * ) ( ( ( uint32_t ) ( xMPUSettings->xSystemCallStackInfo.pulSystemCallStackLimit ) + + ( uint32_t ) ( portBYTE_ALIGNMENT - 1 ) ) & + ( uint32_t ) ( ~( portBYTE_ALIGNMENT_MASK ) ) ); + + /* This is not NULL only for the duration of a system call. */ + xMPUSettings->xSystemCallStackInfo.pulTaskStack = NULL; + } + #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + + return &( xMPUSettings->ulContext[ ulIndex ] ); +} + +#else /* configENABLE_MPU */ + +StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, + StackType_t * pxEndOfStack, + TaskFunction_t pxCode, + void * pvParameters ) /* PRIVILEGED_FUNCTION */ +{ + /* Simulate the stack frame as it would be created by a context switch + * interrupt. */ + #if ( portPRELOAD_REGISTERS == 0 ) + { + pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ + *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR. */ + pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ + pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */ + *pxTopOfStack = portINITIAL_EXC_RETURN; pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ @@ -1029,55 +1561,39 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO #else /* portPRELOAD_REGISTERS */ { pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ - *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ + *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pxCode; /* PC */ + *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR */ + *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x12121212UL; /* R12 */ + *pxTopOfStack = ( StackType_t ) 0x12121212UL; /* R12. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x03030303UL; /* R3 */ + *pxTopOfStack = ( StackType_t ) 0x03030303UL; /* R3. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x02020202UL; /* R2 */ + *pxTopOfStack = ( StackType_t ) 0x02020202UL; /* R2. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x01010101UL; /* R1 */ + *pxTopOfStack = ( StackType_t ) 0x01010101UL; /* R1. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x11111111UL; /* R11 */ + *pxTopOfStack = ( StackType_t ) 0x11111111UL; /* R11. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x10101010UL; /* R10 */ + *pxTopOfStack = ( StackType_t ) 0x10101010UL; /* R10. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x09090909UL; /* R09 */ + *pxTopOfStack = ( StackType_t ) 0x09090909UL; /* R09. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x08080808UL; /* R08 */ + *pxTopOfStack = ( StackType_t ) 0x08080808UL; /* R08. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x07070707UL; /* R07 */ + *pxTopOfStack = ( StackType_t ) 0x07070707UL; /* R07. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x06060606UL; /* R06 */ + *pxTopOfStack = ( StackType_t ) 0x06060606UL; /* R06. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x05050505UL; /* R05 */ + *pxTopOfStack = ( StackType_t ) 0x05050505UL; /* R05. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x04040404UL; /* R04 */ + *pxTopOfStack = ( StackType_t ) 0x04040404UL; /* R04. */ pxTopOfStack--; - *pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN */ - - #if ( configENABLE_MPU == 1 ) - { - pxTopOfStack--; - - if( xRunPrivileged == pdTRUE ) - { - *pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */ - } - else - { - *pxTopOfStack = portINITIAL_CONTROL_UNPRIVILEGED; /* Slot used to hold this task's CONTROL value. */ - } - } - #endif /* configENABLE_MPU */ - + *pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN. */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ @@ -1092,6 +1608,8 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO return pxTopOfStack; } + +#endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ @@ -1128,6 +1646,10 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ configASSERT( ucMaxSysCallPriority ); + /* Check that the bits not implemented in hardware are zero in + * configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & ( ~ucMaxPriorityValue ) ) == 0U ); + /* Calculate the maximum acceptable priority group value for the number * of bits read back. */ @@ -1164,35 +1686,6 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulImplementedPrioBits; } - /* The interrupt priority bits are not modelled in QEMU and the assert that - * checks the number of implemented bits and __NVIC_PRIO_BITS will always fail. - * Therefore, this assert is not adding any value for QEMU targets. The config - * option `configDISABLE_INTERRUPT_PRIO_BITS_CHECK` should be defined in the - * `FreeRTOSConfig.h` for QEMU targets. */ - #ifndef configDISABLE_INTERRUPT_PRIO_BITS_CHECK - { - #ifdef __NVIC_PRIO_BITS - { - /* - * Check that the number of implemented priority bits queried from - * hardware is equal to the CMSIS __NVIC_PRIO_BITS configuration macro. - */ - configASSERT( ulImplementedPrioBits == __NVIC_PRIO_BITS ); - } - #endif /* __NVIC_PRIO_BITS */ - - #ifdef configPRIO_BITS - { - /* - * Check that the number of implemented priority bits queried from - * hardware is equal to the FreeRTOS configPRIO_BITS configuration macro. - */ - configASSERT( ulImplementedPrioBits == configPRIO_BITS ); - } - #endif /* configPRIO_BITS */ - } - #endif /* #ifndef configDISABLE_INTERRUPT_PRIO_BITS_CHECK */ - /* Shift the priority group value back to its position within the AIRCR * register. */ ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT; @@ -1372,6 +1865,54 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ +#if ( configENABLE_MPU == 1 ) + BaseType_t xPortIsAuthorizedToAccessBuffer( const void * pvBuffer, + uint32_t ulBufferLength, + uint32_t ulAccessRequested ) /* PRIVILEGED_FUNCTION */ + + { + uint32_t i, ulBufferStartAddress, ulBufferEndAddress; + BaseType_t xAccessGranted = pdFALSE; + const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */ + + if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) + { + xAccessGranted = pdTRUE; + } + else + { + if( portADD_UINT32_WILL_OVERFLOW( ( ( uint32_t ) pvBuffer ), ( ulBufferLength - 1UL ) ) == pdFALSE ) + { + ulBufferStartAddress = ( uint32_t ) pvBuffer; + ulBufferEndAddress = ( ( ( uint32_t ) pvBuffer ) + ulBufferLength - 1UL ); + + for( i = 0; i < portTOTAL_NUM_REGIONS; i++ ) + { + /* Is the MPU region enabled? */ + if( ( xTaskMpuSettings->xRegionsSettings[ i ].ulRLAR & portMPU_RLAR_REGION_ENABLE ) == portMPU_RLAR_REGION_ENABLE ) + { + if( portIS_ADDRESS_WITHIN_RANGE( ulBufferStartAddress, + portEXTRACT_FIRST_ADDRESS_FROM_RBAR( xTaskMpuSettings->xRegionsSettings[ i ].ulRBAR ), + portEXTRACT_LAST_ADDRESS_FROM_RLAR( xTaskMpuSettings->xRegionsSettings[ i ].ulRLAR ) ) && + portIS_ADDRESS_WITHIN_RANGE( ulBufferEndAddress, + portEXTRACT_FIRST_ADDRESS_FROM_RBAR( xTaskMpuSettings->xRegionsSettings[ i ].ulRBAR ), + portEXTRACT_LAST_ADDRESS_FROM_RLAR( xTaskMpuSettings->xRegionsSettings[ i ].ulRLAR ) ) && + portIS_AUTHORIZED( ulAccessRequested, + prvGetRegionAccessPermissions( xTaskMpuSettings->xRegionsSettings[ i ].ulRBAR ) ) ) + { + xAccessGranted = pdTRUE; + break; + } + } + } + } + } + + return xAccessGranted; + } +#endif /* configENABLE_MPU */ +/*-----------------------------------------------------------*/ + BaseType_t xPortIsInsideInterrupt( void ) { uint32_t ulCurrentInterrupt; diff --git a/portable/GCC/ARM_CM33/non_secure/portasm.c b/portable/GCC/ARM_CM33/non_secure/portasm.c index 9f9b2e68d39..f7ec7d9c072 100644 --- a/portable/GCC/ARM_CM33/non_secure/portasm.c +++ b/portable/GCC/ARM_CM33/non_secure/portasm.c @@ -40,95 +40,120 @@ * header files. */ #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE +#if ( configENABLE_MPU == 1 ) + void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ { __asm volatile ( - " .syntax unified \n" - " \n" - " ldr r2, pxCurrentTCBConst2 \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - " ldr r3, [r2] \n"/* Read pxCurrentTCB. */ - " ldr r0, [r3] \n"/* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ - " \n" - #if ( configENABLE_MPU == 1 ) - " dmb \n"/* Complete outstanding transfers before disabling MPU. */ - " ldr r2, xMPUCTRLConst2 \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ - " ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */ - " bic r4, #1 \n"/* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */ - " str r4, [r2] \n"/* Disable MPU. */ - " \n" - " adds r3, #4 \n"/* r3 = r3 + 4. r3 now points to MAIR0 in TCB. */ - " ldr r4, [r3] \n"/* r4 = *r3 i.e. r4 = MAIR0. */ - " ldr r2, xMAIR0Const2 \n"/* r2 = 0xe000edc0 [Location of MAIR0]. */ - " str r4, [r2] \n"/* Program MAIR0. */ - " ldr r2, xRNRConst2 \n"/* r2 = 0xe000ed98 [Location of RNR]. */ - " movs r4, #4 \n"/* r4 = 4. */ - " str r4, [r2] \n"/* Program RNR = 4. */ - " adds r3, #4 \n"/* r3 = r3 + 4. r3 now points to first RBAR in TCB. */ - " ldr r2, xRBARConst2 \n"/* r2 = 0xe000ed9c [Location of RBAR]. */ - " ldmia r3!, {r4-r11} \n"/* Read 4 set of RBAR/RLAR registers from TCB. */ - " stmia r2!, {r4-r11} \n"/* Write 4 set of RBAR/RLAR registers using alias registers. */ - " \n" + " .syntax unified \n" + " \n" + " program_mpu_first_task: \n" + " ldr r3, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r0, [r3] \n" /* r0 = pxCurrentTCB. */ + " \n" + " dmb \n" /* Complete outstanding transfers before disabling MPU. */ + " ldr r1, xMPUCTRLConst2 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ + " bic r2, #1 \n" /* r2 = r2 & ~1 i.e. Clear the bit 0 in r2. */ + " str r2, [r1] \n" /* Disable MPU. */ + " \n" + " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */ + " ldr r1, [r0] \n" /* r1 = *r0 i.e. r1 = MAIR0. */ + " ldr r2, xMAIR0Const2 \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */ + " str r1, [r2] \n" /* Program MAIR0. */ + " \n" + " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */ + " ldr r1, xRNRConst2 \n" /* r1 = 0xe000ed98 [Location of RNR]. */ + " ldr r2, xRBARConst2 \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ + " \n" + " movs r3, #4 \n" /* r3 = 4. */ + " str r3, [r1] \n" /* Program RNR = 4. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + " \n" #if ( configTOTAL_MPU_REGIONS == 16 ) - " ldr r2, xRNRConst2 \n"/* r2 = 0xe000ed98 [Location of RNR]. */ - " movs r4, #8 \n"/* r4 = 8. */ - " str r4, [r2] \n"/* Program RNR = 8. */ - " ldr r2, xRBARConst2 \n"/* r2 = 0xe000ed9c [Location of RBAR]. */ - " ldmia r3!, {r4-r11} \n"/* Read 4 set of RBAR/RLAR registers from TCB. */ - " stmia r2!, {r4-r11} \n"/* Write 4 set of RBAR/RLAR registers using alias registers. */ - " ldr r2, xRNRConst2 \n"/* r2 = 0xe000ed98 [Location of RNR]. */ - " movs r4, #12 \n"/* r4 = 12. */ - " str r4, [r2] \n"/* Program RNR = 12. */ - " ldr r2, xRBARConst2 \n"/* r2 = 0xe000ed9c [Location of RBAR]. */ - " ldmia r3!, {r4-r11} \n"/* Read 4 set of RBAR/RLAR registers from TCB. */ - " stmia r2!, {r4-r11} \n"/* Write 4 set of RBAR/RLAR registers using alias registers. */ + " movs r3, #8 \n" /* r3 = 8. */ + " str r3, [r1] \n" /* Program RNR = 8. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + " movs r3, #12 \n" /* r3 = 12. */ + " str r3, [r1] \n" /* Program RNR = 12. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ #endif /* configTOTAL_MPU_REGIONS == 16 */ - " \n" - " ldr r2, xMPUCTRLConst2 \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ - " ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */ - " orr r4, #1 \n"/* r4 = r4 | 1 i.e. Set the bit 0 in r4. */ - " str r4, [r2] \n"/* Enable MPU. */ - " dsb \n"/* Force memory writes before continuing. */ - #endif /* configENABLE_MPU */ + " \n" + " ldr r1, xMPUCTRLConst2 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ + " orr r2, #1 \n" /* r2 = r1 | 1 i.e. Set the bit 0 in r2. */ + " str r2, [r1] \n" /* Enable MPU. */ + " dsb \n" /* Force memory writes before continuing. */ + " \n" + " restore_context_first_task: \n" + " ldr r3, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r1, [r3] \n" /* r1 = pxCurrentTCB.*/ + " ldr r2, [r1] \n" /* r2 = Location of saved context in TCB. */ + " \n" + " restore_special_regs_first_task: \n" + " ldmdb r2!, {r0, r3-r5, lr} \n" /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */ + " msr psp, r3 \n" + " msr psplim, r4 \n" + " msr control, r5 \n" + " ldr r4, xSecureContextConst2 \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ + " str r0, [r4] \n" /* Restore xSecureContext. */ + " \n" + " restore_general_regs_first_task: \n" + " ldmdb r2!, {r4-r11} \n" /* r4-r11 contain hardware saved context. */ + " stmia r3!, {r4-r11} \n" /* Copy the hardware saved context on the task stack. */ + " ldmdb r2!, {r4-r11} \n" /* r4-r11 restored. */ + " \n" + " restore_context_done_first_task: \n" + " str r2, [r1] \n" /* Save the location where the context should be saved next as the first member of TCB. */ + " mov r0, #0 \n" + " msr basepri, r0 \n" /* Ensure that interrupts are enabled when the first task starts. */ + " bx lr \n" + " \n" + " .align 4 \n" + " pxCurrentTCBConst2: .word pxCurrentTCB \n" + " xSecureContextConst2: .word xSecureContext \n" + " xMPUCTRLConst2: .word 0xe000ed94 \n" + " xMAIR0Const2: .word 0xe000edc0 \n" + " xRNRConst2: .word 0xe000ed98 \n" + " xRBARConst2: .word 0xe000ed9c \n" + ); +} + +#else /* configENABLE_MPU */ + +void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ +{ + __asm volatile + ( + " .syntax unified \n" " \n" - #if ( configENABLE_MPU == 1 ) - " ldm r0!, {r1-r4} \n"/* Read from stack - r1 = xSecureContext, r2 = PSPLIM, r3 = CONTROL and r4 = EXC_RETURN. */ - " ldr r5, xSecureContextConst2 \n" - " str r1, [r5] \n"/* Set xSecureContext to this task's value for the same. */ - " msr psplim, r2 \n"/* Set this task's PSPLIM value. */ - " msr control, r3 \n"/* Set this task's CONTROL value. */ - " adds r0, #32 \n"/* Discard everything up to r0. */ - " msr psp, r0 \n"/* This is now the new top of stack to use in the task. */ - " isb \n" - " mov r0, #0 \n" - " msr basepri, r0 \n"/* Ensure that interrupts are enabled when the first task starts. */ - " bx r4 \n"/* Finally, branch to EXC_RETURN. */ - #else /* configENABLE_MPU */ - " ldm r0!, {r1-r3} \n"/* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */ - " ldr r4, xSecureContextConst2 \n" - " str r1, [r4] \n"/* Set xSecureContext to this task's value for the same. */ - " msr psplim, r2 \n"/* Set this task's PSPLIM value. */ - " movs r1, #2 \n"/* r1 = 2. */ - " msr CONTROL, r1 \n"/* Switch to use PSP in the thread mode. */ - " adds r0, #32 \n"/* Discard everything up to r0. */ - " msr psp, r0 \n"/* This is now the new top of stack to use in the task. */ - " isb \n" - " mov r0, #0 \n" - " msr basepri, r0 \n"/* Ensure that interrupts are enabled when the first task starts. */ - " bx r3 \n"/* Finally, branch to EXC_RETURN. */ - #endif /* configENABLE_MPU */ + " ldr r2, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r3, [r2] \n" /* Read pxCurrentTCB. */ + " ldr r0, [r3] \n" /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ " \n" + " ldm r0!, {r1-r3} \n" /* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */ + " ldr r4, xSecureContextConst2 \n" + " str r1, [r4] \n" /* Set xSecureContext to this task's value for the same. */ + " msr psplim, r2 \n" /* Set this task's PSPLIM value. */ + " movs r1, #2 \n" /* r1 = 2. */ + " msr CONTROL, r1 \n" /* Switch to use PSP in the thread mode. */ + " adds r0, #32 \n" /* Discard everything up to r0. */ + " msr psp, r0 \n" /* This is now the new top of stack to use in the task. */ + " isb \n" + " mov r0, #0 \n" + " msr basepri, r0 \n" /* Ensure that interrupts are enabled when the first task starts. */ + " bx r3 \n" /* Finally, branch to EXC_RETURN. */ " .align 4 \n" "pxCurrentTCBConst2: .word pxCurrentTCB \n" "xSecureContextConst2: .word xSecureContext \n" - #if ( configENABLE_MPU == 1 ) - "xMPUCTRLConst2: .word 0xe000ed94 \n" - "xMAIR0Const2: .word 0xe000edc0 \n" - "xRNRConst2: .word 0xe000ed98 \n" - "xRBARConst2: .word 0xe000ed9c \n" - #endif /* configENABLE_MPU */ ); } + +#endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */ @@ -236,6 +261,160 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att } /*-----------------------------------------------------------*/ +#if ( configENABLE_MPU == 1 ) + +void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern SecureContext_SaveContext \n" + " .extern SecureContext_LoadContext \n" + " \n" + " ldr r3, xSecureContextConst \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ + " ldr r0, [r3] \n" /* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */ + " ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r1, [r3] \n" /* Read pxCurrentTCB - Value of pxCurrentTCB must be in r1 as it is used as a parameter later. */ + " ldr r2, [r1] \n" /* r2 = Location in TCB where the context should be saved. */ + " \n" + " cbz r0, save_ns_context \n" /* No secure context to save. */ + " save_s_context: \n" + " push {r0-r2, lr} \n" + " bl SecureContext_SaveContext \n" /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ + " pop {r0-r2, lr} \n" + " \n" + " save_ns_context: \n" + " mov r3, lr \n" /* r3 = LR (EXC_RETURN). */ + " lsls r3, r3, #25 \n" /* r3 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ + " bmi save_special_regs \n" /* r3 < 0 ==> Bit[6] in EXC_RETURN is 1 ==> secure stack was used to store the stack frame. */ + " \n" + " save_general_regs: \n" + " mrs r3, psp \n" + " \n" + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + " add r3, r3, #0x20 \n" /* Move r3 to location where s0 is saved. */ + " tst lr, #0x10 \n" + " ittt eq \n" + " vstmiaeq r2!, {s16-s31} \n" /* Store s16-s31. */ + " vldmiaeq r3, {s0-s16} \n" /* Copy hardware saved FP context into s0-s16. */ + " vstmiaeq r2!, {s0-s16} \n" /* Store hardware saved FP context. */ + " sub r3, r3, #0x20 \n" /* Set r3 back to the location of hardware saved context. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ + " \n" + " stmia r2!, {r4-r11} \n" /* Store r4-r11. */ + " ldmia r3, {r4-r11} \n" /* Copy the hardware saved context into r4-r11. */ + " stmia r2!, {r4-r11} \n" /* Store the hardware saved context. */ + " \n" + " save_special_regs: \n" + " mrs r3, psp \n" /* r3 = PSP. */ + " mrs r4, psplim \n" /* r4 = PSPLIM. */ + " mrs r5, control \n" /* r5 = CONTROL. */ + " stmia r2!, {r0, r3-r5, lr} \n" /* Store xSecureContext, original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */ + " str r2, [r1] \n" /* Save the location from where the context should be restored as the first member of TCB. */ + " \n" + " select_next_task: \n" + " mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */ + " msr basepri, r0 \n" /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + " dsb \n" + " isb \n" + " bl vTaskSwitchContext \n" + " mov r0, #0 \n" /* r0 = 0. */ + " msr basepri, r0 \n" /* Enable interrupts. */ + " \n" + " program_mpu: \n" + " ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r0, [r3] \n" /* r0 = pxCurrentTCB.*/ + " \n" + " dmb \n" /* Complete outstanding transfers before disabling MPU. */ + " ldr r1, xMPUCTRLConst \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ + " bic r2, #1 \n" /* r2 = r2 & ~1 i.e. Clear the bit 0 in r2. */ + " str r2, [r1] \n" /* Disable MPU. */ + " \n" + " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */ + " ldr r1, [r0] \n" /* r1 = *r0 i.e. r1 = MAIR0. */ + " ldr r2, xMAIR0Const \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */ + " str r1, [r2] \n" /* Program MAIR0. */ + " \n" + " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */ + " ldr r1, xRNRConst \n" /* r1 = 0xe000ed98 [Location of RNR]. */ + " ldr r2, xRBARConst \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ + " \n" + " movs r3, #4 \n" /* r3 = 4. */ + " str r3, [r1] \n" /* Program RNR = 4. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + " \n" + #if ( configTOTAL_MPU_REGIONS == 16 ) + " movs r3, #8 \n" /* r3 = 8. */ + " str r3, [r1] \n" /* Program RNR = 8. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + " movs r3, #12 \n" /* r3 = 12. */ + " str r3, [r1] \n" /* Program RNR = 12. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + #endif /* configTOTAL_MPU_REGIONS == 16 */ + " \n" + " ldr r1, xMPUCTRLConst \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ + " orr r2, #1 \n" /* r2 = r2 | 1 i.e. Set the bit 0 in r2. */ + " str r2, [r1] \n" /* Enable MPU. */ + " dsb \n" /* Force memory writes before continuing. */ + " \n" + " restore_context: \n" + " ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r1, [r3] \n" /* r1 = pxCurrentTCB.*/ + " ldr r2, [r1] \n" /* r2 = Location of saved context in TCB. */ + " \n" + " restore_special_regs: \n" + " ldmdb r2!, {r0, r3-r5, lr} \n" /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */ + " msr psp, r3 \n" + " msr psplim, r4 \n" + " msr control, r5 \n" + " ldr r4, xSecureContextConst \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ + " str r0, [r4] \n" /* Restore xSecureContext. */ + " cbz r0, restore_ns_context \n" /* No secure context to restore. */ + " \n" + " restore_s_context: \n" + " push {r1-r3, lr} \n" + " bl SecureContext_LoadContext \n" /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ + " pop {r1-r3, lr} \n" + " \n" + " restore_ns_context: \n" + " mov r0, lr \n" /* r0 = LR (EXC_RETURN). */ + " lsls r0, r0, #25 \n" /* r0 = r0 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ + " bmi restore_context_done \n" /* r0 < 0 ==> Bit[6] in EXC_RETURN is 1 ==> secure stack was used to store the stack frame. */ + " \n" + " restore_general_regs: \n" + " ldmdb r2!, {r4-r11} \n" /* r4-r11 contain hardware saved context. */ + " stmia r3!, {r4-r11} \n" /* Copy the hardware saved context on the task stack. */ + " ldmdb r2!, {r4-r11} \n" /* r4-r11 restored. */ + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + " tst lr, #0x10 \n" + " ittt eq \n" + " vldmdbeq r2!, {s0-s16} \n" /* s0-s16 contain hardware saved FP context. */ + " vstmiaeq r3!, {s0-s16} \n" /* Copy hardware saved FP context on the task stack. */ + " vldmdbeq r2!, {s16-s31} \n" /* Restore s16-s31. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ + " \n" + " restore_context_done: \n" + " str r2, [r1] \n" /* Save the location where the context should be saved next as the first member of TCB. */ + " bx lr \n" + " \n" + " .align 4 \n" + " pxCurrentTCBConst: .word pxCurrentTCB \n" + " xSecureContextConst: .word xSecureContext \n" + " xMPUCTRLConst: .word 0xe000ed94 \n" + " xMAIR0Const: .word 0xe000edc0 \n" + " xRNRConst: .word 0xe000ed98 \n" + " xRBARConst: .word 0xe000ed9c \n" + ::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) + ); +} + +#else /* configENABLE_MPU */ + void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ { __asm volatile @@ -260,20 +439,11 @@ void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ " \n" " ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r3] \n"/* Read pxCurrentTCB.*/ - #if ( configENABLE_MPU == 1 ) - " subs r2, r2, #16 \n"/* Make space for xSecureContext, PSPLIM, CONTROL and LR on the stack. */ - " str r2, [r1] \n"/* Save the new top of stack in TCB. */ - " mrs r1, psplim \n"/* r1 = PSPLIM. */ - " mrs r3, control \n"/* r3 = CONTROL. */ - " mov r4, lr \n"/* r4 = LR/EXC_RETURN. */ - " stmia r2!, {r0, r1, r3, r4} \n"/* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */ - #else /* configENABLE_MPU */ - " subs r2, r2, #12 \n"/* Make space for xSecureContext, PSPLIM and LR on the stack. */ - " str r2, [r1] \n"/* Save the new top of stack in TCB. */ - " mrs r1, psplim \n"/* r1 = PSPLIM. */ - " mov r3, lr \n"/* r3 = LR/EXC_RETURN. */ - " stmia r2!, {r0, r1, r3} \n"/* Store xSecureContext, PSPLIM and LR on the stack. */ - #endif /* configENABLE_MPU */ + " subs r2, r2, #12 \n"/* Make space for xSecureContext, PSPLIM and LR on the stack. */ + " str r2, [r1] \n"/* Save the new top of stack in TCB. */ + " mrs r1, psplim \n"/* r1 = PSPLIM. */ + " mov r3, lr \n"/* r3 = LR/EXC_RETURN. */ + " stmia r2!, {r0, r1, r3} \n"/* Store xSecureContext, PSPLIM and LR on the stack. */ " b select_next_task \n" " \n" " save_ns_context: \n" @@ -284,26 +454,14 @@ void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ " it eq \n" " vstmdbeq r2!, {s16-s31} \n"/* Store the additional FP context registers which are not saved automatically. */ #endif /* configENABLE_FPU || configENABLE_MVE */ - #if ( configENABLE_MPU == 1 ) - " subs r2, r2, #48 \n"/* Make space for xSecureContext, PSPLIM, CONTROL, LR and the remaining registers on the stack. */ - " str r2, [r1] \n"/* Save the new top of stack in TCB. */ - " adds r2, r2, #16 \n"/* r2 = r2 + 16. */ - " stm r2, {r4-r11} \n"/* Store the registers that are not saved automatically. */ - " mrs r1, psplim \n"/* r1 = PSPLIM. */ - " mrs r3, control \n"/* r3 = CONTROL. */ - " mov r4, lr \n"/* r4 = LR/EXC_RETURN. */ - " subs r2, r2, #16 \n"/* r2 = r2 - 16. */ - " stmia r2!, {r0, r1, r3, r4} \n"/* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */ - #else /* configENABLE_MPU */ - " subs r2, r2, #44 \n"/* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */ - " str r2, [r1] \n"/* Save the new top of stack in TCB. */ - " adds r2, r2, #12 \n"/* r2 = r2 + 12. */ - " stm r2, {r4-r11} \n"/* Store the registers that are not saved automatically. */ - " mrs r1, psplim \n"/* r1 = PSPLIM. */ - " mov r3, lr \n"/* r3 = LR/EXC_RETURN. */ - " subs r2, r2, #12 \n"/* r2 = r2 - 12. */ - " stmia r2!, {r0, r1, r3} \n"/* Store xSecureContext, PSPLIM and LR on the stack. */ - #endif /* configENABLE_MPU */ + " subs r2, r2, #44 \n"/* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */ + " str r2, [r1] \n"/* Save the new top of stack in TCB. */ + " adds r2, r2, #12 \n"/* r2 = r2 + 12. */ + " stm r2, {r4-r11} \n"/* Store the registers that are not saved automatically. */ + " mrs r1, psplim \n"/* r1 = PSPLIM. */ + " mov r3, lr \n"/* r3 = LR/EXC_RETURN. */ + " subs r2, r2, #12 \n"/* r2 = r2 - 12. */ + " stmia r2!, {r0, r1, r3} \n"/* Store xSecureContext, PSPLIM and LR on the stack. */ " \n" " select_next_task: \n" " mov r0, %0 \n"/* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */ @@ -318,83 +476,22 @@ void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ " ldr r1, [r3] \n"/* Read pxCurrentTCB. */ " ldr r2, [r1] \n"/* The first item in pxCurrentTCB is the task top of stack. r2 now points to the top of stack. */ " \n" - #if ( configENABLE_MPU == 1 ) - " dmb \n"/* Complete outstanding transfers before disabling MPU. */ - " ldr r3, xMPUCTRLConst \n"/* r3 = 0xe000ed94 [Location of MPU_CTRL]. */ - " ldr r4, [r3] \n"/* Read the value of MPU_CTRL. */ - " bic r4, #1 \n"/* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */ - " str r4, [r3] \n"/* Disable MPU. */ - " \n" - " adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */ - " ldr r4, [r1] \n"/* r4 = *r1 i.e. r4 = MAIR0. */ - " ldr r3, xMAIR0Const \n"/* r3 = 0xe000edc0 [Location of MAIR0]. */ - " str r4, [r3] \n"/* Program MAIR0. */ - " ldr r3, xRNRConst \n"/* r3 = 0xe000ed98 [Location of RNR]. */ - " movs r4, #4 \n"/* r4 = 4. */ - " str r4, [r3] \n"/* Program RNR = 4. */ - " adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to first RBAR in TCB. */ - " ldr r3, xRBARConst \n"/* r3 = 0xe000ed9c [Location of RBAR]. */ - " ldmia r1!, {r4-r11} \n"/* Read 4 sets of RBAR/RLAR registers from TCB. */ - " stmia r3!, {r4-r11} \n"/* Write 4 set of RBAR/RLAR registers using alias registers. */ - " \n" - #if ( configTOTAL_MPU_REGIONS == 16 ) - " ldr r3, xRNRConst \n"/* r3 = 0xe000ed98 [Location of RNR]. */ - " movs r4, #8 \n"/* r4 = 8. */ - " str r4, [r3] \n"/* Program RNR = 8. */ - " ldr r3, xRBARConst \n"/* r3 = 0xe000ed9c [Location of RBAR]. */ - " ldmia r1!, {r4-r11} \n"/* Read 4 sets of RBAR/RLAR registers from TCB. */ - " stmia r3!, {r4-r11} \n"/* Write 4 set of RBAR/RLAR registers using alias registers. */ - " ldr r3, xRNRConst \n"/* r3 = 0xe000ed98 [Location of RNR]. */ - " movs r4, #12 \n"/* r4 = 12. */ - " str r4, [r3] \n"/* Program RNR = 12. */ - " ldr r3, xRBARConst \n"/* r3 = 0xe000ed9c [Location of RBAR]. */ - " ldmia r1!, {r4-r11} \n"/* Read 4 sets of RBAR/RLAR registers from TCB. */ - " stmia r3!, {r4-r11} \n"/* Write 4 set of RBAR/RLAR registers using alias registers. */ - #endif /* configTOTAL_MPU_REGIONS == 16 */ - " \n" - " ldr r3, xMPUCTRLConst \n"/* r3 = 0xe000ed94 [Location of MPU_CTRL]. */ - " ldr r4, [r3] \n"/* Read the value of MPU_CTRL. */ - " orr r4, #1 \n"/* r4 = r4 | 1 i.e. Set the bit 0 in r4. */ - " str r4, [r3] \n"/* Enable MPU. */ - " dsb \n"/* Force memory writes before continuing. */ - #endif /* configENABLE_MPU */ - " \n" - #if ( configENABLE_MPU == 1 ) - " ldmia r2!, {r0, r1, r3, r4} \n"/* Read from stack - r0 = xSecureContext, r1 = PSPLIM, r3 = CONTROL and r4 = LR. */ - " msr psplim, r1 \n"/* Restore the PSPLIM register value for the task. */ - " msr control, r3 \n"/* Restore the CONTROL register value for the task. */ - " mov lr, r4 \n"/* LR = r4. */ - " ldr r3, xSecureContextConst \n"/* Read the location of xSecureContext i.e. &( xSecureContext ). */ - " str r0, [r3] \n"/* Restore the task's xSecureContext. */ - " cbz r0, restore_ns_context \n"/* If there is no secure context for the task, restore the non-secure context. */ - " ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - " ldr r1, [r3] \n"/* Read pxCurrentTCB. */ - " push {r2, r4} \n" - " bl SecureContext_LoadContext \n"/* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ - " pop {r2, r4} \n" - " mov lr, r4 \n"/* LR = r4. */ - " lsls r1, r4, #25 \n"/* r1 = r4 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ - " bpl restore_ns_context \n"/* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ - " msr psp, r2 \n"/* Remember the new top of stack for the task. */ - " bx lr \n" - #else /* configENABLE_MPU */ - " ldmia r2!, {r0, r1, r4} \n"/* Read from stack - r0 = xSecureContext, r1 = PSPLIM and r4 = LR. */ - " msr psplim, r1 \n"/* Restore the PSPLIM register value for the task. */ - " mov lr, r4 \n"/* LR = r4. */ - " ldr r3, xSecureContextConst \n"/* Read the location of xSecureContext i.e. &( xSecureContext ). */ - " str r0, [r3] \n"/* Restore the task's xSecureContext. */ - " cbz r0, restore_ns_context \n"/* If there is no secure context for the task, restore the non-secure context. */ - " ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - " ldr r1, [r3] \n"/* Read pxCurrentTCB. */ - " push {r2, r4} \n" - " bl SecureContext_LoadContext \n"/* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ - " pop {r2, r4} \n" - " mov lr, r4 \n"/* LR = r4. */ - " lsls r1, r4, #25 \n"/* r1 = r4 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ - " bpl restore_ns_context \n"/* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ - " msr psp, r2 \n"/* Remember the new top of stack for the task. */ - " bx lr \n" - #endif /* configENABLE_MPU */ + " ldmia r2!, {r0, r1, r4} \n"/* Read from stack - r0 = xSecureContext, r1 = PSPLIM and r4 = LR. */ + " msr psplim, r1 \n"/* Restore the PSPLIM register value for the task. */ + " mov lr, r4 \n"/* LR = r4. */ + " ldr r3, xSecureContextConst \n"/* Read the location of xSecureContext i.e. &( xSecureContext ). */ + " str r0, [r3] \n"/* Restore the task's xSecureContext. */ + " cbz r0, restore_ns_context \n"/* If there is no secure context for the task, restore the non-secure context. */ + " ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r1, [r3] \n"/* Read pxCurrentTCB. */ + " push {r2, r4} \n" + " bl SecureContext_LoadContext \n"/* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ + " pop {r2, r4} \n" + " mov lr, r4 \n"/* LR = r4. */ + " lsls r1, r4, #25 \n"/* r1 = r4 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ + " bpl restore_ns_context \n"/* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ + " msr psp, r2 \n"/* Remember the new top of stack for the task. */ + " bx lr \n" " \n" " restore_ns_context: \n" " ldmia r2!, {r4-r11} \n"/* Restore the registers that are not automatically restored. */ @@ -409,17 +506,60 @@ void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ " .align 4 \n" "pxCurrentTCBConst: .word pxCurrentTCB \n" "xSecureContextConst: .word xSecureContext \n" - #if ( configENABLE_MPU == 1 ) - "xMPUCTRLConst: .word 0xe000ed94 \n" - "xMAIR0Const: .word 0xe000edc0 \n" - "xRNRConst: .word 0xe000ed98 \n" - "xRBARConst: .word 0xe000ed9c \n" - #endif /* configENABLE_MPU */ ::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) ); } + +#endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + +void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ +{ + __asm volatile + ( + ".syntax unified \n" + ".extern vPortSVCHandler_C \n" + ".extern vSystemCallEnter \n" + ".extern vSystemCallEnter_1 \n" + ".extern vSystemCallExit \n" + " \n" + "tst lr, #4 \n" + "ite eq \n" + "mrseq r0, msp \n" + "mrsne r0, psp \n" + " \n" + "ldr r1, [r0, #24] \n" + "ldrb r2, [r1, #-2] \n" + "cmp r2, %0 \n" + "beq syscall_enter \n" + "cmp r2, %1 \n" + "beq syscall_enter_1 \n" + "cmp r2, %2 \n" + "beq syscall_exit \n" + "b vPortSVCHandler_C \n" + " \n" + "syscall_enter: \n" + " mov r1, lr \n" + " b vSystemCallEnter \n" + " \n" + "syscall_enter_1: \n" + " mov r1, lr \n" + " b vSystemCallEnter_1 \n" + " \n" + "syscall_exit: \n" + " mov r1, lr \n" + " b vSystemCallExit \n" + " \n" + : /* No outputs. */ + :"i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_ENTER_1 ), "i" ( portSVC_SYSTEM_CALL_EXIT ) + : "r0", "r1", "r2", "memory" + ); +} + +#else /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ { __asm volatile @@ -437,6 +577,8 @@ void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ "svchandler_address_const: .word vPortSVCHandler_C \n" ); } + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ /*-----------------------------------------------------------*/ void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) /* __attribute__ (( naked )) */ diff --git a/portable/GCC/ARM_CM33/non_secure/portmacro.h b/portable/GCC/ARM_CM33/non_secure/portmacro.h index 19da9b0ecfe..b9efb07ddc7 100644 --- a/portable/GCC/ARM_CM33/non_secure/portmacro.h +++ b/portable/GCC/ARM_CM33/non_secure/portmacro.h @@ -51,7 +51,6 @@ #define portARCH_NAME "Cortex-M33" #define portHAS_BASEPRI 1 #define portDONT_DISCARD __attribute__( ( used ) ) -#define portNORETURN __attribute__( ( noreturn ) ) /*-----------------------------------------------------------*/ /* ARMv8-M common port configurations. */ diff --git a/portable/GCC/ARM_CM33/non_secure/portmacrocommon.h b/portable/GCC/ARM_CM33/non_secure/portmacrocommon.h index c2ca5fa7730..65ac109c802 100644 --- a/portable/GCC/ARM_CM33/non_secure/portmacrocommon.h +++ b/portable/GCC/ARM_CM33/non_secure/portmacrocommon.h @@ -186,23 +186,120 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #define portMPU_REGION_EXECUTE_NEVER ( 1UL ) /*-----------------------------------------------------------*/ -/** - * @brief Settings to define an MPU region. - */ -typedef struct MPURegionSettings -{ - uint32_t ulRBAR; /**< RBAR for the region. */ - uint32_t ulRLAR; /**< RLAR for the region. */ -} MPURegionSettings_t; +#if ( configENABLE_MPU == 1 ) -/** - * @brief MPU settings as stored in the TCB. - */ -typedef struct MPU_SETTINGS -{ - uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ - MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */ -} xMPU_SETTINGS; + /** + * @brief Settings to define an MPU region. + */ + typedef struct MPURegionSettings + { + uint32_t ulRBAR; /**< RBAR for the region. */ + uint32_t ulRLAR; /**< RLAR for the region. */ + } MPURegionSettings_t; + + #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + + #ifndef configSYSTEM_CALL_STACK_SIZE + #error configSYSTEM_CALL_STACK_SIZE must be defined to the desired size of the system call stack in words for using MPU wrappers v2. + #endif + + /** + * @brief System call stack. + */ + typedef struct SYSTEM_CALL_STACK_INFO + { + uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ]; + uint32_t * pulSystemCallStack; + uint32_t * pulSystemCallStackLimit; + uint32_t * pulTaskStack; + uint32_t ulLinkRegisterAtSystemCallEntry; + uint32_t ulStackLimitRegisterAtSystemCallEntry; + } xSYSTEM_CALL_STACK_INFO; + + #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + + /** + * @brief MPU settings as stored in the TCB. + */ + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + + #if( configENABLE_TRUSTZONE == 1 ) + + /* + * +-----------+---------------+----------+-----------------+------------------------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | + * | | | | PC, xPSR | CONTROL, EXC_RETURN | | + * +-----------+---------------+----------+-----------------+------------------------------+-----+ + * + * <-----------><--------------><---------><----------------><-----------------------------><----> + * 16 16 8 8 5 1 + */ + #define MAX_CONTEXT_SIZE 54 + + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ + + /* + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | + * | | | | PC, xPSR | EXC_RETURN | | + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * + * <-----------><--------------><---------><----------------><---------------------><----> + * 16 16 8 8 4 1 + */ + #define MAX_CONTEXT_SIZE 53 + + #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + + #else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ + + #if( configENABLE_TRUSTZONE == 1 ) + + /* + * +----------+-----------------+------------------------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | + * | | PC, xPSR | CONTROL, EXC_RETURN | | + * +----------+-----------------+------------------------------+-----+ + * + * <---------><----------------><------------------------------><----> + * 8 8 5 1 + */ + #define MAX_CONTEXT_SIZE 22 + + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ + + /* + * +----------+-----------------+----------------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | + * | | PC, xPSR | EXC_RETURN | | + * +----------+-----------------+----------------------+-----+ + * + * <---------><----------------><----------------------><----> + * 8 8 4 1 + */ + #define MAX_CONTEXT_SIZE 21 + + #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + + #endif /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ + + /* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ + #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) + #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) + + typedef struct MPU_SETTINGS + { + uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ + MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */ + uint32_t ulContext[ MAX_CONTEXT_SIZE ]; + uint32_t ulTaskFlags; + + #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo; + #endif + } xMPU_SETTINGS; + +#endif /* configENABLE_MPU == 1 */ /*-----------------------------------------------------------*/ /** @@ -223,6 +320,9 @@ typedef struct MPU_SETTINGS #define portSVC_FREE_SECURE_CONTEXT 1 #define portSVC_START_SCHEDULER 2 #define portSVC_RAISE_PRIVILEGE 3 +#define portSVC_SYSTEM_CALL_ENTER 4 /* System calls with upto 4 parameters. */ +#define portSVC_SYSTEM_CALL_ENTER_1 5 /* System calls with 5 parameters. */ +#define portSVC_SYSTEM_CALL_EXIT 6 /*-----------------------------------------------------------*/ /** @@ -315,6 +415,20 @@ typedef struct MPU_SETTINGS #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ +#if ( configENABLE_MPU == 1 ) + + extern BaseType_t xPortIsTaskPrivileged( void ); + + /** + * @brief Checks whether or not the calling task is privileged. + * + * @return pdTRUE if the calling task is privileged, pdFALSE otherwise. + */ + #define portIS_TASK_PRIVILEGED() xPortIsTaskPrivileged() + +#endif /* configENABLE_MPU == 1 */ +/*-----------------------------------------------------------*/ + /** * @brief Barriers. */ diff --git a/portable/GCC/ARM_CM33_NTZ/non_secure/mpu_wrappers_v2_asm.c b/portable/GCC/ARM_CM33_NTZ/non_secure/mpu_wrappers_v2_asm.c new file mode 100644 index 00000000000..6e2043427fe --- /dev/null +++ b/portable/GCC/ARM_CM33_NTZ/non_secure/mpu_wrappers_v2_asm.c @@ -0,0 +1,2349 @@ +/* + * FreeRTOS Kernel + * Copyright (C) 2021 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 + * + */ + +/* 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. */ +#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +/* Scheduler includes. */ +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" +#include "timers.h" +#include "event_groups.h" +#include "stream_buffer.h" + +#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + +#if ( INCLUDE_xTaskDelayUntil == 1 ) + +BaseType_t MPU_xTaskDelayUntil( TickType_t * const pxPreviousWakeTime, + const TickType_t xTimeIncrement ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskDelayUntil( TickType_t * const pxPreviousWakeTime, + const TickType_t xTimeIncrement ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskDelayUntilImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskDelayUntil_Unpriv \n" + " MPU_xTaskDelayUntil_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskDelayUntilImpl \n" + " MPU_xTaskDelayUntil_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskDelayUntilImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_xTaskDelayUntil == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_xTaskAbortDelay == 1 ) + +BaseType_t MPU_xTaskAbortDelay( TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskAbortDelay( TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskAbortDelayImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskAbortDelay_Unpriv \n" + " MPU_xTaskAbortDelay_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskAbortDelayImpl \n" + " MPU_xTaskAbortDelay_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskAbortDelayImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_xTaskAbortDelay == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskDelay == 1 ) + +void MPU_vTaskDelay( const TickType_t xTicksToDelay ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskDelay( const TickType_t xTicksToDelay ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskDelayImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vTaskDelay_Unpriv \n" + " MPU_vTaskDelay_Priv: \n" + " pop {r0} \n" + " b MPU_vTaskDelayImpl \n" + " MPU_vTaskDelay_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vTaskDelayImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_vTaskDelay == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_uxTaskPriorityGet == 1 ) + +UBaseType_t MPU_uxTaskPriorityGet( const TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxTaskPriorityGet( const TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxTaskPriorityGetImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_uxTaskPriorityGet_Unpriv \n" + " MPU_uxTaskPriorityGet_Priv: \n" + " pop {r0} \n" + " b MPU_uxTaskPriorityGetImpl \n" + " MPU_uxTaskPriorityGet_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_uxTaskPriorityGetImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_uxTaskPriorityGet == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_eTaskGetState == 1 ) + +eTaskState MPU_eTaskGetState( TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +eTaskState MPU_eTaskGetState( TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_eTaskGetStateImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_eTaskGetState_Unpriv \n" + " MPU_eTaskGetState_Priv: \n" + " pop {r0} \n" + " b MPU_eTaskGetStateImpl \n" + " MPU_eTaskGetState_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_eTaskGetStateImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_eTaskGetState == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + +void MPU_vTaskGetInfo( TaskHandle_t xTask, + TaskStatus_t * pxTaskStatus, + BaseType_t xGetFreeStackSpace, + eTaskState eState ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskGetInfo( TaskHandle_t xTask, + TaskStatus_t * pxTaskStatus, + BaseType_t xGetFreeStackSpace, + eTaskState eState ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskGetInfoImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vTaskGetInfo_Unpriv \n" + " MPU_vTaskGetInfo_Priv: \n" + " pop {r0} \n" + " b MPU_vTaskGetInfoImpl \n" + " MPU_vTaskGetInfo_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vTaskGetInfoImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TRACE_FACILITY == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) + +TaskHandle_t MPU_xTaskGetIdleTaskHandle( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TaskHandle_t MPU_xTaskGetIdleTaskHandle( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGetIdleTaskHandleImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskGetIdleTaskHandle_Unpriv \n" + " MPU_xTaskGetIdleTaskHandle_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskGetIdleTaskHandleImpl \n" + " MPU_xTaskGetIdleTaskHandle_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskGetIdleTaskHandleImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskSuspend == 1 ) + +void MPU_vTaskSuspend( TaskHandle_t xTaskToSuspend ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskSuspend( TaskHandle_t xTaskToSuspend ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskSuspendImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vTaskSuspend_Unpriv \n" + " MPU_vTaskSuspend_Priv: \n" + " pop {r0} \n" + " b MPU_vTaskSuspendImpl \n" + " MPU_vTaskSuspend_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vTaskSuspendImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_vTaskSuspend == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskSuspend == 1 ) + +void MPU_vTaskResume( TaskHandle_t xTaskToResume ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskResume( TaskHandle_t xTaskToResume ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskResumeImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vTaskResume_Unpriv \n" + " MPU_vTaskResume_Priv: \n" + " pop {r0} \n" + " b MPU_vTaskResumeImpl \n" + " MPU_vTaskResume_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vTaskResumeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_vTaskSuspend == 1 ) */ +/*-----------------------------------------------------------*/ + +TickType_t MPU_xTaskGetTickCount( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TickType_t MPU_xTaskGetTickCount( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGetTickCountImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskGetTickCount_Unpriv \n" + " MPU_xTaskGetTickCount_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskGetTickCountImpl \n" + " MPU_xTaskGetTickCount_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskGetTickCountImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +UBaseType_t MPU_uxTaskGetNumberOfTasks( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxTaskGetNumberOfTasks( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxTaskGetNumberOfTasksImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_uxTaskGetNumberOfTasks_Unpriv \n" + " MPU_uxTaskGetNumberOfTasks_Priv: \n" + " pop {r0} \n" + " b MPU_uxTaskGetNumberOfTasksImpl \n" + " MPU_uxTaskGetNumberOfTasks_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_uxTaskGetNumberOfTasksImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +char * MPU_pcTaskGetName( TaskHandle_t xTaskToQuery ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +char * MPU_pcTaskGetName( TaskHandle_t xTaskToQuery ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_pcTaskGetNameImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_pcTaskGetName_Unpriv \n" + " MPU_pcTaskGetName_Priv: \n" + " pop {r0} \n" + " b MPU_pcTaskGetNameImpl \n" + " MPU_pcTaskGetName_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_pcTaskGetNameImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +#if ( configGENERATE_RUN_TIME_STATS == 1 ) + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetRunTimeCounter( const TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetRunTimeCounter( const TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_ulTaskGetRunTimeCounterImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_ulTaskGetRunTimeCounter_Unpriv \n" + " MPU_ulTaskGetRunTimeCounter_Priv: \n" + " pop {r0} \n" + " b MPU_ulTaskGetRunTimeCounterImpl \n" + " MPU_ulTaskGetRunTimeCounter_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_ulTaskGetRunTimeCounterImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( ( configGENERATE_RUN_TIME_STATS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configGENERATE_RUN_TIME_STATS == 1 ) + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetRunTimePercent( const TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetRunTimePercent( const TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_ulTaskGetRunTimePercentImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_ulTaskGetRunTimePercent_Unpriv \n" + " MPU_ulTaskGetRunTimePercent_Priv: \n" + " pop {r0} \n" + " b MPU_ulTaskGetRunTimePercentImpl \n" + " MPU_ulTaskGetRunTimePercent_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_ulTaskGetRunTimePercentImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( ( configGENERATE_RUN_TIME_STATS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimePercent( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimePercent( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_ulTaskGetIdleRunTimePercentImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_ulTaskGetIdleRunTimePercent_Unpriv \n" + " MPU_ulTaskGetIdleRunTimePercent_Priv: \n" + " pop {r0} \n" + " b MPU_ulTaskGetIdleRunTimePercentImpl \n" + " MPU_ulTaskGetIdleRunTimePercent_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_ulTaskGetIdleRunTimePercentImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimeCounter( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimeCounter( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_ulTaskGetIdleRunTimeCounterImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_ulTaskGetIdleRunTimeCounter_Unpriv \n" + " MPU_ulTaskGetIdleRunTimeCounter_Priv: \n" + " pop {r0} \n" + " b MPU_ulTaskGetIdleRunTimeCounterImpl \n" + " MPU_ulTaskGetIdleRunTimeCounter_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_ulTaskGetIdleRunTimeCounterImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_APPLICATION_TASK_TAG == 1 ) + +void MPU_vTaskSetApplicationTaskTag( TaskHandle_t xTask, + TaskHookFunction_t pxHookFunction ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskSetApplicationTaskTag( TaskHandle_t xTask, + TaskHookFunction_t pxHookFunction ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskSetApplicationTaskTagImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vTaskSetApplicationTaskTag_Unpriv \n" + " MPU_vTaskSetApplicationTaskTag_Priv: \n" + " pop {r0} \n" + " b MPU_vTaskSetApplicationTaskTagImpl \n" + " MPU_vTaskSetApplicationTaskTag_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vTaskSetApplicationTaskTagImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_APPLICATION_TASK_TAG == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_APPLICATION_TASK_TAG == 1 ) + +TaskHookFunction_t MPU_xTaskGetApplicationTaskTag( TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TaskHookFunction_t MPU_xTaskGetApplicationTaskTag( TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGetApplicationTaskTagImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskGetApplicationTaskTag_Unpriv \n" + " MPU_xTaskGetApplicationTaskTag_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskGetApplicationTaskTagImpl \n" + " MPU_xTaskGetApplicationTaskTag_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskGetApplicationTaskTagImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_APPLICATION_TASK_TAG == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) + +void MPU_vTaskSetThreadLocalStoragePointer( TaskHandle_t xTaskToSet, + BaseType_t xIndex, + void * pvValue ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskSetThreadLocalStoragePointer( TaskHandle_t xTaskToSet, + BaseType_t xIndex, + void * pvValue ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskSetThreadLocalStoragePointerImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vTaskSetThreadLocalStoragePointer_Unpriv \n" + " MPU_vTaskSetThreadLocalStoragePointer_Priv: \n" + " pop {r0} \n" + " b MPU_vTaskSetThreadLocalStoragePointerImpl \n" + " MPU_vTaskSetThreadLocalStoragePointer_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vTaskSetThreadLocalStoragePointerImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) + +void * MPU_pvTaskGetThreadLocalStoragePointer( TaskHandle_t xTaskToQuery, + BaseType_t xIndex ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void * MPU_pvTaskGetThreadLocalStoragePointer( TaskHandle_t xTaskToQuery, + BaseType_t xIndex ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_pvTaskGetThreadLocalStoragePointerImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_pvTaskGetThreadLocalStoragePointer_Unpriv \n" + " MPU_pvTaskGetThreadLocalStoragePointer_Priv: \n" + " pop {r0} \n" + " b MPU_pvTaskGetThreadLocalStoragePointerImpl \n" + " MPU_pvTaskGetThreadLocalStoragePointer_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_pvTaskGetThreadLocalStoragePointerImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + +UBaseType_t MPU_uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray, + const UBaseType_t uxArraySize, + configRUN_TIME_COUNTER_TYPE * const pulTotalRunTime ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray, + const UBaseType_t uxArraySize, + configRUN_TIME_COUNTER_TYPE * const pulTotalRunTime ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxTaskGetSystemStateImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_uxTaskGetSystemState_Unpriv \n" + " MPU_uxTaskGetSystemState_Priv: \n" + " pop {r0} \n" + " b MPU_uxTaskGetSystemStateImpl \n" + " MPU_uxTaskGetSystemState_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_uxTaskGetSystemStateImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TRACE_FACILITY == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) + +UBaseType_t MPU_uxTaskGetStackHighWaterMark( TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxTaskGetStackHighWaterMark( TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxTaskGetStackHighWaterMarkImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_uxTaskGetStackHighWaterMark_Unpriv \n" + " MPU_uxTaskGetStackHighWaterMark_Priv: \n" + " pop {r0} \n" + " b MPU_uxTaskGetStackHighWaterMarkImpl \n" + " MPU_uxTaskGetStackHighWaterMark_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_uxTaskGetStackHighWaterMarkImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) + +configSTACK_DEPTH_TYPE MPU_uxTaskGetStackHighWaterMark2( TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +configSTACK_DEPTH_TYPE MPU_uxTaskGetStackHighWaterMark2( TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxTaskGetStackHighWaterMark2Impl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_uxTaskGetStackHighWaterMark2_Unpriv \n" + " MPU_uxTaskGetStackHighWaterMark2_Priv: \n" + " pop {r0} \n" + " b MPU_uxTaskGetStackHighWaterMark2Impl \n" + " MPU_uxTaskGetStackHighWaterMark2_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_uxTaskGetStackHighWaterMark2Impl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) ) + +TaskHandle_t MPU_xTaskGetCurrentTaskHandle( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TaskHandle_t MPU_xTaskGetCurrentTaskHandle( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGetCurrentTaskHandleImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskGetCurrentTaskHandle_Unpriv \n" + " MPU_xTaskGetCurrentTaskHandle_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskGetCurrentTaskHandleImpl \n" + " MPU_xTaskGetCurrentTaskHandle_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskGetCurrentTaskHandleImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_xTaskGetSchedulerState == 1 ) + +BaseType_t MPU_xTaskGetSchedulerState( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskGetSchedulerState( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGetSchedulerStateImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskGetSchedulerState_Unpriv \n" + " MPU_xTaskGetSchedulerState_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskGetSchedulerStateImpl \n" + " MPU_xTaskGetSchedulerState_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskGetSchedulerStateImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_xTaskGetSchedulerState == 1 ) */ +/*-----------------------------------------------------------*/ + +void MPU_vTaskSetTimeOutState( TimeOut_t * const pxTimeOut ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskSetTimeOutState( TimeOut_t * const pxTimeOut ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskSetTimeOutStateImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vTaskSetTimeOutState_Unpriv \n" + " MPU_vTaskSetTimeOutState_Priv: \n" + " pop {r0} \n" + " b MPU_vTaskSetTimeOutStateImpl \n" + " MPU_vTaskSetTimeOutState_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vTaskSetTimeOutStateImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut, + TickType_t * const pxTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut, + TickType_t * const pxTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskCheckForTimeOutImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskCheckForTimeOut_Unpriv \n" + " MPU_xTaskCheckForTimeOut_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskCheckForTimeOutImpl \n" + " MPU_xTaskCheckForTimeOut_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskCheckForTimeOutImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +#if ( configUSE_TASK_NOTIFICATIONS == 1 ) + +BaseType_t MPU_xTaskGenericNotify( TaskHandle_t xTaskToNotify, + UBaseType_t uxIndexToNotify, + uint32_t ulValue, + eNotifyAction eAction, + uint32_t * pulPreviousNotificationValue ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskGenericNotify( TaskHandle_t xTaskToNotify, + UBaseType_t uxIndexToNotify, + uint32_t ulValue, + eNotifyAction eAction, + uint32_t * pulPreviousNotificationValue ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGenericNotifyImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskGenericNotify_Unpriv \n" + " MPU_xTaskGenericNotify_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskGenericNotifyImpl \n" + " MPU_xTaskGenericNotify_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskGenericNotifyImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER_1 ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TASK_NOTIFICATIONS == 1 ) + +BaseType_t MPU_xTaskGenericNotifyWait( UBaseType_t uxIndexToWaitOn, + uint32_t ulBitsToClearOnEntry, + uint32_t ulBitsToClearOnExit, + uint32_t * pulNotificationValue, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskGenericNotifyWait( UBaseType_t uxIndexToWaitOn, + uint32_t ulBitsToClearOnEntry, + uint32_t ulBitsToClearOnExit, + uint32_t * pulNotificationValue, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGenericNotifyWaitImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskGenericNotifyWait_Unpriv \n" + " MPU_xTaskGenericNotifyWait_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskGenericNotifyWaitImpl \n" + " MPU_xTaskGenericNotifyWait_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskGenericNotifyWaitImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER_1 ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TASK_NOTIFICATIONS == 1 ) + +uint32_t MPU_ulTaskGenericNotifyTake( UBaseType_t uxIndexToWaitOn, + BaseType_t xClearCountOnExit, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +uint32_t MPU_ulTaskGenericNotifyTake( UBaseType_t uxIndexToWaitOn, + BaseType_t xClearCountOnExit, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_ulTaskGenericNotifyTakeImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_ulTaskGenericNotifyTake_Unpriv \n" + " MPU_ulTaskGenericNotifyTake_Priv: \n" + " pop {r0} \n" + " b MPU_ulTaskGenericNotifyTakeImpl \n" + " MPU_ulTaskGenericNotifyTake_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_ulTaskGenericNotifyTakeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TASK_NOTIFICATIONS == 1 ) + +BaseType_t MPU_xTaskGenericNotifyStateClear( TaskHandle_t xTask, + UBaseType_t uxIndexToClear ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskGenericNotifyStateClear( TaskHandle_t xTask, + UBaseType_t uxIndexToClear ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGenericNotifyStateClearImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskGenericNotifyStateClear_Unpriv \n" + " MPU_xTaskGenericNotifyStateClear_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskGenericNotifyStateClearImpl \n" + " MPU_xTaskGenericNotifyStateClear_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskGenericNotifyStateClearImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TASK_NOTIFICATIONS == 1 ) + +uint32_t MPU_ulTaskGenericNotifyValueClear( TaskHandle_t xTask, + UBaseType_t uxIndexToClear, + uint32_t ulBitsToClear ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +uint32_t MPU_ulTaskGenericNotifyValueClear( TaskHandle_t xTask, + UBaseType_t uxIndexToClear, + uint32_t ulBitsToClear ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_ulTaskGenericNotifyValueClearImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_ulTaskGenericNotifyValueClear_Unpriv \n" + " MPU_ulTaskGenericNotifyValueClear_Priv: \n" + " pop {r0} \n" + " b MPU_ulTaskGenericNotifyValueClearImpl \n" + " MPU_ulTaskGenericNotifyValueClear_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_ulTaskGenericNotifyValueClearImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xQueueGenericSend( QueueHandle_t xQueue, + const void * const pvItemToQueue, + TickType_t xTicksToWait, + const BaseType_t xCopyPosition ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueueGenericSend( QueueHandle_t xQueue, + const void * const pvItemToQueue, + TickType_t xTicksToWait, + const BaseType_t xCopyPosition ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueGenericSendImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xQueueGenericSend_Unpriv \n" + " MPU_xQueueGenericSend_Priv: \n" + " pop {r0} \n" + " b MPU_xQueueGenericSendImpl \n" + " MPU_xQueueGenericSend_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xQueueGenericSendImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +UBaseType_t MPU_uxQueueMessagesWaiting( const QueueHandle_t xQueue ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxQueueMessagesWaiting( const QueueHandle_t xQueue ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxQueueMessagesWaitingImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_uxQueueMessagesWaiting_Unpriv \n" + " MPU_uxQueueMessagesWaiting_Priv: \n" + " pop {r0} \n" + " b MPU_uxQueueMessagesWaitingImpl \n" + " MPU_uxQueueMessagesWaiting_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_uxQueueMessagesWaitingImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +UBaseType_t MPU_uxQueueSpacesAvailable( const QueueHandle_t xQueue ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxQueueSpacesAvailable( const QueueHandle_t xQueue ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxQueueSpacesAvailableImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_uxQueueSpacesAvailable_Unpriv \n" + " MPU_uxQueueSpacesAvailable_Priv: \n" + " pop {r0} \n" + " b MPU_uxQueueSpacesAvailableImpl \n" + " MPU_uxQueueSpacesAvailable_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_uxQueueSpacesAvailableImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xQueueReceive( QueueHandle_t xQueue, + void * const pvBuffer, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueueReceive( QueueHandle_t xQueue, + void * const pvBuffer, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueReceiveImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xQueueReceive_Unpriv \n" + " MPU_xQueueReceive_Priv: \n" + " pop {r0} \n" + " b MPU_xQueueReceiveImpl \n" + " MPU_xQueueReceive_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xQueueReceiveImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xQueuePeek( QueueHandle_t xQueue, + void * const pvBuffer, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueuePeek( QueueHandle_t xQueue, + void * const pvBuffer, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueuePeekImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xQueuePeek_Unpriv \n" + " MPU_xQueuePeek_Priv: \n" + " pop {r0} \n" + " b MPU_xQueuePeekImpl \n" + " MPU_xQueuePeek_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xQueuePeekImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xQueueSemaphoreTake( QueueHandle_t xQueue, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueueSemaphoreTake( QueueHandle_t xQueue, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueSemaphoreTakeImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xQueueSemaphoreTake_Unpriv \n" + " MPU_xQueueSemaphoreTake_Priv: \n" + " pop {r0} \n" + " b MPU_xQueueSemaphoreTakeImpl \n" + " MPU_xQueueSemaphoreTake_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xQueueSemaphoreTakeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +#if ( ( configUSE_MUTEXES == 1 ) && ( INCLUDE_xSemaphoreGetMutexHolder == 1 ) ) + +TaskHandle_t MPU_xQueueGetMutexHolder( QueueHandle_t xSemaphore ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TaskHandle_t MPU_xQueueGetMutexHolder( QueueHandle_t xSemaphore ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueGetMutexHolderImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xQueueGetMutexHolder_Unpriv \n" + " MPU_xQueueGetMutexHolder_Priv: \n" + " pop {r0} \n" + " b MPU_xQueueGetMutexHolderImpl \n" + " MPU_xQueueGetMutexHolder_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xQueueGetMutexHolderImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( ( configUSE_MUTEXES == 1 ) && ( INCLUDE_xSemaphoreGetMutexHolder == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_RECURSIVE_MUTEXES == 1 ) + +BaseType_t MPU_xQueueTakeMutexRecursive( QueueHandle_t xMutex, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueueTakeMutexRecursive( QueueHandle_t xMutex, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueTakeMutexRecursiveImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xQueueTakeMutexRecursive_Unpriv \n" + " MPU_xQueueTakeMutexRecursive_Priv: \n" + " pop {r0} \n" + " b MPU_xQueueTakeMutexRecursiveImpl \n" + " MPU_xQueueTakeMutexRecursive_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xQueueTakeMutexRecursiveImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_RECURSIVE_MUTEXES == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_RECURSIVE_MUTEXES == 1 ) + +BaseType_t MPU_xQueueGiveMutexRecursive( QueueHandle_t pxMutex ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueueGiveMutexRecursive( QueueHandle_t pxMutex ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueGiveMutexRecursiveImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xQueueGiveMutexRecursive_Unpriv \n" + " MPU_xQueueGiveMutexRecursive_Priv: \n" + " pop {r0} \n" + " b MPU_xQueueGiveMutexRecursiveImpl \n" + " MPU_xQueueGiveMutexRecursive_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xQueueGiveMutexRecursiveImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_RECURSIVE_MUTEXES == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_QUEUE_SETS == 1 ) + +QueueSetMemberHandle_t MPU_xQueueSelectFromSet( QueueSetHandle_t xQueueSet, + const TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +QueueSetMemberHandle_t MPU_xQueueSelectFromSet( QueueSetHandle_t xQueueSet, + const TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueSelectFromSetImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xQueueSelectFromSet_Unpriv \n" + " MPU_xQueueSelectFromSet_Priv: \n" + " pop {r0} \n" + " b MPU_xQueueSelectFromSetImpl \n" + " MPU_xQueueSelectFromSet_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xQueueSelectFromSetImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_QUEUE_SETS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_QUEUE_SETS == 1 ) + +BaseType_t MPU_xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore, + QueueSetHandle_t xQueueSet ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore, + QueueSetHandle_t xQueueSet ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueAddToSetImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xQueueAddToSet_Unpriv \n" + " MPU_xQueueAddToSet_Priv: \n" + " pop {r0} \n" + " b MPU_xQueueAddToSetImpl \n" + " MPU_xQueueAddToSet_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xQueueAddToSetImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_QUEUE_SETS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configQUEUE_REGISTRY_SIZE > 0 ) + +void MPU_vQueueAddToRegistry( QueueHandle_t xQueue, + const char * pcName ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vQueueAddToRegistry( QueueHandle_t xQueue, + const char * pcName ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vQueueAddToRegistryImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vQueueAddToRegistry_Unpriv \n" + " MPU_vQueueAddToRegistry_Priv: \n" + " pop {r0} \n" + " b MPU_vQueueAddToRegistryImpl \n" + " MPU_vQueueAddToRegistry_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vQueueAddToRegistryImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configQUEUE_REGISTRY_SIZE > 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configQUEUE_REGISTRY_SIZE > 0 ) + +void MPU_vQueueUnregisterQueue( QueueHandle_t xQueue ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vQueueUnregisterQueue( QueueHandle_t xQueue ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vQueueUnregisterQueueImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vQueueUnregisterQueue_Unpriv \n" + " MPU_vQueueUnregisterQueue_Priv: \n" + " pop {r0} \n" + " b MPU_vQueueUnregisterQueueImpl \n" + " MPU_vQueueUnregisterQueue_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vQueueUnregisterQueueImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configQUEUE_REGISTRY_SIZE > 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configQUEUE_REGISTRY_SIZE > 0 ) + +const char * MPU_pcQueueGetName( QueueHandle_t xQueue ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +const char * MPU_pcQueueGetName( QueueHandle_t xQueue ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_pcQueueGetNameImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_pcQueueGetName_Unpriv \n" + " MPU_pcQueueGetName_Priv: \n" + " pop {r0} \n" + " b MPU_pcQueueGetNameImpl \n" + " MPU_pcQueueGetName_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_pcQueueGetNameImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configQUEUE_REGISTRY_SIZE > 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +void * MPU_pvTimerGetTimerID( const TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void * MPU_pvTimerGetTimerID( const TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_pvTimerGetTimerIDImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_pvTimerGetTimerID_Unpriv \n" + " MPU_pvTimerGetTimerID_Priv: \n" + " pop {r0} \n" + " b MPU_pvTimerGetTimerIDImpl \n" + " MPU_pvTimerGetTimerID_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_pvTimerGetTimerIDImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +void MPU_vTimerSetTimerID( TimerHandle_t xTimer, + void * pvNewID ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTimerSetTimerID( TimerHandle_t xTimer, + void * pvNewID ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTimerSetTimerIDImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vTimerSetTimerID_Unpriv \n" + " MPU_vTimerSetTimerID_Priv: \n" + " pop {r0} \n" + " b MPU_vTimerSetTimerIDImpl \n" + " MPU_vTimerSetTimerID_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vTimerSetTimerIDImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +BaseType_t MPU_xTimerIsTimerActive( TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTimerIsTimerActive( TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTimerIsTimerActiveImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTimerIsTimerActive_Unpriv \n" + " MPU_xTimerIsTimerActive_Priv: \n" + " pop {r0} \n" + " b MPU_xTimerIsTimerActiveImpl \n" + " MPU_xTimerIsTimerActive_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTimerIsTimerActiveImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +TaskHandle_t MPU_xTimerGetTimerDaemonTaskHandle( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TaskHandle_t MPU_xTimerGetTimerDaemonTaskHandle( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTimerGetTimerDaemonTaskHandleImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTimerGetTimerDaemonTaskHandle_Unpriv \n" + " MPU_xTimerGetTimerDaemonTaskHandle_Priv: \n" + " pop {r0} \n" + " b MPU_xTimerGetTimerDaemonTaskHandleImpl \n" + " MPU_xTimerGetTimerDaemonTaskHandle_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTimerGetTimerDaemonTaskHandleImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +BaseType_t MPU_xTimerGenericCommand( TimerHandle_t xTimer, + const BaseType_t xCommandID, + const TickType_t xOptionalValue, + BaseType_t * const pxHigherPriorityTaskWoken, + const TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTimerGenericCommand( TimerHandle_t xTimer, + const BaseType_t xCommandID, + const TickType_t xOptionalValue, + BaseType_t * const pxHigherPriorityTaskWoken, + const TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTimerGenericCommandImpl \n" + " \n" + " push {r0} \n" + " mrs r0, ipsr \n" + " cmp r0, #0 \n" + " bne MPU_xTimerGenericCommand_Priv \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " beq MPU_xTimerGenericCommand_Priv \n" + " MPU_xTimerGenericCommand_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTimerGenericCommandImpl \n" + " svc %1 \n" + " bx lr \n" + " MPU_xTimerGenericCommand_Priv: \n" + " pop {r0} \n" + " b MPU_xTimerGenericCommandImpl \n" + " \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER_1 ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +const char * MPU_pcTimerGetName( TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +const char * MPU_pcTimerGetName( TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_pcTimerGetNameImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_pcTimerGetName_Unpriv \n" + " MPU_pcTimerGetName_Priv: \n" + " pop {r0} \n" + " b MPU_pcTimerGetNameImpl \n" + " MPU_pcTimerGetName_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_pcTimerGetNameImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, + const BaseType_t uxAutoReload ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, + const BaseType_t uxAutoReload ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTimerSetReloadModeImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vTimerSetReloadMode_Unpriv \n" + " MPU_vTimerSetReloadMode_Priv: \n" + " pop {r0} \n" + " b MPU_vTimerSetReloadModeImpl \n" + " MPU_vTimerSetReloadMode_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vTimerSetReloadModeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +BaseType_t MPU_xTimerGetReloadMode( TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTimerGetReloadMode( TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTimerGetReloadModeImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTimerGetReloadMode_Unpriv \n" + " MPU_xTimerGetReloadMode_Priv: \n" + " pop {r0} \n" + " b MPU_xTimerGetReloadModeImpl \n" + " MPU_xTimerGetReloadMode_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTimerGetReloadModeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +UBaseType_t MPU_uxTimerGetReloadMode( TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxTimerGetReloadMode( TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxTimerGetReloadModeImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_uxTimerGetReloadMode_Unpriv \n" + " MPU_uxTimerGetReloadMode_Priv: \n" + " pop {r0} \n" + " b MPU_uxTimerGetReloadModeImpl \n" + " MPU_uxTimerGetReloadMode_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_uxTimerGetReloadModeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +TickType_t MPU_xTimerGetPeriod( TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TickType_t MPU_xTimerGetPeriod( TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTimerGetPeriodImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTimerGetPeriod_Unpriv \n" + " MPU_xTimerGetPeriod_Priv: \n" + " pop {r0} \n" + " b MPU_xTimerGetPeriodImpl \n" + " MPU_xTimerGetPeriod_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTimerGetPeriodImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +TickType_t MPU_xTimerGetExpiryTime( TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TickType_t MPU_xTimerGetExpiryTime( TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTimerGetExpiryTimeImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTimerGetExpiryTime_Unpriv \n" + " MPU_xTimerGetExpiryTime_Priv: \n" + " pop {r0} \n" + " b MPU_xTimerGetExpiryTimeImpl \n" + " MPU_xTimerGetExpiryTime_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTimerGetExpiryTimeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +EventBits_t MPU_xEventGroupWaitBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToWaitFor, + const BaseType_t xClearOnExit, + const BaseType_t xWaitForAllBits, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +EventBits_t MPU_xEventGroupWaitBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToWaitFor, + const BaseType_t xClearOnExit, + const BaseType_t xWaitForAllBits, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupWaitBitsImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xEventGroupWaitBits_Unpriv \n" + " MPU_xEventGroupWaitBits_Priv: \n" + " pop {r0} \n" + " b MPU_xEventGroupWaitBitsImpl \n" + " MPU_xEventGroupWaitBits_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xEventGroupWaitBitsImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER_1 ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToClear ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToClear ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupClearBitsImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xEventGroupClearBits_Unpriv \n" + " MPU_xEventGroupClearBits_Priv: \n" + " pop {r0} \n" + " b MPU_xEventGroupClearBitsImpl \n" + " MPU_xEventGroupClearBits_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xEventGroupClearBitsImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupSetBitsImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xEventGroupSetBits_Unpriv \n" + " MPU_xEventGroupSetBits_Priv: \n" + " pop {r0} \n" + " b MPU_xEventGroupSetBitsImpl \n" + " MPU_xEventGroupSetBits_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xEventGroupSetBitsImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet, + const EventBits_t uxBitsToWaitFor, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet, + const EventBits_t uxBitsToWaitFor, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupSyncImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xEventGroupSync_Unpriv \n" + " MPU_xEventGroupSync_Priv: \n" + " pop {r0} \n" + " b MPU_xEventGroupSyncImpl \n" + " MPU_xEventGroupSync_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xEventGroupSyncImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + +UBaseType_t MPU_uxEventGroupGetNumber( void * xEventGroup ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxEventGroupGetNumber( void * xEventGroup ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxEventGroupGetNumberImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_uxEventGroupGetNumber_Unpriv \n" + " MPU_uxEventGroupGetNumber_Priv: \n" + " pop {r0} \n" + " b MPU_uxEventGroupGetNumberImpl \n" + " MPU_uxEventGroupGetNumber_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_uxEventGroupGetNumberImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /*( configUSE_TRACE_FACILITY == 1 )*/ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + +void MPU_vEventGroupSetNumber( void * xEventGroup, + UBaseType_t uxEventGroupNumber ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vEventGroupSetNumber( void * xEventGroup, + UBaseType_t uxEventGroupNumber ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vEventGroupSetNumberImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vEventGroupSetNumber_Unpriv \n" + " MPU_vEventGroupSetNumber_Priv: \n" + " pop {r0} \n" + " b MPU_vEventGroupSetNumberImpl \n" + " MPU_vEventGroupSetNumber_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vEventGroupSetNumberImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /*( configUSE_TRACE_FACILITY == 1 )*/ +/*-----------------------------------------------------------*/ + +size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, + const void * pvTxData, + size_t xDataLengthBytes, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, + const void * pvTxData, + size_t xDataLengthBytes, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferSendImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferSend_Unpriv \n" + " MPU_xStreamBufferSend_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferSendImpl \n" + " MPU_xStreamBufferSend_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xStreamBufferSendImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, + void * pvRxData, + size_t xBufferLengthBytes, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, + void * pvRxData, + size_t xBufferLengthBytes, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferReceiveImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferReceive_Unpriv \n" + " MPU_xStreamBufferReceive_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferReceiveImpl \n" + " MPU_xStreamBufferReceive_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xStreamBufferReceiveImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferIsFullImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferIsFull_Unpriv \n" + " MPU_xStreamBufferIsFull_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferIsFullImpl \n" + " MPU_xStreamBufferIsFull_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xStreamBufferIsFullImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferIsEmptyImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferIsEmpty_Unpriv \n" + " MPU_xStreamBufferIsEmpty_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferIsEmptyImpl \n" + " MPU_xStreamBufferIsEmpty_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xStreamBufferIsEmptyImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferSpacesAvailableImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferSpacesAvailable_Unpriv \n" + " MPU_xStreamBufferSpacesAvailable_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferSpacesAvailableImpl \n" + " MPU_xStreamBufferSpacesAvailable_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xStreamBufferSpacesAvailableImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferBytesAvailableImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferBytesAvailable_Unpriv \n" + " MPU_xStreamBufferBytesAvailable_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferBytesAvailableImpl \n" + " MPU_xStreamBufferBytesAvailable_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xStreamBufferBytesAvailableImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, + size_t xTriggerLevel ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, + size_t xTriggerLevel ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferSetTriggerLevelImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferSetTriggerLevel_Unpriv \n" + " MPU_xStreamBufferSetTriggerLevel_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferSetTriggerLevelImpl \n" + " MPU_xStreamBufferSetTriggerLevel_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xStreamBufferSetTriggerLevelImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferNextMessageLengthBytesImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferNextMessageLengthBytes_Unpriv \n" + " MPU_xStreamBufferNextMessageLengthBytes_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferNextMessageLengthBytesImpl \n" + " MPU_xStreamBufferNextMessageLengthBytes_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xStreamBufferNextMessageLengthBytesImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ diff --git a/portable/GCC/ARM_CM33_NTZ/non_secure/port.c b/portable/GCC/ARM_CM33_NTZ/non_secure/port.c index 7bbe1b7bc53..cab1b3668bf 100644 --- a/portable/GCC/ARM_CM33_NTZ/non_secure/port.c +++ b/portable/GCC/ARM_CM33_NTZ/non_secure/port.c @@ -107,6 +107,13 @@ #define portPRIGROUP_SHIFT ( 8UL ) /*-----------------------------------------------------------*/ +/** + * @brief Constants used during system call enter and exit. + */ +#define portPSR_STACK_PADDING_MASK ( 1UL << 9UL ) +#define portEXC_RETURN_STACK_FRAME_TYPE_MASK ( 1UL << 4UL ) +/*-----------------------------------------------------------*/ + /** * @brief Constants required to manipulate the FPU. */ @@ -123,6 +130,14 @@ #define portFPCCR_LSPEN_MASK ( 1UL << portFPCCR_LSPEN_POS ) /*-----------------------------------------------------------*/ +/** + * @brief Offsets in the stack to the parameters when inside the SVC handler. + */ +#define portOFFSET_TO_LR ( 5 ) +#define portOFFSET_TO_PC ( 6 ) +#define portOFFSET_TO_PSR ( 7 ) +/*-----------------------------------------------------------*/ + /** * @brief Constants required to manipulate the MPU. */ @@ -148,6 +163,8 @@ #define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ #define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ +#define portMPU_RBAR_ACCESS_PERMISSIONS_MASK ( 3UL << 1UL ) + #define portMPU_MAIR_ATTR0_POS ( 0UL ) #define portMPU_MAIR_ATTR0_MASK ( 0x000000ff ) @@ -191,6 +208,30 @@ /* Expected value of the portMPU_TYPE register. */ #define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) + +/* Extract first address of the MPU region as encoded in the + * RBAR (Region Base Address Register) value. */ +#define portEXTRACT_FIRST_ADDRESS_FROM_RBAR( rbar ) \ + ( ( rbar ) & portMPU_RBAR_ADDRESS_MASK ) + +/* Extract last address of the MPU region as encoded in the + * RLAR (Region Limit Address Register) value. */ +#define portEXTRACT_LAST_ADDRESS_FROM_RLAR( rlar ) \ + ( ( ( rlar ) & portMPU_RLAR_ADDRESS_MASK ) | ~portMPU_RLAR_ADDRESS_MASK ) + +/* Does addr lies within [start, end] address range? */ +#define portIS_ADDRESS_WITHIN_RANGE( addr, start, end ) \ + ( ( ( addr ) >= ( start ) ) && ( ( addr ) <= ( end ) ) ) + +/* Is the access request satisfied by the available permissions? */ +#define portIS_AUTHORIZED( accessRequest, permissions ) \ + ( ( ( permissions ) & ( accessRequest ) ) == accessRequest ) + +/* 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 ) ) ) /*-----------------------------------------------------------*/ /** @@ -311,6 +352,19 @@ static void prvTaskExitError( void ); #if ( configENABLE_MPU == 1 ) +/** + * @brief Extract MPU region's access permissions from the Region Base Address + * Register (RBAR) value. + * + * @param ulRBARValue RBAR value for the MPU region. + * + * @return uint32_t Access permissions. + */ + static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) PRIVILEGED_FUNCTION; +#endif /* configENABLE_MPU */ + +#if ( configENABLE_MPU == 1 ) + /** * @brief Setup the Memory Protection Unit (MPU). */ @@ -365,6 +419,60 @@ void SysTick_Handler( void ) PRIVILEGED_FUNCTION; * @brief C part of SVC handler. */ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIVILEGED_FUNCTION; + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + + /** + * @brief Sets up the system call stack so that upon returning from + * SVC, the system call stack is used. + * + * It is used for the system calls with up to 4 parameters. + * + * @param pulTaskStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + */ + void vSystemCallEnter( uint32_t * pulTaskStack, uint32_t ulLR ) PRIVILEGED_FUNCTION; + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + + /** + * @brief Sets up the system call stack so that upon returning from + * SVC, the system call stack is used. + * + * It is used for the system calls with 5 parameters. + * + * @param pulTaskStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + */ + void vSystemCallEnter_1( uint32_t * pulTaskStack, uint32_t ulLR ) PRIVILEGED_FUNCTION; + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + + /** + * @brief Sets up the task stack so that upon returning from + * SVC, the task stack is used again. + * + * @param pulSystemCallStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + */ + void vSystemCallExit( uint32_t * pulSystemCallStack, uint32_t ulLR ) PRIVILEGED_FUNCTION; + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + +#if ( configENABLE_MPU == 1 ) + + /** + * @brief Checks whether or not the calling task is privileged. + * + * @return pdTRUE if the calling task is privileged, pdFALSE otherwise. + */ + BaseType_t xPortIsTaskPrivileged( void ) PRIVILEGED_FUNCTION; + +#endif /* configENABLE_MPU == 1 */ /*-----------------------------------------------------------*/ /** @@ -681,6 +789,26 @@ static void prvTaskExitError( void ) } /*-----------------------------------------------------------*/ +#if ( configENABLE_MPU == 1 ) + static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) /* PRIVILEGED_FUNCTION */ + { + uint32_t ulAccessPermissions = 0; + + if( ( ulRBARValue & portMPU_RBAR_ACCESS_PERMISSIONS_MASK ) == portMPU_REGION_READ_ONLY ) + { + ulAccessPermissions = tskMPU_READ_PERMISSION; + } + + if( ( ulRBARValue & portMPU_RBAR_ACCESS_PERMISSIONS_MASK ) == portMPU_REGION_READ_WRITE ) + { + ulAccessPermissions = ( tskMPU_READ_PERMISSION | tskMPU_WRITE_PERMISSION ); + } + + return ulAccessPermissions; + } +#endif /* configENABLE_MPU */ +/*-----------------------------------------------------------*/ + #if ( configENABLE_MPU == 1 ) static void prvSetupMPU( void ) /* PRIVILEGED_FUNCTION */ { @@ -853,7 +981,7 @@ void SysTick_Handler( void ) /* PRIVILEGED_FUNCTION */ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTION portDONT_DISCARD */ { - #if ( configENABLE_MPU == 1 ) + #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) ) #if defined( __ARMCC_VERSION ) /* Declaration when these variable are defined in code instead of being @@ -865,7 +993,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO extern uint32_t __syscalls_flash_start__[]; extern uint32_t __syscalls_flash_end__[]; #endif /* defined( __ARMCC_VERSION ) */ - #endif /* configENABLE_MPU */ + #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */ uint32_t ulPC; @@ -880,7 +1008,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO /* Register are stored on the stack in the following order - R0, R1, R2, R3, * R12, LR, PC, xPSR. */ - ulPC = pulCallerStackAddress[ 6 ]; + ulPC = pulCallerStackAddress[ portOFFSET_TO_PC ]; ucSVCNumber = ( ( uint8_t * ) ulPC )[ -2 ]; switch( ucSVCNumber ) @@ -951,18 +1079,18 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO vRestoreContextOfFirstTask(); break; - #if ( configENABLE_MPU == 1 ) - case portSVC_RAISE_PRIVILEGE: + #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) ) + case portSVC_RAISE_PRIVILEGE: - /* Only raise the privilege, if the svc was raised from any of - * the system calls. */ - if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) && - ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ) - { - vRaisePrivilege(); - } - break; - #endif /* configENABLE_MPU */ + /* Only raise the privilege, if the svc was raised from any of + * the system calls. */ + if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ) + { + vRaisePrivilege(); + } + break; + #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */ default: /* Incorrect SVC call. */ @@ -971,51 +1099,455 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } /*-----------------------------------------------------------*/ -/* *INDENT-OFF* */ -#if ( configENABLE_MPU == 1 ) - StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, - StackType_t * pxEndOfStack, - TaskFunction_t pxCode, - void * pvParameters, - BaseType_t xRunPrivileged ) /* PRIVILEGED_FUNCTION */ -#else - StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, - StackType_t * pxEndOfStack, - TaskFunction_t pxCode, - void * pvParameters ) /* PRIVILEGED_FUNCTION */ -#endif /* configENABLE_MPU */ -/* *INDENT-ON* */ +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + +void vSystemCallEnter( uint32_t * pulTaskStack, uint32_t ulLR ) /* PRIVILEGED_FUNCTION */ { - /* Simulate the stack frame as it would be created by a context switch - * interrupt. */ - #if ( portPRELOAD_REGISTERS == 0 ) + extern TaskHandle_t pxCurrentTCB; + xMPU_SETTINGS * pxMpuSettings; + uint32_t * pulSystemCallStack; + uint32_t ulStackFrameSize, ulSystemCallLocation, i; + #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being + * exported from linker scripts. */ + extern uint32_t * __syscalls_flash_start__; + extern uint32_t * __syscalls_flash_end__; + #else + /* Declaration when these variable are exported from linker scripts. */ + extern uint32_t __syscalls_flash_start__[]; + extern uint32_t __syscalls_flash_end__[]; + #endif /* #if defined( __ARMCC_VERSION ) */ + + ulSystemCallLocation = pulTaskStack[ portOFFSET_TO_PC ]; + + /* If the request did not come from the system call section, do nothing. */ + if( ( ulSystemCallLocation >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulSystemCallLocation <= ( uint32_t ) __syscalls_flash_end__ ) ) { - pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ - *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ - pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pxCode; /* PC */ - pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR */ - pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ - *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ - pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */ - *pxTopOfStack = portINITIAL_EXC_RETURN; + pxMpuSettings = xTaskGetMPUSettings( pxCurrentTCB ); + pulSystemCallStack = pxMpuSettings->xSystemCallStackInfo.pulSystemCallStack; - #if ( configENABLE_MPU == 1 ) + /* This is not NULL only for the duration of the system call. */ + configASSERT( pxMpuSettings->xSystemCallStackInfo.pulTaskStack == NULL ); + + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) { - pxTopOfStack--; + if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) + { + /* Extended frame i.e. FPU in use. */ + ulStackFrameSize = 26; + __asm volatile ( + " vpush {s0} \n" /* Trigger lazy stacking. */ + " vpop {s0} \n" /* Nullify the affect of the above instruction. */ + ::: "memory" + ); + } + else + { + /* Standard frame i.e. FPU not in use. */ + ulStackFrameSize = 8; + } + } + #else + { + ulStackFrameSize = 8; + } + #endif /* configENABLE_FPU || configENABLE_MVE */ + + /* Make space on the system call stack for the stack frame. */ + pulSystemCallStack = pulSystemCallStack - ulStackFrameSize; + + /* Copy the stack frame. */ + for( i = 0; i < ulStackFrameSize; i++ ) + { + pulSystemCallStack[ i ] = pulTaskStack[ i ]; + } + + /* Store the value of the LR and PSPLIM registers before the SVC was raised. We need to + * restore it when we exit from the system call. */ + pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; + __asm volatile ( "mrs %0, psplim" : "=r" ( pxMpuSettings->xSystemCallStackInfo.ulStackLimitRegisterAtSystemCallEntry ) ); + + /* Use the pulSystemCallStack in thread mode. */ + __asm volatile ( "msr psp, %0" : : "r" ( pulSystemCallStack ) ); + __asm volatile ( "msr psplim, %0" : : "r" ( pxMpuSettings->xSystemCallStackInfo.pulSystemCallStackLimit ) ); + + /* Remember the location where we should copy the stack frame when we exit from + * the system call. */ + pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulStackFrameSize; + + /* Record if the hardware used padding to force the stack pointer + * to be double word aligned. */ + if( ( pulTaskStack[ portOFFSET_TO_PSR ] & portPSR_STACK_PADDING_MASK ) == portPSR_STACK_PADDING_MASK ) + { + pxMpuSettings->ulTaskFlags |= portSTACK_FRAME_HAS_PADDING_FLAG; + } + else + { + pxMpuSettings->ulTaskFlags &= ( ~portSTACK_FRAME_HAS_PADDING_FLAG ); + } + + /* We ensure in pxPortInitialiseStack that the system call stack is + * double word aligned and therefore, there is no need of padding. + * Clear the bit[9] of stacked xPSR. */ + pulSystemCallStack[ portOFFSET_TO_PSR ] &= ( ~portPSR_STACK_PADDING_MASK ); + + /* Raise the privilege for the duration of the system call. */ + __asm volatile ( + " mrs r0, control \n" /* Obtain current control value. */ + " movs r1, #1 \n" /* r1 = 1. */ + " bics r0, r1 \n" /* Clear nPRIV bit. */ + " msr control, r0 \n" /* Write back new control value. */ + ::: "r0", "r1", "memory" + ); + } +} - if( xRunPrivileged == pdTRUE ) +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + +void vSystemCallEnter_1( uint32_t * pulTaskStack, uint32_t ulLR ) /* PRIVILEGED_FUNCTION */ +{ + extern TaskHandle_t pxCurrentTCB; + xMPU_SETTINGS * pxMpuSettings; + uint32_t * pulSystemCallStack; + uint32_t ulStackFrameSize, ulSystemCallLocation, i; + #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being + * exported from linker scripts. */ + extern uint32_t * __syscalls_flash_start__; + extern uint32_t * __syscalls_flash_end__; + #else + /* Declaration when these variable are exported from linker scripts. */ + extern uint32_t __syscalls_flash_start__[]; + extern uint32_t __syscalls_flash_end__[]; + #endif /* #if defined( __ARMCC_VERSION ) */ + + ulSystemCallLocation = pulTaskStack[ portOFFSET_TO_PC ]; + + /* If the request did not come from the system call section, do nothing. */ + if( ( ulSystemCallLocation >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulSystemCallLocation <= ( uint32_t ) __syscalls_flash_end__ ) ) + { + pxMpuSettings = xTaskGetMPUSettings( pxCurrentTCB ); + pulSystemCallStack = pxMpuSettings->xSystemCallStackInfo.pulSystemCallStack; + + /* This is not NULL only for the duration of the system call. */ + configASSERT( pxMpuSettings->xSystemCallStackInfo.pulTaskStack == NULL ); + + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + { + if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) { - *pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */ + /* Extended frame i.e. FPU in use. */ + ulStackFrameSize = 26; + __asm volatile ( + " vpush {s0} \n" /* Trigger lazy stacking. */ + " vpop {s0} \n" /* Nullify the affect of the above instruction. */ + ::: "memory" + ); } else { - *pxTopOfStack = portINITIAL_CONTROL_UNPRIVILEGED; /* Slot used to hold this task's CONTROL value. */ + /* Standard frame i.e. FPU not in use. */ + ulStackFrameSize = 8; } } - #endif /* configENABLE_MPU */ + #else + { + ulStackFrameSize = 8; + } + #endif /* configENABLE_FPU || configENABLE_MVE */ + + /* Make space on the system call stack for the stack frame and + * the parameter passed on the stack. We only need to copy one + * parameter but we still reserve 2 spaces to keep the stack + * double word aligned. */ + pulSystemCallStack = pulSystemCallStack - ulStackFrameSize - 2UL; + + /* Copy the stack frame. */ + for( i = 0; i < ulStackFrameSize; i++ ) + { + pulSystemCallStack[ i ] = pulTaskStack[ i ]; + } + + /* Copy the parameter which is passed the stack. */ + if( ( pulTaskStack[ portOFFSET_TO_PSR ] & portPSR_STACK_PADDING_MASK ) == portPSR_STACK_PADDING_MASK ) + { + pulSystemCallStack[ ulStackFrameSize ] = pulTaskStack[ ulStackFrameSize + 1 ]; + /* Record if the hardware used padding to force the stack pointer + * to be double word aligned. */ + pxMpuSettings->ulTaskFlags |= portSTACK_FRAME_HAS_PADDING_FLAG; + } + else + { + pulSystemCallStack[ ulStackFrameSize ] = pulTaskStack[ ulStackFrameSize ]; + /* Record if the hardware used padding to force the stack pointer + * to be double word aligned. */ + pxMpuSettings->ulTaskFlags &= ( ~portSTACK_FRAME_HAS_PADDING_FLAG ); + } + + /* Store the value of the LR and PSPLIM registers before the SVC was raised. + * We need to restore it when we exit from the system call. */ + pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; + __asm volatile ( "mrs %0, psplim" : "=r" ( pxMpuSettings->xSystemCallStackInfo.ulStackLimitRegisterAtSystemCallEntry ) ); + + /* Use the pulSystemCallStack in thread mode. */ + __asm volatile ( "msr psp, %0" : : "r" ( pulSystemCallStack ) ); + __asm volatile ( "msr psplim, %0" : : "r" ( pxMpuSettings->xSystemCallStackInfo.pulSystemCallStackLimit ) ); + + /* Remember the location where we should copy the stack frame when we exit from + * the system call. */ + pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulStackFrameSize; + + /* We ensure in pxPortInitialiseStack that the system call stack is + * double word aligned and therefore, there is no need of padding. + * Clear the bit[9] of stacked xPSR. */ + pulSystemCallStack[ portOFFSET_TO_PSR ] &= ( ~portPSR_STACK_PADDING_MASK ); + + /* Raise the privilege for the duration of the system call. */ + __asm volatile ( + " mrs r0, control \n" /* Obtain current control value. */ + " movs r1, #1 \n" /* r1 = 1. */ + " bics r0, r1 \n" /* Clear nPRIV bit. */ + " msr control, r0 \n" /* Write back new control value. */ + ::: "r0", "r1", "memory" + ); + } +} + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) +void vSystemCallExit( uint32_t * pulSystemCallStack, uint32_t ulLR ) /* PRIVILEGED_FUNCTION */ +{ + extern TaskHandle_t pxCurrentTCB; + xMPU_SETTINGS * pxMpuSettings; + uint32_t * pulTaskStack; + uint32_t ulStackFrameSize, ulSystemCallLocation, i; + #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being + * exported from linker scripts. */ + extern uint32_t * __syscalls_flash_start__; + extern uint32_t * __syscalls_flash_end__; + #else + /* Declaration when these variable are exported from linker scripts. */ + extern uint32_t __syscalls_flash_start__[]; + extern uint32_t __syscalls_flash_end__[]; + #endif /* #if defined( __ARMCC_VERSION ) */ + + ulSystemCallLocation = pulSystemCallStack[ portOFFSET_TO_PC ]; + + /* If the request did not come from the system call section, do nothing. */ + if( ( ulSystemCallLocation >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulSystemCallLocation <= ( uint32_t ) __syscalls_flash_end__ ) ) + { + pxMpuSettings = xTaskGetMPUSettings( pxCurrentTCB ); + pulTaskStack = pxMpuSettings->xSystemCallStackInfo.pulTaskStack; + + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + { + if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) + { + /* Extended frame i.e. FPU in use. */ + ulStackFrameSize = 26; + __asm volatile ( + " vpush {s0} \n" /* Trigger lazy stacking. */ + " vpop {s0} \n" /* Nullify the affect of the above instruction. */ + ::: "memory" + ); + } + else + { + /* Standard frame i.e. FPU not in use. */ + ulStackFrameSize = 8; + } + } + #else + { + ulStackFrameSize = 8; + } + #endif /* configENABLE_FPU || configENABLE_MVE */ + + /* Make space on the task stack for the stack frame. */ + pulTaskStack = pulTaskStack - ulStackFrameSize; + + /* Copy the stack frame. */ + for( i = 0; i < ulStackFrameSize; i++ ) + { + pulTaskStack[ i ] = pulSystemCallStack[ i ]; + } + + /* Use the pulTaskStack in thread mode. */ + __asm volatile ( "msr psp, %0" : : "r" ( pulTaskStack ) ); + + /* Restore the LR and PSPLIM to what they were at the time of + * system call entry. */ + pulTaskStack[ portOFFSET_TO_LR ] = pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry; + __asm volatile ( "msr psplim, %0" : : "r" ( pxMpuSettings->xSystemCallStackInfo.ulStackLimitRegisterAtSystemCallEntry ) ); + + /* If the hardware used padding to force the stack pointer + * to be double word aligned, set the stacked xPSR bit[9], + * otherwise clear it. */ + if( ( pxMpuSettings->ulTaskFlags & portSTACK_FRAME_HAS_PADDING_FLAG ) == portSTACK_FRAME_HAS_PADDING_FLAG ) + { + pulTaskStack[ portOFFSET_TO_PSR ] |= portPSR_STACK_PADDING_MASK; + } + else + { + pulTaskStack[ portOFFSET_TO_PSR ] &= ( ~portPSR_STACK_PADDING_MASK ); + } + + /* This is not NULL only for the duration of the system call. */ + pxMpuSettings->xSystemCallStackInfo.pulTaskStack = NULL; + + /* Drop the privilege before returning to the thread mode. */ + __asm volatile ( + " mrs r0, control \n" /* Obtain current control value. */ + " movs r1, #1 \n" /* r1 = 1. */ + " orrs r0, r1 \n" /* Set nPRIV bit. */ + " msr control, r0 \n" /* Write back new control value. */ + ::: "r0", "r1", "memory" + ); + } +} + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configENABLE_MPU == 1 ) + +BaseType_t xPortIsTaskPrivileged( void ) /* PRIVILEGED_FUNCTION */ +{ + BaseType_t xTaskIsPrivileged = pdFALSE; + const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */ + + if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) + { + xTaskIsPrivileged = pdTRUE; + } + + return xTaskIsPrivileged; +} + +#endif /* configENABLE_MPU == 1 */ +/*-----------------------------------------------------------*/ + +#if( configENABLE_MPU == 1 ) + +StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, + StackType_t * pxEndOfStack, + TaskFunction_t pxCode, + void * pvParameters, + BaseType_t xRunPrivileged, + xMPU_SETTINGS * xMPUSettings ) /* PRIVILEGED_FUNCTION */ +{ + uint32_t ulIndex = 0; + + xMPUSettings->ulContext[ ulIndex ] = 0x04040404; /* r4. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x05050505; /* r5. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x06060606; /* r6. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x07070707; /* r7. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x08080808; /* r8. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x09090909; /* r9. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x10101010; /* r10. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x11111111; /* r11. */ + ulIndex++; + + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pvParameters; /* r0. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x01010101; /* r1. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x02020202; /* r2. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x03030303; /* r3. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x12121212; /* r12. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portTASK_RETURN_ADDRESS; /* LR. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxCode; /* PC. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = portINITIAL_XPSR; /* xPSR. */ + ulIndex++; + + #if ( configENABLE_TRUSTZONE == 1 ) + { + xMPUSettings->ulContext[ ulIndex ] = portNO_SECURE_CONTEXT; /* xSecureContext. */ + ulIndex++; + } + #endif /* configENABLE_TRUSTZONE */ + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) ( pxTopOfStack - 8 ); /* PSP with the hardware saved stack. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */ + ulIndex++; + if( xRunPrivileged == pdTRUE ) + { + xMPUSettings->ulTaskFlags |= portTASK_IS_PRIVILEGED_FLAG; + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_PRIVILEGED; /* CONTROL. */ + ulIndex++; + } + else + { + xMPUSettings->ulTaskFlags &= ( ~portTASK_IS_PRIVILEGED_FLAG ); + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_UNPRIVILEGED; /* CONTROL. */ + ulIndex++; + } + xMPUSettings->ulContext[ ulIndex ] = portINITIAL_EXC_RETURN; /* LR (EXC_RETURN). */ + ulIndex++; + + #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + { + /* Ensure that the system call stack is double word aligned. */ + xMPUSettings->xSystemCallStackInfo.pulSystemCallStack = &( xMPUSettings->xSystemCallStackInfo.ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE - 1 ] ); + xMPUSettings->xSystemCallStackInfo.pulSystemCallStack = ( uint32_t * ) ( ( uint32_t ) ( xMPUSettings->xSystemCallStackInfo.pulSystemCallStack ) & + ( uint32_t ) ( ~( portBYTE_ALIGNMENT_MASK ) ) ); + + xMPUSettings->xSystemCallStackInfo.pulSystemCallStackLimit = &( xMPUSettings->xSystemCallStackInfo.ulSystemCallStackBuffer[ 0 ] ); + xMPUSettings->xSystemCallStackInfo.pulSystemCallStackLimit = ( uint32_t * ) ( ( ( uint32_t ) ( xMPUSettings->xSystemCallStackInfo.pulSystemCallStackLimit ) + + ( uint32_t ) ( portBYTE_ALIGNMENT - 1 ) ) & + ( uint32_t ) ( ~( portBYTE_ALIGNMENT_MASK ) ) ); + + /* This is not NULL only for the duration of a system call. */ + xMPUSettings->xSystemCallStackInfo.pulTaskStack = NULL; + } + #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + + return &( xMPUSettings->ulContext[ ulIndex ] ); +} + +#else /* configENABLE_MPU */ + +StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, + StackType_t * pxEndOfStack, + TaskFunction_t pxCode, + void * pvParameters ) /* PRIVILEGED_FUNCTION */ +{ + /* Simulate the stack frame as it would be created by a context switch + * interrupt. */ + #if ( portPRELOAD_REGISTERS == 0 ) + { + pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ + *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR. */ + pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ + pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */ + *pxTopOfStack = portINITIAL_EXC_RETURN; pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ @@ -1029,55 +1561,39 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO #else /* portPRELOAD_REGISTERS */ { pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ - *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ + *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pxCode; /* PC */ + *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR */ + *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x12121212UL; /* R12 */ + *pxTopOfStack = ( StackType_t ) 0x12121212UL; /* R12. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x03030303UL; /* R3 */ + *pxTopOfStack = ( StackType_t ) 0x03030303UL; /* R3. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x02020202UL; /* R2 */ + *pxTopOfStack = ( StackType_t ) 0x02020202UL; /* R2. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x01010101UL; /* R1 */ + *pxTopOfStack = ( StackType_t ) 0x01010101UL; /* R1. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x11111111UL; /* R11 */ + *pxTopOfStack = ( StackType_t ) 0x11111111UL; /* R11. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x10101010UL; /* R10 */ + *pxTopOfStack = ( StackType_t ) 0x10101010UL; /* R10. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x09090909UL; /* R09 */ + *pxTopOfStack = ( StackType_t ) 0x09090909UL; /* R09. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x08080808UL; /* R08 */ + *pxTopOfStack = ( StackType_t ) 0x08080808UL; /* R08. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x07070707UL; /* R07 */ + *pxTopOfStack = ( StackType_t ) 0x07070707UL; /* R07. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x06060606UL; /* R06 */ + *pxTopOfStack = ( StackType_t ) 0x06060606UL; /* R06. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x05050505UL; /* R05 */ + *pxTopOfStack = ( StackType_t ) 0x05050505UL; /* R05. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x04040404UL; /* R04 */ + *pxTopOfStack = ( StackType_t ) 0x04040404UL; /* R04. */ pxTopOfStack--; - *pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN */ - - #if ( configENABLE_MPU == 1 ) - { - pxTopOfStack--; - - if( xRunPrivileged == pdTRUE ) - { - *pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */ - } - else - { - *pxTopOfStack = portINITIAL_CONTROL_UNPRIVILEGED; /* Slot used to hold this task's CONTROL value. */ - } - } - #endif /* configENABLE_MPU */ - + *pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN. */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ @@ -1092,6 +1608,8 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO return pxTopOfStack; } + +#endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ @@ -1128,6 +1646,10 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ configASSERT( ucMaxSysCallPriority ); + /* Check that the bits not implemented in hardware are zero in + * configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & ( ~ucMaxPriorityValue ) ) == 0U ); + /* Calculate the maximum acceptable priority group value for the number * of bits read back. */ @@ -1164,35 +1686,6 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulImplementedPrioBits; } - /* The interrupt priority bits are not modelled in QEMU and the assert that - * checks the number of implemented bits and __NVIC_PRIO_BITS will always fail. - * Therefore, this assert is not adding any value for QEMU targets. The config - * option `configDISABLE_INTERRUPT_PRIO_BITS_CHECK` should be defined in the - * `FreeRTOSConfig.h` for QEMU targets. */ - #ifndef configDISABLE_INTERRUPT_PRIO_BITS_CHECK - { - #ifdef __NVIC_PRIO_BITS - { - /* - * Check that the number of implemented priority bits queried from - * hardware is equal to the CMSIS __NVIC_PRIO_BITS configuration macro. - */ - configASSERT( ulImplementedPrioBits == __NVIC_PRIO_BITS ); - } - #endif /* __NVIC_PRIO_BITS */ - - #ifdef configPRIO_BITS - { - /* - * Check that the number of implemented priority bits queried from - * hardware is equal to the FreeRTOS configPRIO_BITS configuration macro. - */ - configASSERT( ulImplementedPrioBits == configPRIO_BITS ); - } - #endif /* configPRIO_BITS */ - } - #endif /* #ifndef configDISABLE_INTERRUPT_PRIO_BITS_CHECK */ - /* Shift the priority group value back to its position within the AIRCR * register. */ ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT; @@ -1372,6 +1865,54 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ +#if ( configENABLE_MPU == 1 ) + BaseType_t xPortIsAuthorizedToAccessBuffer( const void * pvBuffer, + uint32_t ulBufferLength, + uint32_t ulAccessRequested ) /* PRIVILEGED_FUNCTION */ + + { + uint32_t i, ulBufferStartAddress, ulBufferEndAddress; + BaseType_t xAccessGranted = pdFALSE; + const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */ + + if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) + { + xAccessGranted = pdTRUE; + } + else + { + if( portADD_UINT32_WILL_OVERFLOW( ( ( uint32_t ) pvBuffer ), ( ulBufferLength - 1UL ) ) == pdFALSE ) + { + ulBufferStartAddress = ( uint32_t ) pvBuffer; + ulBufferEndAddress = ( ( ( uint32_t ) pvBuffer ) + ulBufferLength - 1UL ); + + for( i = 0; i < portTOTAL_NUM_REGIONS; i++ ) + { + /* Is the MPU region enabled? */ + if( ( xTaskMpuSettings->xRegionsSettings[ i ].ulRLAR & portMPU_RLAR_REGION_ENABLE ) == portMPU_RLAR_REGION_ENABLE ) + { + if( portIS_ADDRESS_WITHIN_RANGE( ulBufferStartAddress, + portEXTRACT_FIRST_ADDRESS_FROM_RBAR( xTaskMpuSettings->xRegionsSettings[ i ].ulRBAR ), + portEXTRACT_LAST_ADDRESS_FROM_RLAR( xTaskMpuSettings->xRegionsSettings[ i ].ulRLAR ) ) && + portIS_ADDRESS_WITHIN_RANGE( ulBufferEndAddress, + portEXTRACT_FIRST_ADDRESS_FROM_RBAR( xTaskMpuSettings->xRegionsSettings[ i ].ulRBAR ), + portEXTRACT_LAST_ADDRESS_FROM_RLAR( xTaskMpuSettings->xRegionsSettings[ i ].ulRLAR ) ) && + portIS_AUTHORIZED( ulAccessRequested, + prvGetRegionAccessPermissions( xTaskMpuSettings->xRegionsSettings[ i ].ulRBAR ) ) ) + { + xAccessGranted = pdTRUE; + break; + } + } + } + } + } + + return xAccessGranted; + } +#endif /* configENABLE_MPU */ +/*-----------------------------------------------------------*/ + BaseType_t xPortIsInsideInterrupt( void ) { uint32_t ulCurrentInterrupt; diff --git a/portable/GCC/ARM_CM33_NTZ/non_secure/portasm.c b/portable/GCC/ARM_CM33_NTZ/non_secure/portasm.c index a78529d04d9..504b6bf3be3 100644 --- a/portable/GCC/ARM_CM33_NTZ/non_secure/portasm.c +++ b/portable/GCC/ARM_CM33_NTZ/non_secure/portasm.c @@ -40,6 +40,88 @@ * header files. */ #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE +#if ( configENABLE_MPU == 1 ) + +void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ +{ + __asm volatile + ( + " .syntax unified \n" + " \n" + " program_mpu_first_task: \n" + " ldr r2, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r0, [r2] \n" /* r0 = pxCurrentTCB. */ + " \n" + " dmb \n" /* Complete outstanding transfers before disabling MPU. */ + " ldr r1, xMPUCTRLConst2 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ + " bic r2, #1 \n" /* r2 = r2 & ~1 i.e. Clear the bit 0 in r2. */ + " str r2, [r1] \n" /* Disable MPU. */ + " \n" + " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */ + " ldr r1, [r0] \n" /* r1 = *r0 i.e. r1 = MAIR0. */ + " ldr r2, xMAIR0Const2 \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */ + " str r1, [r2] \n" /* Program MAIR0. */ + " \n" + " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */ + " ldr r1, xRNRConst2 \n" /* r1 = 0xe000ed98 [Location of RNR]. */ + " ldr r2, xRBARConst2 \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ + " \n" + " movs r3, #4 \n" /* r3 = 4. */ + " str r3, [r1] \n" /* Program RNR = 4. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + " \n" + #if ( configTOTAL_MPU_REGIONS == 16 ) + " movs r3, #8 \n" /* r3 = 8. */ + " str r3, [r1] \n" /* Program RNR = 8. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + " movs r3, #12 \n" /* r3 = 12. */ + " str r3, [r1] \n" /* Program RNR = 12. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + #endif /* configTOTAL_MPU_REGIONS == 16 */ + " \n" + " ldr r1, xMPUCTRLConst2 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ + " orr r2, #1 \n" /* r2 = r2 | 1 i.e. Set the bit 0 in r2. */ + " str r2, [r1] \n" /* Enable MPU. */ + " dsb \n" /* Force memory writes before continuing. */ + " \n" + " restore_context_first_task: \n" + " ldr r2, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r0, [r2] \n" /* r0 = pxCurrentTCB.*/ + " ldr r1, [r0] \n" /* r1 = Location of saved context in TCB. */ + " \n" + " restore_special_regs_first_task: \n" + " ldmdb r1!, {r2-r4, lr} \n" /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */ + " msr psp, r2 \n" + " msr psplim, r3 \n" + " msr control, r4 \n" + " \n" + " restore_general_regs_first_task: \n" + " ldmdb r1!, {r4-r11} \n" /* r4-r11 contain hardware saved context. */ + " stmia r2!, {r4-r11} \n" /* Copy the hardware saved context on the task stack. */ + " ldmdb r1!, {r4-r11} \n" /* r4-r11 restored. */ + " \n" + " restore_context_done_first_task: \n" + " str r1, [r0] \n" /* Save the location where the context should be saved next as the first member of TCB. */ + " mov r0, #0 \n" + " msr basepri, r0 \n" /* Ensure that interrupts are enabled when the first task starts. */ + " bx lr \n" + " \n" + " .align 4 \n" + " pxCurrentTCBConst2: .word pxCurrentTCB \n" + " xMPUCTRLConst2: .word 0xe000ed94 \n" + " xMAIR0Const2: .word 0xe000edc0 \n" + " xRNRConst2: .word 0xe000ed98 \n" + " xRBARConst2: .word 0xe000ed9c \n" + ); +} + +#else /* configENABLE_MPU */ + void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ { __asm volatile @@ -50,80 +132,23 @@ void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_ " ldr r1, [r2] \n"/* Read pxCurrentTCB. */ " ldr r0, [r1] \n"/* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ " \n" - #if ( configENABLE_MPU == 1 ) - " dmb \n"/* Complete outstanding transfers before disabling MPU. */ - " ldr r2, xMPUCTRLConst2 \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ - " ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */ - " bic r4, #1 \n"/* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */ - " str r4, [r2] \n"/* Disable MPU. */ - " \n" - " adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */ - " ldr r3, [r1] \n"/* r3 = *r1 i.e. r3 = MAIR0. */ - " ldr r2, xMAIR0Const2 \n"/* r2 = 0xe000edc0 [Location of MAIR0]. */ - " str r3, [r2] \n"/* Program MAIR0. */ - " ldr r2, xRNRConst2 \n"/* r2 = 0xe000ed98 [Location of RNR]. */ - " movs r3, #4 \n"/* r3 = 4. */ - " str r3, [r2] \n"/* Program RNR = 4. */ - " adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to first RBAR in TCB. */ - " ldr r2, xRBARConst2 \n"/* r2 = 0xe000ed9c [Location of RBAR]. */ - " ldmia r1!, {r4-r11} \n"/* Read 4 set of RBAR/RLAR registers from TCB. */ - " stmia r2!, {r4-r11} \n"/* Write 4 set of RBAR/RLAR registers using alias registers. */ - " \n" - #if ( configTOTAL_MPU_REGIONS == 16 ) - " ldr r2, xRNRConst2 \n"/* r2 = 0xe000ed98 [Location of RNR]. */ - " movs r3, #8 \n"/* r3 = 8. */ - " str r3, [r2] \n"/* Program RNR = 8. */ - " ldr r2, xRBARConst2 \n"/* r2 = 0xe000ed9c [Location of RBAR]. */ - " ldmia r1!, {r4-r11} \n"/* Read 4 set of RBAR/RLAR registers from TCB. */ - " stmia r2!, {r4-r11} \n"/* Write 4 set of RBAR/RLAR registers using alias registers. */ - " ldr r2, xRNRConst2 \n"/* r2 = 0xe000ed98 [Location of RNR]. */ - " movs r3, #12 \n"/* r3 = 12. */ - " str r3, [r2] \n"/* Program RNR = 12. */ - " ldr r2, xRBARConst2 \n"/* r2 = 0xe000ed9c [Location of RBAR]. */ - " ldmia r1!, {r4-r11} \n"/* Read 4 set of RBAR/RLAR registers from TCB. */ - " stmia r2!, {r4-r11} \n"/* Write 4 set of RBAR/RLAR registers using alias registers. */ - #endif /* configTOTAL_MPU_REGIONS == 16 */ - " \n" - " ldr r2, xMPUCTRLConst2 \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ - " ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */ - " orr r4, #1 \n"/* r4 = r4 | 1 i.e. Set the bit 0 in r4. */ - " str r4, [r2] \n"/* Enable MPU. */ - " dsb \n"/* Force memory writes before continuing. */ - #endif /* configENABLE_MPU */ - " \n" - #if ( configENABLE_MPU == 1 ) - " ldm r0!, {r1-r3} \n"/* Read from stack - r1 = PSPLIM, r2 = CONTROL and r3 = EXC_RETURN. */ - " msr psplim, r1 \n"/* Set this task's PSPLIM value. */ - " msr control, r2 \n"/* Set this task's CONTROL value. */ - " adds r0, #32 \n"/* Discard everything up to r0. */ - " msr psp, r0 \n"/* This is now the new top of stack to use in the task. */ - " isb \n" - " mov r0, #0 \n" - " msr basepri, r0 \n"/* Ensure that interrupts are enabled when the first task starts. */ - " bx r3 \n"/* Finally, branch to EXC_RETURN. */ - #else /* configENABLE_MPU */ - " ldm r0!, {r1-r2} \n"/* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */ - " msr psplim, r1 \n"/* Set this task's PSPLIM value. */ - " movs r1, #2 \n"/* r1 = 2. */ - " msr CONTROL, r1 \n"/* Switch to use PSP in the thread mode. */ - " adds r0, #32 \n"/* Discard everything up to r0. */ - " msr psp, r0 \n"/* This is now the new top of stack to use in the task. */ - " isb \n" - " mov r0, #0 \n" - " msr basepri, r0 \n"/* Ensure that interrupts are enabled when the first task starts. */ - " bx r2 \n"/* Finally, branch to EXC_RETURN. */ - #endif /* configENABLE_MPU */ + " ldm r0!, {r1-r2} \n"/* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */ + " msr psplim, r1 \n"/* Set this task's PSPLIM value. */ + " movs r1, #2 \n"/* r1 = 2. */ + " msr CONTROL, r1 \n"/* Switch to use PSP in the thread mode. */ + " adds r0, #32 \n"/* Discard everything up to r0. */ + " msr psp, r0 \n"/* This is now the new top of stack to use in the task. */ + " isb \n" + " mov r0, #0 \n" + " msr basepri, r0 \n"/* Ensure that interrupts are enabled when the first task starts. */ + " bx r2 \n"/* Finally, branch to EXC_RETURN. */ " \n" " .align 4 \n" "pxCurrentTCBConst2: .word pxCurrentTCB \n" - #if ( configENABLE_MPU == 1 ) - "xMPUCTRLConst2: .word 0xe000ed94 \n" - "xMAIR0Const2: .word 0xe000edc0 \n" - "xRNRConst2: .word 0xe000ed98 \n" - "xRBARConst2: .word 0xe000ed9c \n" - #endif /* configENABLE_MPU */ ); } + +#endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */ @@ -231,6 +256,129 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att } /*-----------------------------------------------------------*/ +#if ( configENABLE_MPU == 1 ) + +void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ +{ + __asm volatile + ( + " .syntax unified \n" + " \n" + " ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r0, [r2] \n" /* r0 = pxCurrentTCB. */ + " ldr r1, [r0] \n" /* r1 = Location in TCB where the context should be saved. */ + " mrs r2, psp \n" /* r2 = PSP. */ + " \n" + " save_general_regs: \n" + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + " add r2, r2, #0x20 \n" /* Move r2 to location where s0 is saved. */ + " tst lr, #0x10 \n" + " ittt eq \n" + " vstmiaeq r1!, {s16-s31} \n" /* Store s16-s31. */ + " vldmiaeq r2, {s0-s16} \n" /* Copy hardware saved FP context into s0-s16. */ + " vstmiaeq r1!, {s0-s16} \n" /* Store hardware saved FP context. */ + " sub r2, r2, #0x20 \n" /* Set r2 back to the location of hardware saved context. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ + " \n" + " stmia r1!, {r4-r11} \n" /* Store r4-r11. */ + " ldmia r2, {r4-r11} \n" /* Copy the hardware saved context into r4-r11. */ + " stmia r1!, {r4-r11} \n" /* Store the hardware saved context. */ + " \n" + " save_special_regs: \n" + " mrs r3, psplim \n" /* r3 = PSPLIM. */ + " mrs r4, control \n" /* r4 = CONTROL. */ + " stmia r1!, {r2-r4, lr} \n" /* Store original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */ + " str r1, [r0] \n" /* Save the location from where the context should be restored as the first member of TCB. */ + " \n" + " select_next_task: \n" + " mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */ + " msr basepri, r0 \n" /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + " dsb \n" + " isb \n" + " bl vTaskSwitchContext \n" + " mov r0, #0 \n" /* r0 = 0. */ + " msr basepri, r0 \n" /* Enable interrupts. */ + " \n" + " program_mpu: \n" + " ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r0, [r2] \n" /* r0 = pxCurrentTCB. */ + " \n" + " dmb \n" /* Complete outstanding transfers before disabling MPU. */ + " ldr r1, xMPUCTRLConst \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ + " bic r2, #1 \n" /* r2 = r2 & ~1 i.e. Clear the bit 0 in r2. */ + " str r2, [r1] \n" /* Disable MPU. */ + " \n" + " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */ + " ldr r1, [r0] \n" /* r1 = *r0 i.e. r1 = MAIR0. */ + " ldr r2, xMAIR0Const \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */ + " str r1, [r2] \n" /* Program MAIR0. */ + " \n" + " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */ + " ldr r1, xRNRConst \n" /* r1 = 0xe000ed98 [Location of RNR]. */ + " ldr r2, xRBARConst \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ + " \n" + " movs r3, #4 \n" /* r3 = 4. */ + " str r3, [r1] \n" /* Program RNR = 4. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + " \n" + #if ( configTOTAL_MPU_REGIONS == 16 ) + " movs r3, #8 \n" /* r3 = 8. */ + " str r3, [r1] \n" /* Program RNR = 8. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + " movs r3, #12 \n" /* r3 = 12. */ + " str r3, [r1] \n" /* Program RNR = 12. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + #endif /* configTOTAL_MPU_REGIONS == 16 */ + " \n" + " ldr r1, xMPUCTRLConst \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ + " orr r2, #1 \n" /* r2 = r2 | 1 i.e. Set the bit 0 in r2. */ + " str r2, [r1] \n" /* Enable MPU. */ + " dsb \n" /* Force memory writes before continuing. */ + " \n" + " restore_context: \n" + " ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r0, [r2] \n" /* r0 = pxCurrentTCB.*/ + " ldr r1, [r0] \n" /* r1 = Location of saved context in TCB. */ + " \n" + " restore_special_regs: \n" + " ldmdb r1!, {r2-r4, lr} \n" /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */ + " msr psp, r2 \n" + " msr psplim, r3 \n" + " msr control, r4 \n" + " \n" + " restore_general_regs: \n" + " ldmdb r1!, {r4-r11} \n" /* r4-r11 contain hardware saved context. */ + " stmia r2!, {r4-r11} \n" /* Copy the hardware saved context on the task stack. */ + " ldmdb r1!, {r4-r11} \n" /* r4-r11 restored. */ + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + " tst lr, #0x10 \n" + " ittt eq \n" + " vldmdbeq r1!, {s0-s16} \n" /* s0-s16 contain hardware saved FP context. */ + " vstmiaeq r2!, {s0-s16} \n" /* Copy hardware saved FP context on the task stack. */ + " vldmdbeq r1!, {s16-s31} \n" /* Restore s16-s31. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ + " \n" + " restore_context_done: \n" + " str r1, [r0] \n" /* Save the location where the context should be saved next as the first member of TCB. */ + " bx lr \n" + " \n" + " .align 4 \n" + " pxCurrentTCBConst: .word pxCurrentTCB \n" + " xMPUCTRLConst: .word 0xe000ed94 \n" + " xMAIR0Const: .word 0xe000edc0 \n" + " xRNRConst: .word 0xe000ed98 \n" + " xRBARConst: .word 0xe000ed9c \n" + ::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) + ); +} + +#else /* configENABLE_MPU */ + void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ { __asm volatile @@ -238,21 +386,16 @@ void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ " .syntax unified \n" " \n" " mrs r0, psp \n"/* Read PSP in r0. */ + " \n" #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) " tst lr, #0x10 \n"/* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ " it eq \n" " vstmdbeq r0!, {s16-s31} \n"/* Store the additional FP context registers which are not saved automatically. */ #endif /* configENABLE_FPU || configENABLE_MVE */ - #if ( configENABLE_MPU == 1 ) - " mrs r1, psplim \n"/* r1 = PSPLIM. */ - " mrs r2, control \n"/* r2 = CONTROL. */ - " mov r3, lr \n"/* r3 = LR/EXC_RETURN. */ - " stmdb r0!, {r1-r11} \n"/* Store on the stack - PSPLIM, CONTROL, LR and registers that are not automatically saved. */ - #else /* configENABLE_MPU */ - " mrs r2, psplim \n"/* r2 = PSPLIM. */ - " mov r3, lr \n"/* r3 = LR/EXC_RETURN. */ - " stmdb r0!, {r2-r11} \n"/* Store on the stack - PSPLIM, LR and registers that are not automatically saved. */ - #endif /* configENABLE_MPU */ + " \n" + " mrs r2, psplim \n"/* r2 = PSPLIM. */ + " mov r3, lr \n"/* r3 = LR/EXC_RETURN. */ + " stmdb r0!, {r2-r11} \n"/* Store on the stack - PSPLIM, LR and registers that are not automatically saved. */ " \n" " ldr r2, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r2] \n"/* Read pxCurrentTCB. */ @@ -270,52 +413,7 @@ void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ " ldr r1, [r2] \n"/* Read pxCurrentTCB. */ " ldr r0, [r1] \n"/* The first item in pxCurrentTCB is the task top of stack. r0 now points to the top of stack. */ " \n" - #if ( configENABLE_MPU == 1 ) - " dmb \n"/* Complete outstanding transfers before disabling MPU. */ - " ldr r2, xMPUCTRLConst \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ - " ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */ - " bic r4, #1 \n"/* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */ - " str r4, [r2] \n"/* Disable MPU. */ - " \n" - " adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */ - " ldr r3, [r1] \n"/* r3 = *r1 i.e. r3 = MAIR0. */ - " ldr r2, xMAIR0Const \n"/* r2 = 0xe000edc0 [Location of MAIR0]. */ - " str r3, [r2] \n"/* Program MAIR0. */ - " ldr r2, xRNRConst \n"/* r2 = 0xe000ed98 [Location of RNR]. */ - " movs r3, #4 \n"/* r3 = 4. */ - " str r3, [r2] \n"/* Program RNR = 4. */ - " adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to first RBAR in TCB. */ - " ldr r2, xRBARConst \n"/* r2 = 0xe000ed9c [Location of RBAR]. */ - " ldmia r1!, {r4-r11} \n"/* Read 4 sets of RBAR/RLAR registers from TCB. */ - " stmia r2!, {r4-r11} \n"/* Write 4 set of RBAR/RLAR registers using alias registers. */ - " \n" - #if ( configTOTAL_MPU_REGIONS == 16 ) - " ldr r2, xRNRConst \n"/* r2 = 0xe000ed98 [Location of RNR]. */ - " movs r3, #8 \n"/* r3 = 8. */ - " str r3, [r2] \n"/* Program RNR = 8. */ - " ldr r2, xRBARConst \n"/* r2 = 0xe000ed9c [Location of RBAR]. */ - " ldmia r1!, {r4-r11} \n"/* Read 4 sets of RBAR/RLAR registers from TCB. */ - " stmia r2!, {r4-r11} \n"/* Write 4 set of RBAR/RLAR registers using alias registers. */ - " ldr r2, xRNRConst \n"/* r2 = 0xe000ed98 [Location of RNR]. */ - " movs r3, #12 \n"/* r3 = 12. */ - " str r3, [r2] \n"/* Program RNR = 12. */ - " ldr r2, xRBARConst \n"/* r2 = 0xe000ed9c [Location of RBAR]. */ - " ldmia r1!, {r4-r11} \n"/* Read 4 sets of RBAR/RLAR registers from TCB. */ - " stmia r2!, {r4-r11} \n"/* Write 4 set of RBAR/RLAR registers using alias registers. */ - #endif /* configTOTAL_MPU_REGIONS == 16 */ - " \n" - " ldr r2, xMPUCTRLConst \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ - " ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */ - " orr r4, #1 \n"/* r4 = r4 | 1 i.e. Set the bit 0 in r4. */ - " str r4, [r2] \n"/* Enable MPU. */ - " dsb \n"/* Force memory writes before continuing. */ - #endif /* configENABLE_MPU */ - " \n" - #if ( configENABLE_MPU == 1 ) - " ldmia r0!, {r1-r11} \n"/* Read from stack - r1 = PSPLIM, r2 = CONTROL, r3 = LR and r4-r11 restored. */ - #else /* configENABLE_MPU */ - " ldmia r0!, {r2-r11} \n"/* Read from stack - r2 = PSPLIM, r3 = LR and r4-r11 restored. */ - #endif /* configENABLE_MPU */ + " ldmia r0!, {r2-r11} \n"/* Read from stack - r2 = PSPLIM, r3 = LR and r4-r11 restored. */ " \n" #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) " tst r3, #0x10 \n"/* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ @@ -323,28 +421,66 @@ void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ " vldmiaeq r0!, {s16-s31} \n"/* Restore the additional FP context registers which are not restored automatically. */ #endif /* configENABLE_FPU || configENABLE_MVE */ " \n" - #if ( configENABLE_MPU == 1 ) - " msr psplim, r1 \n"/* Restore the PSPLIM register value for the task. */ - " msr control, r2 \n"/* Restore the CONTROL register value for the task. */ - #else /* configENABLE_MPU */ - " msr psplim, r2 \n"/* Restore the PSPLIM register value for the task. */ - #endif /* configENABLE_MPU */ + " msr psplim, r2 \n"/* Restore the PSPLIM register value for the task. */ " msr psp, r0 \n"/* Remember the new top of stack for the task. */ " bx r3 \n" " \n" " .align 4 \n" "pxCurrentTCBConst: .word pxCurrentTCB \n" - #if ( configENABLE_MPU == 1 ) - "xMPUCTRLConst: .word 0xe000ed94 \n" - "xMAIR0Const: .word 0xe000edc0 \n" - "xRNRConst: .word 0xe000ed98 \n" - "xRBARConst: .word 0xe000ed9c \n" - #endif /* configENABLE_MPU */ ::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) ); } + +#endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + +void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ +{ + __asm volatile + ( + ".syntax unified \n" + ".extern vPortSVCHandler_C \n" + ".extern vSystemCallEnter \n" + ".extern vSystemCallEnter_1 \n" + ".extern vSystemCallExit \n" + " \n" + "tst lr, #4 \n" + "ite eq \n" + "mrseq r0, msp \n" + "mrsne r0, psp \n" + " \n" + "ldr r1, [r0, #24] \n" + "ldrb r2, [r1, #-2] \n" + "cmp r2, %0 \n" + "beq syscall_enter \n" + "cmp r2, %1 \n" + "beq syscall_enter_1 \n" + "cmp r2, %2 \n" + "beq syscall_exit \n" + "b vPortSVCHandler_C \n" + " \n" + "syscall_enter: \n" + " mov r1, lr \n" + " b vSystemCallEnter \n" + " \n" + "syscall_enter_1: \n" + " mov r1, lr \n" + " b vSystemCallEnter_1 \n" + " \n" + "syscall_exit: \n" + " mov r1, lr \n" + " b vSystemCallExit \n" + " \n" + : /* No outputs. */ + :"i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_ENTER_1 ), "i" ( portSVC_SYSTEM_CALL_EXIT ) + : "r0", "r1", "r2", "memory" + ); +} + +#else /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ { __asm volatile @@ -362,4 +498,6 @@ void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ "svchandler_address_const: .word vPortSVCHandler_C \n" ); } + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ /*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM33_NTZ/non_secure/portmacro.h b/portable/GCC/ARM_CM33_NTZ/non_secure/portmacro.h index 19da9b0ecfe..b9efb07ddc7 100644 --- a/portable/GCC/ARM_CM33_NTZ/non_secure/portmacro.h +++ b/portable/GCC/ARM_CM33_NTZ/non_secure/portmacro.h @@ -51,7 +51,6 @@ #define portARCH_NAME "Cortex-M33" #define portHAS_BASEPRI 1 #define portDONT_DISCARD __attribute__( ( used ) ) -#define portNORETURN __attribute__( ( noreturn ) ) /*-----------------------------------------------------------*/ /* ARMv8-M common port configurations. */ diff --git a/portable/GCC/ARM_CM33_NTZ/non_secure/portmacrocommon.h b/portable/GCC/ARM_CM33_NTZ/non_secure/portmacrocommon.h index c2ca5fa7730..65ac109c802 100644 --- a/portable/GCC/ARM_CM33_NTZ/non_secure/portmacrocommon.h +++ b/portable/GCC/ARM_CM33_NTZ/non_secure/portmacrocommon.h @@ -186,23 +186,120 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #define portMPU_REGION_EXECUTE_NEVER ( 1UL ) /*-----------------------------------------------------------*/ -/** - * @brief Settings to define an MPU region. - */ -typedef struct MPURegionSettings -{ - uint32_t ulRBAR; /**< RBAR for the region. */ - uint32_t ulRLAR; /**< RLAR for the region. */ -} MPURegionSettings_t; +#if ( configENABLE_MPU == 1 ) -/** - * @brief MPU settings as stored in the TCB. - */ -typedef struct MPU_SETTINGS -{ - uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ - MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */ -} xMPU_SETTINGS; + /** + * @brief Settings to define an MPU region. + */ + typedef struct MPURegionSettings + { + uint32_t ulRBAR; /**< RBAR for the region. */ + uint32_t ulRLAR; /**< RLAR for the region. */ + } MPURegionSettings_t; + + #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + + #ifndef configSYSTEM_CALL_STACK_SIZE + #error configSYSTEM_CALL_STACK_SIZE must be defined to the desired size of the system call stack in words for using MPU wrappers v2. + #endif + + /** + * @brief System call stack. + */ + typedef struct SYSTEM_CALL_STACK_INFO + { + uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ]; + uint32_t * pulSystemCallStack; + uint32_t * pulSystemCallStackLimit; + uint32_t * pulTaskStack; + uint32_t ulLinkRegisterAtSystemCallEntry; + uint32_t ulStackLimitRegisterAtSystemCallEntry; + } xSYSTEM_CALL_STACK_INFO; + + #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + + /** + * @brief MPU settings as stored in the TCB. + */ + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + + #if( configENABLE_TRUSTZONE == 1 ) + + /* + * +-----------+---------------+----------+-----------------+------------------------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | + * | | | | PC, xPSR | CONTROL, EXC_RETURN | | + * +-----------+---------------+----------+-----------------+------------------------------+-----+ + * + * <-----------><--------------><---------><----------------><-----------------------------><----> + * 16 16 8 8 5 1 + */ + #define MAX_CONTEXT_SIZE 54 + + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ + + /* + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | + * | | | | PC, xPSR | EXC_RETURN | | + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * + * <-----------><--------------><---------><----------------><---------------------><----> + * 16 16 8 8 4 1 + */ + #define MAX_CONTEXT_SIZE 53 + + #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + + #else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ + + #if( configENABLE_TRUSTZONE == 1 ) + + /* + * +----------+-----------------+------------------------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | + * | | PC, xPSR | CONTROL, EXC_RETURN | | + * +----------+-----------------+------------------------------+-----+ + * + * <---------><----------------><------------------------------><----> + * 8 8 5 1 + */ + #define MAX_CONTEXT_SIZE 22 + + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ + + /* + * +----------+-----------------+----------------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | + * | | PC, xPSR | EXC_RETURN | | + * +----------+-----------------+----------------------+-----+ + * + * <---------><----------------><----------------------><----> + * 8 8 4 1 + */ + #define MAX_CONTEXT_SIZE 21 + + #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + + #endif /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ + + /* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ + #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) + #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) + + typedef struct MPU_SETTINGS + { + uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ + MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */ + uint32_t ulContext[ MAX_CONTEXT_SIZE ]; + uint32_t ulTaskFlags; + + #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo; + #endif + } xMPU_SETTINGS; + +#endif /* configENABLE_MPU == 1 */ /*-----------------------------------------------------------*/ /** @@ -223,6 +320,9 @@ typedef struct MPU_SETTINGS #define portSVC_FREE_SECURE_CONTEXT 1 #define portSVC_START_SCHEDULER 2 #define portSVC_RAISE_PRIVILEGE 3 +#define portSVC_SYSTEM_CALL_ENTER 4 /* System calls with upto 4 parameters. */ +#define portSVC_SYSTEM_CALL_ENTER_1 5 /* System calls with 5 parameters. */ +#define portSVC_SYSTEM_CALL_EXIT 6 /*-----------------------------------------------------------*/ /** @@ -315,6 +415,20 @@ typedef struct MPU_SETTINGS #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ +#if ( configENABLE_MPU == 1 ) + + extern BaseType_t xPortIsTaskPrivileged( void ); + + /** + * @brief Checks whether or not the calling task is privileged. + * + * @return pdTRUE if the calling task is privileged, pdFALSE otherwise. + */ + #define portIS_TASK_PRIVILEGED() xPortIsTaskPrivileged() + +#endif /* configENABLE_MPU == 1 */ +/*-----------------------------------------------------------*/ + /** * @brief Barriers. */ diff --git a/portable/GCC/ARM_CM35P/non_secure/mpu_wrappers_v2_asm.c b/portable/GCC/ARM_CM35P/non_secure/mpu_wrappers_v2_asm.c new file mode 100644 index 00000000000..6e2043427fe --- /dev/null +++ b/portable/GCC/ARM_CM35P/non_secure/mpu_wrappers_v2_asm.c @@ -0,0 +1,2349 @@ +/* + * FreeRTOS Kernel + * Copyright (C) 2021 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 + * + */ + +/* 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. */ +#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +/* Scheduler includes. */ +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" +#include "timers.h" +#include "event_groups.h" +#include "stream_buffer.h" + +#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + +#if ( INCLUDE_xTaskDelayUntil == 1 ) + +BaseType_t MPU_xTaskDelayUntil( TickType_t * const pxPreviousWakeTime, + const TickType_t xTimeIncrement ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskDelayUntil( TickType_t * const pxPreviousWakeTime, + const TickType_t xTimeIncrement ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskDelayUntilImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskDelayUntil_Unpriv \n" + " MPU_xTaskDelayUntil_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskDelayUntilImpl \n" + " MPU_xTaskDelayUntil_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskDelayUntilImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_xTaskDelayUntil == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_xTaskAbortDelay == 1 ) + +BaseType_t MPU_xTaskAbortDelay( TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskAbortDelay( TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskAbortDelayImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskAbortDelay_Unpriv \n" + " MPU_xTaskAbortDelay_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskAbortDelayImpl \n" + " MPU_xTaskAbortDelay_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskAbortDelayImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_xTaskAbortDelay == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskDelay == 1 ) + +void MPU_vTaskDelay( const TickType_t xTicksToDelay ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskDelay( const TickType_t xTicksToDelay ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskDelayImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vTaskDelay_Unpriv \n" + " MPU_vTaskDelay_Priv: \n" + " pop {r0} \n" + " b MPU_vTaskDelayImpl \n" + " MPU_vTaskDelay_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vTaskDelayImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_vTaskDelay == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_uxTaskPriorityGet == 1 ) + +UBaseType_t MPU_uxTaskPriorityGet( const TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxTaskPriorityGet( const TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxTaskPriorityGetImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_uxTaskPriorityGet_Unpriv \n" + " MPU_uxTaskPriorityGet_Priv: \n" + " pop {r0} \n" + " b MPU_uxTaskPriorityGetImpl \n" + " MPU_uxTaskPriorityGet_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_uxTaskPriorityGetImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_uxTaskPriorityGet == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_eTaskGetState == 1 ) + +eTaskState MPU_eTaskGetState( TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +eTaskState MPU_eTaskGetState( TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_eTaskGetStateImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_eTaskGetState_Unpriv \n" + " MPU_eTaskGetState_Priv: \n" + " pop {r0} \n" + " b MPU_eTaskGetStateImpl \n" + " MPU_eTaskGetState_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_eTaskGetStateImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_eTaskGetState == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + +void MPU_vTaskGetInfo( TaskHandle_t xTask, + TaskStatus_t * pxTaskStatus, + BaseType_t xGetFreeStackSpace, + eTaskState eState ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskGetInfo( TaskHandle_t xTask, + TaskStatus_t * pxTaskStatus, + BaseType_t xGetFreeStackSpace, + eTaskState eState ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskGetInfoImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vTaskGetInfo_Unpriv \n" + " MPU_vTaskGetInfo_Priv: \n" + " pop {r0} \n" + " b MPU_vTaskGetInfoImpl \n" + " MPU_vTaskGetInfo_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vTaskGetInfoImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TRACE_FACILITY == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) + +TaskHandle_t MPU_xTaskGetIdleTaskHandle( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TaskHandle_t MPU_xTaskGetIdleTaskHandle( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGetIdleTaskHandleImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskGetIdleTaskHandle_Unpriv \n" + " MPU_xTaskGetIdleTaskHandle_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskGetIdleTaskHandleImpl \n" + " MPU_xTaskGetIdleTaskHandle_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskGetIdleTaskHandleImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskSuspend == 1 ) + +void MPU_vTaskSuspend( TaskHandle_t xTaskToSuspend ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskSuspend( TaskHandle_t xTaskToSuspend ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskSuspendImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vTaskSuspend_Unpriv \n" + " MPU_vTaskSuspend_Priv: \n" + " pop {r0} \n" + " b MPU_vTaskSuspendImpl \n" + " MPU_vTaskSuspend_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vTaskSuspendImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_vTaskSuspend == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskSuspend == 1 ) + +void MPU_vTaskResume( TaskHandle_t xTaskToResume ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskResume( TaskHandle_t xTaskToResume ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskResumeImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vTaskResume_Unpriv \n" + " MPU_vTaskResume_Priv: \n" + " pop {r0} \n" + " b MPU_vTaskResumeImpl \n" + " MPU_vTaskResume_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vTaskResumeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_vTaskSuspend == 1 ) */ +/*-----------------------------------------------------------*/ + +TickType_t MPU_xTaskGetTickCount( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TickType_t MPU_xTaskGetTickCount( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGetTickCountImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskGetTickCount_Unpriv \n" + " MPU_xTaskGetTickCount_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskGetTickCountImpl \n" + " MPU_xTaskGetTickCount_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskGetTickCountImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +UBaseType_t MPU_uxTaskGetNumberOfTasks( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxTaskGetNumberOfTasks( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxTaskGetNumberOfTasksImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_uxTaskGetNumberOfTasks_Unpriv \n" + " MPU_uxTaskGetNumberOfTasks_Priv: \n" + " pop {r0} \n" + " b MPU_uxTaskGetNumberOfTasksImpl \n" + " MPU_uxTaskGetNumberOfTasks_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_uxTaskGetNumberOfTasksImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +char * MPU_pcTaskGetName( TaskHandle_t xTaskToQuery ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +char * MPU_pcTaskGetName( TaskHandle_t xTaskToQuery ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_pcTaskGetNameImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_pcTaskGetName_Unpriv \n" + " MPU_pcTaskGetName_Priv: \n" + " pop {r0} \n" + " b MPU_pcTaskGetNameImpl \n" + " MPU_pcTaskGetName_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_pcTaskGetNameImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +#if ( configGENERATE_RUN_TIME_STATS == 1 ) + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetRunTimeCounter( const TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetRunTimeCounter( const TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_ulTaskGetRunTimeCounterImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_ulTaskGetRunTimeCounter_Unpriv \n" + " MPU_ulTaskGetRunTimeCounter_Priv: \n" + " pop {r0} \n" + " b MPU_ulTaskGetRunTimeCounterImpl \n" + " MPU_ulTaskGetRunTimeCounter_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_ulTaskGetRunTimeCounterImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( ( configGENERATE_RUN_TIME_STATS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configGENERATE_RUN_TIME_STATS == 1 ) + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetRunTimePercent( const TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetRunTimePercent( const TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_ulTaskGetRunTimePercentImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_ulTaskGetRunTimePercent_Unpriv \n" + " MPU_ulTaskGetRunTimePercent_Priv: \n" + " pop {r0} \n" + " b MPU_ulTaskGetRunTimePercentImpl \n" + " MPU_ulTaskGetRunTimePercent_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_ulTaskGetRunTimePercentImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( ( configGENERATE_RUN_TIME_STATS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimePercent( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimePercent( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_ulTaskGetIdleRunTimePercentImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_ulTaskGetIdleRunTimePercent_Unpriv \n" + " MPU_ulTaskGetIdleRunTimePercent_Priv: \n" + " pop {r0} \n" + " b MPU_ulTaskGetIdleRunTimePercentImpl \n" + " MPU_ulTaskGetIdleRunTimePercent_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_ulTaskGetIdleRunTimePercentImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimeCounter( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimeCounter( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_ulTaskGetIdleRunTimeCounterImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_ulTaskGetIdleRunTimeCounter_Unpriv \n" + " MPU_ulTaskGetIdleRunTimeCounter_Priv: \n" + " pop {r0} \n" + " b MPU_ulTaskGetIdleRunTimeCounterImpl \n" + " MPU_ulTaskGetIdleRunTimeCounter_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_ulTaskGetIdleRunTimeCounterImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_APPLICATION_TASK_TAG == 1 ) + +void MPU_vTaskSetApplicationTaskTag( TaskHandle_t xTask, + TaskHookFunction_t pxHookFunction ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskSetApplicationTaskTag( TaskHandle_t xTask, + TaskHookFunction_t pxHookFunction ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskSetApplicationTaskTagImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vTaskSetApplicationTaskTag_Unpriv \n" + " MPU_vTaskSetApplicationTaskTag_Priv: \n" + " pop {r0} \n" + " b MPU_vTaskSetApplicationTaskTagImpl \n" + " MPU_vTaskSetApplicationTaskTag_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vTaskSetApplicationTaskTagImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_APPLICATION_TASK_TAG == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_APPLICATION_TASK_TAG == 1 ) + +TaskHookFunction_t MPU_xTaskGetApplicationTaskTag( TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TaskHookFunction_t MPU_xTaskGetApplicationTaskTag( TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGetApplicationTaskTagImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskGetApplicationTaskTag_Unpriv \n" + " MPU_xTaskGetApplicationTaskTag_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskGetApplicationTaskTagImpl \n" + " MPU_xTaskGetApplicationTaskTag_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskGetApplicationTaskTagImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_APPLICATION_TASK_TAG == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) + +void MPU_vTaskSetThreadLocalStoragePointer( TaskHandle_t xTaskToSet, + BaseType_t xIndex, + void * pvValue ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskSetThreadLocalStoragePointer( TaskHandle_t xTaskToSet, + BaseType_t xIndex, + void * pvValue ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskSetThreadLocalStoragePointerImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vTaskSetThreadLocalStoragePointer_Unpriv \n" + " MPU_vTaskSetThreadLocalStoragePointer_Priv: \n" + " pop {r0} \n" + " b MPU_vTaskSetThreadLocalStoragePointerImpl \n" + " MPU_vTaskSetThreadLocalStoragePointer_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vTaskSetThreadLocalStoragePointerImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) + +void * MPU_pvTaskGetThreadLocalStoragePointer( TaskHandle_t xTaskToQuery, + BaseType_t xIndex ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void * MPU_pvTaskGetThreadLocalStoragePointer( TaskHandle_t xTaskToQuery, + BaseType_t xIndex ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_pvTaskGetThreadLocalStoragePointerImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_pvTaskGetThreadLocalStoragePointer_Unpriv \n" + " MPU_pvTaskGetThreadLocalStoragePointer_Priv: \n" + " pop {r0} \n" + " b MPU_pvTaskGetThreadLocalStoragePointerImpl \n" + " MPU_pvTaskGetThreadLocalStoragePointer_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_pvTaskGetThreadLocalStoragePointerImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + +UBaseType_t MPU_uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray, + const UBaseType_t uxArraySize, + configRUN_TIME_COUNTER_TYPE * const pulTotalRunTime ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray, + const UBaseType_t uxArraySize, + configRUN_TIME_COUNTER_TYPE * const pulTotalRunTime ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxTaskGetSystemStateImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_uxTaskGetSystemState_Unpriv \n" + " MPU_uxTaskGetSystemState_Priv: \n" + " pop {r0} \n" + " b MPU_uxTaskGetSystemStateImpl \n" + " MPU_uxTaskGetSystemState_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_uxTaskGetSystemStateImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TRACE_FACILITY == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) + +UBaseType_t MPU_uxTaskGetStackHighWaterMark( TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxTaskGetStackHighWaterMark( TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxTaskGetStackHighWaterMarkImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_uxTaskGetStackHighWaterMark_Unpriv \n" + " MPU_uxTaskGetStackHighWaterMark_Priv: \n" + " pop {r0} \n" + " b MPU_uxTaskGetStackHighWaterMarkImpl \n" + " MPU_uxTaskGetStackHighWaterMark_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_uxTaskGetStackHighWaterMarkImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) + +configSTACK_DEPTH_TYPE MPU_uxTaskGetStackHighWaterMark2( TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +configSTACK_DEPTH_TYPE MPU_uxTaskGetStackHighWaterMark2( TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxTaskGetStackHighWaterMark2Impl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_uxTaskGetStackHighWaterMark2_Unpriv \n" + " MPU_uxTaskGetStackHighWaterMark2_Priv: \n" + " pop {r0} \n" + " b MPU_uxTaskGetStackHighWaterMark2Impl \n" + " MPU_uxTaskGetStackHighWaterMark2_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_uxTaskGetStackHighWaterMark2Impl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) ) + +TaskHandle_t MPU_xTaskGetCurrentTaskHandle( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TaskHandle_t MPU_xTaskGetCurrentTaskHandle( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGetCurrentTaskHandleImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskGetCurrentTaskHandle_Unpriv \n" + " MPU_xTaskGetCurrentTaskHandle_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskGetCurrentTaskHandleImpl \n" + " MPU_xTaskGetCurrentTaskHandle_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskGetCurrentTaskHandleImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_xTaskGetSchedulerState == 1 ) + +BaseType_t MPU_xTaskGetSchedulerState( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskGetSchedulerState( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGetSchedulerStateImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskGetSchedulerState_Unpriv \n" + " MPU_xTaskGetSchedulerState_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskGetSchedulerStateImpl \n" + " MPU_xTaskGetSchedulerState_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskGetSchedulerStateImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_xTaskGetSchedulerState == 1 ) */ +/*-----------------------------------------------------------*/ + +void MPU_vTaskSetTimeOutState( TimeOut_t * const pxTimeOut ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskSetTimeOutState( TimeOut_t * const pxTimeOut ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskSetTimeOutStateImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vTaskSetTimeOutState_Unpriv \n" + " MPU_vTaskSetTimeOutState_Priv: \n" + " pop {r0} \n" + " b MPU_vTaskSetTimeOutStateImpl \n" + " MPU_vTaskSetTimeOutState_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vTaskSetTimeOutStateImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut, + TickType_t * const pxTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut, + TickType_t * const pxTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskCheckForTimeOutImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskCheckForTimeOut_Unpriv \n" + " MPU_xTaskCheckForTimeOut_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskCheckForTimeOutImpl \n" + " MPU_xTaskCheckForTimeOut_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskCheckForTimeOutImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +#if ( configUSE_TASK_NOTIFICATIONS == 1 ) + +BaseType_t MPU_xTaskGenericNotify( TaskHandle_t xTaskToNotify, + UBaseType_t uxIndexToNotify, + uint32_t ulValue, + eNotifyAction eAction, + uint32_t * pulPreviousNotificationValue ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskGenericNotify( TaskHandle_t xTaskToNotify, + UBaseType_t uxIndexToNotify, + uint32_t ulValue, + eNotifyAction eAction, + uint32_t * pulPreviousNotificationValue ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGenericNotifyImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskGenericNotify_Unpriv \n" + " MPU_xTaskGenericNotify_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskGenericNotifyImpl \n" + " MPU_xTaskGenericNotify_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskGenericNotifyImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER_1 ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TASK_NOTIFICATIONS == 1 ) + +BaseType_t MPU_xTaskGenericNotifyWait( UBaseType_t uxIndexToWaitOn, + uint32_t ulBitsToClearOnEntry, + uint32_t ulBitsToClearOnExit, + uint32_t * pulNotificationValue, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskGenericNotifyWait( UBaseType_t uxIndexToWaitOn, + uint32_t ulBitsToClearOnEntry, + uint32_t ulBitsToClearOnExit, + uint32_t * pulNotificationValue, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGenericNotifyWaitImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskGenericNotifyWait_Unpriv \n" + " MPU_xTaskGenericNotifyWait_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskGenericNotifyWaitImpl \n" + " MPU_xTaskGenericNotifyWait_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskGenericNotifyWaitImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER_1 ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TASK_NOTIFICATIONS == 1 ) + +uint32_t MPU_ulTaskGenericNotifyTake( UBaseType_t uxIndexToWaitOn, + BaseType_t xClearCountOnExit, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +uint32_t MPU_ulTaskGenericNotifyTake( UBaseType_t uxIndexToWaitOn, + BaseType_t xClearCountOnExit, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_ulTaskGenericNotifyTakeImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_ulTaskGenericNotifyTake_Unpriv \n" + " MPU_ulTaskGenericNotifyTake_Priv: \n" + " pop {r0} \n" + " b MPU_ulTaskGenericNotifyTakeImpl \n" + " MPU_ulTaskGenericNotifyTake_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_ulTaskGenericNotifyTakeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TASK_NOTIFICATIONS == 1 ) + +BaseType_t MPU_xTaskGenericNotifyStateClear( TaskHandle_t xTask, + UBaseType_t uxIndexToClear ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskGenericNotifyStateClear( TaskHandle_t xTask, + UBaseType_t uxIndexToClear ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGenericNotifyStateClearImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskGenericNotifyStateClear_Unpriv \n" + " MPU_xTaskGenericNotifyStateClear_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskGenericNotifyStateClearImpl \n" + " MPU_xTaskGenericNotifyStateClear_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskGenericNotifyStateClearImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TASK_NOTIFICATIONS == 1 ) + +uint32_t MPU_ulTaskGenericNotifyValueClear( TaskHandle_t xTask, + UBaseType_t uxIndexToClear, + uint32_t ulBitsToClear ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +uint32_t MPU_ulTaskGenericNotifyValueClear( TaskHandle_t xTask, + UBaseType_t uxIndexToClear, + uint32_t ulBitsToClear ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_ulTaskGenericNotifyValueClearImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_ulTaskGenericNotifyValueClear_Unpriv \n" + " MPU_ulTaskGenericNotifyValueClear_Priv: \n" + " pop {r0} \n" + " b MPU_ulTaskGenericNotifyValueClearImpl \n" + " MPU_ulTaskGenericNotifyValueClear_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_ulTaskGenericNotifyValueClearImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xQueueGenericSend( QueueHandle_t xQueue, + const void * const pvItemToQueue, + TickType_t xTicksToWait, + const BaseType_t xCopyPosition ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueueGenericSend( QueueHandle_t xQueue, + const void * const pvItemToQueue, + TickType_t xTicksToWait, + const BaseType_t xCopyPosition ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueGenericSendImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xQueueGenericSend_Unpriv \n" + " MPU_xQueueGenericSend_Priv: \n" + " pop {r0} \n" + " b MPU_xQueueGenericSendImpl \n" + " MPU_xQueueGenericSend_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xQueueGenericSendImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +UBaseType_t MPU_uxQueueMessagesWaiting( const QueueHandle_t xQueue ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxQueueMessagesWaiting( const QueueHandle_t xQueue ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxQueueMessagesWaitingImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_uxQueueMessagesWaiting_Unpriv \n" + " MPU_uxQueueMessagesWaiting_Priv: \n" + " pop {r0} \n" + " b MPU_uxQueueMessagesWaitingImpl \n" + " MPU_uxQueueMessagesWaiting_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_uxQueueMessagesWaitingImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +UBaseType_t MPU_uxQueueSpacesAvailable( const QueueHandle_t xQueue ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxQueueSpacesAvailable( const QueueHandle_t xQueue ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxQueueSpacesAvailableImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_uxQueueSpacesAvailable_Unpriv \n" + " MPU_uxQueueSpacesAvailable_Priv: \n" + " pop {r0} \n" + " b MPU_uxQueueSpacesAvailableImpl \n" + " MPU_uxQueueSpacesAvailable_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_uxQueueSpacesAvailableImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xQueueReceive( QueueHandle_t xQueue, + void * const pvBuffer, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueueReceive( QueueHandle_t xQueue, + void * const pvBuffer, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueReceiveImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xQueueReceive_Unpriv \n" + " MPU_xQueueReceive_Priv: \n" + " pop {r0} \n" + " b MPU_xQueueReceiveImpl \n" + " MPU_xQueueReceive_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xQueueReceiveImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xQueuePeek( QueueHandle_t xQueue, + void * const pvBuffer, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueuePeek( QueueHandle_t xQueue, + void * const pvBuffer, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueuePeekImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xQueuePeek_Unpriv \n" + " MPU_xQueuePeek_Priv: \n" + " pop {r0} \n" + " b MPU_xQueuePeekImpl \n" + " MPU_xQueuePeek_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xQueuePeekImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xQueueSemaphoreTake( QueueHandle_t xQueue, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueueSemaphoreTake( QueueHandle_t xQueue, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueSemaphoreTakeImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xQueueSemaphoreTake_Unpriv \n" + " MPU_xQueueSemaphoreTake_Priv: \n" + " pop {r0} \n" + " b MPU_xQueueSemaphoreTakeImpl \n" + " MPU_xQueueSemaphoreTake_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xQueueSemaphoreTakeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +#if ( ( configUSE_MUTEXES == 1 ) && ( INCLUDE_xSemaphoreGetMutexHolder == 1 ) ) + +TaskHandle_t MPU_xQueueGetMutexHolder( QueueHandle_t xSemaphore ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TaskHandle_t MPU_xQueueGetMutexHolder( QueueHandle_t xSemaphore ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueGetMutexHolderImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xQueueGetMutexHolder_Unpriv \n" + " MPU_xQueueGetMutexHolder_Priv: \n" + " pop {r0} \n" + " b MPU_xQueueGetMutexHolderImpl \n" + " MPU_xQueueGetMutexHolder_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xQueueGetMutexHolderImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( ( configUSE_MUTEXES == 1 ) && ( INCLUDE_xSemaphoreGetMutexHolder == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_RECURSIVE_MUTEXES == 1 ) + +BaseType_t MPU_xQueueTakeMutexRecursive( QueueHandle_t xMutex, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueueTakeMutexRecursive( QueueHandle_t xMutex, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueTakeMutexRecursiveImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xQueueTakeMutexRecursive_Unpriv \n" + " MPU_xQueueTakeMutexRecursive_Priv: \n" + " pop {r0} \n" + " b MPU_xQueueTakeMutexRecursiveImpl \n" + " MPU_xQueueTakeMutexRecursive_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xQueueTakeMutexRecursiveImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_RECURSIVE_MUTEXES == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_RECURSIVE_MUTEXES == 1 ) + +BaseType_t MPU_xQueueGiveMutexRecursive( QueueHandle_t pxMutex ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueueGiveMutexRecursive( QueueHandle_t pxMutex ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueGiveMutexRecursiveImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xQueueGiveMutexRecursive_Unpriv \n" + " MPU_xQueueGiveMutexRecursive_Priv: \n" + " pop {r0} \n" + " b MPU_xQueueGiveMutexRecursiveImpl \n" + " MPU_xQueueGiveMutexRecursive_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xQueueGiveMutexRecursiveImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_RECURSIVE_MUTEXES == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_QUEUE_SETS == 1 ) + +QueueSetMemberHandle_t MPU_xQueueSelectFromSet( QueueSetHandle_t xQueueSet, + const TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +QueueSetMemberHandle_t MPU_xQueueSelectFromSet( QueueSetHandle_t xQueueSet, + const TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueSelectFromSetImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xQueueSelectFromSet_Unpriv \n" + " MPU_xQueueSelectFromSet_Priv: \n" + " pop {r0} \n" + " b MPU_xQueueSelectFromSetImpl \n" + " MPU_xQueueSelectFromSet_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xQueueSelectFromSetImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_QUEUE_SETS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_QUEUE_SETS == 1 ) + +BaseType_t MPU_xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore, + QueueSetHandle_t xQueueSet ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore, + QueueSetHandle_t xQueueSet ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueAddToSetImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xQueueAddToSet_Unpriv \n" + " MPU_xQueueAddToSet_Priv: \n" + " pop {r0} \n" + " b MPU_xQueueAddToSetImpl \n" + " MPU_xQueueAddToSet_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xQueueAddToSetImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_QUEUE_SETS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configQUEUE_REGISTRY_SIZE > 0 ) + +void MPU_vQueueAddToRegistry( QueueHandle_t xQueue, + const char * pcName ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vQueueAddToRegistry( QueueHandle_t xQueue, + const char * pcName ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vQueueAddToRegistryImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vQueueAddToRegistry_Unpriv \n" + " MPU_vQueueAddToRegistry_Priv: \n" + " pop {r0} \n" + " b MPU_vQueueAddToRegistryImpl \n" + " MPU_vQueueAddToRegistry_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vQueueAddToRegistryImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configQUEUE_REGISTRY_SIZE > 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configQUEUE_REGISTRY_SIZE > 0 ) + +void MPU_vQueueUnregisterQueue( QueueHandle_t xQueue ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vQueueUnregisterQueue( QueueHandle_t xQueue ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vQueueUnregisterQueueImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vQueueUnregisterQueue_Unpriv \n" + " MPU_vQueueUnregisterQueue_Priv: \n" + " pop {r0} \n" + " b MPU_vQueueUnregisterQueueImpl \n" + " MPU_vQueueUnregisterQueue_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vQueueUnregisterQueueImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configQUEUE_REGISTRY_SIZE > 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configQUEUE_REGISTRY_SIZE > 0 ) + +const char * MPU_pcQueueGetName( QueueHandle_t xQueue ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +const char * MPU_pcQueueGetName( QueueHandle_t xQueue ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_pcQueueGetNameImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_pcQueueGetName_Unpriv \n" + " MPU_pcQueueGetName_Priv: \n" + " pop {r0} \n" + " b MPU_pcQueueGetNameImpl \n" + " MPU_pcQueueGetName_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_pcQueueGetNameImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configQUEUE_REGISTRY_SIZE > 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +void * MPU_pvTimerGetTimerID( const TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void * MPU_pvTimerGetTimerID( const TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_pvTimerGetTimerIDImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_pvTimerGetTimerID_Unpriv \n" + " MPU_pvTimerGetTimerID_Priv: \n" + " pop {r0} \n" + " b MPU_pvTimerGetTimerIDImpl \n" + " MPU_pvTimerGetTimerID_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_pvTimerGetTimerIDImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +void MPU_vTimerSetTimerID( TimerHandle_t xTimer, + void * pvNewID ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTimerSetTimerID( TimerHandle_t xTimer, + void * pvNewID ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTimerSetTimerIDImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vTimerSetTimerID_Unpriv \n" + " MPU_vTimerSetTimerID_Priv: \n" + " pop {r0} \n" + " b MPU_vTimerSetTimerIDImpl \n" + " MPU_vTimerSetTimerID_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vTimerSetTimerIDImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +BaseType_t MPU_xTimerIsTimerActive( TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTimerIsTimerActive( TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTimerIsTimerActiveImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTimerIsTimerActive_Unpriv \n" + " MPU_xTimerIsTimerActive_Priv: \n" + " pop {r0} \n" + " b MPU_xTimerIsTimerActiveImpl \n" + " MPU_xTimerIsTimerActive_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTimerIsTimerActiveImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +TaskHandle_t MPU_xTimerGetTimerDaemonTaskHandle( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TaskHandle_t MPU_xTimerGetTimerDaemonTaskHandle( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTimerGetTimerDaemonTaskHandleImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTimerGetTimerDaemonTaskHandle_Unpriv \n" + " MPU_xTimerGetTimerDaemonTaskHandle_Priv: \n" + " pop {r0} \n" + " b MPU_xTimerGetTimerDaemonTaskHandleImpl \n" + " MPU_xTimerGetTimerDaemonTaskHandle_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTimerGetTimerDaemonTaskHandleImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +BaseType_t MPU_xTimerGenericCommand( TimerHandle_t xTimer, + const BaseType_t xCommandID, + const TickType_t xOptionalValue, + BaseType_t * const pxHigherPriorityTaskWoken, + const TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTimerGenericCommand( TimerHandle_t xTimer, + const BaseType_t xCommandID, + const TickType_t xOptionalValue, + BaseType_t * const pxHigherPriorityTaskWoken, + const TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTimerGenericCommandImpl \n" + " \n" + " push {r0} \n" + " mrs r0, ipsr \n" + " cmp r0, #0 \n" + " bne MPU_xTimerGenericCommand_Priv \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " beq MPU_xTimerGenericCommand_Priv \n" + " MPU_xTimerGenericCommand_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTimerGenericCommandImpl \n" + " svc %1 \n" + " bx lr \n" + " MPU_xTimerGenericCommand_Priv: \n" + " pop {r0} \n" + " b MPU_xTimerGenericCommandImpl \n" + " \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER_1 ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +const char * MPU_pcTimerGetName( TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +const char * MPU_pcTimerGetName( TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_pcTimerGetNameImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_pcTimerGetName_Unpriv \n" + " MPU_pcTimerGetName_Priv: \n" + " pop {r0} \n" + " b MPU_pcTimerGetNameImpl \n" + " MPU_pcTimerGetName_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_pcTimerGetNameImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, + const BaseType_t uxAutoReload ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, + const BaseType_t uxAutoReload ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTimerSetReloadModeImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vTimerSetReloadMode_Unpriv \n" + " MPU_vTimerSetReloadMode_Priv: \n" + " pop {r0} \n" + " b MPU_vTimerSetReloadModeImpl \n" + " MPU_vTimerSetReloadMode_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vTimerSetReloadModeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +BaseType_t MPU_xTimerGetReloadMode( TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTimerGetReloadMode( TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTimerGetReloadModeImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTimerGetReloadMode_Unpriv \n" + " MPU_xTimerGetReloadMode_Priv: \n" + " pop {r0} \n" + " b MPU_xTimerGetReloadModeImpl \n" + " MPU_xTimerGetReloadMode_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTimerGetReloadModeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +UBaseType_t MPU_uxTimerGetReloadMode( TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxTimerGetReloadMode( TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxTimerGetReloadModeImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_uxTimerGetReloadMode_Unpriv \n" + " MPU_uxTimerGetReloadMode_Priv: \n" + " pop {r0} \n" + " b MPU_uxTimerGetReloadModeImpl \n" + " MPU_uxTimerGetReloadMode_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_uxTimerGetReloadModeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +TickType_t MPU_xTimerGetPeriod( TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TickType_t MPU_xTimerGetPeriod( TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTimerGetPeriodImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTimerGetPeriod_Unpriv \n" + " MPU_xTimerGetPeriod_Priv: \n" + " pop {r0} \n" + " b MPU_xTimerGetPeriodImpl \n" + " MPU_xTimerGetPeriod_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTimerGetPeriodImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +TickType_t MPU_xTimerGetExpiryTime( TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TickType_t MPU_xTimerGetExpiryTime( TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTimerGetExpiryTimeImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTimerGetExpiryTime_Unpriv \n" + " MPU_xTimerGetExpiryTime_Priv: \n" + " pop {r0} \n" + " b MPU_xTimerGetExpiryTimeImpl \n" + " MPU_xTimerGetExpiryTime_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTimerGetExpiryTimeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +EventBits_t MPU_xEventGroupWaitBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToWaitFor, + const BaseType_t xClearOnExit, + const BaseType_t xWaitForAllBits, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +EventBits_t MPU_xEventGroupWaitBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToWaitFor, + const BaseType_t xClearOnExit, + const BaseType_t xWaitForAllBits, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupWaitBitsImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xEventGroupWaitBits_Unpriv \n" + " MPU_xEventGroupWaitBits_Priv: \n" + " pop {r0} \n" + " b MPU_xEventGroupWaitBitsImpl \n" + " MPU_xEventGroupWaitBits_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xEventGroupWaitBitsImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER_1 ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToClear ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToClear ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupClearBitsImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xEventGroupClearBits_Unpriv \n" + " MPU_xEventGroupClearBits_Priv: \n" + " pop {r0} \n" + " b MPU_xEventGroupClearBitsImpl \n" + " MPU_xEventGroupClearBits_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xEventGroupClearBitsImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupSetBitsImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xEventGroupSetBits_Unpriv \n" + " MPU_xEventGroupSetBits_Priv: \n" + " pop {r0} \n" + " b MPU_xEventGroupSetBitsImpl \n" + " MPU_xEventGroupSetBits_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xEventGroupSetBitsImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet, + const EventBits_t uxBitsToWaitFor, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet, + const EventBits_t uxBitsToWaitFor, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupSyncImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xEventGroupSync_Unpriv \n" + " MPU_xEventGroupSync_Priv: \n" + " pop {r0} \n" + " b MPU_xEventGroupSyncImpl \n" + " MPU_xEventGroupSync_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xEventGroupSyncImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + +UBaseType_t MPU_uxEventGroupGetNumber( void * xEventGroup ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxEventGroupGetNumber( void * xEventGroup ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxEventGroupGetNumberImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_uxEventGroupGetNumber_Unpriv \n" + " MPU_uxEventGroupGetNumber_Priv: \n" + " pop {r0} \n" + " b MPU_uxEventGroupGetNumberImpl \n" + " MPU_uxEventGroupGetNumber_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_uxEventGroupGetNumberImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /*( configUSE_TRACE_FACILITY == 1 )*/ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + +void MPU_vEventGroupSetNumber( void * xEventGroup, + UBaseType_t uxEventGroupNumber ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vEventGroupSetNumber( void * xEventGroup, + UBaseType_t uxEventGroupNumber ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vEventGroupSetNumberImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vEventGroupSetNumber_Unpriv \n" + " MPU_vEventGroupSetNumber_Priv: \n" + " pop {r0} \n" + " b MPU_vEventGroupSetNumberImpl \n" + " MPU_vEventGroupSetNumber_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vEventGroupSetNumberImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /*( configUSE_TRACE_FACILITY == 1 )*/ +/*-----------------------------------------------------------*/ + +size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, + const void * pvTxData, + size_t xDataLengthBytes, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, + const void * pvTxData, + size_t xDataLengthBytes, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferSendImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferSend_Unpriv \n" + " MPU_xStreamBufferSend_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferSendImpl \n" + " MPU_xStreamBufferSend_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xStreamBufferSendImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, + void * pvRxData, + size_t xBufferLengthBytes, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, + void * pvRxData, + size_t xBufferLengthBytes, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferReceiveImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferReceive_Unpriv \n" + " MPU_xStreamBufferReceive_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferReceiveImpl \n" + " MPU_xStreamBufferReceive_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xStreamBufferReceiveImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferIsFullImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferIsFull_Unpriv \n" + " MPU_xStreamBufferIsFull_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferIsFullImpl \n" + " MPU_xStreamBufferIsFull_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xStreamBufferIsFullImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferIsEmptyImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferIsEmpty_Unpriv \n" + " MPU_xStreamBufferIsEmpty_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferIsEmptyImpl \n" + " MPU_xStreamBufferIsEmpty_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xStreamBufferIsEmptyImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferSpacesAvailableImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferSpacesAvailable_Unpriv \n" + " MPU_xStreamBufferSpacesAvailable_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferSpacesAvailableImpl \n" + " MPU_xStreamBufferSpacesAvailable_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xStreamBufferSpacesAvailableImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferBytesAvailableImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferBytesAvailable_Unpriv \n" + " MPU_xStreamBufferBytesAvailable_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferBytesAvailableImpl \n" + " MPU_xStreamBufferBytesAvailable_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xStreamBufferBytesAvailableImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, + size_t xTriggerLevel ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, + size_t xTriggerLevel ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferSetTriggerLevelImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferSetTriggerLevel_Unpriv \n" + " MPU_xStreamBufferSetTriggerLevel_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferSetTriggerLevelImpl \n" + " MPU_xStreamBufferSetTriggerLevel_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xStreamBufferSetTriggerLevelImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferNextMessageLengthBytesImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferNextMessageLengthBytes_Unpriv \n" + " MPU_xStreamBufferNextMessageLengthBytes_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferNextMessageLengthBytesImpl \n" + " MPU_xStreamBufferNextMessageLengthBytes_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xStreamBufferNextMessageLengthBytesImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ diff --git a/portable/GCC/ARM_CM35P/non_secure/port.c b/portable/GCC/ARM_CM35P/non_secure/port.c index 7bbe1b7bc53..cab1b3668bf 100644 --- a/portable/GCC/ARM_CM35P/non_secure/port.c +++ b/portable/GCC/ARM_CM35P/non_secure/port.c @@ -107,6 +107,13 @@ #define portPRIGROUP_SHIFT ( 8UL ) /*-----------------------------------------------------------*/ +/** + * @brief Constants used during system call enter and exit. + */ +#define portPSR_STACK_PADDING_MASK ( 1UL << 9UL ) +#define portEXC_RETURN_STACK_FRAME_TYPE_MASK ( 1UL << 4UL ) +/*-----------------------------------------------------------*/ + /** * @brief Constants required to manipulate the FPU. */ @@ -123,6 +130,14 @@ #define portFPCCR_LSPEN_MASK ( 1UL << portFPCCR_LSPEN_POS ) /*-----------------------------------------------------------*/ +/** + * @brief Offsets in the stack to the parameters when inside the SVC handler. + */ +#define portOFFSET_TO_LR ( 5 ) +#define portOFFSET_TO_PC ( 6 ) +#define portOFFSET_TO_PSR ( 7 ) +/*-----------------------------------------------------------*/ + /** * @brief Constants required to manipulate the MPU. */ @@ -148,6 +163,8 @@ #define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ #define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ +#define portMPU_RBAR_ACCESS_PERMISSIONS_MASK ( 3UL << 1UL ) + #define portMPU_MAIR_ATTR0_POS ( 0UL ) #define portMPU_MAIR_ATTR0_MASK ( 0x000000ff ) @@ -191,6 +208,30 @@ /* Expected value of the portMPU_TYPE register. */ #define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) + +/* Extract first address of the MPU region as encoded in the + * RBAR (Region Base Address Register) value. */ +#define portEXTRACT_FIRST_ADDRESS_FROM_RBAR( rbar ) \ + ( ( rbar ) & portMPU_RBAR_ADDRESS_MASK ) + +/* Extract last address of the MPU region as encoded in the + * RLAR (Region Limit Address Register) value. */ +#define portEXTRACT_LAST_ADDRESS_FROM_RLAR( rlar ) \ + ( ( ( rlar ) & portMPU_RLAR_ADDRESS_MASK ) | ~portMPU_RLAR_ADDRESS_MASK ) + +/* Does addr lies within [start, end] address range? */ +#define portIS_ADDRESS_WITHIN_RANGE( addr, start, end ) \ + ( ( ( addr ) >= ( start ) ) && ( ( addr ) <= ( end ) ) ) + +/* Is the access request satisfied by the available permissions? */ +#define portIS_AUTHORIZED( accessRequest, permissions ) \ + ( ( ( permissions ) & ( accessRequest ) ) == accessRequest ) + +/* 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 ) ) ) /*-----------------------------------------------------------*/ /** @@ -311,6 +352,19 @@ static void prvTaskExitError( void ); #if ( configENABLE_MPU == 1 ) +/** + * @brief Extract MPU region's access permissions from the Region Base Address + * Register (RBAR) value. + * + * @param ulRBARValue RBAR value for the MPU region. + * + * @return uint32_t Access permissions. + */ + static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) PRIVILEGED_FUNCTION; +#endif /* configENABLE_MPU */ + +#if ( configENABLE_MPU == 1 ) + /** * @brief Setup the Memory Protection Unit (MPU). */ @@ -365,6 +419,60 @@ void SysTick_Handler( void ) PRIVILEGED_FUNCTION; * @brief C part of SVC handler. */ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIVILEGED_FUNCTION; + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + + /** + * @brief Sets up the system call stack so that upon returning from + * SVC, the system call stack is used. + * + * It is used for the system calls with up to 4 parameters. + * + * @param pulTaskStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + */ + void vSystemCallEnter( uint32_t * pulTaskStack, uint32_t ulLR ) PRIVILEGED_FUNCTION; + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + + /** + * @brief Sets up the system call stack so that upon returning from + * SVC, the system call stack is used. + * + * It is used for the system calls with 5 parameters. + * + * @param pulTaskStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + */ + void vSystemCallEnter_1( uint32_t * pulTaskStack, uint32_t ulLR ) PRIVILEGED_FUNCTION; + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + + /** + * @brief Sets up the task stack so that upon returning from + * SVC, the task stack is used again. + * + * @param pulSystemCallStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + */ + void vSystemCallExit( uint32_t * pulSystemCallStack, uint32_t ulLR ) PRIVILEGED_FUNCTION; + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + +#if ( configENABLE_MPU == 1 ) + + /** + * @brief Checks whether or not the calling task is privileged. + * + * @return pdTRUE if the calling task is privileged, pdFALSE otherwise. + */ + BaseType_t xPortIsTaskPrivileged( void ) PRIVILEGED_FUNCTION; + +#endif /* configENABLE_MPU == 1 */ /*-----------------------------------------------------------*/ /** @@ -681,6 +789,26 @@ static void prvTaskExitError( void ) } /*-----------------------------------------------------------*/ +#if ( configENABLE_MPU == 1 ) + static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) /* PRIVILEGED_FUNCTION */ + { + uint32_t ulAccessPermissions = 0; + + if( ( ulRBARValue & portMPU_RBAR_ACCESS_PERMISSIONS_MASK ) == portMPU_REGION_READ_ONLY ) + { + ulAccessPermissions = tskMPU_READ_PERMISSION; + } + + if( ( ulRBARValue & portMPU_RBAR_ACCESS_PERMISSIONS_MASK ) == portMPU_REGION_READ_WRITE ) + { + ulAccessPermissions = ( tskMPU_READ_PERMISSION | tskMPU_WRITE_PERMISSION ); + } + + return ulAccessPermissions; + } +#endif /* configENABLE_MPU */ +/*-----------------------------------------------------------*/ + #if ( configENABLE_MPU == 1 ) static void prvSetupMPU( void ) /* PRIVILEGED_FUNCTION */ { @@ -853,7 +981,7 @@ void SysTick_Handler( void ) /* PRIVILEGED_FUNCTION */ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTION portDONT_DISCARD */ { - #if ( configENABLE_MPU == 1 ) + #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) ) #if defined( __ARMCC_VERSION ) /* Declaration when these variable are defined in code instead of being @@ -865,7 +993,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO extern uint32_t __syscalls_flash_start__[]; extern uint32_t __syscalls_flash_end__[]; #endif /* defined( __ARMCC_VERSION ) */ - #endif /* configENABLE_MPU */ + #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */ uint32_t ulPC; @@ -880,7 +1008,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO /* Register are stored on the stack in the following order - R0, R1, R2, R3, * R12, LR, PC, xPSR. */ - ulPC = pulCallerStackAddress[ 6 ]; + ulPC = pulCallerStackAddress[ portOFFSET_TO_PC ]; ucSVCNumber = ( ( uint8_t * ) ulPC )[ -2 ]; switch( ucSVCNumber ) @@ -951,18 +1079,18 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO vRestoreContextOfFirstTask(); break; - #if ( configENABLE_MPU == 1 ) - case portSVC_RAISE_PRIVILEGE: + #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) ) + case portSVC_RAISE_PRIVILEGE: - /* Only raise the privilege, if the svc was raised from any of - * the system calls. */ - if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) && - ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ) - { - vRaisePrivilege(); - } - break; - #endif /* configENABLE_MPU */ + /* Only raise the privilege, if the svc was raised from any of + * the system calls. */ + if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ) + { + vRaisePrivilege(); + } + break; + #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */ default: /* Incorrect SVC call. */ @@ -971,51 +1099,455 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } /*-----------------------------------------------------------*/ -/* *INDENT-OFF* */ -#if ( configENABLE_MPU == 1 ) - StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, - StackType_t * pxEndOfStack, - TaskFunction_t pxCode, - void * pvParameters, - BaseType_t xRunPrivileged ) /* PRIVILEGED_FUNCTION */ -#else - StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, - StackType_t * pxEndOfStack, - TaskFunction_t pxCode, - void * pvParameters ) /* PRIVILEGED_FUNCTION */ -#endif /* configENABLE_MPU */ -/* *INDENT-ON* */ +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + +void vSystemCallEnter( uint32_t * pulTaskStack, uint32_t ulLR ) /* PRIVILEGED_FUNCTION */ { - /* Simulate the stack frame as it would be created by a context switch - * interrupt. */ - #if ( portPRELOAD_REGISTERS == 0 ) + extern TaskHandle_t pxCurrentTCB; + xMPU_SETTINGS * pxMpuSettings; + uint32_t * pulSystemCallStack; + uint32_t ulStackFrameSize, ulSystemCallLocation, i; + #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being + * exported from linker scripts. */ + extern uint32_t * __syscalls_flash_start__; + extern uint32_t * __syscalls_flash_end__; + #else + /* Declaration when these variable are exported from linker scripts. */ + extern uint32_t __syscalls_flash_start__[]; + extern uint32_t __syscalls_flash_end__[]; + #endif /* #if defined( __ARMCC_VERSION ) */ + + ulSystemCallLocation = pulTaskStack[ portOFFSET_TO_PC ]; + + /* If the request did not come from the system call section, do nothing. */ + if( ( ulSystemCallLocation >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulSystemCallLocation <= ( uint32_t ) __syscalls_flash_end__ ) ) { - pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ - *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ - pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pxCode; /* PC */ - pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR */ - pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ - *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ - pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */ - *pxTopOfStack = portINITIAL_EXC_RETURN; + pxMpuSettings = xTaskGetMPUSettings( pxCurrentTCB ); + pulSystemCallStack = pxMpuSettings->xSystemCallStackInfo.pulSystemCallStack; - #if ( configENABLE_MPU == 1 ) + /* This is not NULL only for the duration of the system call. */ + configASSERT( pxMpuSettings->xSystemCallStackInfo.pulTaskStack == NULL ); + + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) { - pxTopOfStack--; + if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) + { + /* Extended frame i.e. FPU in use. */ + ulStackFrameSize = 26; + __asm volatile ( + " vpush {s0} \n" /* Trigger lazy stacking. */ + " vpop {s0} \n" /* Nullify the affect of the above instruction. */ + ::: "memory" + ); + } + else + { + /* Standard frame i.e. FPU not in use. */ + ulStackFrameSize = 8; + } + } + #else + { + ulStackFrameSize = 8; + } + #endif /* configENABLE_FPU || configENABLE_MVE */ + + /* Make space on the system call stack for the stack frame. */ + pulSystemCallStack = pulSystemCallStack - ulStackFrameSize; + + /* Copy the stack frame. */ + for( i = 0; i < ulStackFrameSize; i++ ) + { + pulSystemCallStack[ i ] = pulTaskStack[ i ]; + } + + /* Store the value of the LR and PSPLIM registers before the SVC was raised. We need to + * restore it when we exit from the system call. */ + pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; + __asm volatile ( "mrs %0, psplim" : "=r" ( pxMpuSettings->xSystemCallStackInfo.ulStackLimitRegisterAtSystemCallEntry ) ); + + /* Use the pulSystemCallStack in thread mode. */ + __asm volatile ( "msr psp, %0" : : "r" ( pulSystemCallStack ) ); + __asm volatile ( "msr psplim, %0" : : "r" ( pxMpuSettings->xSystemCallStackInfo.pulSystemCallStackLimit ) ); + + /* Remember the location where we should copy the stack frame when we exit from + * the system call. */ + pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulStackFrameSize; + + /* Record if the hardware used padding to force the stack pointer + * to be double word aligned. */ + if( ( pulTaskStack[ portOFFSET_TO_PSR ] & portPSR_STACK_PADDING_MASK ) == portPSR_STACK_PADDING_MASK ) + { + pxMpuSettings->ulTaskFlags |= portSTACK_FRAME_HAS_PADDING_FLAG; + } + else + { + pxMpuSettings->ulTaskFlags &= ( ~portSTACK_FRAME_HAS_PADDING_FLAG ); + } + + /* We ensure in pxPortInitialiseStack that the system call stack is + * double word aligned and therefore, there is no need of padding. + * Clear the bit[9] of stacked xPSR. */ + pulSystemCallStack[ portOFFSET_TO_PSR ] &= ( ~portPSR_STACK_PADDING_MASK ); + + /* Raise the privilege for the duration of the system call. */ + __asm volatile ( + " mrs r0, control \n" /* Obtain current control value. */ + " movs r1, #1 \n" /* r1 = 1. */ + " bics r0, r1 \n" /* Clear nPRIV bit. */ + " msr control, r0 \n" /* Write back new control value. */ + ::: "r0", "r1", "memory" + ); + } +} - if( xRunPrivileged == pdTRUE ) +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + +void vSystemCallEnter_1( uint32_t * pulTaskStack, uint32_t ulLR ) /* PRIVILEGED_FUNCTION */ +{ + extern TaskHandle_t pxCurrentTCB; + xMPU_SETTINGS * pxMpuSettings; + uint32_t * pulSystemCallStack; + uint32_t ulStackFrameSize, ulSystemCallLocation, i; + #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being + * exported from linker scripts. */ + extern uint32_t * __syscalls_flash_start__; + extern uint32_t * __syscalls_flash_end__; + #else + /* Declaration when these variable are exported from linker scripts. */ + extern uint32_t __syscalls_flash_start__[]; + extern uint32_t __syscalls_flash_end__[]; + #endif /* #if defined( __ARMCC_VERSION ) */ + + ulSystemCallLocation = pulTaskStack[ portOFFSET_TO_PC ]; + + /* If the request did not come from the system call section, do nothing. */ + if( ( ulSystemCallLocation >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulSystemCallLocation <= ( uint32_t ) __syscalls_flash_end__ ) ) + { + pxMpuSettings = xTaskGetMPUSettings( pxCurrentTCB ); + pulSystemCallStack = pxMpuSettings->xSystemCallStackInfo.pulSystemCallStack; + + /* This is not NULL only for the duration of the system call. */ + configASSERT( pxMpuSettings->xSystemCallStackInfo.pulTaskStack == NULL ); + + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + { + if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) { - *pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */ + /* Extended frame i.e. FPU in use. */ + ulStackFrameSize = 26; + __asm volatile ( + " vpush {s0} \n" /* Trigger lazy stacking. */ + " vpop {s0} \n" /* Nullify the affect of the above instruction. */ + ::: "memory" + ); } else { - *pxTopOfStack = portINITIAL_CONTROL_UNPRIVILEGED; /* Slot used to hold this task's CONTROL value. */ + /* Standard frame i.e. FPU not in use. */ + ulStackFrameSize = 8; } } - #endif /* configENABLE_MPU */ + #else + { + ulStackFrameSize = 8; + } + #endif /* configENABLE_FPU || configENABLE_MVE */ + + /* Make space on the system call stack for the stack frame and + * the parameter passed on the stack. We only need to copy one + * parameter but we still reserve 2 spaces to keep the stack + * double word aligned. */ + pulSystemCallStack = pulSystemCallStack - ulStackFrameSize - 2UL; + + /* Copy the stack frame. */ + for( i = 0; i < ulStackFrameSize; i++ ) + { + pulSystemCallStack[ i ] = pulTaskStack[ i ]; + } + + /* Copy the parameter which is passed the stack. */ + if( ( pulTaskStack[ portOFFSET_TO_PSR ] & portPSR_STACK_PADDING_MASK ) == portPSR_STACK_PADDING_MASK ) + { + pulSystemCallStack[ ulStackFrameSize ] = pulTaskStack[ ulStackFrameSize + 1 ]; + /* Record if the hardware used padding to force the stack pointer + * to be double word aligned. */ + pxMpuSettings->ulTaskFlags |= portSTACK_FRAME_HAS_PADDING_FLAG; + } + else + { + pulSystemCallStack[ ulStackFrameSize ] = pulTaskStack[ ulStackFrameSize ]; + /* Record if the hardware used padding to force the stack pointer + * to be double word aligned. */ + pxMpuSettings->ulTaskFlags &= ( ~portSTACK_FRAME_HAS_PADDING_FLAG ); + } + + /* Store the value of the LR and PSPLIM registers before the SVC was raised. + * We need to restore it when we exit from the system call. */ + pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; + __asm volatile ( "mrs %0, psplim" : "=r" ( pxMpuSettings->xSystemCallStackInfo.ulStackLimitRegisterAtSystemCallEntry ) ); + + /* Use the pulSystemCallStack in thread mode. */ + __asm volatile ( "msr psp, %0" : : "r" ( pulSystemCallStack ) ); + __asm volatile ( "msr psplim, %0" : : "r" ( pxMpuSettings->xSystemCallStackInfo.pulSystemCallStackLimit ) ); + + /* Remember the location where we should copy the stack frame when we exit from + * the system call. */ + pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulStackFrameSize; + + /* We ensure in pxPortInitialiseStack that the system call stack is + * double word aligned and therefore, there is no need of padding. + * Clear the bit[9] of stacked xPSR. */ + pulSystemCallStack[ portOFFSET_TO_PSR ] &= ( ~portPSR_STACK_PADDING_MASK ); + + /* Raise the privilege for the duration of the system call. */ + __asm volatile ( + " mrs r0, control \n" /* Obtain current control value. */ + " movs r1, #1 \n" /* r1 = 1. */ + " bics r0, r1 \n" /* Clear nPRIV bit. */ + " msr control, r0 \n" /* Write back new control value. */ + ::: "r0", "r1", "memory" + ); + } +} + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) +void vSystemCallExit( uint32_t * pulSystemCallStack, uint32_t ulLR ) /* PRIVILEGED_FUNCTION */ +{ + extern TaskHandle_t pxCurrentTCB; + xMPU_SETTINGS * pxMpuSettings; + uint32_t * pulTaskStack; + uint32_t ulStackFrameSize, ulSystemCallLocation, i; + #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being + * exported from linker scripts. */ + extern uint32_t * __syscalls_flash_start__; + extern uint32_t * __syscalls_flash_end__; + #else + /* Declaration when these variable are exported from linker scripts. */ + extern uint32_t __syscalls_flash_start__[]; + extern uint32_t __syscalls_flash_end__[]; + #endif /* #if defined( __ARMCC_VERSION ) */ + + ulSystemCallLocation = pulSystemCallStack[ portOFFSET_TO_PC ]; + + /* If the request did not come from the system call section, do nothing. */ + if( ( ulSystemCallLocation >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulSystemCallLocation <= ( uint32_t ) __syscalls_flash_end__ ) ) + { + pxMpuSettings = xTaskGetMPUSettings( pxCurrentTCB ); + pulTaskStack = pxMpuSettings->xSystemCallStackInfo.pulTaskStack; + + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + { + if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) + { + /* Extended frame i.e. FPU in use. */ + ulStackFrameSize = 26; + __asm volatile ( + " vpush {s0} \n" /* Trigger lazy stacking. */ + " vpop {s0} \n" /* Nullify the affect of the above instruction. */ + ::: "memory" + ); + } + else + { + /* Standard frame i.e. FPU not in use. */ + ulStackFrameSize = 8; + } + } + #else + { + ulStackFrameSize = 8; + } + #endif /* configENABLE_FPU || configENABLE_MVE */ + + /* Make space on the task stack for the stack frame. */ + pulTaskStack = pulTaskStack - ulStackFrameSize; + + /* Copy the stack frame. */ + for( i = 0; i < ulStackFrameSize; i++ ) + { + pulTaskStack[ i ] = pulSystemCallStack[ i ]; + } + + /* Use the pulTaskStack in thread mode. */ + __asm volatile ( "msr psp, %0" : : "r" ( pulTaskStack ) ); + + /* Restore the LR and PSPLIM to what they were at the time of + * system call entry. */ + pulTaskStack[ portOFFSET_TO_LR ] = pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry; + __asm volatile ( "msr psplim, %0" : : "r" ( pxMpuSettings->xSystemCallStackInfo.ulStackLimitRegisterAtSystemCallEntry ) ); + + /* If the hardware used padding to force the stack pointer + * to be double word aligned, set the stacked xPSR bit[9], + * otherwise clear it. */ + if( ( pxMpuSettings->ulTaskFlags & portSTACK_FRAME_HAS_PADDING_FLAG ) == portSTACK_FRAME_HAS_PADDING_FLAG ) + { + pulTaskStack[ portOFFSET_TO_PSR ] |= portPSR_STACK_PADDING_MASK; + } + else + { + pulTaskStack[ portOFFSET_TO_PSR ] &= ( ~portPSR_STACK_PADDING_MASK ); + } + + /* This is not NULL only for the duration of the system call. */ + pxMpuSettings->xSystemCallStackInfo.pulTaskStack = NULL; + + /* Drop the privilege before returning to the thread mode. */ + __asm volatile ( + " mrs r0, control \n" /* Obtain current control value. */ + " movs r1, #1 \n" /* r1 = 1. */ + " orrs r0, r1 \n" /* Set nPRIV bit. */ + " msr control, r0 \n" /* Write back new control value. */ + ::: "r0", "r1", "memory" + ); + } +} + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configENABLE_MPU == 1 ) + +BaseType_t xPortIsTaskPrivileged( void ) /* PRIVILEGED_FUNCTION */ +{ + BaseType_t xTaskIsPrivileged = pdFALSE; + const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */ + + if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) + { + xTaskIsPrivileged = pdTRUE; + } + + return xTaskIsPrivileged; +} + +#endif /* configENABLE_MPU == 1 */ +/*-----------------------------------------------------------*/ + +#if( configENABLE_MPU == 1 ) + +StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, + StackType_t * pxEndOfStack, + TaskFunction_t pxCode, + void * pvParameters, + BaseType_t xRunPrivileged, + xMPU_SETTINGS * xMPUSettings ) /* PRIVILEGED_FUNCTION */ +{ + uint32_t ulIndex = 0; + + xMPUSettings->ulContext[ ulIndex ] = 0x04040404; /* r4. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x05050505; /* r5. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x06060606; /* r6. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x07070707; /* r7. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x08080808; /* r8. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x09090909; /* r9. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x10101010; /* r10. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x11111111; /* r11. */ + ulIndex++; + + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pvParameters; /* r0. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x01010101; /* r1. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x02020202; /* r2. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x03030303; /* r3. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x12121212; /* r12. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portTASK_RETURN_ADDRESS; /* LR. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxCode; /* PC. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = portINITIAL_XPSR; /* xPSR. */ + ulIndex++; + + #if ( configENABLE_TRUSTZONE == 1 ) + { + xMPUSettings->ulContext[ ulIndex ] = portNO_SECURE_CONTEXT; /* xSecureContext. */ + ulIndex++; + } + #endif /* configENABLE_TRUSTZONE */ + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) ( pxTopOfStack - 8 ); /* PSP with the hardware saved stack. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */ + ulIndex++; + if( xRunPrivileged == pdTRUE ) + { + xMPUSettings->ulTaskFlags |= portTASK_IS_PRIVILEGED_FLAG; + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_PRIVILEGED; /* CONTROL. */ + ulIndex++; + } + else + { + xMPUSettings->ulTaskFlags &= ( ~portTASK_IS_PRIVILEGED_FLAG ); + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_UNPRIVILEGED; /* CONTROL. */ + ulIndex++; + } + xMPUSettings->ulContext[ ulIndex ] = portINITIAL_EXC_RETURN; /* LR (EXC_RETURN). */ + ulIndex++; + + #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + { + /* Ensure that the system call stack is double word aligned. */ + xMPUSettings->xSystemCallStackInfo.pulSystemCallStack = &( xMPUSettings->xSystemCallStackInfo.ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE - 1 ] ); + xMPUSettings->xSystemCallStackInfo.pulSystemCallStack = ( uint32_t * ) ( ( uint32_t ) ( xMPUSettings->xSystemCallStackInfo.pulSystemCallStack ) & + ( uint32_t ) ( ~( portBYTE_ALIGNMENT_MASK ) ) ); + + xMPUSettings->xSystemCallStackInfo.pulSystemCallStackLimit = &( xMPUSettings->xSystemCallStackInfo.ulSystemCallStackBuffer[ 0 ] ); + xMPUSettings->xSystemCallStackInfo.pulSystemCallStackLimit = ( uint32_t * ) ( ( ( uint32_t ) ( xMPUSettings->xSystemCallStackInfo.pulSystemCallStackLimit ) + + ( uint32_t ) ( portBYTE_ALIGNMENT - 1 ) ) & + ( uint32_t ) ( ~( portBYTE_ALIGNMENT_MASK ) ) ); + + /* This is not NULL only for the duration of a system call. */ + xMPUSettings->xSystemCallStackInfo.pulTaskStack = NULL; + } + #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + + return &( xMPUSettings->ulContext[ ulIndex ] ); +} + +#else /* configENABLE_MPU */ + +StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, + StackType_t * pxEndOfStack, + TaskFunction_t pxCode, + void * pvParameters ) /* PRIVILEGED_FUNCTION */ +{ + /* Simulate the stack frame as it would be created by a context switch + * interrupt. */ + #if ( portPRELOAD_REGISTERS == 0 ) + { + pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ + *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR. */ + pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ + pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */ + *pxTopOfStack = portINITIAL_EXC_RETURN; pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ @@ -1029,55 +1561,39 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO #else /* portPRELOAD_REGISTERS */ { pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ - *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ + *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pxCode; /* PC */ + *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR */ + *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x12121212UL; /* R12 */ + *pxTopOfStack = ( StackType_t ) 0x12121212UL; /* R12. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x03030303UL; /* R3 */ + *pxTopOfStack = ( StackType_t ) 0x03030303UL; /* R3. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x02020202UL; /* R2 */ + *pxTopOfStack = ( StackType_t ) 0x02020202UL; /* R2. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x01010101UL; /* R1 */ + *pxTopOfStack = ( StackType_t ) 0x01010101UL; /* R1. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x11111111UL; /* R11 */ + *pxTopOfStack = ( StackType_t ) 0x11111111UL; /* R11. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x10101010UL; /* R10 */ + *pxTopOfStack = ( StackType_t ) 0x10101010UL; /* R10. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x09090909UL; /* R09 */ + *pxTopOfStack = ( StackType_t ) 0x09090909UL; /* R09. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x08080808UL; /* R08 */ + *pxTopOfStack = ( StackType_t ) 0x08080808UL; /* R08. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x07070707UL; /* R07 */ + *pxTopOfStack = ( StackType_t ) 0x07070707UL; /* R07. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x06060606UL; /* R06 */ + *pxTopOfStack = ( StackType_t ) 0x06060606UL; /* R06. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x05050505UL; /* R05 */ + *pxTopOfStack = ( StackType_t ) 0x05050505UL; /* R05. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x04040404UL; /* R04 */ + *pxTopOfStack = ( StackType_t ) 0x04040404UL; /* R04. */ pxTopOfStack--; - *pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN */ - - #if ( configENABLE_MPU == 1 ) - { - pxTopOfStack--; - - if( xRunPrivileged == pdTRUE ) - { - *pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */ - } - else - { - *pxTopOfStack = portINITIAL_CONTROL_UNPRIVILEGED; /* Slot used to hold this task's CONTROL value. */ - } - } - #endif /* configENABLE_MPU */ - + *pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN. */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ @@ -1092,6 +1608,8 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO return pxTopOfStack; } + +#endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ @@ -1128,6 +1646,10 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ configASSERT( ucMaxSysCallPriority ); + /* Check that the bits not implemented in hardware are zero in + * configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & ( ~ucMaxPriorityValue ) ) == 0U ); + /* Calculate the maximum acceptable priority group value for the number * of bits read back. */ @@ -1164,35 +1686,6 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulImplementedPrioBits; } - /* The interrupt priority bits are not modelled in QEMU and the assert that - * checks the number of implemented bits and __NVIC_PRIO_BITS will always fail. - * Therefore, this assert is not adding any value for QEMU targets. The config - * option `configDISABLE_INTERRUPT_PRIO_BITS_CHECK` should be defined in the - * `FreeRTOSConfig.h` for QEMU targets. */ - #ifndef configDISABLE_INTERRUPT_PRIO_BITS_CHECK - { - #ifdef __NVIC_PRIO_BITS - { - /* - * Check that the number of implemented priority bits queried from - * hardware is equal to the CMSIS __NVIC_PRIO_BITS configuration macro. - */ - configASSERT( ulImplementedPrioBits == __NVIC_PRIO_BITS ); - } - #endif /* __NVIC_PRIO_BITS */ - - #ifdef configPRIO_BITS - { - /* - * Check that the number of implemented priority bits queried from - * hardware is equal to the FreeRTOS configPRIO_BITS configuration macro. - */ - configASSERT( ulImplementedPrioBits == configPRIO_BITS ); - } - #endif /* configPRIO_BITS */ - } - #endif /* #ifndef configDISABLE_INTERRUPT_PRIO_BITS_CHECK */ - /* Shift the priority group value back to its position within the AIRCR * register. */ ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT; @@ -1372,6 +1865,54 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ +#if ( configENABLE_MPU == 1 ) + BaseType_t xPortIsAuthorizedToAccessBuffer( const void * pvBuffer, + uint32_t ulBufferLength, + uint32_t ulAccessRequested ) /* PRIVILEGED_FUNCTION */ + + { + uint32_t i, ulBufferStartAddress, ulBufferEndAddress; + BaseType_t xAccessGranted = pdFALSE; + const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */ + + if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) + { + xAccessGranted = pdTRUE; + } + else + { + if( portADD_UINT32_WILL_OVERFLOW( ( ( uint32_t ) pvBuffer ), ( ulBufferLength - 1UL ) ) == pdFALSE ) + { + ulBufferStartAddress = ( uint32_t ) pvBuffer; + ulBufferEndAddress = ( ( ( uint32_t ) pvBuffer ) + ulBufferLength - 1UL ); + + for( i = 0; i < portTOTAL_NUM_REGIONS; i++ ) + { + /* Is the MPU region enabled? */ + if( ( xTaskMpuSettings->xRegionsSettings[ i ].ulRLAR & portMPU_RLAR_REGION_ENABLE ) == portMPU_RLAR_REGION_ENABLE ) + { + if( portIS_ADDRESS_WITHIN_RANGE( ulBufferStartAddress, + portEXTRACT_FIRST_ADDRESS_FROM_RBAR( xTaskMpuSettings->xRegionsSettings[ i ].ulRBAR ), + portEXTRACT_LAST_ADDRESS_FROM_RLAR( xTaskMpuSettings->xRegionsSettings[ i ].ulRLAR ) ) && + portIS_ADDRESS_WITHIN_RANGE( ulBufferEndAddress, + portEXTRACT_FIRST_ADDRESS_FROM_RBAR( xTaskMpuSettings->xRegionsSettings[ i ].ulRBAR ), + portEXTRACT_LAST_ADDRESS_FROM_RLAR( xTaskMpuSettings->xRegionsSettings[ i ].ulRLAR ) ) && + portIS_AUTHORIZED( ulAccessRequested, + prvGetRegionAccessPermissions( xTaskMpuSettings->xRegionsSettings[ i ].ulRBAR ) ) ) + { + xAccessGranted = pdTRUE; + break; + } + } + } + } + } + + return xAccessGranted; + } +#endif /* configENABLE_MPU */ +/*-----------------------------------------------------------*/ + BaseType_t xPortIsInsideInterrupt( void ) { uint32_t ulCurrentInterrupt; diff --git a/portable/GCC/ARM_CM35P/non_secure/portasm.c b/portable/GCC/ARM_CM35P/non_secure/portasm.c index 9f9b2e68d39..f7ec7d9c072 100644 --- a/portable/GCC/ARM_CM35P/non_secure/portasm.c +++ b/portable/GCC/ARM_CM35P/non_secure/portasm.c @@ -40,95 +40,120 @@ * header files. */ #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE +#if ( configENABLE_MPU == 1 ) + void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ { __asm volatile ( - " .syntax unified \n" - " \n" - " ldr r2, pxCurrentTCBConst2 \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - " ldr r3, [r2] \n"/* Read pxCurrentTCB. */ - " ldr r0, [r3] \n"/* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ - " \n" - #if ( configENABLE_MPU == 1 ) - " dmb \n"/* Complete outstanding transfers before disabling MPU. */ - " ldr r2, xMPUCTRLConst2 \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ - " ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */ - " bic r4, #1 \n"/* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */ - " str r4, [r2] \n"/* Disable MPU. */ - " \n" - " adds r3, #4 \n"/* r3 = r3 + 4. r3 now points to MAIR0 in TCB. */ - " ldr r4, [r3] \n"/* r4 = *r3 i.e. r4 = MAIR0. */ - " ldr r2, xMAIR0Const2 \n"/* r2 = 0xe000edc0 [Location of MAIR0]. */ - " str r4, [r2] \n"/* Program MAIR0. */ - " ldr r2, xRNRConst2 \n"/* r2 = 0xe000ed98 [Location of RNR]. */ - " movs r4, #4 \n"/* r4 = 4. */ - " str r4, [r2] \n"/* Program RNR = 4. */ - " adds r3, #4 \n"/* r3 = r3 + 4. r3 now points to first RBAR in TCB. */ - " ldr r2, xRBARConst2 \n"/* r2 = 0xe000ed9c [Location of RBAR]. */ - " ldmia r3!, {r4-r11} \n"/* Read 4 set of RBAR/RLAR registers from TCB. */ - " stmia r2!, {r4-r11} \n"/* Write 4 set of RBAR/RLAR registers using alias registers. */ - " \n" + " .syntax unified \n" + " \n" + " program_mpu_first_task: \n" + " ldr r3, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r0, [r3] \n" /* r0 = pxCurrentTCB. */ + " \n" + " dmb \n" /* Complete outstanding transfers before disabling MPU. */ + " ldr r1, xMPUCTRLConst2 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ + " bic r2, #1 \n" /* r2 = r2 & ~1 i.e. Clear the bit 0 in r2. */ + " str r2, [r1] \n" /* Disable MPU. */ + " \n" + " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */ + " ldr r1, [r0] \n" /* r1 = *r0 i.e. r1 = MAIR0. */ + " ldr r2, xMAIR0Const2 \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */ + " str r1, [r2] \n" /* Program MAIR0. */ + " \n" + " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */ + " ldr r1, xRNRConst2 \n" /* r1 = 0xe000ed98 [Location of RNR]. */ + " ldr r2, xRBARConst2 \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ + " \n" + " movs r3, #4 \n" /* r3 = 4. */ + " str r3, [r1] \n" /* Program RNR = 4. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + " \n" #if ( configTOTAL_MPU_REGIONS == 16 ) - " ldr r2, xRNRConst2 \n"/* r2 = 0xe000ed98 [Location of RNR]. */ - " movs r4, #8 \n"/* r4 = 8. */ - " str r4, [r2] \n"/* Program RNR = 8. */ - " ldr r2, xRBARConst2 \n"/* r2 = 0xe000ed9c [Location of RBAR]. */ - " ldmia r3!, {r4-r11} \n"/* Read 4 set of RBAR/RLAR registers from TCB. */ - " stmia r2!, {r4-r11} \n"/* Write 4 set of RBAR/RLAR registers using alias registers. */ - " ldr r2, xRNRConst2 \n"/* r2 = 0xe000ed98 [Location of RNR]. */ - " movs r4, #12 \n"/* r4 = 12. */ - " str r4, [r2] \n"/* Program RNR = 12. */ - " ldr r2, xRBARConst2 \n"/* r2 = 0xe000ed9c [Location of RBAR]. */ - " ldmia r3!, {r4-r11} \n"/* Read 4 set of RBAR/RLAR registers from TCB. */ - " stmia r2!, {r4-r11} \n"/* Write 4 set of RBAR/RLAR registers using alias registers. */ + " movs r3, #8 \n" /* r3 = 8. */ + " str r3, [r1] \n" /* Program RNR = 8. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + " movs r3, #12 \n" /* r3 = 12. */ + " str r3, [r1] \n" /* Program RNR = 12. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ #endif /* configTOTAL_MPU_REGIONS == 16 */ - " \n" - " ldr r2, xMPUCTRLConst2 \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ - " ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */ - " orr r4, #1 \n"/* r4 = r4 | 1 i.e. Set the bit 0 in r4. */ - " str r4, [r2] \n"/* Enable MPU. */ - " dsb \n"/* Force memory writes before continuing. */ - #endif /* configENABLE_MPU */ + " \n" + " ldr r1, xMPUCTRLConst2 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ + " orr r2, #1 \n" /* r2 = r1 | 1 i.e. Set the bit 0 in r2. */ + " str r2, [r1] \n" /* Enable MPU. */ + " dsb \n" /* Force memory writes before continuing. */ + " \n" + " restore_context_first_task: \n" + " ldr r3, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r1, [r3] \n" /* r1 = pxCurrentTCB.*/ + " ldr r2, [r1] \n" /* r2 = Location of saved context in TCB. */ + " \n" + " restore_special_regs_first_task: \n" + " ldmdb r2!, {r0, r3-r5, lr} \n" /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */ + " msr psp, r3 \n" + " msr psplim, r4 \n" + " msr control, r5 \n" + " ldr r4, xSecureContextConst2 \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ + " str r0, [r4] \n" /* Restore xSecureContext. */ + " \n" + " restore_general_regs_first_task: \n" + " ldmdb r2!, {r4-r11} \n" /* r4-r11 contain hardware saved context. */ + " stmia r3!, {r4-r11} \n" /* Copy the hardware saved context on the task stack. */ + " ldmdb r2!, {r4-r11} \n" /* r4-r11 restored. */ + " \n" + " restore_context_done_first_task: \n" + " str r2, [r1] \n" /* Save the location where the context should be saved next as the first member of TCB. */ + " mov r0, #0 \n" + " msr basepri, r0 \n" /* Ensure that interrupts are enabled when the first task starts. */ + " bx lr \n" + " \n" + " .align 4 \n" + " pxCurrentTCBConst2: .word pxCurrentTCB \n" + " xSecureContextConst2: .word xSecureContext \n" + " xMPUCTRLConst2: .word 0xe000ed94 \n" + " xMAIR0Const2: .word 0xe000edc0 \n" + " xRNRConst2: .word 0xe000ed98 \n" + " xRBARConst2: .word 0xe000ed9c \n" + ); +} + +#else /* configENABLE_MPU */ + +void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ +{ + __asm volatile + ( + " .syntax unified \n" " \n" - #if ( configENABLE_MPU == 1 ) - " ldm r0!, {r1-r4} \n"/* Read from stack - r1 = xSecureContext, r2 = PSPLIM, r3 = CONTROL and r4 = EXC_RETURN. */ - " ldr r5, xSecureContextConst2 \n" - " str r1, [r5] \n"/* Set xSecureContext to this task's value for the same. */ - " msr psplim, r2 \n"/* Set this task's PSPLIM value. */ - " msr control, r3 \n"/* Set this task's CONTROL value. */ - " adds r0, #32 \n"/* Discard everything up to r0. */ - " msr psp, r0 \n"/* This is now the new top of stack to use in the task. */ - " isb \n" - " mov r0, #0 \n" - " msr basepri, r0 \n"/* Ensure that interrupts are enabled when the first task starts. */ - " bx r4 \n"/* Finally, branch to EXC_RETURN. */ - #else /* configENABLE_MPU */ - " ldm r0!, {r1-r3} \n"/* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */ - " ldr r4, xSecureContextConst2 \n" - " str r1, [r4] \n"/* Set xSecureContext to this task's value for the same. */ - " msr psplim, r2 \n"/* Set this task's PSPLIM value. */ - " movs r1, #2 \n"/* r1 = 2. */ - " msr CONTROL, r1 \n"/* Switch to use PSP in the thread mode. */ - " adds r0, #32 \n"/* Discard everything up to r0. */ - " msr psp, r0 \n"/* This is now the new top of stack to use in the task. */ - " isb \n" - " mov r0, #0 \n" - " msr basepri, r0 \n"/* Ensure that interrupts are enabled when the first task starts. */ - " bx r3 \n"/* Finally, branch to EXC_RETURN. */ - #endif /* configENABLE_MPU */ + " ldr r2, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r3, [r2] \n" /* Read pxCurrentTCB. */ + " ldr r0, [r3] \n" /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ " \n" + " ldm r0!, {r1-r3} \n" /* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */ + " ldr r4, xSecureContextConst2 \n" + " str r1, [r4] \n" /* Set xSecureContext to this task's value for the same. */ + " msr psplim, r2 \n" /* Set this task's PSPLIM value. */ + " movs r1, #2 \n" /* r1 = 2. */ + " msr CONTROL, r1 \n" /* Switch to use PSP in the thread mode. */ + " adds r0, #32 \n" /* Discard everything up to r0. */ + " msr psp, r0 \n" /* This is now the new top of stack to use in the task. */ + " isb \n" + " mov r0, #0 \n" + " msr basepri, r0 \n" /* Ensure that interrupts are enabled when the first task starts. */ + " bx r3 \n" /* Finally, branch to EXC_RETURN. */ " .align 4 \n" "pxCurrentTCBConst2: .word pxCurrentTCB \n" "xSecureContextConst2: .word xSecureContext \n" - #if ( configENABLE_MPU == 1 ) - "xMPUCTRLConst2: .word 0xe000ed94 \n" - "xMAIR0Const2: .word 0xe000edc0 \n" - "xRNRConst2: .word 0xe000ed98 \n" - "xRBARConst2: .word 0xe000ed9c \n" - #endif /* configENABLE_MPU */ ); } + +#endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */ @@ -236,6 +261,160 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att } /*-----------------------------------------------------------*/ +#if ( configENABLE_MPU == 1 ) + +void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern SecureContext_SaveContext \n" + " .extern SecureContext_LoadContext \n" + " \n" + " ldr r3, xSecureContextConst \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ + " ldr r0, [r3] \n" /* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */ + " ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r1, [r3] \n" /* Read pxCurrentTCB - Value of pxCurrentTCB must be in r1 as it is used as a parameter later. */ + " ldr r2, [r1] \n" /* r2 = Location in TCB where the context should be saved. */ + " \n" + " cbz r0, save_ns_context \n" /* No secure context to save. */ + " save_s_context: \n" + " push {r0-r2, lr} \n" + " bl SecureContext_SaveContext \n" /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ + " pop {r0-r2, lr} \n" + " \n" + " save_ns_context: \n" + " mov r3, lr \n" /* r3 = LR (EXC_RETURN). */ + " lsls r3, r3, #25 \n" /* r3 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ + " bmi save_special_regs \n" /* r3 < 0 ==> Bit[6] in EXC_RETURN is 1 ==> secure stack was used to store the stack frame. */ + " \n" + " save_general_regs: \n" + " mrs r3, psp \n" + " \n" + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + " add r3, r3, #0x20 \n" /* Move r3 to location where s0 is saved. */ + " tst lr, #0x10 \n" + " ittt eq \n" + " vstmiaeq r2!, {s16-s31} \n" /* Store s16-s31. */ + " vldmiaeq r3, {s0-s16} \n" /* Copy hardware saved FP context into s0-s16. */ + " vstmiaeq r2!, {s0-s16} \n" /* Store hardware saved FP context. */ + " sub r3, r3, #0x20 \n" /* Set r3 back to the location of hardware saved context. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ + " \n" + " stmia r2!, {r4-r11} \n" /* Store r4-r11. */ + " ldmia r3, {r4-r11} \n" /* Copy the hardware saved context into r4-r11. */ + " stmia r2!, {r4-r11} \n" /* Store the hardware saved context. */ + " \n" + " save_special_regs: \n" + " mrs r3, psp \n" /* r3 = PSP. */ + " mrs r4, psplim \n" /* r4 = PSPLIM. */ + " mrs r5, control \n" /* r5 = CONTROL. */ + " stmia r2!, {r0, r3-r5, lr} \n" /* Store xSecureContext, original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */ + " str r2, [r1] \n" /* Save the location from where the context should be restored as the first member of TCB. */ + " \n" + " select_next_task: \n" + " mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */ + " msr basepri, r0 \n" /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + " dsb \n" + " isb \n" + " bl vTaskSwitchContext \n" + " mov r0, #0 \n" /* r0 = 0. */ + " msr basepri, r0 \n" /* Enable interrupts. */ + " \n" + " program_mpu: \n" + " ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r0, [r3] \n" /* r0 = pxCurrentTCB.*/ + " \n" + " dmb \n" /* Complete outstanding transfers before disabling MPU. */ + " ldr r1, xMPUCTRLConst \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ + " bic r2, #1 \n" /* r2 = r2 & ~1 i.e. Clear the bit 0 in r2. */ + " str r2, [r1] \n" /* Disable MPU. */ + " \n" + " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */ + " ldr r1, [r0] \n" /* r1 = *r0 i.e. r1 = MAIR0. */ + " ldr r2, xMAIR0Const \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */ + " str r1, [r2] \n" /* Program MAIR0. */ + " \n" + " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */ + " ldr r1, xRNRConst \n" /* r1 = 0xe000ed98 [Location of RNR]. */ + " ldr r2, xRBARConst \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ + " \n" + " movs r3, #4 \n" /* r3 = 4. */ + " str r3, [r1] \n" /* Program RNR = 4. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + " \n" + #if ( configTOTAL_MPU_REGIONS == 16 ) + " movs r3, #8 \n" /* r3 = 8. */ + " str r3, [r1] \n" /* Program RNR = 8. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + " movs r3, #12 \n" /* r3 = 12. */ + " str r3, [r1] \n" /* Program RNR = 12. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + #endif /* configTOTAL_MPU_REGIONS == 16 */ + " \n" + " ldr r1, xMPUCTRLConst \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ + " orr r2, #1 \n" /* r2 = r2 | 1 i.e. Set the bit 0 in r2. */ + " str r2, [r1] \n" /* Enable MPU. */ + " dsb \n" /* Force memory writes before continuing. */ + " \n" + " restore_context: \n" + " ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r1, [r3] \n" /* r1 = pxCurrentTCB.*/ + " ldr r2, [r1] \n" /* r2 = Location of saved context in TCB. */ + " \n" + " restore_special_regs: \n" + " ldmdb r2!, {r0, r3-r5, lr} \n" /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */ + " msr psp, r3 \n" + " msr psplim, r4 \n" + " msr control, r5 \n" + " ldr r4, xSecureContextConst \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ + " str r0, [r4] \n" /* Restore xSecureContext. */ + " cbz r0, restore_ns_context \n" /* No secure context to restore. */ + " \n" + " restore_s_context: \n" + " push {r1-r3, lr} \n" + " bl SecureContext_LoadContext \n" /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ + " pop {r1-r3, lr} \n" + " \n" + " restore_ns_context: \n" + " mov r0, lr \n" /* r0 = LR (EXC_RETURN). */ + " lsls r0, r0, #25 \n" /* r0 = r0 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ + " bmi restore_context_done \n" /* r0 < 0 ==> Bit[6] in EXC_RETURN is 1 ==> secure stack was used to store the stack frame. */ + " \n" + " restore_general_regs: \n" + " ldmdb r2!, {r4-r11} \n" /* r4-r11 contain hardware saved context. */ + " stmia r3!, {r4-r11} \n" /* Copy the hardware saved context on the task stack. */ + " ldmdb r2!, {r4-r11} \n" /* r4-r11 restored. */ + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + " tst lr, #0x10 \n" + " ittt eq \n" + " vldmdbeq r2!, {s0-s16} \n" /* s0-s16 contain hardware saved FP context. */ + " vstmiaeq r3!, {s0-s16} \n" /* Copy hardware saved FP context on the task stack. */ + " vldmdbeq r2!, {s16-s31} \n" /* Restore s16-s31. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ + " \n" + " restore_context_done: \n" + " str r2, [r1] \n" /* Save the location where the context should be saved next as the first member of TCB. */ + " bx lr \n" + " \n" + " .align 4 \n" + " pxCurrentTCBConst: .word pxCurrentTCB \n" + " xSecureContextConst: .word xSecureContext \n" + " xMPUCTRLConst: .word 0xe000ed94 \n" + " xMAIR0Const: .word 0xe000edc0 \n" + " xRNRConst: .word 0xe000ed98 \n" + " xRBARConst: .word 0xe000ed9c \n" + ::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) + ); +} + +#else /* configENABLE_MPU */ + void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ { __asm volatile @@ -260,20 +439,11 @@ void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ " \n" " ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r3] \n"/* Read pxCurrentTCB.*/ - #if ( configENABLE_MPU == 1 ) - " subs r2, r2, #16 \n"/* Make space for xSecureContext, PSPLIM, CONTROL and LR on the stack. */ - " str r2, [r1] \n"/* Save the new top of stack in TCB. */ - " mrs r1, psplim \n"/* r1 = PSPLIM. */ - " mrs r3, control \n"/* r3 = CONTROL. */ - " mov r4, lr \n"/* r4 = LR/EXC_RETURN. */ - " stmia r2!, {r0, r1, r3, r4} \n"/* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */ - #else /* configENABLE_MPU */ - " subs r2, r2, #12 \n"/* Make space for xSecureContext, PSPLIM and LR on the stack. */ - " str r2, [r1] \n"/* Save the new top of stack in TCB. */ - " mrs r1, psplim \n"/* r1 = PSPLIM. */ - " mov r3, lr \n"/* r3 = LR/EXC_RETURN. */ - " stmia r2!, {r0, r1, r3} \n"/* Store xSecureContext, PSPLIM and LR on the stack. */ - #endif /* configENABLE_MPU */ + " subs r2, r2, #12 \n"/* Make space for xSecureContext, PSPLIM and LR on the stack. */ + " str r2, [r1] \n"/* Save the new top of stack in TCB. */ + " mrs r1, psplim \n"/* r1 = PSPLIM. */ + " mov r3, lr \n"/* r3 = LR/EXC_RETURN. */ + " stmia r2!, {r0, r1, r3} \n"/* Store xSecureContext, PSPLIM and LR on the stack. */ " b select_next_task \n" " \n" " save_ns_context: \n" @@ -284,26 +454,14 @@ void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ " it eq \n" " vstmdbeq r2!, {s16-s31} \n"/* Store the additional FP context registers which are not saved automatically. */ #endif /* configENABLE_FPU || configENABLE_MVE */ - #if ( configENABLE_MPU == 1 ) - " subs r2, r2, #48 \n"/* Make space for xSecureContext, PSPLIM, CONTROL, LR and the remaining registers on the stack. */ - " str r2, [r1] \n"/* Save the new top of stack in TCB. */ - " adds r2, r2, #16 \n"/* r2 = r2 + 16. */ - " stm r2, {r4-r11} \n"/* Store the registers that are not saved automatically. */ - " mrs r1, psplim \n"/* r1 = PSPLIM. */ - " mrs r3, control \n"/* r3 = CONTROL. */ - " mov r4, lr \n"/* r4 = LR/EXC_RETURN. */ - " subs r2, r2, #16 \n"/* r2 = r2 - 16. */ - " stmia r2!, {r0, r1, r3, r4} \n"/* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */ - #else /* configENABLE_MPU */ - " subs r2, r2, #44 \n"/* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */ - " str r2, [r1] \n"/* Save the new top of stack in TCB. */ - " adds r2, r2, #12 \n"/* r2 = r2 + 12. */ - " stm r2, {r4-r11} \n"/* Store the registers that are not saved automatically. */ - " mrs r1, psplim \n"/* r1 = PSPLIM. */ - " mov r3, lr \n"/* r3 = LR/EXC_RETURN. */ - " subs r2, r2, #12 \n"/* r2 = r2 - 12. */ - " stmia r2!, {r0, r1, r3} \n"/* Store xSecureContext, PSPLIM and LR on the stack. */ - #endif /* configENABLE_MPU */ + " subs r2, r2, #44 \n"/* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */ + " str r2, [r1] \n"/* Save the new top of stack in TCB. */ + " adds r2, r2, #12 \n"/* r2 = r2 + 12. */ + " stm r2, {r4-r11} \n"/* Store the registers that are not saved automatically. */ + " mrs r1, psplim \n"/* r1 = PSPLIM. */ + " mov r3, lr \n"/* r3 = LR/EXC_RETURN. */ + " subs r2, r2, #12 \n"/* r2 = r2 - 12. */ + " stmia r2!, {r0, r1, r3} \n"/* Store xSecureContext, PSPLIM and LR on the stack. */ " \n" " select_next_task: \n" " mov r0, %0 \n"/* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */ @@ -318,83 +476,22 @@ void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ " ldr r1, [r3] \n"/* Read pxCurrentTCB. */ " ldr r2, [r1] \n"/* The first item in pxCurrentTCB is the task top of stack. r2 now points to the top of stack. */ " \n" - #if ( configENABLE_MPU == 1 ) - " dmb \n"/* Complete outstanding transfers before disabling MPU. */ - " ldr r3, xMPUCTRLConst \n"/* r3 = 0xe000ed94 [Location of MPU_CTRL]. */ - " ldr r4, [r3] \n"/* Read the value of MPU_CTRL. */ - " bic r4, #1 \n"/* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */ - " str r4, [r3] \n"/* Disable MPU. */ - " \n" - " adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */ - " ldr r4, [r1] \n"/* r4 = *r1 i.e. r4 = MAIR0. */ - " ldr r3, xMAIR0Const \n"/* r3 = 0xe000edc0 [Location of MAIR0]. */ - " str r4, [r3] \n"/* Program MAIR0. */ - " ldr r3, xRNRConst \n"/* r3 = 0xe000ed98 [Location of RNR]. */ - " movs r4, #4 \n"/* r4 = 4. */ - " str r4, [r3] \n"/* Program RNR = 4. */ - " adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to first RBAR in TCB. */ - " ldr r3, xRBARConst \n"/* r3 = 0xe000ed9c [Location of RBAR]. */ - " ldmia r1!, {r4-r11} \n"/* Read 4 sets of RBAR/RLAR registers from TCB. */ - " stmia r3!, {r4-r11} \n"/* Write 4 set of RBAR/RLAR registers using alias registers. */ - " \n" - #if ( configTOTAL_MPU_REGIONS == 16 ) - " ldr r3, xRNRConst \n"/* r3 = 0xe000ed98 [Location of RNR]. */ - " movs r4, #8 \n"/* r4 = 8. */ - " str r4, [r3] \n"/* Program RNR = 8. */ - " ldr r3, xRBARConst \n"/* r3 = 0xe000ed9c [Location of RBAR]. */ - " ldmia r1!, {r4-r11} \n"/* Read 4 sets of RBAR/RLAR registers from TCB. */ - " stmia r3!, {r4-r11} \n"/* Write 4 set of RBAR/RLAR registers using alias registers. */ - " ldr r3, xRNRConst \n"/* r3 = 0xe000ed98 [Location of RNR]. */ - " movs r4, #12 \n"/* r4 = 12. */ - " str r4, [r3] \n"/* Program RNR = 12. */ - " ldr r3, xRBARConst \n"/* r3 = 0xe000ed9c [Location of RBAR]. */ - " ldmia r1!, {r4-r11} \n"/* Read 4 sets of RBAR/RLAR registers from TCB. */ - " stmia r3!, {r4-r11} \n"/* Write 4 set of RBAR/RLAR registers using alias registers. */ - #endif /* configTOTAL_MPU_REGIONS == 16 */ - " \n" - " ldr r3, xMPUCTRLConst \n"/* r3 = 0xe000ed94 [Location of MPU_CTRL]. */ - " ldr r4, [r3] \n"/* Read the value of MPU_CTRL. */ - " orr r4, #1 \n"/* r4 = r4 | 1 i.e. Set the bit 0 in r4. */ - " str r4, [r3] \n"/* Enable MPU. */ - " dsb \n"/* Force memory writes before continuing. */ - #endif /* configENABLE_MPU */ - " \n" - #if ( configENABLE_MPU == 1 ) - " ldmia r2!, {r0, r1, r3, r4} \n"/* Read from stack - r0 = xSecureContext, r1 = PSPLIM, r3 = CONTROL and r4 = LR. */ - " msr psplim, r1 \n"/* Restore the PSPLIM register value for the task. */ - " msr control, r3 \n"/* Restore the CONTROL register value for the task. */ - " mov lr, r4 \n"/* LR = r4. */ - " ldr r3, xSecureContextConst \n"/* Read the location of xSecureContext i.e. &( xSecureContext ). */ - " str r0, [r3] \n"/* Restore the task's xSecureContext. */ - " cbz r0, restore_ns_context \n"/* If there is no secure context for the task, restore the non-secure context. */ - " ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - " ldr r1, [r3] \n"/* Read pxCurrentTCB. */ - " push {r2, r4} \n" - " bl SecureContext_LoadContext \n"/* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ - " pop {r2, r4} \n" - " mov lr, r4 \n"/* LR = r4. */ - " lsls r1, r4, #25 \n"/* r1 = r4 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ - " bpl restore_ns_context \n"/* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ - " msr psp, r2 \n"/* Remember the new top of stack for the task. */ - " bx lr \n" - #else /* configENABLE_MPU */ - " ldmia r2!, {r0, r1, r4} \n"/* Read from stack - r0 = xSecureContext, r1 = PSPLIM and r4 = LR. */ - " msr psplim, r1 \n"/* Restore the PSPLIM register value for the task. */ - " mov lr, r4 \n"/* LR = r4. */ - " ldr r3, xSecureContextConst \n"/* Read the location of xSecureContext i.e. &( xSecureContext ). */ - " str r0, [r3] \n"/* Restore the task's xSecureContext. */ - " cbz r0, restore_ns_context \n"/* If there is no secure context for the task, restore the non-secure context. */ - " ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - " ldr r1, [r3] \n"/* Read pxCurrentTCB. */ - " push {r2, r4} \n" - " bl SecureContext_LoadContext \n"/* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ - " pop {r2, r4} \n" - " mov lr, r4 \n"/* LR = r4. */ - " lsls r1, r4, #25 \n"/* r1 = r4 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ - " bpl restore_ns_context \n"/* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ - " msr psp, r2 \n"/* Remember the new top of stack for the task. */ - " bx lr \n" - #endif /* configENABLE_MPU */ + " ldmia r2!, {r0, r1, r4} \n"/* Read from stack - r0 = xSecureContext, r1 = PSPLIM and r4 = LR. */ + " msr psplim, r1 \n"/* Restore the PSPLIM register value for the task. */ + " mov lr, r4 \n"/* LR = r4. */ + " ldr r3, xSecureContextConst \n"/* Read the location of xSecureContext i.e. &( xSecureContext ). */ + " str r0, [r3] \n"/* Restore the task's xSecureContext. */ + " cbz r0, restore_ns_context \n"/* If there is no secure context for the task, restore the non-secure context. */ + " ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r1, [r3] \n"/* Read pxCurrentTCB. */ + " push {r2, r4} \n" + " bl SecureContext_LoadContext \n"/* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ + " pop {r2, r4} \n" + " mov lr, r4 \n"/* LR = r4. */ + " lsls r1, r4, #25 \n"/* r1 = r4 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ + " bpl restore_ns_context \n"/* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ + " msr psp, r2 \n"/* Remember the new top of stack for the task. */ + " bx lr \n" " \n" " restore_ns_context: \n" " ldmia r2!, {r4-r11} \n"/* Restore the registers that are not automatically restored. */ @@ -409,17 +506,60 @@ void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ " .align 4 \n" "pxCurrentTCBConst: .word pxCurrentTCB \n" "xSecureContextConst: .word xSecureContext \n" - #if ( configENABLE_MPU == 1 ) - "xMPUCTRLConst: .word 0xe000ed94 \n" - "xMAIR0Const: .word 0xe000edc0 \n" - "xRNRConst: .word 0xe000ed98 \n" - "xRBARConst: .word 0xe000ed9c \n" - #endif /* configENABLE_MPU */ ::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) ); } + +#endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + +void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ +{ + __asm volatile + ( + ".syntax unified \n" + ".extern vPortSVCHandler_C \n" + ".extern vSystemCallEnter \n" + ".extern vSystemCallEnter_1 \n" + ".extern vSystemCallExit \n" + " \n" + "tst lr, #4 \n" + "ite eq \n" + "mrseq r0, msp \n" + "mrsne r0, psp \n" + " \n" + "ldr r1, [r0, #24] \n" + "ldrb r2, [r1, #-2] \n" + "cmp r2, %0 \n" + "beq syscall_enter \n" + "cmp r2, %1 \n" + "beq syscall_enter_1 \n" + "cmp r2, %2 \n" + "beq syscall_exit \n" + "b vPortSVCHandler_C \n" + " \n" + "syscall_enter: \n" + " mov r1, lr \n" + " b vSystemCallEnter \n" + " \n" + "syscall_enter_1: \n" + " mov r1, lr \n" + " b vSystemCallEnter_1 \n" + " \n" + "syscall_exit: \n" + " mov r1, lr \n" + " b vSystemCallExit \n" + " \n" + : /* No outputs. */ + :"i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_ENTER_1 ), "i" ( portSVC_SYSTEM_CALL_EXIT ) + : "r0", "r1", "r2", "memory" + ); +} + +#else /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ { __asm volatile @@ -437,6 +577,8 @@ void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ "svchandler_address_const: .word vPortSVCHandler_C \n" ); } + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ /*-----------------------------------------------------------*/ void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) /* __attribute__ (( naked )) */ diff --git a/portable/GCC/ARM_CM35P/non_secure/portmacro.h b/portable/GCC/ARM_CM35P/non_secure/portmacro.h index cc643459770..9545737c550 100644 --- a/portable/GCC/ARM_CM35P/non_secure/portmacro.h +++ b/portable/GCC/ARM_CM35P/non_secure/portmacro.h @@ -51,7 +51,6 @@ #define portARCH_NAME "Cortex-M35P" #define portHAS_BASEPRI 1 #define portDONT_DISCARD __attribute__( ( used ) ) -#define portNORETURN __attribute__( ( noreturn ) ) /*-----------------------------------------------------------*/ /* ARMv8-M common port configurations. */ diff --git a/portable/GCC/ARM_CM35P/non_secure/portmacrocommon.h b/portable/GCC/ARM_CM35P/non_secure/portmacrocommon.h index c2ca5fa7730..65ac109c802 100644 --- a/portable/GCC/ARM_CM35P/non_secure/portmacrocommon.h +++ b/portable/GCC/ARM_CM35P/non_secure/portmacrocommon.h @@ -186,23 +186,120 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #define portMPU_REGION_EXECUTE_NEVER ( 1UL ) /*-----------------------------------------------------------*/ -/** - * @brief Settings to define an MPU region. - */ -typedef struct MPURegionSettings -{ - uint32_t ulRBAR; /**< RBAR for the region. */ - uint32_t ulRLAR; /**< RLAR for the region. */ -} MPURegionSettings_t; +#if ( configENABLE_MPU == 1 ) -/** - * @brief MPU settings as stored in the TCB. - */ -typedef struct MPU_SETTINGS -{ - uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ - MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */ -} xMPU_SETTINGS; + /** + * @brief Settings to define an MPU region. + */ + typedef struct MPURegionSettings + { + uint32_t ulRBAR; /**< RBAR for the region. */ + uint32_t ulRLAR; /**< RLAR for the region. */ + } MPURegionSettings_t; + + #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + + #ifndef configSYSTEM_CALL_STACK_SIZE + #error configSYSTEM_CALL_STACK_SIZE must be defined to the desired size of the system call stack in words for using MPU wrappers v2. + #endif + + /** + * @brief System call stack. + */ + typedef struct SYSTEM_CALL_STACK_INFO + { + uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ]; + uint32_t * pulSystemCallStack; + uint32_t * pulSystemCallStackLimit; + uint32_t * pulTaskStack; + uint32_t ulLinkRegisterAtSystemCallEntry; + uint32_t ulStackLimitRegisterAtSystemCallEntry; + } xSYSTEM_CALL_STACK_INFO; + + #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + + /** + * @brief MPU settings as stored in the TCB. + */ + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + + #if( configENABLE_TRUSTZONE == 1 ) + + /* + * +-----------+---------------+----------+-----------------+------------------------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | + * | | | | PC, xPSR | CONTROL, EXC_RETURN | | + * +-----------+---------------+----------+-----------------+------------------------------+-----+ + * + * <-----------><--------------><---------><----------------><-----------------------------><----> + * 16 16 8 8 5 1 + */ + #define MAX_CONTEXT_SIZE 54 + + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ + + /* + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | + * | | | | PC, xPSR | EXC_RETURN | | + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * + * <-----------><--------------><---------><----------------><---------------------><----> + * 16 16 8 8 4 1 + */ + #define MAX_CONTEXT_SIZE 53 + + #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + + #else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ + + #if( configENABLE_TRUSTZONE == 1 ) + + /* + * +----------+-----------------+------------------------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | + * | | PC, xPSR | CONTROL, EXC_RETURN | | + * +----------+-----------------+------------------------------+-----+ + * + * <---------><----------------><------------------------------><----> + * 8 8 5 1 + */ + #define MAX_CONTEXT_SIZE 22 + + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ + + /* + * +----------+-----------------+----------------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | + * | | PC, xPSR | EXC_RETURN | | + * +----------+-----------------+----------------------+-----+ + * + * <---------><----------------><----------------------><----> + * 8 8 4 1 + */ + #define MAX_CONTEXT_SIZE 21 + + #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + + #endif /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ + + /* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ + #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) + #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) + + typedef struct MPU_SETTINGS + { + uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ + MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */ + uint32_t ulContext[ MAX_CONTEXT_SIZE ]; + uint32_t ulTaskFlags; + + #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo; + #endif + } xMPU_SETTINGS; + +#endif /* configENABLE_MPU == 1 */ /*-----------------------------------------------------------*/ /** @@ -223,6 +320,9 @@ typedef struct MPU_SETTINGS #define portSVC_FREE_SECURE_CONTEXT 1 #define portSVC_START_SCHEDULER 2 #define portSVC_RAISE_PRIVILEGE 3 +#define portSVC_SYSTEM_CALL_ENTER 4 /* System calls with upto 4 parameters. */ +#define portSVC_SYSTEM_CALL_ENTER_1 5 /* System calls with 5 parameters. */ +#define portSVC_SYSTEM_CALL_EXIT 6 /*-----------------------------------------------------------*/ /** @@ -315,6 +415,20 @@ typedef struct MPU_SETTINGS #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ +#if ( configENABLE_MPU == 1 ) + + extern BaseType_t xPortIsTaskPrivileged( void ); + + /** + * @brief Checks whether or not the calling task is privileged. + * + * @return pdTRUE if the calling task is privileged, pdFALSE otherwise. + */ + #define portIS_TASK_PRIVILEGED() xPortIsTaskPrivileged() + +#endif /* configENABLE_MPU == 1 */ +/*-----------------------------------------------------------*/ + /** * @brief Barriers. */ diff --git a/portable/GCC/ARM_CM35P_NTZ/non_secure/mpu_wrappers_v2_asm.c b/portable/GCC/ARM_CM35P_NTZ/non_secure/mpu_wrappers_v2_asm.c new file mode 100644 index 00000000000..6e2043427fe --- /dev/null +++ b/portable/GCC/ARM_CM35P_NTZ/non_secure/mpu_wrappers_v2_asm.c @@ -0,0 +1,2349 @@ +/* + * FreeRTOS Kernel + * Copyright (C) 2021 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 + * + */ + +/* 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. */ +#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +/* Scheduler includes. */ +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" +#include "timers.h" +#include "event_groups.h" +#include "stream_buffer.h" + +#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + +#if ( INCLUDE_xTaskDelayUntil == 1 ) + +BaseType_t MPU_xTaskDelayUntil( TickType_t * const pxPreviousWakeTime, + const TickType_t xTimeIncrement ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskDelayUntil( TickType_t * const pxPreviousWakeTime, + const TickType_t xTimeIncrement ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskDelayUntilImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskDelayUntil_Unpriv \n" + " MPU_xTaskDelayUntil_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskDelayUntilImpl \n" + " MPU_xTaskDelayUntil_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskDelayUntilImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_xTaskDelayUntil == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_xTaskAbortDelay == 1 ) + +BaseType_t MPU_xTaskAbortDelay( TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskAbortDelay( TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskAbortDelayImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskAbortDelay_Unpriv \n" + " MPU_xTaskAbortDelay_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskAbortDelayImpl \n" + " MPU_xTaskAbortDelay_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskAbortDelayImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_xTaskAbortDelay == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskDelay == 1 ) + +void MPU_vTaskDelay( const TickType_t xTicksToDelay ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskDelay( const TickType_t xTicksToDelay ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskDelayImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vTaskDelay_Unpriv \n" + " MPU_vTaskDelay_Priv: \n" + " pop {r0} \n" + " b MPU_vTaskDelayImpl \n" + " MPU_vTaskDelay_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vTaskDelayImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_vTaskDelay == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_uxTaskPriorityGet == 1 ) + +UBaseType_t MPU_uxTaskPriorityGet( const TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxTaskPriorityGet( const TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxTaskPriorityGetImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_uxTaskPriorityGet_Unpriv \n" + " MPU_uxTaskPriorityGet_Priv: \n" + " pop {r0} \n" + " b MPU_uxTaskPriorityGetImpl \n" + " MPU_uxTaskPriorityGet_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_uxTaskPriorityGetImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_uxTaskPriorityGet == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_eTaskGetState == 1 ) + +eTaskState MPU_eTaskGetState( TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +eTaskState MPU_eTaskGetState( TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_eTaskGetStateImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_eTaskGetState_Unpriv \n" + " MPU_eTaskGetState_Priv: \n" + " pop {r0} \n" + " b MPU_eTaskGetStateImpl \n" + " MPU_eTaskGetState_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_eTaskGetStateImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_eTaskGetState == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + +void MPU_vTaskGetInfo( TaskHandle_t xTask, + TaskStatus_t * pxTaskStatus, + BaseType_t xGetFreeStackSpace, + eTaskState eState ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskGetInfo( TaskHandle_t xTask, + TaskStatus_t * pxTaskStatus, + BaseType_t xGetFreeStackSpace, + eTaskState eState ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskGetInfoImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vTaskGetInfo_Unpriv \n" + " MPU_vTaskGetInfo_Priv: \n" + " pop {r0} \n" + " b MPU_vTaskGetInfoImpl \n" + " MPU_vTaskGetInfo_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vTaskGetInfoImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TRACE_FACILITY == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) + +TaskHandle_t MPU_xTaskGetIdleTaskHandle( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TaskHandle_t MPU_xTaskGetIdleTaskHandle( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGetIdleTaskHandleImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskGetIdleTaskHandle_Unpriv \n" + " MPU_xTaskGetIdleTaskHandle_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskGetIdleTaskHandleImpl \n" + " MPU_xTaskGetIdleTaskHandle_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskGetIdleTaskHandleImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskSuspend == 1 ) + +void MPU_vTaskSuspend( TaskHandle_t xTaskToSuspend ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskSuspend( TaskHandle_t xTaskToSuspend ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskSuspendImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vTaskSuspend_Unpriv \n" + " MPU_vTaskSuspend_Priv: \n" + " pop {r0} \n" + " b MPU_vTaskSuspendImpl \n" + " MPU_vTaskSuspend_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vTaskSuspendImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_vTaskSuspend == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskSuspend == 1 ) + +void MPU_vTaskResume( TaskHandle_t xTaskToResume ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskResume( TaskHandle_t xTaskToResume ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskResumeImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vTaskResume_Unpriv \n" + " MPU_vTaskResume_Priv: \n" + " pop {r0} \n" + " b MPU_vTaskResumeImpl \n" + " MPU_vTaskResume_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vTaskResumeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_vTaskSuspend == 1 ) */ +/*-----------------------------------------------------------*/ + +TickType_t MPU_xTaskGetTickCount( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TickType_t MPU_xTaskGetTickCount( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGetTickCountImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskGetTickCount_Unpriv \n" + " MPU_xTaskGetTickCount_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskGetTickCountImpl \n" + " MPU_xTaskGetTickCount_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskGetTickCountImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +UBaseType_t MPU_uxTaskGetNumberOfTasks( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxTaskGetNumberOfTasks( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxTaskGetNumberOfTasksImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_uxTaskGetNumberOfTasks_Unpriv \n" + " MPU_uxTaskGetNumberOfTasks_Priv: \n" + " pop {r0} \n" + " b MPU_uxTaskGetNumberOfTasksImpl \n" + " MPU_uxTaskGetNumberOfTasks_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_uxTaskGetNumberOfTasksImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +char * MPU_pcTaskGetName( TaskHandle_t xTaskToQuery ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +char * MPU_pcTaskGetName( TaskHandle_t xTaskToQuery ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_pcTaskGetNameImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_pcTaskGetName_Unpriv \n" + " MPU_pcTaskGetName_Priv: \n" + " pop {r0} \n" + " b MPU_pcTaskGetNameImpl \n" + " MPU_pcTaskGetName_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_pcTaskGetNameImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +#if ( configGENERATE_RUN_TIME_STATS == 1 ) + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetRunTimeCounter( const TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetRunTimeCounter( const TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_ulTaskGetRunTimeCounterImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_ulTaskGetRunTimeCounter_Unpriv \n" + " MPU_ulTaskGetRunTimeCounter_Priv: \n" + " pop {r0} \n" + " b MPU_ulTaskGetRunTimeCounterImpl \n" + " MPU_ulTaskGetRunTimeCounter_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_ulTaskGetRunTimeCounterImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( ( configGENERATE_RUN_TIME_STATS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configGENERATE_RUN_TIME_STATS == 1 ) + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetRunTimePercent( const TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetRunTimePercent( const TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_ulTaskGetRunTimePercentImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_ulTaskGetRunTimePercent_Unpriv \n" + " MPU_ulTaskGetRunTimePercent_Priv: \n" + " pop {r0} \n" + " b MPU_ulTaskGetRunTimePercentImpl \n" + " MPU_ulTaskGetRunTimePercent_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_ulTaskGetRunTimePercentImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( ( configGENERATE_RUN_TIME_STATS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimePercent( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimePercent( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_ulTaskGetIdleRunTimePercentImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_ulTaskGetIdleRunTimePercent_Unpriv \n" + " MPU_ulTaskGetIdleRunTimePercent_Priv: \n" + " pop {r0} \n" + " b MPU_ulTaskGetIdleRunTimePercentImpl \n" + " MPU_ulTaskGetIdleRunTimePercent_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_ulTaskGetIdleRunTimePercentImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimeCounter( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimeCounter( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_ulTaskGetIdleRunTimeCounterImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_ulTaskGetIdleRunTimeCounter_Unpriv \n" + " MPU_ulTaskGetIdleRunTimeCounter_Priv: \n" + " pop {r0} \n" + " b MPU_ulTaskGetIdleRunTimeCounterImpl \n" + " MPU_ulTaskGetIdleRunTimeCounter_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_ulTaskGetIdleRunTimeCounterImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_APPLICATION_TASK_TAG == 1 ) + +void MPU_vTaskSetApplicationTaskTag( TaskHandle_t xTask, + TaskHookFunction_t pxHookFunction ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskSetApplicationTaskTag( TaskHandle_t xTask, + TaskHookFunction_t pxHookFunction ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskSetApplicationTaskTagImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vTaskSetApplicationTaskTag_Unpriv \n" + " MPU_vTaskSetApplicationTaskTag_Priv: \n" + " pop {r0} \n" + " b MPU_vTaskSetApplicationTaskTagImpl \n" + " MPU_vTaskSetApplicationTaskTag_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vTaskSetApplicationTaskTagImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_APPLICATION_TASK_TAG == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_APPLICATION_TASK_TAG == 1 ) + +TaskHookFunction_t MPU_xTaskGetApplicationTaskTag( TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TaskHookFunction_t MPU_xTaskGetApplicationTaskTag( TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGetApplicationTaskTagImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskGetApplicationTaskTag_Unpriv \n" + " MPU_xTaskGetApplicationTaskTag_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskGetApplicationTaskTagImpl \n" + " MPU_xTaskGetApplicationTaskTag_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskGetApplicationTaskTagImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_APPLICATION_TASK_TAG == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) + +void MPU_vTaskSetThreadLocalStoragePointer( TaskHandle_t xTaskToSet, + BaseType_t xIndex, + void * pvValue ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskSetThreadLocalStoragePointer( TaskHandle_t xTaskToSet, + BaseType_t xIndex, + void * pvValue ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskSetThreadLocalStoragePointerImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vTaskSetThreadLocalStoragePointer_Unpriv \n" + " MPU_vTaskSetThreadLocalStoragePointer_Priv: \n" + " pop {r0} \n" + " b MPU_vTaskSetThreadLocalStoragePointerImpl \n" + " MPU_vTaskSetThreadLocalStoragePointer_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vTaskSetThreadLocalStoragePointerImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) + +void * MPU_pvTaskGetThreadLocalStoragePointer( TaskHandle_t xTaskToQuery, + BaseType_t xIndex ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void * MPU_pvTaskGetThreadLocalStoragePointer( TaskHandle_t xTaskToQuery, + BaseType_t xIndex ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_pvTaskGetThreadLocalStoragePointerImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_pvTaskGetThreadLocalStoragePointer_Unpriv \n" + " MPU_pvTaskGetThreadLocalStoragePointer_Priv: \n" + " pop {r0} \n" + " b MPU_pvTaskGetThreadLocalStoragePointerImpl \n" + " MPU_pvTaskGetThreadLocalStoragePointer_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_pvTaskGetThreadLocalStoragePointerImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + +UBaseType_t MPU_uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray, + const UBaseType_t uxArraySize, + configRUN_TIME_COUNTER_TYPE * const pulTotalRunTime ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray, + const UBaseType_t uxArraySize, + configRUN_TIME_COUNTER_TYPE * const pulTotalRunTime ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxTaskGetSystemStateImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_uxTaskGetSystemState_Unpriv \n" + " MPU_uxTaskGetSystemState_Priv: \n" + " pop {r0} \n" + " b MPU_uxTaskGetSystemStateImpl \n" + " MPU_uxTaskGetSystemState_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_uxTaskGetSystemStateImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TRACE_FACILITY == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) + +UBaseType_t MPU_uxTaskGetStackHighWaterMark( TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxTaskGetStackHighWaterMark( TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxTaskGetStackHighWaterMarkImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_uxTaskGetStackHighWaterMark_Unpriv \n" + " MPU_uxTaskGetStackHighWaterMark_Priv: \n" + " pop {r0} \n" + " b MPU_uxTaskGetStackHighWaterMarkImpl \n" + " MPU_uxTaskGetStackHighWaterMark_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_uxTaskGetStackHighWaterMarkImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) + +configSTACK_DEPTH_TYPE MPU_uxTaskGetStackHighWaterMark2( TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +configSTACK_DEPTH_TYPE MPU_uxTaskGetStackHighWaterMark2( TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxTaskGetStackHighWaterMark2Impl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_uxTaskGetStackHighWaterMark2_Unpriv \n" + " MPU_uxTaskGetStackHighWaterMark2_Priv: \n" + " pop {r0} \n" + " b MPU_uxTaskGetStackHighWaterMark2Impl \n" + " MPU_uxTaskGetStackHighWaterMark2_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_uxTaskGetStackHighWaterMark2Impl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) ) + +TaskHandle_t MPU_xTaskGetCurrentTaskHandle( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TaskHandle_t MPU_xTaskGetCurrentTaskHandle( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGetCurrentTaskHandleImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskGetCurrentTaskHandle_Unpriv \n" + " MPU_xTaskGetCurrentTaskHandle_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskGetCurrentTaskHandleImpl \n" + " MPU_xTaskGetCurrentTaskHandle_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskGetCurrentTaskHandleImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_xTaskGetSchedulerState == 1 ) + +BaseType_t MPU_xTaskGetSchedulerState( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskGetSchedulerState( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGetSchedulerStateImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskGetSchedulerState_Unpriv \n" + " MPU_xTaskGetSchedulerState_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskGetSchedulerStateImpl \n" + " MPU_xTaskGetSchedulerState_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskGetSchedulerStateImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_xTaskGetSchedulerState == 1 ) */ +/*-----------------------------------------------------------*/ + +void MPU_vTaskSetTimeOutState( TimeOut_t * const pxTimeOut ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskSetTimeOutState( TimeOut_t * const pxTimeOut ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskSetTimeOutStateImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vTaskSetTimeOutState_Unpriv \n" + " MPU_vTaskSetTimeOutState_Priv: \n" + " pop {r0} \n" + " b MPU_vTaskSetTimeOutStateImpl \n" + " MPU_vTaskSetTimeOutState_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vTaskSetTimeOutStateImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut, + TickType_t * const pxTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut, + TickType_t * const pxTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskCheckForTimeOutImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskCheckForTimeOut_Unpriv \n" + " MPU_xTaskCheckForTimeOut_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskCheckForTimeOutImpl \n" + " MPU_xTaskCheckForTimeOut_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskCheckForTimeOutImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +#if ( configUSE_TASK_NOTIFICATIONS == 1 ) + +BaseType_t MPU_xTaskGenericNotify( TaskHandle_t xTaskToNotify, + UBaseType_t uxIndexToNotify, + uint32_t ulValue, + eNotifyAction eAction, + uint32_t * pulPreviousNotificationValue ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskGenericNotify( TaskHandle_t xTaskToNotify, + UBaseType_t uxIndexToNotify, + uint32_t ulValue, + eNotifyAction eAction, + uint32_t * pulPreviousNotificationValue ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGenericNotifyImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskGenericNotify_Unpriv \n" + " MPU_xTaskGenericNotify_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskGenericNotifyImpl \n" + " MPU_xTaskGenericNotify_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskGenericNotifyImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER_1 ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TASK_NOTIFICATIONS == 1 ) + +BaseType_t MPU_xTaskGenericNotifyWait( UBaseType_t uxIndexToWaitOn, + uint32_t ulBitsToClearOnEntry, + uint32_t ulBitsToClearOnExit, + uint32_t * pulNotificationValue, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskGenericNotifyWait( UBaseType_t uxIndexToWaitOn, + uint32_t ulBitsToClearOnEntry, + uint32_t ulBitsToClearOnExit, + uint32_t * pulNotificationValue, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGenericNotifyWaitImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskGenericNotifyWait_Unpriv \n" + " MPU_xTaskGenericNotifyWait_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskGenericNotifyWaitImpl \n" + " MPU_xTaskGenericNotifyWait_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskGenericNotifyWaitImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER_1 ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TASK_NOTIFICATIONS == 1 ) + +uint32_t MPU_ulTaskGenericNotifyTake( UBaseType_t uxIndexToWaitOn, + BaseType_t xClearCountOnExit, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +uint32_t MPU_ulTaskGenericNotifyTake( UBaseType_t uxIndexToWaitOn, + BaseType_t xClearCountOnExit, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_ulTaskGenericNotifyTakeImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_ulTaskGenericNotifyTake_Unpriv \n" + " MPU_ulTaskGenericNotifyTake_Priv: \n" + " pop {r0} \n" + " b MPU_ulTaskGenericNotifyTakeImpl \n" + " MPU_ulTaskGenericNotifyTake_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_ulTaskGenericNotifyTakeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TASK_NOTIFICATIONS == 1 ) + +BaseType_t MPU_xTaskGenericNotifyStateClear( TaskHandle_t xTask, + UBaseType_t uxIndexToClear ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskGenericNotifyStateClear( TaskHandle_t xTask, + UBaseType_t uxIndexToClear ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGenericNotifyStateClearImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskGenericNotifyStateClear_Unpriv \n" + " MPU_xTaskGenericNotifyStateClear_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskGenericNotifyStateClearImpl \n" + " MPU_xTaskGenericNotifyStateClear_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskGenericNotifyStateClearImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TASK_NOTIFICATIONS == 1 ) + +uint32_t MPU_ulTaskGenericNotifyValueClear( TaskHandle_t xTask, + UBaseType_t uxIndexToClear, + uint32_t ulBitsToClear ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +uint32_t MPU_ulTaskGenericNotifyValueClear( TaskHandle_t xTask, + UBaseType_t uxIndexToClear, + uint32_t ulBitsToClear ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_ulTaskGenericNotifyValueClearImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_ulTaskGenericNotifyValueClear_Unpriv \n" + " MPU_ulTaskGenericNotifyValueClear_Priv: \n" + " pop {r0} \n" + " b MPU_ulTaskGenericNotifyValueClearImpl \n" + " MPU_ulTaskGenericNotifyValueClear_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_ulTaskGenericNotifyValueClearImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xQueueGenericSend( QueueHandle_t xQueue, + const void * const pvItemToQueue, + TickType_t xTicksToWait, + const BaseType_t xCopyPosition ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueueGenericSend( QueueHandle_t xQueue, + const void * const pvItemToQueue, + TickType_t xTicksToWait, + const BaseType_t xCopyPosition ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueGenericSendImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xQueueGenericSend_Unpriv \n" + " MPU_xQueueGenericSend_Priv: \n" + " pop {r0} \n" + " b MPU_xQueueGenericSendImpl \n" + " MPU_xQueueGenericSend_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xQueueGenericSendImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +UBaseType_t MPU_uxQueueMessagesWaiting( const QueueHandle_t xQueue ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxQueueMessagesWaiting( const QueueHandle_t xQueue ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxQueueMessagesWaitingImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_uxQueueMessagesWaiting_Unpriv \n" + " MPU_uxQueueMessagesWaiting_Priv: \n" + " pop {r0} \n" + " b MPU_uxQueueMessagesWaitingImpl \n" + " MPU_uxQueueMessagesWaiting_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_uxQueueMessagesWaitingImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +UBaseType_t MPU_uxQueueSpacesAvailable( const QueueHandle_t xQueue ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxQueueSpacesAvailable( const QueueHandle_t xQueue ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxQueueSpacesAvailableImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_uxQueueSpacesAvailable_Unpriv \n" + " MPU_uxQueueSpacesAvailable_Priv: \n" + " pop {r0} \n" + " b MPU_uxQueueSpacesAvailableImpl \n" + " MPU_uxQueueSpacesAvailable_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_uxQueueSpacesAvailableImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xQueueReceive( QueueHandle_t xQueue, + void * const pvBuffer, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueueReceive( QueueHandle_t xQueue, + void * const pvBuffer, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueReceiveImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xQueueReceive_Unpriv \n" + " MPU_xQueueReceive_Priv: \n" + " pop {r0} \n" + " b MPU_xQueueReceiveImpl \n" + " MPU_xQueueReceive_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xQueueReceiveImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xQueuePeek( QueueHandle_t xQueue, + void * const pvBuffer, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueuePeek( QueueHandle_t xQueue, + void * const pvBuffer, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueuePeekImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xQueuePeek_Unpriv \n" + " MPU_xQueuePeek_Priv: \n" + " pop {r0} \n" + " b MPU_xQueuePeekImpl \n" + " MPU_xQueuePeek_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xQueuePeekImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xQueueSemaphoreTake( QueueHandle_t xQueue, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueueSemaphoreTake( QueueHandle_t xQueue, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueSemaphoreTakeImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xQueueSemaphoreTake_Unpriv \n" + " MPU_xQueueSemaphoreTake_Priv: \n" + " pop {r0} \n" + " b MPU_xQueueSemaphoreTakeImpl \n" + " MPU_xQueueSemaphoreTake_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xQueueSemaphoreTakeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +#if ( ( configUSE_MUTEXES == 1 ) && ( INCLUDE_xSemaphoreGetMutexHolder == 1 ) ) + +TaskHandle_t MPU_xQueueGetMutexHolder( QueueHandle_t xSemaphore ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TaskHandle_t MPU_xQueueGetMutexHolder( QueueHandle_t xSemaphore ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueGetMutexHolderImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xQueueGetMutexHolder_Unpriv \n" + " MPU_xQueueGetMutexHolder_Priv: \n" + " pop {r0} \n" + " b MPU_xQueueGetMutexHolderImpl \n" + " MPU_xQueueGetMutexHolder_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xQueueGetMutexHolderImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( ( configUSE_MUTEXES == 1 ) && ( INCLUDE_xSemaphoreGetMutexHolder == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_RECURSIVE_MUTEXES == 1 ) + +BaseType_t MPU_xQueueTakeMutexRecursive( QueueHandle_t xMutex, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueueTakeMutexRecursive( QueueHandle_t xMutex, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueTakeMutexRecursiveImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xQueueTakeMutexRecursive_Unpriv \n" + " MPU_xQueueTakeMutexRecursive_Priv: \n" + " pop {r0} \n" + " b MPU_xQueueTakeMutexRecursiveImpl \n" + " MPU_xQueueTakeMutexRecursive_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xQueueTakeMutexRecursiveImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_RECURSIVE_MUTEXES == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_RECURSIVE_MUTEXES == 1 ) + +BaseType_t MPU_xQueueGiveMutexRecursive( QueueHandle_t pxMutex ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueueGiveMutexRecursive( QueueHandle_t pxMutex ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueGiveMutexRecursiveImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xQueueGiveMutexRecursive_Unpriv \n" + " MPU_xQueueGiveMutexRecursive_Priv: \n" + " pop {r0} \n" + " b MPU_xQueueGiveMutexRecursiveImpl \n" + " MPU_xQueueGiveMutexRecursive_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xQueueGiveMutexRecursiveImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_RECURSIVE_MUTEXES == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_QUEUE_SETS == 1 ) + +QueueSetMemberHandle_t MPU_xQueueSelectFromSet( QueueSetHandle_t xQueueSet, + const TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +QueueSetMemberHandle_t MPU_xQueueSelectFromSet( QueueSetHandle_t xQueueSet, + const TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueSelectFromSetImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xQueueSelectFromSet_Unpriv \n" + " MPU_xQueueSelectFromSet_Priv: \n" + " pop {r0} \n" + " b MPU_xQueueSelectFromSetImpl \n" + " MPU_xQueueSelectFromSet_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xQueueSelectFromSetImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_QUEUE_SETS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_QUEUE_SETS == 1 ) + +BaseType_t MPU_xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore, + QueueSetHandle_t xQueueSet ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore, + QueueSetHandle_t xQueueSet ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueAddToSetImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xQueueAddToSet_Unpriv \n" + " MPU_xQueueAddToSet_Priv: \n" + " pop {r0} \n" + " b MPU_xQueueAddToSetImpl \n" + " MPU_xQueueAddToSet_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xQueueAddToSetImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_QUEUE_SETS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configQUEUE_REGISTRY_SIZE > 0 ) + +void MPU_vQueueAddToRegistry( QueueHandle_t xQueue, + const char * pcName ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vQueueAddToRegistry( QueueHandle_t xQueue, + const char * pcName ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vQueueAddToRegistryImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vQueueAddToRegistry_Unpriv \n" + " MPU_vQueueAddToRegistry_Priv: \n" + " pop {r0} \n" + " b MPU_vQueueAddToRegistryImpl \n" + " MPU_vQueueAddToRegistry_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vQueueAddToRegistryImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configQUEUE_REGISTRY_SIZE > 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configQUEUE_REGISTRY_SIZE > 0 ) + +void MPU_vQueueUnregisterQueue( QueueHandle_t xQueue ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vQueueUnregisterQueue( QueueHandle_t xQueue ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vQueueUnregisterQueueImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vQueueUnregisterQueue_Unpriv \n" + " MPU_vQueueUnregisterQueue_Priv: \n" + " pop {r0} \n" + " b MPU_vQueueUnregisterQueueImpl \n" + " MPU_vQueueUnregisterQueue_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vQueueUnregisterQueueImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configQUEUE_REGISTRY_SIZE > 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configQUEUE_REGISTRY_SIZE > 0 ) + +const char * MPU_pcQueueGetName( QueueHandle_t xQueue ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +const char * MPU_pcQueueGetName( QueueHandle_t xQueue ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_pcQueueGetNameImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_pcQueueGetName_Unpriv \n" + " MPU_pcQueueGetName_Priv: \n" + " pop {r0} \n" + " b MPU_pcQueueGetNameImpl \n" + " MPU_pcQueueGetName_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_pcQueueGetNameImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configQUEUE_REGISTRY_SIZE > 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +void * MPU_pvTimerGetTimerID( const TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void * MPU_pvTimerGetTimerID( const TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_pvTimerGetTimerIDImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_pvTimerGetTimerID_Unpriv \n" + " MPU_pvTimerGetTimerID_Priv: \n" + " pop {r0} \n" + " b MPU_pvTimerGetTimerIDImpl \n" + " MPU_pvTimerGetTimerID_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_pvTimerGetTimerIDImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +void MPU_vTimerSetTimerID( TimerHandle_t xTimer, + void * pvNewID ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTimerSetTimerID( TimerHandle_t xTimer, + void * pvNewID ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTimerSetTimerIDImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vTimerSetTimerID_Unpriv \n" + " MPU_vTimerSetTimerID_Priv: \n" + " pop {r0} \n" + " b MPU_vTimerSetTimerIDImpl \n" + " MPU_vTimerSetTimerID_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vTimerSetTimerIDImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +BaseType_t MPU_xTimerIsTimerActive( TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTimerIsTimerActive( TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTimerIsTimerActiveImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTimerIsTimerActive_Unpriv \n" + " MPU_xTimerIsTimerActive_Priv: \n" + " pop {r0} \n" + " b MPU_xTimerIsTimerActiveImpl \n" + " MPU_xTimerIsTimerActive_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTimerIsTimerActiveImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +TaskHandle_t MPU_xTimerGetTimerDaemonTaskHandle( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TaskHandle_t MPU_xTimerGetTimerDaemonTaskHandle( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTimerGetTimerDaemonTaskHandleImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTimerGetTimerDaemonTaskHandle_Unpriv \n" + " MPU_xTimerGetTimerDaemonTaskHandle_Priv: \n" + " pop {r0} \n" + " b MPU_xTimerGetTimerDaemonTaskHandleImpl \n" + " MPU_xTimerGetTimerDaemonTaskHandle_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTimerGetTimerDaemonTaskHandleImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +BaseType_t MPU_xTimerGenericCommand( TimerHandle_t xTimer, + const BaseType_t xCommandID, + const TickType_t xOptionalValue, + BaseType_t * const pxHigherPriorityTaskWoken, + const TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTimerGenericCommand( TimerHandle_t xTimer, + const BaseType_t xCommandID, + const TickType_t xOptionalValue, + BaseType_t * const pxHigherPriorityTaskWoken, + const TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTimerGenericCommandImpl \n" + " \n" + " push {r0} \n" + " mrs r0, ipsr \n" + " cmp r0, #0 \n" + " bne MPU_xTimerGenericCommand_Priv \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " beq MPU_xTimerGenericCommand_Priv \n" + " MPU_xTimerGenericCommand_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTimerGenericCommandImpl \n" + " svc %1 \n" + " bx lr \n" + " MPU_xTimerGenericCommand_Priv: \n" + " pop {r0} \n" + " b MPU_xTimerGenericCommandImpl \n" + " \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER_1 ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +const char * MPU_pcTimerGetName( TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +const char * MPU_pcTimerGetName( TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_pcTimerGetNameImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_pcTimerGetName_Unpriv \n" + " MPU_pcTimerGetName_Priv: \n" + " pop {r0} \n" + " b MPU_pcTimerGetNameImpl \n" + " MPU_pcTimerGetName_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_pcTimerGetNameImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, + const BaseType_t uxAutoReload ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, + const BaseType_t uxAutoReload ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTimerSetReloadModeImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vTimerSetReloadMode_Unpriv \n" + " MPU_vTimerSetReloadMode_Priv: \n" + " pop {r0} \n" + " b MPU_vTimerSetReloadModeImpl \n" + " MPU_vTimerSetReloadMode_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vTimerSetReloadModeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +BaseType_t MPU_xTimerGetReloadMode( TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTimerGetReloadMode( TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTimerGetReloadModeImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTimerGetReloadMode_Unpriv \n" + " MPU_xTimerGetReloadMode_Priv: \n" + " pop {r0} \n" + " b MPU_xTimerGetReloadModeImpl \n" + " MPU_xTimerGetReloadMode_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTimerGetReloadModeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +UBaseType_t MPU_uxTimerGetReloadMode( TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxTimerGetReloadMode( TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxTimerGetReloadModeImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_uxTimerGetReloadMode_Unpriv \n" + " MPU_uxTimerGetReloadMode_Priv: \n" + " pop {r0} \n" + " b MPU_uxTimerGetReloadModeImpl \n" + " MPU_uxTimerGetReloadMode_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_uxTimerGetReloadModeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +TickType_t MPU_xTimerGetPeriod( TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TickType_t MPU_xTimerGetPeriod( TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTimerGetPeriodImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTimerGetPeriod_Unpriv \n" + " MPU_xTimerGetPeriod_Priv: \n" + " pop {r0} \n" + " b MPU_xTimerGetPeriodImpl \n" + " MPU_xTimerGetPeriod_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTimerGetPeriodImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +TickType_t MPU_xTimerGetExpiryTime( TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TickType_t MPU_xTimerGetExpiryTime( TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTimerGetExpiryTimeImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTimerGetExpiryTime_Unpriv \n" + " MPU_xTimerGetExpiryTime_Priv: \n" + " pop {r0} \n" + " b MPU_xTimerGetExpiryTimeImpl \n" + " MPU_xTimerGetExpiryTime_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTimerGetExpiryTimeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +EventBits_t MPU_xEventGroupWaitBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToWaitFor, + const BaseType_t xClearOnExit, + const BaseType_t xWaitForAllBits, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +EventBits_t MPU_xEventGroupWaitBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToWaitFor, + const BaseType_t xClearOnExit, + const BaseType_t xWaitForAllBits, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupWaitBitsImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xEventGroupWaitBits_Unpriv \n" + " MPU_xEventGroupWaitBits_Priv: \n" + " pop {r0} \n" + " b MPU_xEventGroupWaitBitsImpl \n" + " MPU_xEventGroupWaitBits_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xEventGroupWaitBitsImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER_1 ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToClear ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToClear ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupClearBitsImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xEventGroupClearBits_Unpriv \n" + " MPU_xEventGroupClearBits_Priv: \n" + " pop {r0} \n" + " b MPU_xEventGroupClearBitsImpl \n" + " MPU_xEventGroupClearBits_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xEventGroupClearBitsImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupSetBitsImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xEventGroupSetBits_Unpriv \n" + " MPU_xEventGroupSetBits_Priv: \n" + " pop {r0} \n" + " b MPU_xEventGroupSetBitsImpl \n" + " MPU_xEventGroupSetBits_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xEventGroupSetBitsImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet, + const EventBits_t uxBitsToWaitFor, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet, + const EventBits_t uxBitsToWaitFor, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupSyncImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xEventGroupSync_Unpriv \n" + " MPU_xEventGroupSync_Priv: \n" + " pop {r0} \n" + " b MPU_xEventGroupSyncImpl \n" + " MPU_xEventGroupSync_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xEventGroupSyncImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + +UBaseType_t MPU_uxEventGroupGetNumber( void * xEventGroup ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxEventGroupGetNumber( void * xEventGroup ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxEventGroupGetNumberImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_uxEventGroupGetNumber_Unpriv \n" + " MPU_uxEventGroupGetNumber_Priv: \n" + " pop {r0} \n" + " b MPU_uxEventGroupGetNumberImpl \n" + " MPU_uxEventGroupGetNumber_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_uxEventGroupGetNumberImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /*( configUSE_TRACE_FACILITY == 1 )*/ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + +void MPU_vEventGroupSetNumber( void * xEventGroup, + UBaseType_t uxEventGroupNumber ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vEventGroupSetNumber( void * xEventGroup, + UBaseType_t uxEventGroupNumber ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vEventGroupSetNumberImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vEventGroupSetNumber_Unpriv \n" + " MPU_vEventGroupSetNumber_Priv: \n" + " pop {r0} \n" + " b MPU_vEventGroupSetNumberImpl \n" + " MPU_vEventGroupSetNumber_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vEventGroupSetNumberImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /*( configUSE_TRACE_FACILITY == 1 )*/ +/*-----------------------------------------------------------*/ + +size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, + const void * pvTxData, + size_t xDataLengthBytes, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, + const void * pvTxData, + size_t xDataLengthBytes, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferSendImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferSend_Unpriv \n" + " MPU_xStreamBufferSend_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferSendImpl \n" + " MPU_xStreamBufferSend_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xStreamBufferSendImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, + void * pvRxData, + size_t xBufferLengthBytes, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, + void * pvRxData, + size_t xBufferLengthBytes, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferReceiveImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferReceive_Unpriv \n" + " MPU_xStreamBufferReceive_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferReceiveImpl \n" + " MPU_xStreamBufferReceive_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xStreamBufferReceiveImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferIsFullImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferIsFull_Unpriv \n" + " MPU_xStreamBufferIsFull_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferIsFullImpl \n" + " MPU_xStreamBufferIsFull_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xStreamBufferIsFullImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferIsEmptyImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferIsEmpty_Unpriv \n" + " MPU_xStreamBufferIsEmpty_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferIsEmptyImpl \n" + " MPU_xStreamBufferIsEmpty_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xStreamBufferIsEmptyImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferSpacesAvailableImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferSpacesAvailable_Unpriv \n" + " MPU_xStreamBufferSpacesAvailable_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferSpacesAvailableImpl \n" + " MPU_xStreamBufferSpacesAvailable_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xStreamBufferSpacesAvailableImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferBytesAvailableImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferBytesAvailable_Unpriv \n" + " MPU_xStreamBufferBytesAvailable_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferBytesAvailableImpl \n" + " MPU_xStreamBufferBytesAvailable_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xStreamBufferBytesAvailableImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, + size_t xTriggerLevel ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, + size_t xTriggerLevel ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferSetTriggerLevelImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferSetTriggerLevel_Unpriv \n" + " MPU_xStreamBufferSetTriggerLevel_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferSetTriggerLevelImpl \n" + " MPU_xStreamBufferSetTriggerLevel_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xStreamBufferSetTriggerLevelImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferNextMessageLengthBytesImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferNextMessageLengthBytes_Unpriv \n" + " MPU_xStreamBufferNextMessageLengthBytes_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferNextMessageLengthBytesImpl \n" + " MPU_xStreamBufferNextMessageLengthBytes_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xStreamBufferNextMessageLengthBytesImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ diff --git a/portable/GCC/ARM_CM35P_NTZ/non_secure/port.c b/portable/GCC/ARM_CM35P_NTZ/non_secure/port.c index 7bbe1b7bc53..cab1b3668bf 100644 --- a/portable/GCC/ARM_CM35P_NTZ/non_secure/port.c +++ b/portable/GCC/ARM_CM35P_NTZ/non_secure/port.c @@ -107,6 +107,13 @@ #define portPRIGROUP_SHIFT ( 8UL ) /*-----------------------------------------------------------*/ +/** + * @brief Constants used during system call enter and exit. + */ +#define portPSR_STACK_PADDING_MASK ( 1UL << 9UL ) +#define portEXC_RETURN_STACK_FRAME_TYPE_MASK ( 1UL << 4UL ) +/*-----------------------------------------------------------*/ + /** * @brief Constants required to manipulate the FPU. */ @@ -123,6 +130,14 @@ #define portFPCCR_LSPEN_MASK ( 1UL << portFPCCR_LSPEN_POS ) /*-----------------------------------------------------------*/ +/** + * @brief Offsets in the stack to the parameters when inside the SVC handler. + */ +#define portOFFSET_TO_LR ( 5 ) +#define portOFFSET_TO_PC ( 6 ) +#define portOFFSET_TO_PSR ( 7 ) +/*-----------------------------------------------------------*/ + /** * @brief Constants required to manipulate the MPU. */ @@ -148,6 +163,8 @@ #define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ #define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ +#define portMPU_RBAR_ACCESS_PERMISSIONS_MASK ( 3UL << 1UL ) + #define portMPU_MAIR_ATTR0_POS ( 0UL ) #define portMPU_MAIR_ATTR0_MASK ( 0x000000ff ) @@ -191,6 +208,30 @@ /* Expected value of the portMPU_TYPE register. */ #define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) + +/* Extract first address of the MPU region as encoded in the + * RBAR (Region Base Address Register) value. */ +#define portEXTRACT_FIRST_ADDRESS_FROM_RBAR( rbar ) \ + ( ( rbar ) & portMPU_RBAR_ADDRESS_MASK ) + +/* Extract last address of the MPU region as encoded in the + * RLAR (Region Limit Address Register) value. */ +#define portEXTRACT_LAST_ADDRESS_FROM_RLAR( rlar ) \ + ( ( ( rlar ) & portMPU_RLAR_ADDRESS_MASK ) | ~portMPU_RLAR_ADDRESS_MASK ) + +/* Does addr lies within [start, end] address range? */ +#define portIS_ADDRESS_WITHIN_RANGE( addr, start, end ) \ + ( ( ( addr ) >= ( start ) ) && ( ( addr ) <= ( end ) ) ) + +/* Is the access request satisfied by the available permissions? */ +#define portIS_AUTHORIZED( accessRequest, permissions ) \ + ( ( ( permissions ) & ( accessRequest ) ) == accessRequest ) + +/* 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 ) ) ) /*-----------------------------------------------------------*/ /** @@ -311,6 +352,19 @@ static void prvTaskExitError( void ); #if ( configENABLE_MPU == 1 ) +/** + * @brief Extract MPU region's access permissions from the Region Base Address + * Register (RBAR) value. + * + * @param ulRBARValue RBAR value for the MPU region. + * + * @return uint32_t Access permissions. + */ + static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) PRIVILEGED_FUNCTION; +#endif /* configENABLE_MPU */ + +#if ( configENABLE_MPU == 1 ) + /** * @brief Setup the Memory Protection Unit (MPU). */ @@ -365,6 +419,60 @@ void SysTick_Handler( void ) PRIVILEGED_FUNCTION; * @brief C part of SVC handler. */ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIVILEGED_FUNCTION; + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + + /** + * @brief Sets up the system call stack so that upon returning from + * SVC, the system call stack is used. + * + * It is used for the system calls with up to 4 parameters. + * + * @param pulTaskStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + */ + void vSystemCallEnter( uint32_t * pulTaskStack, uint32_t ulLR ) PRIVILEGED_FUNCTION; + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + + /** + * @brief Sets up the system call stack so that upon returning from + * SVC, the system call stack is used. + * + * It is used for the system calls with 5 parameters. + * + * @param pulTaskStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + */ + void vSystemCallEnter_1( uint32_t * pulTaskStack, uint32_t ulLR ) PRIVILEGED_FUNCTION; + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + + /** + * @brief Sets up the task stack so that upon returning from + * SVC, the task stack is used again. + * + * @param pulSystemCallStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + */ + void vSystemCallExit( uint32_t * pulSystemCallStack, uint32_t ulLR ) PRIVILEGED_FUNCTION; + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + +#if ( configENABLE_MPU == 1 ) + + /** + * @brief Checks whether or not the calling task is privileged. + * + * @return pdTRUE if the calling task is privileged, pdFALSE otherwise. + */ + BaseType_t xPortIsTaskPrivileged( void ) PRIVILEGED_FUNCTION; + +#endif /* configENABLE_MPU == 1 */ /*-----------------------------------------------------------*/ /** @@ -681,6 +789,26 @@ static void prvTaskExitError( void ) } /*-----------------------------------------------------------*/ +#if ( configENABLE_MPU == 1 ) + static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) /* PRIVILEGED_FUNCTION */ + { + uint32_t ulAccessPermissions = 0; + + if( ( ulRBARValue & portMPU_RBAR_ACCESS_PERMISSIONS_MASK ) == portMPU_REGION_READ_ONLY ) + { + ulAccessPermissions = tskMPU_READ_PERMISSION; + } + + if( ( ulRBARValue & portMPU_RBAR_ACCESS_PERMISSIONS_MASK ) == portMPU_REGION_READ_WRITE ) + { + ulAccessPermissions = ( tskMPU_READ_PERMISSION | tskMPU_WRITE_PERMISSION ); + } + + return ulAccessPermissions; + } +#endif /* configENABLE_MPU */ +/*-----------------------------------------------------------*/ + #if ( configENABLE_MPU == 1 ) static void prvSetupMPU( void ) /* PRIVILEGED_FUNCTION */ { @@ -853,7 +981,7 @@ void SysTick_Handler( void ) /* PRIVILEGED_FUNCTION */ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTION portDONT_DISCARD */ { - #if ( configENABLE_MPU == 1 ) + #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) ) #if defined( __ARMCC_VERSION ) /* Declaration when these variable are defined in code instead of being @@ -865,7 +993,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO extern uint32_t __syscalls_flash_start__[]; extern uint32_t __syscalls_flash_end__[]; #endif /* defined( __ARMCC_VERSION ) */ - #endif /* configENABLE_MPU */ + #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */ uint32_t ulPC; @@ -880,7 +1008,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO /* Register are stored on the stack in the following order - R0, R1, R2, R3, * R12, LR, PC, xPSR. */ - ulPC = pulCallerStackAddress[ 6 ]; + ulPC = pulCallerStackAddress[ portOFFSET_TO_PC ]; ucSVCNumber = ( ( uint8_t * ) ulPC )[ -2 ]; switch( ucSVCNumber ) @@ -951,18 +1079,18 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO vRestoreContextOfFirstTask(); break; - #if ( configENABLE_MPU == 1 ) - case portSVC_RAISE_PRIVILEGE: + #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) ) + case portSVC_RAISE_PRIVILEGE: - /* Only raise the privilege, if the svc was raised from any of - * the system calls. */ - if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) && - ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ) - { - vRaisePrivilege(); - } - break; - #endif /* configENABLE_MPU */ + /* Only raise the privilege, if the svc was raised from any of + * the system calls. */ + if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ) + { + vRaisePrivilege(); + } + break; + #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */ default: /* Incorrect SVC call. */ @@ -971,51 +1099,455 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } /*-----------------------------------------------------------*/ -/* *INDENT-OFF* */ -#if ( configENABLE_MPU == 1 ) - StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, - StackType_t * pxEndOfStack, - TaskFunction_t pxCode, - void * pvParameters, - BaseType_t xRunPrivileged ) /* PRIVILEGED_FUNCTION */ -#else - StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, - StackType_t * pxEndOfStack, - TaskFunction_t pxCode, - void * pvParameters ) /* PRIVILEGED_FUNCTION */ -#endif /* configENABLE_MPU */ -/* *INDENT-ON* */ +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + +void vSystemCallEnter( uint32_t * pulTaskStack, uint32_t ulLR ) /* PRIVILEGED_FUNCTION */ { - /* Simulate the stack frame as it would be created by a context switch - * interrupt. */ - #if ( portPRELOAD_REGISTERS == 0 ) + extern TaskHandle_t pxCurrentTCB; + xMPU_SETTINGS * pxMpuSettings; + uint32_t * pulSystemCallStack; + uint32_t ulStackFrameSize, ulSystemCallLocation, i; + #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being + * exported from linker scripts. */ + extern uint32_t * __syscalls_flash_start__; + extern uint32_t * __syscalls_flash_end__; + #else + /* Declaration when these variable are exported from linker scripts. */ + extern uint32_t __syscalls_flash_start__[]; + extern uint32_t __syscalls_flash_end__[]; + #endif /* #if defined( __ARMCC_VERSION ) */ + + ulSystemCallLocation = pulTaskStack[ portOFFSET_TO_PC ]; + + /* If the request did not come from the system call section, do nothing. */ + if( ( ulSystemCallLocation >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulSystemCallLocation <= ( uint32_t ) __syscalls_flash_end__ ) ) { - pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ - *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ - pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pxCode; /* PC */ - pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR */ - pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ - *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ - pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */ - *pxTopOfStack = portINITIAL_EXC_RETURN; + pxMpuSettings = xTaskGetMPUSettings( pxCurrentTCB ); + pulSystemCallStack = pxMpuSettings->xSystemCallStackInfo.pulSystemCallStack; - #if ( configENABLE_MPU == 1 ) + /* This is not NULL only for the duration of the system call. */ + configASSERT( pxMpuSettings->xSystemCallStackInfo.pulTaskStack == NULL ); + + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) { - pxTopOfStack--; + if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) + { + /* Extended frame i.e. FPU in use. */ + ulStackFrameSize = 26; + __asm volatile ( + " vpush {s0} \n" /* Trigger lazy stacking. */ + " vpop {s0} \n" /* Nullify the affect of the above instruction. */ + ::: "memory" + ); + } + else + { + /* Standard frame i.e. FPU not in use. */ + ulStackFrameSize = 8; + } + } + #else + { + ulStackFrameSize = 8; + } + #endif /* configENABLE_FPU || configENABLE_MVE */ + + /* Make space on the system call stack for the stack frame. */ + pulSystemCallStack = pulSystemCallStack - ulStackFrameSize; + + /* Copy the stack frame. */ + for( i = 0; i < ulStackFrameSize; i++ ) + { + pulSystemCallStack[ i ] = pulTaskStack[ i ]; + } + + /* Store the value of the LR and PSPLIM registers before the SVC was raised. We need to + * restore it when we exit from the system call. */ + pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; + __asm volatile ( "mrs %0, psplim" : "=r" ( pxMpuSettings->xSystemCallStackInfo.ulStackLimitRegisterAtSystemCallEntry ) ); + + /* Use the pulSystemCallStack in thread mode. */ + __asm volatile ( "msr psp, %0" : : "r" ( pulSystemCallStack ) ); + __asm volatile ( "msr psplim, %0" : : "r" ( pxMpuSettings->xSystemCallStackInfo.pulSystemCallStackLimit ) ); + + /* Remember the location where we should copy the stack frame when we exit from + * the system call. */ + pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulStackFrameSize; + + /* Record if the hardware used padding to force the stack pointer + * to be double word aligned. */ + if( ( pulTaskStack[ portOFFSET_TO_PSR ] & portPSR_STACK_PADDING_MASK ) == portPSR_STACK_PADDING_MASK ) + { + pxMpuSettings->ulTaskFlags |= portSTACK_FRAME_HAS_PADDING_FLAG; + } + else + { + pxMpuSettings->ulTaskFlags &= ( ~portSTACK_FRAME_HAS_PADDING_FLAG ); + } + + /* We ensure in pxPortInitialiseStack that the system call stack is + * double word aligned and therefore, there is no need of padding. + * Clear the bit[9] of stacked xPSR. */ + pulSystemCallStack[ portOFFSET_TO_PSR ] &= ( ~portPSR_STACK_PADDING_MASK ); + + /* Raise the privilege for the duration of the system call. */ + __asm volatile ( + " mrs r0, control \n" /* Obtain current control value. */ + " movs r1, #1 \n" /* r1 = 1. */ + " bics r0, r1 \n" /* Clear nPRIV bit. */ + " msr control, r0 \n" /* Write back new control value. */ + ::: "r0", "r1", "memory" + ); + } +} - if( xRunPrivileged == pdTRUE ) +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + +void vSystemCallEnter_1( uint32_t * pulTaskStack, uint32_t ulLR ) /* PRIVILEGED_FUNCTION */ +{ + extern TaskHandle_t pxCurrentTCB; + xMPU_SETTINGS * pxMpuSettings; + uint32_t * pulSystemCallStack; + uint32_t ulStackFrameSize, ulSystemCallLocation, i; + #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being + * exported from linker scripts. */ + extern uint32_t * __syscalls_flash_start__; + extern uint32_t * __syscalls_flash_end__; + #else + /* Declaration when these variable are exported from linker scripts. */ + extern uint32_t __syscalls_flash_start__[]; + extern uint32_t __syscalls_flash_end__[]; + #endif /* #if defined( __ARMCC_VERSION ) */ + + ulSystemCallLocation = pulTaskStack[ portOFFSET_TO_PC ]; + + /* If the request did not come from the system call section, do nothing. */ + if( ( ulSystemCallLocation >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulSystemCallLocation <= ( uint32_t ) __syscalls_flash_end__ ) ) + { + pxMpuSettings = xTaskGetMPUSettings( pxCurrentTCB ); + pulSystemCallStack = pxMpuSettings->xSystemCallStackInfo.pulSystemCallStack; + + /* This is not NULL only for the duration of the system call. */ + configASSERT( pxMpuSettings->xSystemCallStackInfo.pulTaskStack == NULL ); + + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + { + if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) { - *pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */ + /* Extended frame i.e. FPU in use. */ + ulStackFrameSize = 26; + __asm volatile ( + " vpush {s0} \n" /* Trigger lazy stacking. */ + " vpop {s0} \n" /* Nullify the affect of the above instruction. */ + ::: "memory" + ); } else { - *pxTopOfStack = portINITIAL_CONTROL_UNPRIVILEGED; /* Slot used to hold this task's CONTROL value. */ + /* Standard frame i.e. FPU not in use. */ + ulStackFrameSize = 8; } } - #endif /* configENABLE_MPU */ + #else + { + ulStackFrameSize = 8; + } + #endif /* configENABLE_FPU || configENABLE_MVE */ + + /* Make space on the system call stack for the stack frame and + * the parameter passed on the stack. We only need to copy one + * parameter but we still reserve 2 spaces to keep the stack + * double word aligned. */ + pulSystemCallStack = pulSystemCallStack - ulStackFrameSize - 2UL; + + /* Copy the stack frame. */ + for( i = 0; i < ulStackFrameSize; i++ ) + { + pulSystemCallStack[ i ] = pulTaskStack[ i ]; + } + + /* Copy the parameter which is passed the stack. */ + if( ( pulTaskStack[ portOFFSET_TO_PSR ] & portPSR_STACK_PADDING_MASK ) == portPSR_STACK_PADDING_MASK ) + { + pulSystemCallStack[ ulStackFrameSize ] = pulTaskStack[ ulStackFrameSize + 1 ]; + /* Record if the hardware used padding to force the stack pointer + * to be double word aligned. */ + pxMpuSettings->ulTaskFlags |= portSTACK_FRAME_HAS_PADDING_FLAG; + } + else + { + pulSystemCallStack[ ulStackFrameSize ] = pulTaskStack[ ulStackFrameSize ]; + /* Record if the hardware used padding to force the stack pointer + * to be double word aligned. */ + pxMpuSettings->ulTaskFlags &= ( ~portSTACK_FRAME_HAS_PADDING_FLAG ); + } + + /* Store the value of the LR and PSPLIM registers before the SVC was raised. + * We need to restore it when we exit from the system call. */ + pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; + __asm volatile ( "mrs %0, psplim" : "=r" ( pxMpuSettings->xSystemCallStackInfo.ulStackLimitRegisterAtSystemCallEntry ) ); + + /* Use the pulSystemCallStack in thread mode. */ + __asm volatile ( "msr psp, %0" : : "r" ( pulSystemCallStack ) ); + __asm volatile ( "msr psplim, %0" : : "r" ( pxMpuSettings->xSystemCallStackInfo.pulSystemCallStackLimit ) ); + + /* Remember the location where we should copy the stack frame when we exit from + * the system call. */ + pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulStackFrameSize; + + /* We ensure in pxPortInitialiseStack that the system call stack is + * double word aligned and therefore, there is no need of padding. + * Clear the bit[9] of stacked xPSR. */ + pulSystemCallStack[ portOFFSET_TO_PSR ] &= ( ~portPSR_STACK_PADDING_MASK ); + + /* Raise the privilege for the duration of the system call. */ + __asm volatile ( + " mrs r0, control \n" /* Obtain current control value. */ + " movs r1, #1 \n" /* r1 = 1. */ + " bics r0, r1 \n" /* Clear nPRIV bit. */ + " msr control, r0 \n" /* Write back new control value. */ + ::: "r0", "r1", "memory" + ); + } +} + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) +void vSystemCallExit( uint32_t * pulSystemCallStack, uint32_t ulLR ) /* PRIVILEGED_FUNCTION */ +{ + extern TaskHandle_t pxCurrentTCB; + xMPU_SETTINGS * pxMpuSettings; + uint32_t * pulTaskStack; + uint32_t ulStackFrameSize, ulSystemCallLocation, i; + #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being + * exported from linker scripts. */ + extern uint32_t * __syscalls_flash_start__; + extern uint32_t * __syscalls_flash_end__; + #else + /* Declaration when these variable are exported from linker scripts. */ + extern uint32_t __syscalls_flash_start__[]; + extern uint32_t __syscalls_flash_end__[]; + #endif /* #if defined( __ARMCC_VERSION ) */ + + ulSystemCallLocation = pulSystemCallStack[ portOFFSET_TO_PC ]; + + /* If the request did not come from the system call section, do nothing. */ + if( ( ulSystemCallLocation >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulSystemCallLocation <= ( uint32_t ) __syscalls_flash_end__ ) ) + { + pxMpuSettings = xTaskGetMPUSettings( pxCurrentTCB ); + pulTaskStack = pxMpuSettings->xSystemCallStackInfo.pulTaskStack; + + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + { + if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) + { + /* Extended frame i.e. FPU in use. */ + ulStackFrameSize = 26; + __asm volatile ( + " vpush {s0} \n" /* Trigger lazy stacking. */ + " vpop {s0} \n" /* Nullify the affect of the above instruction. */ + ::: "memory" + ); + } + else + { + /* Standard frame i.e. FPU not in use. */ + ulStackFrameSize = 8; + } + } + #else + { + ulStackFrameSize = 8; + } + #endif /* configENABLE_FPU || configENABLE_MVE */ + + /* Make space on the task stack for the stack frame. */ + pulTaskStack = pulTaskStack - ulStackFrameSize; + + /* Copy the stack frame. */ + for( i = 0; i < ulStackFrameSize; i++ ) + { + pulTaskStack[ i ] = pulSystemCallStack[ i ]; + } + + /* Use the pulTaskStack in thread mode. */ + __asm volatile ( "msr psp, %0" : : "r" ( pulTaskStack ) ); + + /* Restore the LR and PSPLIM to what they were at the time of + * system call entry. */ + pulTaskStack[ portOFFSET_TO_LR ] = pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry; + __asm volatile ( "msr psplim, %0" : : "r" ( pxMpuSettings->xSystemCallStackInfo.ulStackLimitRegisterAtSystemCallEntry ) ); + + /* If the hardware used padding to force the stack pointer + * to be double word aligned, set the stacked xPSR bit[9], + * otherwise clear it. */ + if( ( pxMpuSettings->ulTaskFlags & portSTACK_FRAME_HAS_PADDING_FLAG ) == portSTACK_FRAME_HAS_PADDING_FLAG ) + { + pulTaskStack[ portOFFSET_TO_PSR ] |= portPSR_STACK_PADDING_MASK; + } + else + { + pulTaskStack[ portOFFSET_TO_PSR ] &= ( ~portPSR_STACK_PADDING_MASK ); + } + + /* This is not NULL only for the duration of the system call. */ + pxMpuSettings->xSystemCallStackInfo.pulTaskStack = NULL; + + /* Drop the privilege before returning to the thread mode. */ + __asm volatile ( + " mrs r0, control \n" /* Obtain current control value. */ + " movs r1, #1 \n" /* r1 = 1. */ + " orrs r0, r1 \n" /* Set nPRIV bit. */ + " msr control, r0 \n" /* Write back new control value. */ + ::: "r0", "r1", "memory" + ); + } +} + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configENABLE_MPU == 1 ) + +BaseType_t xPortIsTaskPrivileged( void ) /* PRIVILEGED_FUNCTION */ +{ + BaseType_t xTaskIsPrivileged = pdFALSE; + const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */ + + if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) + { + xTaskIsPrivileged = pdTRUE; + } + + return xTaskIsPrivileged; +} + +#endif /* configENABLE_MPU == 1 */ +/*-----------------------------------------------------------*/ + +#if( configENABLE_MPU == 1 ) + +StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, + StackType_t * pxEndOfStack, + TaskFunction_t pxCode, + void * pvParameters, + BaseType_t xRunPrivileged, + xMPU_SETTINGS * xMPUSettings ) /* PRIVILEGED_FUNCTION */ +{ + uint32_t ulIndex = 0; + + xMPUSettings->ulContext[ ulIndex ] = 0x04040404; /* r4. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x05050505; /* r5. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x06060606; /* r6. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x07070707; /* r7. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x08080808; /* r8. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x09090909; /* r9. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x10101010; /* r10. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x11111111; /* r11. */ + ulIndex++; + + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pvParameters; /* r0. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x01010101; /* r1. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x02020202; /* r2. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x03030303; /* r3. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x12121212; /* r12. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portTASK_RETURN_ADDRESS; /* LR. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxCode; /* PC. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = portINITIAL_XPSR; /* xPSR. */ + ulIndex++; + + #if ( configENABLE_TRUSTZONE == 1 ) + { + xMPUSettings->ulContext[ ulIndex ] = portNO_SECURE_CONTEXT; /* xSecureContext. */ + ulIndex++; + } + #endif /* configENABLE_TRUSTZONE */ + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) ( pxTopOfStack - 8 ); /* PSP with the hardware saved stack. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */ + ulIndex++; + if( xRunPrivileged == pdTRUE ) + { + xMPUSettings->ulTaskFlags |= portTASK_IS_PRIVILEGED_FLAG; + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_PRIVILEGED; /* CONTROL. */ + ulIndex++; + } + else + { + xMPUSettings->ulTaskFlags &= ( ~portTASK_IS_PRIVILEGED_FLAG ); + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_UNPRIVILEGED; /* CONTROL. */ + ulIndex++; + } + xMPUSettings->ulContext[ ulIndex ] = portINITIAL_EXC_RETURN; /* LR (EXC_RETURN). */ + ulIndex++; + + #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + { + /* Ensure that the system call stack is double word aligned. */ + xMPUSettings->xSystemCallStackInfo.pulSystemCallStack = &( xMPUSettings->xSystemCallStackInfo.ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE - 1 ] ); + xMPUSettings->xSystemCallStackInfo.pulSystemCallStack = ( uint32_t * ) ( ( uint32_t ) ( xMPUSettings->xSystemCallStackInfo.pulSystemCallStack ) & + ( uint32_t ) ( ~( portBYTE_ALIGNMENT_MASK ) ) ); + + xMPUSettings->xSystemCallStackInfo.pulSystemCallStackLimit = &( xMPUSettings->xSystemCallStackInfo.ulSystemCallStackBuffer[ 0 ] ); + xMPUSettings->xSystemCallStackInfo.pulSystemCallStackLimit = ( uint32_t * ) ( ( ( uint32_t ) ( xMPUSettings->xSystemCallStackInfo.pulSystemCallStackLimit ) + + ( uint32_t ) ( portBYTE_ALIGNMENT - 1 ) ) & + ( uint32_t ) ( ~( portBYTE_ALIGNMENT_MASK ) ) ); + + /* This is not NULL only for the duration of a system call. */ + xMPUSettings->xSystemCallStackInfo.pulTaskStack = NULL; + } + #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + + return &( xMPUSettings->ulContext[ ulIndex ] ); +} + +#else /* configENABLE_MPU */ + +StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, + StackType_t * pxEndOfStack, + TaskFunction_t pxCode, + void * pvParameters ) /* PRIVILEGED_FUNCTION */ +{ + /* Simulate the stack frame as it would be created by a context switch + * interrupt. */ + #if ( portPRELOAD_REGISTERS == 0 ) + { + pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ + *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR. */ + pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ + pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */ + *pxTopOfStack = portINITIAL_EXC_RETURN; pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ @@ -1029,55 +1561,39 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO #else /* portPRELOAD_REGISTERS */ { pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ - *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ + *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pxCode; /* PC */ + *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR */ + *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x12121212UL; /* R12 */ + *pxTopOfStack = ( StackType_t ) 0x12121212UL; /* R12. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x03030303UL; /* R3 */ + *pxTopOfStack = ( StackType_t ) 0x03030303UL; /* R3. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x02020202UL; /* R2 */ + *pxTopOfStack = ( StackType_t ) 0x02020202UL; /* R2. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x01010101UL; /* R1 */ + *pxTopOfStack = ( StackType_t ) 0x01010101UL; /* R1. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x11111111UL; /* R11 */ + *pxTopOfStack = ( StackType_t ) 0x11111111UL; /* R11. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x10101010UL; /* R10 */ + *pxTopOfStack = ( StackType_t ) 0x10101010UL; /* R10. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x09090909UL; /* R09 */ + *pxTopOfStack = ( StackType_t ) 0x09090909UL; /* R09. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x08080808UL; /* R08 */ + *pxTopOfStack = ( StackType_t ) 0x08080808UL; /* R08. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x07070707UL; /* R07 */ + *pxTopOfStack = ( StackType_t ) 0x07070707UL; /* R07. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x06060606UL; /* R06 */ + *pxTopOfStack = ( StackType_t ) 0x06060606UL; /* R06. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x05050505UL; /* R05 */ + *pxTopOfStack = ( StackType_t ) 0x05050505UL; /* R05. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x04040404UL; /* R04 */ + *pxTopOfStack = ( StackType_t ) 0x04040404UL; /* R04. */ pxTopOfStack--; - *pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN */ - - #if ( configENABLE_MPU == 1 ) - { - pxTopOfStack--; - - if( xRunPrivileged == pdTRUE ) - { - *pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */ - } - else - { - *pxTopOfStack = portINITIAL_CONTROL_UNPRIVILEGED; /* Slot used to hold this task's CONTROL value. */ - } - } - #endif /* configENABLE_MPU */ - + *pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN. */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ @@ -1092,6 +1608,8 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO return pxTopOfStack; } + +#endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ @@ -1128,6 +1646,10 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ configASSERT( ucMaxSysCallPriority ); + /* Check that the bits not implemented in hardware are zero in + * configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & ( ~ucMaxPriorityValue ) ) == 0U ); + /* Calculate the maximum acceptable priority group value for the number * of bits read back. */ @@ -1164,35 +1686,6 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulImplementedPrioBits; } - /* The interrupt priority bits are not modelled in QEMU and the assert that - * checks the number of implemented bits and __NVIC_PRIO_BITS will always fail. - * Therefore, this assert is not adding any value for QEMU targets. The config - * option `configDISABLE_INTERRUPT_PRIO_BITS_CHECK` should be defined in the - * `FreeRTOSConfig.h` for QEMU targets. */ - #ifndef configDISABLE_INTERRUPT_PRIO_BITS_CHECK - { - #ifdef __NVIC_PRIO_BITS - { - /* - * Check that the number of implemented priority bits queried from - * hardware is equal to the CMSIS __NVIC_PRIO_BITS configuration macro. - */ - configASSERT( ulImplementedPrioBits == __NVIC_PRIO_BITS ); - } - #endif /* __NVIC_PRIO_BITS */ - - #ifdef configPRIO_BITS - { - /* - * Check that the number of implemented priority bits queried from - * hardware is equal to the FreeRTOS configPRIO_BITS configuration macro. - */ - configASSERT( ulImplementedPrioBits == configPRIO_BITS ); - } - #endif /* configPRIO_BITS */ - } - #endif /* #ifndef configDISABLE_INTERRUPT_PRIO_BITS_CHECK */ - /* Shift the priority group value back to its position within the AIRCR * register. */ ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT; @@ -1372,6 +1865,54 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ +#if ( configENABLE_MPU == 1 ) + BaseType_t xPortIsAuthorizedToAccessBuffer( const void * pvBuffer, + uint32_t ulBufferLength, + uint32_t ulAccessRequested ) /* PRIVILEGED_FUNCTION */ + + { + uint32_t i, ulBufferStartAddress, ulBufferEndAddress; + BaseType_t xAccessGranted = pdFALSE; + const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */ + + if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) + { + xAccessGranted = pdTRUE; + } + else + { + if( portADD_UINT32_WILL_OVERFLOW( ( ( uint32_t ) pvBuffer ), ( ulBufferLength - 1UL ) ) == pdFALSE ) + { + ulBufferStartAddress = ( uint32_t ) pvBuffer; + ulBufferEndAddress = ( ( ( uint32_t ) pvBuffer ) + ulBufferLength - 1UL ); + + for( i = 0; i < portTOTAL_NUM_REGIONS; i++ ) + { + /* Is the MPU region enabled? */ + if( ( xTaskMpuSettings->xRegionsSettings[ i ].ulRLAR & portMPU_RLAR_REGION_ENABLE ) == portMPU_RLAR_REGION_ENABLE ) + { + if( portIS_ADDRESS_WITHIN_RANGE( ulBufferStartAddress, + portEXTRACT_FIRST_ADDRESS_FROM_RBAR( xTaskMpuSettings->xRegionsSettings[ i ].ulRBAR ), + portEXTRACT_LAST_ADDRESS_FROM_RLAR( xTaskMpuSettings->xRegionsSettings[ i ].ulRLAR ) ) && + portIS_ADDRESS_WITHIN_RANGE( ulBufferEndAddress, + portEXTRACT_FIRST_ADDRESS_FROM_RBAR( xTaskMpuSettings->xRegionsSettings[ i ].ulRBAR ), + portEXTRACT_LAST_ADDRESS_FROM_RLAR( xTaskMpuSettings->xRegionsSettings[ i ].ulRLAR ) ) && + portIS_AUTHORIZED( ulAccessRequested, + prvGetRegionAccessPermissions( xTaskMpuSettings->xRegionsSettings[ i ].ulRBAR ) ) ) + { + xAccessGranted = pdTRUE; + break; + } + } + } + } + } + + return xAccessGranted; + } +#endif /* configENABLE_MPU */ +/*-----------------------------------------------------------*/ + BaseType_t xPortIsInsideInterrupt( void ) { uint32_t ulCurrentInterrupt; diff --git a/portable/GCC/ARM_CM35P_NTZ/non_secure/portasm.c b/portable/GCC/ARM_CM35P_NTZ/non_secure/portasm.c index a78529d04d9..504b6bf3be3 100644 --- a/portable/GCC/ARM_CM35P_NTZ/non_secure/portasm.c +++ b/portable/GCC/ARM_CM35P_NTZ/non_secure/portasm.c @@ -40,6 +40,88 @@ * header files. */ #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE +#if ( configENABLE_MPU == 1 ) + +void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ +{ + __asm volatile + ( + " .syntax unified \n" + " \n" + " program_mpu_first_task: \n" + " ldr r2, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r0, [r2] \n" /* r0 = pxCurrentTCB. */ + " \n" + " dmb \n" /* Complete outstanding transfers before disabling MPU. */ + " ldr r1, xMPUCTRLConst2 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ + " bic r2, #1 \n" /* r2 = r2 & ~1 i.e. Clear the bit 0 in r2. */ + " str r2, [r1] \n" /* Disable MPU. */ + " \n" + " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */ + " ldr r1, [r0] \n" /* r1 = *r0 i.e. r1 = MAIR0. */ + " ldr r2, xMAIR0Const2 \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */ + " str r1, [r2] \n" /* Program MAIR0. */ + " \n" + " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */ + " ldr r1, xRNRConst2 \n" /* r1 = 0xe000ed98 [Location of RNR]. */ + " ldr r2, xRBARConst2 \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ + " \n" + " movs r3, #4 \n" /* r3 = 4. */ + " str r3, [r1] \n" /* Program RNR = 4. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + " \n" + #if ( configTOTAL_MPU_REGIONS == 16 ) + " movs r3, #8 \n" /* r3 = 8. */ + " str r3, [r1] \n" /* Program RNR = 8. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + " movs r3, #12 \n" /* r3 = 12. */ + " str r3, [r1] \n" /* Program RNR = 12. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + #endif /* configTOTAL_MPU_REGIONS == 16 */ + " \n" + " ldr r1, xMPUCTRLConst2 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ + " orr r2, #1 \n" /* r2 = r2 | 1 i.e. Set the bit 0 in r2. */ + " str r2, [r1] \n" /* Enable MPU. */ + " dsb \n" /* Force memory writes before continuing. */ + " \n" + " restore_context_first_task: \n" + " ldr r2, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r0, [r2] \n" /* r0 = pxCurrentTCB.*/ + " ldr r1, [r0] \n" /* r1 = Location of saved context in TCB. */ + " \n" + " restore_special_regs_first_task: \n" + " ldmdb r1!, {r2-r4, lr} \n" /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */ + " msr psp, r2 \n" + " msr psplim, r3 \n" + " msr control, r4 \n" + " \n" + " restore_general_regs_first_task: \n" + " ldmdb r1!, {r4-r11} \n" /* r4-r11 contain hardware saved context. */ + " stmia r2!, {r4-r11} \n" /* Copy the hardware saved context on the task stack. */ + " ldmdb r1!, {r4-r11} \n" /* r4-r11 restored. */ + " \n" + " restore_context_done_first_task: \n" + " str r1, [r0] \n" /* Save the location where the context should be saved next as the first member of TCB. */ + " mov r0, #0 \n" + " msr basepri, r0 \n" /* Ensure that interrupts are enabled when the first task starts. */ + " bx lr \n" + " \n" + " .align 4 \n" + " pxCurrentTCBConst2: .word pxCurrentTCB \n" + " xMPUCTRLConst2: .word 0xe000ed94 \n" + " xMAIR0Const2: .word 0xe000edc0 \n" + " xRNRConst2: .word 0xe000ed98 \n" + " xRBARConst2: .word 0xe000ed9c \n" + ); +} + +#else /* configENABLE_MPU */ + void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ { __asm volatile @@ -50,80 +132,23 @@ void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_ " ldr r1, [r2] \n"/* Read pxCurrentTCB. */ " ldr r0, [r1] \n"/* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ " \n" - #if ( configENABLE_MPU == 1 ) - " dmb \n"/* Complete outstanding transfers before disabling MPU. */ - " ldr r2, xMPUCTRLConst2 \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ - " ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */ - " bic r4, #1 \n"/* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */ - " str r4, [r2] \n"/* Disable MPU. */ - " \n" - " adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */ - " ldr r3, [r1] \n"/* r3 = *r1 i.e. r3 = MAIR0. */ - " ldr r2, xMAIR0Const2 \n"/* r2 = 0xe000edc0 [Location of MAIR0]. */ - " str r3, [r2] \n"/* Program MAIR0. */ - " ldr r2, xRNRConst2 \n"/* r2 = 0xe000ed98 [Location of RNR]. */ - " movs r3, #4 \n"/* r3 = 4. */ - " str r3, [r2] \n"/* Program RNR = 4. */ - " adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to first RBAR in TCB. */ - " ldr r2, xRBARConst2 \n"/* r2 = 0xe000ed9c [Location of RBAR]. */ - " ldmia r1!, {r4-r11} \n"/* Read 4 set of RBAR/RLAR registers from TCB. */ - " stmia r2!, {r4-r11} \n"/* Write 4 set of RBAR/RLAR registers using alias registers. */ - " \n" - #if ( configTOTAL_MPU_REGIONS == 16 ) - " ldr r2, xRNRConst2 \n"/* r2 = 0xe000ed98 [Location of RNR]. */ - " movs r3, #8 \n"/* r3 = 8. */ - " str r3, [r2] \n"/* Program RNR = 8. */ - " ldr r2, xRBARConst2 \n"/* r2 = 0xe000ed9c [Location of RBAR]. */ - " ldmia r1!, {r4-r11} \n"/* Read 4 set of RBAR/RLAR registers from TCB. */ - " stmia r2!, {r4-r11} \n"/* Write 4 set of RBAR/RLAR registers using alias registers. */ - " ldr r2, xRNRConst2 \n"/* r2 = 0xe000ed98 [Location of RNR]. */ - " movs r3, #12 \n"/* r3 = 12. */ - " str r3, [r2] \n"/* Program RNR = 12. */ - " ldr r2, xRBARConst2 \n"/* r2 = 0xe000ed9c [Location of RBAR]. */ - " ldmia r1!, {r4-r11} \n"/* Read 4 set of RBAR/RLAR registers from TCB. */ - " stmia r2!, {r4-r11} \n"/* Write 4 set of RBAR/RLAR registers using alias registers. */ - #endif /* configTOTAL_MPU_REGIONS == 16 */ - " \n" - " ldr r2, xMPUCTRLConst2 \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ - " ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */ - " orr r4, #1 \n"/* r4 = r4 | 1 i.e. Set the bit 0 in r4. */ - " str r4, [r2] \n"/* Enable MPU. */ - " dsb \n"/* Force memory writes before continuing. */ - #endif /* configENABLE_MPU */ - " \n" - #if ( configENABLE_MPU == 1 ) - " ldm r0!, {r1-r3} \n"/* Read from stack - r1 = PSPLIM, r2 = CONTROL and r3 = EXC_RETURN. */ - " msr psplim, r1 \n"/* Set this task's PSPLIM value. */ - " msr control, r2 \n"/* Set this task's CONTROL value. */ - " adds r0, #32 \n"/* Discard everything up to r0. */ - " msr psp, r0 \n"/* This is now the new top of stack to use in the task. */ - " isb \n" - " mov r0, #0 \n" - " msr basepri, r0 \n"/* Ensure that interrupts are enabled when the first task starts. */ - " bx r3 \n"/* Finally, branch to EXC_RETURN. */ - #else /* configENABLE_MPU */ - " ldm r0!, {r1-r2} \n"/* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */ - " msr psplim, r1 \n"/* Set this task's PSPLIM value. */ - " movs r1, #2 \n"/* r1 = 2. */ - " msr CONTROL, r1 \n"/* Switch to use PSP in the thread mode. */ - " adds r0, #32 \n"/* Discard everything up to r0. */ - " msr psp, r0 \n"/* This is now the new top of stack to use in the task. */ - " isb \n" - " mov r0, #0 \n" - " msr basepri, r0 \n"/* Ensure that interrupts are enabled when the first task starts. */ - " bx r2 \n"/* Finally, branch to EXC_RETURN. */ - #endif /* configENABLE_MPU */ + " ldm r0!, {r1-r2} \n"/* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */ + " msr psplim, r1 \n"/* Set this task's PSPLIM value. */ + " movs r1, #2 \n"/* r1 = 2. */ + " msr CONTROL, r1 \n"/* Switch to use PSP in the thread mode. */ + " adds r0, #32 \n"/* Discard everything up to r0. */ + " msr psp, r0 \n"/* This is now the new top of stack to use in the task. */ + " isb \n" + " mov r0, #0 \n" + " msr basepri, r0 \n"/* Ensure that interrupts are enabled when the first task starts. */ + " bx r2 \n"/* Finally, branch to EXC_RETURN. */ " \n" " .align 4 \n" "pxCurrentTCBConst2: .word pxCurrentTCB \n" - #if ( configENABLE_MPU == 1 ) - "xMPUCTRLConst2: .word 0xe000ed94 \n" - "xMAIR0Const2: .word 0xe000edc0 \n" - "xRNRConst2: .word 0xe000ed98 \n" - "xRBARConst2: .word 0xe000ed9c \n" - #endif /* configENABLE_MPU */ ); } + +#endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */ @@ -231,6 +256,129 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att } /*-----------------------------------------------------------*/ +#if ( configENABLE_MPU == 1 ) + +void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ +{ + __asm volatile + ( + " .syntax unified \n" + " \n" + " ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r0, [r2] \n" /* r0 = pxCurrentTCB. */ + " ldr r1, [r0] \n" /* r1 = Location in TCB where the context should be saved. */ + " mrs r2, psp \n" /* r2 = PSP. */ + " \n" + " save_general_regs: \n" + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + " add r2, r2, #0x20 \n" /* Move r2 to location where s0 is saved. */ + " tst lr, #0x10 \n" + " ittt eq \n" + " vstmiaeq r1!, {s16-s31} \n" /* Store s16-s31. */ + " vldmiaeq r2, {s0-s16} \n" /* Copy hardware saved FP context into s0-s16. */ + " vstmiaeq r1!, {s0-s16} \n" /* Store hardware saved FP context. */ + " sub r2, r2, #0x20 \n" /* Set r2 back to the location of hardware saved context. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ + " \n" + " stmia r1!, {r4-r11} \n" /* Store r4-r11. */ + " ldmia r2, {r4-r11} \n" /* Copy the hardware saved context into r4-r11. */ + " stmia r1!, {r4-r11} \n" /* Store the hardware saved context. */ + " \n" + " save_special_regs: \n" + " mrs r3, psplim \n" /* r3 = PSPLIM. */ + " mrs r4, control \n" /* r4 = CONTROL. */ + " stmia r1!, {r2-r4, lr} \n" /* Store original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */ + " str r1, [r0] \n" /* Save the location from where the context should be restored as the first member of TCB. */ + " \n" + " select_next_task: \n" + " mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */ + " msr basepri, r0 \n" /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + " dsb \n" + " isb \n" + " bl vTaskSwitchContext \n" + " mov r0, #0 \n" /* r0 = 0. */ + " msr basepri, r0 \n" /* Enable interrupts. */ + " \n" + " program_mpu: \n" + " ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r0, [r2] \n" /* r0 = pxCurrentTCB. */ + " \n" + " dmb \n" /* Complete outstanding transfers before disabling MPU. */ + " ldr r1, xMPUCTRLConst \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ + " bic r2, #1 \n" /* r2 = r2 & ~1 i.e. Clear the bit 0 in r2. */ + " str r2, [r1] \n" /* Disable MPU. */ + " \n" + " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */ + " ldr r1, [r0] \n" /* r1 = *r0 i.e. r1 = MAIR0. */ + " ldr r2, xMAIR0Const \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */ + " str r1, [r2] \n" /* Program MAIR0. */ + " \n" + " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */ + " ldr r1, xRNRConst \n" /* r1 = 0xe000ed98 [Location of RNR]. */ + " ldr r2, xRBARConst \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ + " \n" + " movs r3, #4 \n" /* r3 = 4. */ + " str r3, [r1] \n" /* Program RNR = 4. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + " \n" + #if ( configTOTAL_MPU_REGIONS == 16 ) + " movs r3, #8 \n" /* r3 = 8. */ + " str r3, [r1] \n" /* Program RNR = 8. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + " movs r3, #12 \n" /* r3 = 12. */ + " str r3, [r1] \n" /* Program RNR = 12. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + #endif /* configTOTAL_MPU_REGIONS == 16 */ + " \n" + " ldr r1, xMPUCTRLConst \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ + " orr r2, #1 \n" /* r2 = r2 | 1 i.e. Set the bit 0 in r2. */ + " str r2, [r1] \n" /* Enable MPU. */ + " dsb \n" /* Force memory writes before continuing. */ + " \n" + " restore_context: \n" + " ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r0, [r2] \n" /* r0 = pxCurrentTCB.*/ + " ldr r1, [r0] \n" /* r1 = Location of saved context in TCB. */ + " \n" + " restore_special_regs: \n" + " ldmdb r1!, {r2-r4, lr} \n" /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */ + " msr psp, r2 \n" + " msr psplim, r3 \n" + " msr control, r4 \n" + " \n" + " restore_general_regs: \n" + " ldmdb r1!, {r4-r11} \n" /* r4-r11 contain hardware saved context. */ + " stmia r2!, {r4-r11} \n" /* Copy the hardware saved context on the task stack. */ + " ldmdb r1!, {r4-r11} \n" /* r4-r11 restored. */ + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + " tst lr, #0x10 \n" + " ittt eq \n" + " vldmdbeq r1!, {s0-s16} \n" /* s0-s16 contain hardware saved FP context. */ + " vstmiaeq r2!, {s0-s16} \n" /* Copy hardware saved FP context on the task stack. */ + " vldmdbeq r1!, {s16-s31} \n" /* Restore s16-s31. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ + " \n" + " restore_context_done: \n" + " str r1, [r0] \n" /* Save the location where the context should be saved next as the first member of TCB. */ + " bx lr \n" + " \n" + " .align 4 \n" + " pxCurrentTCBConst: .word pxCurrentTCB \n" + " xMPUCTRLConst: .word 0xe000ed94 \n" + " xMAIR0Const: .word 0xe000edc0 \n" + " xRNRConst: .word 0xe000ed98 \n" + " xRBARConst: .word 0xe000ed9c \n" + ::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) + ); +} + +#else /* configENABLE_MPU */ + void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ { __asm volatile @@ -238,21 +386,16 @@ void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ " .syntax unified \n" " \n" " mrs r0, psp \n"/* Read PSP in r0. */ + " \n" #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) " tst lr, #0x10 \n"/* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ " it eq \n" " vstmdbeq r0!, {s16-s31} \n"/* Store the additional FP context registers which are not saved automatically. */ #endif /* configENABLE_FPU || configENABLE_MVE */ - #if ( configENABLE_MPU == 1 ) - " mrs r1, psplim \n"/* r1 = PSPLIM. */ - " mrs r2, control \n"/* r2 = CONTROL. */ - " mov r3, lr \n"/* r3 = LR/EXC_RETURN. */ - " stmdb r0!, {r1-r11} \n"/* Store on the stack - PSPLIM, CONTROL, LR and registers that are not automatically saved. */ - #else /* configENABLE_MPU */ - " mrs r2, psplim \n"/* r2 = PSPLIM. */ - " mov r3, lr \n"/* r3 = LR/EXC_RETURN. */ - " stmdb r0!, {r2-r11} \n"/* Store on the stack - PSPLIM, LR and registers that are not automatically saved. */ - #endif /* configENABLE_MPU */ + " \n" + " mrs r2, psplim \n"/* r2 = PSPLIM. */ + " mov r3, lr \n"/* r3 = LR/EXC_RETURN. */ + " stmdb r0!, {r2-r11} \n"/* Store on the stack - PSPLIM, LR and registers that are not automatically saved. */ " \n" " ldr r2, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r2] \n"/* Read pxCurrentTCB. */ @@ -270,52 +413,7 @@ void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ " ldr r1, [r2] \n"/* Read pxCurrentTCB. */ " ldr r0, [r1] \n"/* The first item in pxCurrentTCB is the task top of stack. r0 now points to the top of stack. */ " \n" - #if ( configENABLE_MPU == 1 ) - " dmb \n"/* Complete outstanding transfers before disabling MPU. */ - " ldr r2, xMPUCTRLConst \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ - " ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */ - " bic r4, #1 \n"/* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */ - " str r4, [r2] \n"/* Disable MPU. */ - " \n" - " adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */ - " ldr r3, [r1] \n"/* r3 = *r1 i.e. r3 = MAIR0. */ - " ldr r2, xMAIR0Const \n"/* r2 = 0xe000edc0 [Location of MAIR0]. */ - " str r3, [r2] \n"/* Program MAIR0. */ - " ldr r2, xRNRConst \n"/* r2 = 0xe000ed98 [Location of RNR]. */ - " movs r3, #4 \n"/* r3 = 4. */ - " str r3, [r2] \n"/* Program RNR = 4. */ - " adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to first RBAR in TCB. */ - " ldr r2, xRBARConst \n"/* r2 = 0xe000ed9c [Location of RBAR]. */ - " ldmia r1!, {r4-r11} \n"/* Read 4 sets of RBAR/RLAR registers from TCB. */ - " stmia r2!, {r4-r11} \n"/* Write 4 set of RBAR/RLAR registers using alias registers. */ - " \n" - #if ( configTOTAL_MPU_REGIONS == 16 ) - " ldr r2, xRNRConst \n"/* r2 = 0xe000ed98 [Location of RNR]. */ - " movs r3, #8 \n"/* r3 = 8. */ - " str r3, [r2] \n"/* Program RNR = 8. */ - " ldr r2, xRBARConst \n"/* r2 = 0xe000ed9c [Location of RBAR]. */ - " ldmia r1!, {r4-r11} \n"/* Read 4 sets of RBAR/RLAR registers from TCB. */ - " stmia r2!, {r4-r11} \n"/* Write 4 set of RBAR/RLAR registers using alias registers. */ - " ldr r2, xRNRConst \n"/* r2 = 0xe000ed98 [Location of RNR]. */ - " movs r3, #12 \n"/* r3 = 12. */ - " str r3, [r2] \n"/* Program RNR = 12. */ - " ldr r2, xRBARConst \n"/* r2 = 0xe000ed9c [Location of RBAR]. */ - " ldmia r1!, {r4-r11} \n"/* Read 4 sets of RBAR/RLAR registers from TCB. */ - " stmia r2!, {r4-r11} \n"/* Write 4 set of RBAR/RLAR registers using alias registers. */ - #endif /* configTOTAL_MPU_REGIONS == 16 */ - " \n" - " ldr r2, xMPUCTRLConst \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ - " ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */ - " orr r4, #1 \n"/* r4 = r4 | 1 i.e. Set the bit 0 in r4. */ - " str r4, [r2] \n"/* Enable MPU. */ - " dsb \n"/* Force memory writes before continuing. */ - #endif /* configENABLE_MPU */ - " \n" - #if ( configENABLE_MPU == 1 ) - " ldmia r0!, {r1-r11} \n"/* Read from stack - r1 = PSPLIM, r2 = CONTROL, r3 = LR and r4-r11 restored. */ - #else /* configENABLE_MPU */ - " ldmia r0!, {r2-r11} \n"/* Read from stack - r2 = PSPLIM, r3 = LR and r4-r11 restored. */ - #endif /* configENABLE_MPU */ + " ldmia r0!, {r2-r11} \n"/* Read from stack - r2 = PSPLIM, r3 = LR and r4-r11 restored. */ " \n" #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) " tst r3, #0x10 \n"/* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ @@ -323,28 +421,66 @@ void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ " vldmiaeq r0!, {s16-s31} \n"/* Restore the additional FP context registers which are not restored automatically. */ #endif /* configENABLE_FPU || configENABLE_MVE */ " \n" - #if ( configENABLE_MPU == 1 ) - " msr psplim, r1 \n"/* Restore the PSPLIM register value for the task. */ - " msr control, r2 \n"/* Restore the CONTROL register value for the task. */ - #else /* configENABLE_MPU */ - " msr psplim, r2 \n"/* Restore the PSPLIM register value for the task. */ - #endif /* configENABLE_MPU */ + " msr psplim, r2 \n"/* Restore the PSPLIM register value for the task. */ " msr psp, r0 \n"/* Remember the new top of stack for the task. */ " bx r3 \n" " \n" " .align 4 \n" "pxCurrentTCBConst: .word pxCurrentTCB \n" - #if ( configENABLE_MPU == 1 ) - "xMPUCTRLConst: .word 0xe000ed94 \n" - "xMAIR0Const: .word 0xe000edc0 \n" - "xRNRConst: .word 0xe000ed98 \n" - "xRBARConst: .word 0xe000ed9c \n" - #endif /* configENABLE_MPU */ ::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) ); } + +#endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + +void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ +{ + __asm volatile + ( + ".syntax unified \n" + ".extern vPortSVCHandler_C \n" + ".extern vSystemCallEnter \n" + ".extern vSystemCallEnter_1 \n" + ".extern vSystemCallExit \n" + " \n" + "tst lr, #4 \n" + "ite eq \n" + "mrseq r0, msp \n" + "mrsne r0, psp \n" + " \n" + "ldr r1, [r0, #24] \n" + "ldrb r2, [r1, #-2] \n" + "cmp r2, %0 \n" + "beq syscall_enter \n" + "cmp r2, %1 \n" + "beq syscall_enter_1 \n" + "cmp r2, %2 \n" + "beq syscall_exit \n" + "b vPortSVCHandler_C \n" + " \n" + "syscall_enter: \n" + " mov r1, lr \n" + " b vSystemCallEnter \n" + " \n" + "syscall_enter_1: \n" + " mov r1, lr \n" + " b vSystemCallEnter_1 \n" + " \n" + "syscall_exit: \n" + " mov r1, lr \n" + " b vSystemCallExit \n" + " \n" + : /* No outputs. */ + :"i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_ENTER_1 ), "i" ( portSVC_SYSTEM_CALL_EXIT ) + : "r0", "r1", "r2", "memory" + ); +} + +#else /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ { __asm volatile @@ -362,4 +498,6 @@ void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ "svchandler_address_const: .word vPortSVCHandler_C \n" ); } + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ /*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM35P_NTZ/non_secure/portmacro.h b/portable/GCC/ARM_CM35P_NTZ/non_secure/portmacro.h index cc643459770..9545737c550 100644 --- a/portable/GCC/ARM_CM35P_NTZ/non_secure/portmacro.h +++ b/portable/GCC/ARM_CM35P_NTZ/non_secure/portmacro.h @@ -51,7 +51,6 @@ #define portARCH_NAME "Cortex-M35P" #define portHAS_BASEPRI 1 #define portDONT_DISCARD __attribute__( ( used ) ) -#define portNORETURN __attribute__( ( noreturn ) ) /*-----------------------------------------------------------*/ /* ARMv8-M common port configurations. */ diff --git a/portable/GCC/ARM_CM35P_NTZ/non_secure/portmacrocommon.h b/portable/GCC/ARM_CM35P_NTZ/non_secure/portmacrocommon.h index c2ca5fa7730..65ac109c802 100644 --- a/portable/GCC/ARM_CM35P_NTZ/non_secure/portmacrocommon.h +++ b/portable/GCC/ARM_CM35P_NTZ/non_secure/portmacrocommon.h @@ -186,23 +186,120 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #define portMPU_REGION_EXECUTE_NEVER ( 1UL ) /*-----------------------------------------------------------*/ -/** - * @brief Settings to define an MPU region. - */ -typedef struct MPURegionSettings -{ - uint32_t ulRBAR; /**< RBAR for the region. */ - uint32_t ulRLAR; /**< RLAR for the region. */ -} MPURegionSettings_t; +#if ( configENABLE_MPU == 1 ) -/** - * @brief MPU settings as stored in the TCB. - */ -typedef struct MPU_SETTINGS -{ - uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ - MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */ -} xMPU_SETTINGS; + /** + * @brief Settings to define an MPU region. + */ + typedef struct MPURegionSettings + { + uint32_t ulRBAR; /**< RBAR for the region. */ + uint32_t ulRLAR; /**< RLAR for the region. */ + } MPURegionSettings_t; + + #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + + #ifndef configSYSTEM_CALL_STACK_SIZE + #error configSYSTEM_CALL_STACK_SIZE must be defined to the desired size of the system call stack in words for using MPU wrappers v2. + #endif + + /** + * @brief System call stack. + */ + typedef struct SYSTEM_CALL_STACK_INFO + { + uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ]; + uint32_t * pulSystemCallStack; + uint32_t * pulSystemCallStackLimit; + uint32_t * pulTaskStack; + uint32_t ulLinkRegisterAtSystemCallEntry; + uint32_t ulStackLimitRegisterAtSystemCallEntry; + } xSYSTEM_CALL_STACK_INFO; + + #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + + /** + * @brief MPU settings as stored in the TCB. + */ + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + + #if( configENABLE_TRUSTZONE == 1 ) + + /* + * +-----------+---------------+----------+-----------------+------------------------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | + * | | | | PC, xPSR | CONTROL, EXC_RETURN | | + * +-----------+---------------+----------+-----------------+------------------------------+-----+ + * + * <-----------><--------------><---------><----------------><-----------------------------><----> + * 16 16 8 8 5 1 + */ + #define MAX_CONTEXT_SIZE 54 + + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ + + /* + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | + * | | | | PC, xPSR | EXC_RETURN | | + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * + * <-----------><--------------><---------><----------------><---------------------><----> + * 16 16 8 8 4 1 + */ + #define MAX_CONTEXT_SIZE 53 + + #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + + #else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ + + #if( configENABLE_TRUSTZONE == 1 ) + + /* + * +----------+-----------------+------------------------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | + * | | PC, xPSR | CONTROL, EXC_RETURN | | + * +----------+-----------------+------------------------------+-----+ + * + * <---------><----------------><------------------------------><----> + * 8 8 5 1 + */ + #define MAX_CONTEXT_SIZE 22 + + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ + + /* + * +----------+-----------------+----------------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | + * | | PC, xPSR | EXC_RETURN | | + * +----------+-----------------+----------------------+-----+ + * + * <---------><----------------><----------------------><----> + * 8 8 4 1 + */ + #define MAX_CONTEXT_SIZE 21 + + #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + + #endif /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ + + /* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ + #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) + #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) + + typedef struct MPU_SETTINGS + { + uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ + MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */ + uint32_t ulContext[ MAX_CONTEXT_SIZE ]; + uint32_t ulTaskFlags; + + #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo; + #endif + } xMPU_SETTINGS; + +#endif /* configENABLE_MPU == 1 */ /*-----------------------------------------------------------*/ /** @@ -223,6 +320,9 @@ typedef struct MPU_SETTINGS #define portSVC_FREE_SECURE_CONTEXT 1 #define portSVC_START_SCHEDULER 2 #define portSVC_RAISE_PRIVILEGE 3 +#define portSVC_SYSTEM_CALL_ENTER 4 /* System calls with upto 4 parameters. */ +#define portSVC_SYSTEM_CALL_ENTER_1 5 /* System calls with 5 parameters. */ +#define portSVC_SYSTEM_CALL_EXIT 6 /*-----------------------------------------------------------*/ /** @@ -315,6 +415,20 @@ typedef struct MPU_SETTINGS #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ +#if ( configENABLE_MPU == 1 ) + + extern BaseType_t xPortIsTaskPrivileged( void ); + + /** + * @brief Checks whether or not the calling task is privileged. + * + * @return pdTRUE if the calling task is privileged, pdFALSE otherwise. + */ + #define portIS_TASK_PRIVILEGED() xPortIsTaskPrivileged() + +#endif /* configENABLE_MPU == 1 */ +/*-----------------------------------------------------------*/ + /** * @brief Barriers. */ diff --git a/portable/GCC/ARM_CM3_MPU/mpu_wrappers_v2_asm.c b/portable/GCC/ARM_CM3_MPU/mpu_wrappers_v2_asm.c new file mode 100644 index 00000000000..df9239a41d6 --- /dev/null +++ b/portable/GCC/ARM_CM3_MPU/mpu_wrappers_v2_asm.c @@ -0,0 +1,2349 @@ +/* + * FreeRTOS Kernel + * Copyright (C) 2021 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 + * + */ + +/* 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. */ +#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +/* Scheduler includes. */ +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" +#include "timers.h" +#include "event_groups.h" +#include "stream_buffer.h" + +#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE +/*-----------------------------------------------------------*/ + +#if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + +#if ( INCLUDE_xTaskDelayUntil == 1 ) + +BaseType_t MPU_xTaskDelayUntil( TickType_t * const pxPreviousWakeTime, + const TickType_t xTimeIncrement ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskDelayUntil( TickType_t * const pxPreviousWakeTime, + const TickType_t xTimeIncrement ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskDelayUntilImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskDelayUntil_Unpriv \n" + " MPU_xTaskDelayUntil_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskDelayUntilImpl \n" + " MPU_xTaskDelayUntil_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskDelayUntilImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_xTaskDelayUntil == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_xTaskAbortDelay == 1 ) + +BaseType_t MPU_xTaskAbortDelay( TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskAbortDelay( TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskAbortDelayImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskAbortDelay_Unpriv \n" + " MPU_xTaskAbortDelay_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskAbortDelayImpl \n" + " MPU_xTaskAbortDelay_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskAbortDelayImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_xTaskAbortDelay == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskDelay == 1 ) + +void MPU_vTaskDelay( const TickType_t xTicksToDelay ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskDelay( const TickType_t xTicksToDelay ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskDelayImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vTaskDelay_Unpriv \n" + " MPU_vTaskDelay_Priv: \n" + " pop {r0} \n" + " b MPU_vTaskDelayImpl \n" + " MPU_vTaskDelay_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vTaskDelayImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_vTaskDelay == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_uxTaskPriorityGet == 1 ) + +UBaseType_t MPU_uxTaskPriorityGet( const TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxTaskPriorityGet( const TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxTaskPriorityGetImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_uxTaskPriorityGet_Unpriv \n" + " MPU_uxTaskPriorityGet_Priv: \n" + " pop {r0} \n" + " b MPU_uxTaskPriorityGetImpl \n" + " MPU_uxTaskPriorityGet_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_uxTaskPriorityGetImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_uxTaskPriorityGet == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_eTaskGetState == 1 ) + +eTaskState MPU_eTaskGetState( TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +eTaskState MPU_eTaskGetState( TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_eTaskGetStateImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_eTaskGetState_Unpriv \n" + " MPU_eTaskGetState_Priv: \n" + " pop {r0} \n" + " b MPU_eTaskGetStateImpl \n" + " MPU_eTaskGetState_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_eTaskGetStateImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_eTaskGetState == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + +void MPU_vTaskGetInfo( TaskHandle_t xTask, + TaskStatus_t * pxTaskStatus, + BaseType_t xGetFreeStackSpace, + eTaskState eState ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskGetInfo( TaskHandle_t xTask, + TaskStatus_t * pxTaskStatus, + BaseType_t xGetFreeStackSpace, + eTaskState eState ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskGetInfoImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vTaskGetInfo_Unpriv \n" + " MPU_vTaskGetInfo_Priv: \n" + " pop {r0} \n" + " b MPU_vTaskGetInfoImpl \n" + " MPU_vTaskGetInfo_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vTaskGetInfoImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TRACE_FACILITY == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) + +TaskHandle_t MPU_xTaskGetIdleTaskHandle( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TaskHandle_t MPU_xTaskGetIdleTaskHandle( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGetIdleTaskHandleImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskGetIdleTaskHandle_Unpriv \n" + " MPU_xTaskGetIdleTaskHandle_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskGetIdleTaskHandleImpl \n" + " MPU_xTaskGetIdleTaskHandle_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskGetIdleTaskHandleImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskSuspend == 1 ) + +void MPU_vTaskSuspend( TaskHandle_t xTaskToSuspend ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskSuspend( TaskHandle_t xTaskToSuspend ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskSuspendImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vTaskSuspend_Unpriv \n" + " MPU_vTaskSuspend_Priv: \n" + " pop {r0} \n" + " b MPU_vTaskSuspendImpl \n" + " MPU_vTaskSuspend_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vTaskSuspendImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_vTaskSuspend == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskSuspend == 1 ) + +void MPU_vTaskResume( TaskHandle_t xTaskToResume ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskResume( TaskHandle_t xTaskToResume ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskResumeImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vTaskResume_Unpriv \n" + " MPU_vTaskResume_Priv: \n" + " pop {r0} \n" + " b MPU_vTaskResumeImpl \n" + " MPU_vTaskResume_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vTaskResumeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_vTaskSuspend == 1 ) */ +/*-----------------------------------------------------------*/ + +TickType_t MPU_xTaskGetTickCount( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TickType_t MPU_xTaskGetTickCount( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGetTickCountImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskGetTickCount_Unpriv \n" + " MPU_xTaskGetTickCount_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskGetTickCountImpl \n" + " MPU_xTaskGetTickCount_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskGetTickCountImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +UBaseType_t MPU_uxTaskGetNumberOfTasks( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxTaskGetNumberOfTasks( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxTaskGetNumberOfTasksImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_uxTaskGetNumberOfTasks_Unpriv \n" + " MPU_uxTaskGetNumberOfTasks_Priv: \n" + " pop {r0} \n" + " b MPU_uxTaskGetNumberOfTasksImpl \n" + " MPU_uxTaskGetNumberOfTasks_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_uxTaskGetNumberOfTasksImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +char * MPU_pcTaskGetName( TaskHandle_t xTaskToQuery ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +char * MPU_pcTaskGetName( TaskHandle_t xTaskToQuery ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_pcTaskGetNameImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_pcTaskGetName_Unpriv \n" + " MPU_pcTaskGetName_Priv: \n" + " pop {r0} \n" + " b MPU_pcTaskGetNameImpl \n" + " MPU_pcTaskGetName_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_pcTaskGetNameImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +#if ( configGENERATE_RUN_TIME_STATS == 1 ) + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetRunTimeCounter( const TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetRunTimeCounter( const TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_ulTaskGetRunTimeCounterImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_ulTaskGetRunTimeCounter_Unpriv \n" + " MPU_ulTaskGetRunTimeCounter_Priv: \n" + " pop {r0} \n" + " b MPU_ulTaskGetRunTimeCounterImpl \n" + " MPU_ulTaskGetRunTimeCounter_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_ulTaskGetRunTimeCounterImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( ( configGENERATE_RUN_TIME_STATS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configGENERATE_RUN_TIME_STATS == 1 ) + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetRunTimePercent( const TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetRunTimePercent( const TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_ulTaskGetRunTimePercentImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_ulTaskGetRunTimePercent_Unpriv \n" + " MPU_ulTaskGetRunTimePercent_Priv: \n" + " pop {r0} \n" + " b MPU_ulTaskGetRunTimePercentImpl \n" + " MPU_ulTaskGetRunTimePercent_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_ulTaskGetRunTimePercentImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( ( configGENERATE_RUN_TIME_STATS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimePercent( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimePercent( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_ulTaskGetIdleRunTimePercentImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_ulTaskGetIdleRunTimePercent_Unpriv \n" + " MPU_ulTaskGetIdleRunTimePercent_Priv: \n" + " pop {r0} \n" + " b MPU_ulTaskGetIdleRunTimePercentImpl \n" + " MPU_ulTaskGetIdleRunTimePercent_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_ulTaskGetIdleRunTimePercentImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimeCounter( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimeCounter( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_ulTaskGetIdleRunTimeCounterImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_ulTaskGetIdleRunTimeCounter_Unpriv \n" + " MPU_ulTaskGetIdleRunTimeCounter_Priv: \n" + " pop {r0} \n" + " b MPU_ulTaskGetIdleRunTimeCounterImpl \n" + " MPU_ulTaskGetIdleRunTimeCounter_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_ulTaskGetIdleRunTimeCounterImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_APPLICATION_TASK_TAG == 1 ) + +void MPU_vTaskSetApplicationTaskTag( TaskHandle_t xTask, + TaskHookFunction_t pxHookFunction ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskSetApplicationTaskTag( TaskHandle_t xTask, + TaskHookFunction_t pxHookFunction ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskSetApplicationTaskTagImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vTaskSetApplicationTaskTag_Unpriv \n" + " MPU_vTaskSetApplicationTaskTag_Priv: \n" + " pop {r0} \n" + " b MPU_vTaskSetApplicationTaskTagImpl \n" + " MPU_vTaskSetApplicationTaskTag_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vTaskSetApplicationTaskTagImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_APPLICATION_TASK_TAG == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_APPLICATION_TASK_TAG == 1 ) + +TaskHookFunction_t MPU_xTaskGetApplicationTaskTag( TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TaskHookFunction_t MPU_xTaskGetApplicationTaskTag( TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGetApplicationTaskTagImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskGetApplicationTaskTag_Unpriv \n" + " MPU_xTaskGetApplicationTaskTag_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskGetApplicationTaskTagImpl \n" + " MPU_xTaskGetApplicationTaskTag_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskGetApplicationTaskTagImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_APPLICATION_TASK_TAG == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) + +void MPU_vTaskSetThreadLocalStoragePointer( TaskHandle_t xTaskToSet, + BaseType_t xIndex, + void * pvValue ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskSetThreadLocalStoragePointer( TaskHandle_t xTaskToSet, + BaseType_t xIndex, + void * pvValue ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskSetThreadLocalStoragePointerImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vTaskSetThreadLocalStoragePointer_Unpriv \n" + " MPU_vTaskSetThreadLocalStoragePointer_Priv: \n" + " pop {r0} \n" + " b MPU_vTaskSetThreadLocalStoragePointerImpl \n" + " MPU_vTaskSetThreadLocalStoragePointer_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vTaskSetThreadLocalStoragePointerImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) + +void * MPU_pvTaskGetThreadLocalStoragePointer( TaskHandle_t xTaskToQuery, + BaseType_t xIndex ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void * MPU_pvTaskGetThreadLocalStoragePointer( TaskHandle_t xTaskToQuery, + BaseType_t xIndex ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_pvTaskGetThreadLocalStoragePointerImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_pvTaskGetThreadLocalStoragePointer_Unpriv \n" + " MPU_pvTaskGetThreadLocalStoragePointer_Priv: \n" + " pop {r0} \n" + " b MPU_pvTaskGetThreadLocalStoragePointerImpl \n" + " MPU_pvTaskGetThreadLocalStoragePointer_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_pvTaskGetThreadLocalStoragePointerImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + +UBaseType_t MPU_uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray, + const UBaseType_t uxArraySize, + configRUN_TIME_COUNTER_TYPE * const pulTotalRunTime ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray, + const UBaseType_t uxArraySize, + configRUN_TIME_COUNTER_TYPE * const pulTotalRunTime ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxTaskGetSystemStateImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_uxTaskGetSystemState_Unpriv \n" + " MPU_uxTaskGetSystemState_Priv: \n" + " pop {r0} \n" + " b MPU_uxTaskGetSystemStateImpl \n" + " MPU_uxTaskGetSystemState_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_uxTaskGetSystemStateImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TRACE_FACILITY == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) + +UBaseType_t MPU_uxTaskGetStackHighWaterMark( TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxTaskGetStackHighWaterMark( TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxTaskGetStackHighWaterMarkImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_uxTaskGetStackHighWaterMark_Unpriv \n" + " MPU_uxTaskGetStackHighWaterMark_Priv: \n" + " pop {r0} \n" + " b MPU_uxTaskGetStackHighWaterMarkImpl \n" + " MPU_uxTaskGetStackHighWaterMark_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_uxTaskGetStackHighWaterMarkImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) + +configSTACK_DEPTH_TYPE MPU_uxTaskGetStackHighWaterMark2( TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +configSTACK_DEPTH_TYPE MPU_uxTaskGetStackHighWaterMark2( TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxTaskGetStackHighWaterMark2Impl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_uxTaskGetStackHighWaterMark2_Unpriv \n" + " MPU_uxTaskGetStackHighWaterMark2_Priv: \n" + " pop {r0} \n" + " b MPU_uxTaskGetStackHighWaterMark2Impl \n" + " MPU_uxTaskGetStackHighWaterMark2_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_uxTaskGetStackHighWaterMark2Impl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) ) + +TaskHandle_t MPU_xTaskGetCurrentTaskHandle( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TaskHandle_t MPU_xTaskGetCurrentTaskHandle( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGetCurrentTaskHandleImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskGetCurrentTaskHandle_Unpriv \n" + " MPU_xTaskGetCurrentTaskHandle_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskGetCurrentTaskHandleImpl \n" + " MPU_xTaskGetCurrentTaskHandle_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskGetCurrentTaskHandleImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_xTaskGetSchedulerState == 1 ) + +BaseType_t MPU_xTaskGetSchedulerState( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskGetSchedulerState( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGetSchedulerStateImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskGetSchedulerState_Unpriv \n" + " MPU_xTaskGetSchedulerState_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskGetSchedulerStateImpl \n" + " MPU_xTaskGetSchedulerState_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskGetSchedulerStateImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_xTaskGetSchedulerState == 1 ) */ +/*-----------------------------------------------------------*/ + +void MPU_vTaskSetTimeOutState( TimeOut_t * const pxTimeOut ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskSetTimeOutState( TimeOut_t * const pxTimeOut ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskSetTimeOutStateImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vTaskSetTimeOutState_Unpriv \n" + " MPU_vTaskSetTimeOutState_Priv: \n" + " pop {r0} \n" + " b MPU_vTaskSetTimeOutStateImpl \n" + " MPU_vTaskSetTimeOutState_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vTaskSetTimeOutStateImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut, + TickType_t * const pxTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut, + TickType_t * const pxTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskCheckForTimeOutImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskCheckForTimeOut_Unpriv \n" + " MPU_xTaskCheckForTimeOut_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskCheckForTimeOutImpl \n" + " MPU_xTaskCheckForTimeOut_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskCheckForTimeOutImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +#if ( configUSE_TASK_NOTIFICATIONS == 1 ) + +BaseType_t MPU_xTaskGenericNotify( TaskHandle_t xTaskToNotify, + UBaseType_t uxIndexToNotify, + uint32_t ulValue, + eNotifyAction eAction, + uint32_t * pulPreviousNotificationValue ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskGenericNotify( TaskHandle_t xTaskToNotify, + UBaseType_t uxIndexToNotify, + uint32_t ulValue, + eNotifyAction eAction, + uint32_t * pulPreviousNotificationValue ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGenericNotifyImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskGenericNotify_Unpriv \n" + " MPU_xTaskGenericNotify_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskGenericNotifyImpl \n" + " MPU_xTaskGenericNotify_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskGenericNotifyImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER_1 ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TASK_NOTIFICATIONS == 1 ) + +BaseType_t MPU_xTaskGenericNotifyWait( UBaseType_t uxIndexToWaitOn, + uint32_t ulBitsToClearOnEntry, + uint32_t ulBitsToClearOnExit, + uint32_t * pulNotificationValue, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskGenericNotifyWait( UBaseType_t uxIndexToWaitOn, + uint32_t ulBitsToClearOnEntry, + uint32_t ulBitsToClearOnExit, + uint32_t * pulNotificationValue, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGenericNotifyWaitImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskGenericNotifyWait_Unpriv \n" + " MPU_xTaskGenericNotifyWait_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskGenericNotifyWaitImpl \n" + " MPU_xTaskGenericNotifyWait_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskGenericNotifyWaitImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER_1 ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TASK_NOTIFICATIONS == 1 ) + +uint32_t MPU_ulTaskGenericNotifyTake( UBaseType_t uxIndexToWaitOn, + BaseType_t xClearCountOnExit, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +uint32_t MPU_ulTaskGenericNotifyTake( UBaseType_t uxIndexToWaitOn, + BaseType_t xClearCountOnExit, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_ulTaskGenericNotifyTakeImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_ulTaskGenericNotifyTake_Unpriv \n" + " MPU_ulTaskGenericNotifyTake_Priv: \n" + " pop {r0} \n" + " b MPU_ulTaskGenericNotifyTakeImpl \n" + " MPU_ulTaskGenericNotifyTake_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_ulTaskGenericNotifyTakeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TASK_NOTIFICATIONS == 1 ) + +BaseType_t MPU_xTaskGenericNotifyStateClear( TaskHandle_t xTask, + UBaseType_t uxIndexToClear ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskGenericNotifyStateClear( TaskHandle_t xTask, + UBaseType_t uxIndexToClear ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGenericNotifyStateClearImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskGenericNotifyStateClear_Unpriv \n" + " MPU_xTaskGenericNotifyStateClear_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskGenericNotifyStateClearImpl \n" + " MPU_xTaskGenericNotifyStateClear_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskGenericNotifyStateClearImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TASK_NOTIFICATIONS == 1 ) + +uint32_t MPU_ulTaskGenericNotifyValueClear( TaskHandle_t xTask, + UBaseType_t uxIndexToClear, + uint32_t ulBitsToClear ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +uint32_t MPU_ulTaskGenericNotifyValueClear( TaskHandle_t xTask, + UBaseType_t uxIndexToClear, + uint32_t ulBitsToClear ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_ulTaskGenericNotifyValueClearImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_ulTaskGenericNotifyValueClear_Unpriv \n" + " MPU_ulTaskGenericNotifyValueClear_Priv: \n" + " pop {r0} \n" + " b MPU_ulTaskGenericNotifyValueClearImpl \n" + " MPU_ulTaskGenericNotifyValueClear_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_ulTaskGenericNotifyValueClearImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xQueueGenericSend( QueueHandle_t xQueue, + const void * const pvItemToQueue, + TickType_t xTicksToWait, + const BaseType_t xCopyPosition ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueueGenericSend( QueueHandle_t xQueue, + const void * const pvItemToQueue, + TickType_t xTicksToWait, + const BaseType_t xCopyPosition ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueGenericSendImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xQueueGenericSend_Unpriv \n" + " MPU_xQueueGenericSend_Priv: \n" + " pop {r0} \n" + " b MPU_xQueueGenericSendImpl \n" + " MPU_xQueueGenericSend_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xQueueGenericSendImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +UBaseType_t MPU_uxQueueMessagesWaiting( const QueueHandle_t xQueue ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxQueueMessagesWaiting( const QueueHandle_t xQueue ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxQueueMessagesWaitingImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_uxQueueMessagesWaiting_Unpriv \n" + " MPU_uxQueueMessagesWaiting_Priv: \n" + " pop {r0} \n" + " b MPU_uxQueueMessagesWaitingImpl \n" + " MPU_uxQueueMessagesWaiting_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_uxQueueMessagesWaitingImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +UBaseType_t MPU_uxQueueSpacesAvailable( const QueueHandle_t xQueue ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxQueueSpacesAvailable( const QueueHandle_t xQueue ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxQueueSpacesAvailableImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_uxQueueSpacesAvailable_Unpriv \n" + " MPU_uxQueueSpacesAvailable_Priv: \n" + " pop {r0} \n" + " b MPU_uxQueueSpacesAvailableImpl \n" + " MPU_uxQueueSpacesAvailable_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_uxQueueSpacesAvailableImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xQueueReceive( QueueHandle_t xQueue, + void * const pvBuffer, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueueReceive( QueueHandle_t xQueue, + void * const pvBuffer, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueReceiveImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xQueueReceive_Unpriv \n" + " MPU_xQueueReceive_Priv: \n" + " pop {r0} \n" + " b MPU_xQueueReceiveImpl \n" + " MPU_xQueueReceive_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xQueueReceiveImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xQueuePeek( QueueHandle_t xQueue, + void * const pvBuffer, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueuePeek( QueueHandle_t xQueue, + void * const pvBuffer, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueuePeekImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xQueuePeek_Unpriv \n" + " MPU_xQueuePeek_Priv: \n" + " pop {r0} \n" + " b MPU_xQueuePeekImpl \n" + " MPU_xQueuePeek_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xQueuePeekImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xQueueSemaphoreTake( QueueHandle_t xQueue, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueueSemaphoreTake( QueueHandle_t xQueue, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueSemaphoreTakeImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xQueueSemaphoreTake_Unpriv \n" + " MPU_xQueueSemaphoreTake_Priv: \n" + " pop {r0} \n" + " b MPU_xQueueSemaphoreTakeImpl \n" + " MPU_xQueueSemaphoreTake_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xQueueSemaphoreTakeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +#if ( ( configUSE_MUTEXES == 1 ) && ( INCLUDE_xSemaphoreGetMutexHolder == 1 ) ) + +TaskHandle_t MPU_xQueueGetMutexHolder( QueueHandle_t xSemaphore ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TaskHandle_t MPU_xQueueGetMutexHolder( QueueHandle_t xSemaphore ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueGetMutexHolderImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xQueueGetMutexHolder_Unpriv \n" + " MPU_xQueueGetMutexHolder_Priv: \n" + " pop {r0} \n" + " b MPU_xQueueGetMutexHolderImpl \n" + " MPU_xQueueGetMutexHolder_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xQueueGetMutexHolderImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( ( configUSE_MUTEXES == 1 ) && ( INCLUDE_xSemaphoreGetMutexHolder == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_RECURSIVE_MUTEXES == 1 ) + +BaseType_t MPU_xQueueTakeMutexRecursive( QueueHandle_t xMutex, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueueTakeMutexRecursive( QueueHandle_t xMutex, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueTakeMutexRecursiveImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xQueueTakeMutexRecursive_Unpriv \n" + " MPU_xQueueTakeMutexRecursive_Priv: \n" + " pop {r0} \n" + " b MPU_xQueueTakeMutexRecursiveImpl \n" + " MPU_xQueueTakeMutexRecursive_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xQueueTakeMutexRecursiveImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_RECURSIVE_MUTEXES == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_RECURSIVE_MUTEXES == 1 ) + +BaseType_t MPU_xQueueGiveMutexRecursive( QueueHandle_t pxMutex ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueueGiveMutexRecursive( QueueHandle_t pxMutex ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueGiveMutexRecursiveImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xQueueGiveMutexRecursive_Unpriv \n" + " MPU_xQueueGiveMutexRecursive_Priv: \n" + " pop {r0} \n" + " b MPU_xQueueGiveMutexRecursiveImpl \n" + " MPU_xQueueGiveMutexRecursive_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xQueueGiveMutexRecursiveImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_RECURSIVE_MUTEXES == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_QUEUE_SETS == 1 ) + +QueueSetMemberHandle_t MPU_xQueueSelectFromSet( QueueSetHandle_t xQueueSet, + const TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +QueueSetMemberHandle_t MPU_xQueueSelectFromSet( QueueSetHandle_t xQueueSet, + const TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueSelectFromSetImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xQueueSelectFromSet_Unpriv \n" + " MPU_xQueueSelectFromSet_Priv: \n" + " pop {r0} \n" + " b MPU_xQueueSelectFromSetImpl \n" + " MPU_xQueueSelectFromSet_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xQueueSelectFromSetImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_QUEUE_SETS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_QUEUE_SETS == 1 ) + +BaseType_t MPU_xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore, + QueueSetHandle_t xQueueSet ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore, + QueueSetHandle_t xQueueSet ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueAddToSetImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xQueueAddToSet_Unpriv \n" + " MPU_xQueueAddToSet_Priv: \n" + " pop {r0} \n" + " b MPU_xQueueAddToSetImpl \n" + " MPU_xQueueAddToSet_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xQueueAddToSetImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_QUEUE_SETS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configQUEUE_REGISTRY_SIZE > 0 ) + +void MPU_vQueueAddToRegistry( QueueHandle_t xQueue, + const char * pcName ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vQueueAddToRegistry( QueueHandle_t xQueue, + const char * pcName ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vQueueAddToRegistryImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vQueueAddToRegistry_Unpriv \n" + " MPU_vQueueAddToRegistry_Priv: \n" + " pop {r0} \n" + " b MPU_vQueueAddToRegistryImpl \n" + " MPU_vQueueAddToRegistry_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vQueueAddToRegistryImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configQUEUE_REGISTRY_SIZE > 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configQUEUE_REGISTRY_SIZE > 0 ) + +void MPU_vQueueUnregisterQueue( QueueHandle_t xQueue ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vQueueUnregisterQueue( QueueHandle_t xQueue ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vQueueUnregisterQueueImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vQueueUnregisterQueue_Unpriv \n" + " MPU_vQueueUnregisterQueue_Priv: \n" + " pop {r0} \n" + " b MPU_vQueueUnregisterQueueImpl \n" + " MPU_vQueueUnregisterQueue_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vQueueUnregisterQueueImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configQUEUE_REGISTRY_SIZE > 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configQUEUE_REGISTRY_SIZE > 0 ) + +const char * MPU_pcQueueGetName( QueueHandle_t xQueue ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +const char * MPU_pcQueueGetName( QueueHandle_t xQueue ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_pcQueueGetNameImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_pcQueueGetName_Unpriv \n" + " MPU_pcQueueGetName_Priv: \n" + " pop {r0} \n" + " b MPU_pcQueueGetNameImpl \n" + " MPU_pcQueueGetName_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_pcQueueGetNameImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configQUEUE_REGISTRY_SIZE > 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +void * MPU_pvTimerGetTimerID( const TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void * MPU_pvTimerGetTimerID( const TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_pvTimerGetTimerIDImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_pvTimerGetTimerID_Unpriv \n" + " MPU_pvTimerGetTimerID_Priv: \n" + " pop {r0} \n" + " b MPU_pvTimerGetTimerIDImpl \n" + " MPU_pvTimerGetTimerID_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_pvTimerGetTimerIDImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +void MPU_vTimerSetTimerID( TimerHandle_t xTimer, + void * pvNewID ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTimerSetTimerID( TimerHandle_t xTimer, + void * pvNewID ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTimerSetTimerIDImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vTimerSetTimerID_Unpriv \n" + " MPU_vTimerSetTimerID_Priv: \n" + " pop {r0} \n" + " b MPU_vTimerSetTimerIDImpl \n" + " MPU_vTimerSetTimerID_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vTimerSetTimerIDImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +BaseType_t MPU_xTimerIsTimerActive( TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTimerIsTimerActive( TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTimerIsTimerActiveImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTimerIsTimerActive_Unpriv \n" + " MPU_xTimerIsTimerActive_Priv: \n" + " pop {r0} \n" + " b MPU_xTimerIsTimerActiveImpl \n" + " MPU_xTimerIsTimerActive_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTimerIsTimerActiveImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +TaskHandle_t MPU_xTimerGetTimerDaemonTaskHandle( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TaskHandle_t MPU_xTimerGetTimerDaemonTaskHandle( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTimerGetTimerDaemonTaskHandleImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTimerGetTimerDaemonTaskHandle_Unpriv \n" + " MPU_xTimerGetTimerDaemonTaskHandle_Priv: \n" + " pop {r0} \n" + " b MPU_xTimerGetTimerDaemonTaskHandleImpl \n" + " MPU_xTimerGetTimerDaemonTaskHandle_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTimerGetTimerDaemonTaskHandleImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +BaseType_t MPU_xTimerGenericCommand( TimerHandle_t xTimer, + const BaseType_t xCommandID, + const TickType_t xOptionalValue, + BaseType_t * const pxHigherPriorityTaskWoken, + const TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTimerGenericCommand( TimerHandle_t xTimer, + const BaseType_t xCommandID, + const TickType_t xOptionalValue, + BaseType_t * const pxHigherPriorityTaskWoken, + const TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTimerGenericCommandImpl \n" + " \n" + " push {r0} \n" + " mrs r0, ipsr \n" + " cmp r0, #0 \n" + " bne MPU_xTimerGenericCommand_Priv \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " beq MPU_xTimerGenericCommand_Priv \n" + " MPU_xTimerGenericCommand_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTimerGenericCommandImpl \n" + " svc %1 \n" + " bx lr \n" + " MPU_xTimerGenericCommand_Priv: \n" + " pop {r0} \n" + " b MPU_xTimerGenericCommandImpl \n" + " \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER_1 ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +const char * MPU_pcTimerGetName( TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +const char * MPU_pcTimerGetName( TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_pcTimerGetNameImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_pcTimerGetName_Unpriv \n" + " MPU_pcTimerGetName_Priv: \n" + " pop {r0} \n" + " b MPU_pcTimerGetNameImpl \n" + " MPU_pcTimerGetName_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_pcTimerGetNameImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, + const BaseType_t uxAutoReload ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, + const BaseType_t uxAutoReload ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTimerSetReloadModeImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vTimerSetReloadMode_Unpriv \n" + " MPU_vTimerSetReloadMode_Priv: \n" + " pop {r0} \n" + " b MPU_vTimerSetReloadModeImpl \n" + " MPU_vTimerSetReloadMode_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vTimerSetReloadModeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +BaseType_t MPU_xTimerGetReloadMode( TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTimerGetReloadMode( TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTimerGetReloadModeImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTimerGetReloadMode_Unpriv \n" + " MPU_xTimerGetReloadMode_Priv: \n" + " pop {r0} \n" + " b MPU_xTimerGetReloadModeImpl \n" + " MPU_xTimerGetReloadMode_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTimerGetReloadModeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +UBaseType_t MPU_uxTimerGetReloadMode( TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxTimerGetReloadMode( TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxTimerGetReloadModeImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_uxTimerGetReloadMode_Unpriv \n" + " MPU_uxTimerGetReloadMode_Priv: \n" + " pop {r0} \n" + " b MPU_uxTimerGetReloadModeImpl \n" + " MPU_uxTimerGetReloadMode_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_uxTimerGetReloadModeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +TickType_t MPU_xTimerGetPeriod( TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TickType_t MPU_xTimerGetPeriod( TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTimerGetPeriodImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTimerGetPeriod_Unpriv \n" + " MPU_xTimerGetPeriod_Priv: \n" + " pop {r0} \n" + " b MPU_xTimerGetPeriodImpl \n" + " MPU_xTimerGetPeriod_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTimerGetPeriodImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +TickType_t MPU_xTimerGetExpiryTime( TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TickType_t MPU_xTimerGetExpiryTime( TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTimerGetExpiryTimeImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTimerGetExpiryTime_Unpriv \n" + " MPU_xTimerGetExpiryTime_Priv: \n" + " pop {r0} \n" + " b MPU_xTimerGetExpiryTimeImpl \n" + " MPU_xTimerGetExpiryTime_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTimerGetExpiryTimeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +EventBits_t MPU_xEventGroupWaitBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToWaitFor, + const BaseType_t xClearOnExit, + const BaseType_t xWaitForAllBits, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +EventBits_t MPU_xEventGroupWaitBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToWaitFor, + const BaseType_t xClearOnExit, + const BaseType_t xWaitForAllBits, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupWaitBitsImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xEventGroupWaitBits_Unpriv \n" + " MPU_xEventGroupWaitBits_Priv: \n" + " pop {r0} \n" + " b MPU_xEventGroupWaitBitsImpl \n" + " MPU_xEventGroupWaitBits_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xEventGroupWaitBitsImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER_1 ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToClear ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToClear ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupClearBitsImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xEventGroupClearBits_Unpriv \n" + " MPU_xEventGroupClearBits_Priv: \n" + " pop {r0} \n" + " b MPU_xEventGroupClearBitsImpl \n" + " MPU_xEventGroupClearBits_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xEventGroupClearBitsImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupSetBitsImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xEventGroupSetBits_Unpriv \n" + " MPU_xEventGroupSetBits_Priv: \n" + " pop {r0} \n" + " b MPU_xEventGroupSetBitsImpl \n" + " MPU_xEventGroupSetBits_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xEventGroupSetBitsImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet, + const EventBits_t uxBitsToWaitFor, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet, + const EventBits_t uxBitsToWaitFor, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupSyncImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xEventGroupSync_Unpriv \n" + " MPU_xEventGroupSync_Priv: \n" + " pop {r0} \n" + " b MPU_xEventGroupSyncImpl \n" + " MPU_xEventGroupSync_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xEventGroupSyncImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + +UBaseType_t MPU_uxEventGroupGetNumber( void * xEventGroup ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxEventGroupGetNumber( void * xEventGroup ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxEventGroupGetNumberImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_uxEventGroupGetNumber_Unpriv \n" + " MPU_uxEventGroupGetNumber_Priv: \n" + " pop {r0} \n" + " b MPU_uxEventGroupGetNumberImpl \n" + " MPU_uxEventGroupGetNumber_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_uxEventGroupGetNumberImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /*( configUSE_TRACE_FACILITY == 1 )*/ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + +void MPU_vEventGroupSetNumber( void * xEventGroup, + UBaseType_t uxEventGroupNumber ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vEventGroupSetNumber( void * xEventGroup, + UBaseType_t uxEventGroupNumber ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vEventGroupSetNumberImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vEventGroupSetNumber_Unpriv \n" + " MPU_vEventGroupSetNumber_Priv: \n" + " pop {r0} \n" + " b MPU_vEventGroupSetNumberImpl \n" + " MPU_vEventGroupSetNumber_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vEventGroupSetNumberImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /*( configUSE_TRACE_FACILITY == 1 )*/ +/*-----------------------------------------------------------*/ + +size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, + const void * pvTxData, + size_t xDataLengthBytes, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, + const void * pvTxData, + size_t xDataLengthBytes, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferSendImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferSend_Unpriv \n" + " MPU_xStreamBufferSend_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferSendImpl \n" + " MPU_xStreamBufferSend_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xStreamBufferSendImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, + void * pvRxData, + size_t xBufferLengthBytes, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, + void * pvRxData, + size_t xBufferLengthBytes, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferReceiveImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferReceive_Unpriv \n" + " MPU_xStreamBufferReceive_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferReceiveImpl \n" + " MPU_xStreamBufferReceive_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xStreamBufferReceiveImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferIsFullImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferIsFull_Unpriv \n" + " MPU_xStreamBufferIsFull_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferIsFullImpl \n" + " MPU_xStreamBufferIsFull_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xStreamBufferIsFullImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferIsEmptyImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferIsEmpty_Unpriv \n" + " MPU_xStreamBufferIsEmpty_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferIsEmptyImpl \n" + " MPU_xStreamBufferIsEmpty_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xStreamBufferIsEmptyImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferSpacesAvailableImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferSpacesAvailable_Unpriv \n" + " MPU_xStreamBufferSpacesAvailable_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferSpacesAvailableImpl \n" + " MPU_xStreamBufferSpacesAvailable_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xStreamBufferSpacesAvailableImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferBytesAvailableImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferBytesAvailable_Unpriv \n" + " MPU_xStreamBufferBytesAvailable_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferBytesAvailableImpl \n" + " MPU_xStreamBufferBytesAvailable_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xStreamBufferBytesAvailableImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, + size_t xTriggerLevel ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, + size_t xTriggerLevel ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferSetTriggerLevelImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferSetTriggerLevel_Unpriv \n" + " MPU_xStreamBufferSetTriggerLevel_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferSetTriggerLevelImpl \n" + " MPU_xStreamBufferSetTriggerLevel_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xStreamBufferSetTriggerLevelImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferNextMessageLengthBytesImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferNextMessageLengthBytes_Unpriv \n" + " MPU_xStreamBufferNextMessageLengthBytes_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferNextMessageLengthBytesImpl \n" + " MPU_xStreamBufferNextMessageLengthBytes_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xStreamBufferNextMessageLengthBytesImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +#endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ diff --git a/portable/GCC/ARM_CM3_MPU/port.c b/portable/GCC/ARM_CM3_MPU/port.c old mode 100755 new mode 100644 index 619f2b0c8be..844b2ce1f53 --- a/portable/GCC/ARM_CM3_MPU/port.c +++ b/portable/GCC/ARM_CM3_MPU/port.c @@ -90,6 +90,7 @@ /* Constants required to set up the initial stack. */ #define portINITIAL_XPSR ( 0x01000000 ) +#define portINITIAL_EXC_RETURN ( 0xfffffffdUL ) #define portINITIAL_CONTROL_IF_UNPRIVILEGED ( 0x03 ) #define portINITIAL_CONTROL_IF_PRIVILEGED ( 0x02 ) @@ -103,12 +104,31 @@ #define portPRIORITY_GROUP_MASK ( 0x07UL << 8UL ) #define portPRIGROUP_SHIFT ( 8UL ) +/* Constants used during system call enter and exit. */ +#define portPSR_STACK_PADDING_MASK ( 1UL << 9UL ) + /* Offsets in the stack to the parameters when inside the SVC handler. */ +#define portOFFSET_TO_LR ( 5 ) #define portOFFSET_TO_PC ( 6 ) +#define portOFFSET_TO_PSR ( 7 ) /* For strict compliance with the Cortex-M spec the task start address should * have bit-0 clear, as it is loaded into the PC on exit from an ISR. */ #define portSTART_ADDRESS_MASK ( ( StackType_t ) 0xfffffffeUL ) + +/* Does addr lie within [start, end] address range? */ +#define portIS_ADDRESS_WITHIN_RANGE( addr, start, end ) \ + ( ( ( addr ) >= ( start ) ) && ( ( addr ) <= ( end ) ) ) + +/* Is the access request satisfied by the available permissions? */ +#define portIS_AUTHORIZED( accessRequest, permissions ) \ + ( ( ( permissions ) & ( accessRequest ) ) == accessRequest ) + +/* 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 ) ) ) /*-----------------------------------------------------------*/ /* @@ -146,7 +166,7 @@ static void prvRestoreContextOfFirstTask( void ) __attribute__( ( naked ) ) PRIV * C portion of the SVC handler. The SVC handler is split between an asm entry * and a C wrapper for simplicity of coding and maintenance. */ -static void prvSVCHandler( uint32_t * pulRegisters ) __attribute__( ( noinline ) ) PRIVILEGED_FUNCTION; +void vSVCHandler_C( uint32_t * pulRegisters ) __attribute__( ( noinline ) ) PRIVILEGED_FUNCTION; /** * @brief Checks whether or not the processor is privileged. @@ -182,6 +202,53 @@ void vResetPrivilege( void ) __attribute__( ( naked ) ); #else void vPortExitCritical( void ) PRIVILEGED_FUNCTION; #endif + +#if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + + /** + * @brief Sets up the system call stack so that upon returning from + * SVC, the system call stack is used. + * + * It is used for the system calls with up to 4 parameters. + * + * @param pulTaskStack The current SP when the SVC was raised. + */ + void vSystemCallEnter( uint32_t * pulTaskStack ) PRIVILEGED_FUNCTION; + +#endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + +#if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + + /** + * @brief Sets up the system call stack so that upon returning from + * SVC, the system call stack is used. + * + * It is used for the system calls with 5 parameters. + * + * @param pulTaskStack The current SP when the SVC was raised. + */ + void vSystemCallEnter_1( uint32_t * pulTaskStack ) PRIVILEGED_FUNCTION; + +#endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + +#if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + + /** + * @brief Sets up the task stack so that upon returning from + * SVC, the task stack is used again. + * + * @param pulSystemCallStack The current SP when the SVC was raised. + */ + void vSystemCallExit( uint32_t * pulSystemCallStack ) PRIVILEGED_FUNCTION; + +#endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + +/** + * @brief Checks whether or not the calling task is privileged. + * + * @return pdTRUE if the calling task is privileged, pdFALSE otherwise. + */ +BaseType_t xPortIsTaskPrivileged( void ) PRIVILEGED_FUNCTION; /*-----------------------------------------------------------*/ /* Each task maintains its own interrupt status in the critical nesting @@ -207,34 +274,91 @@ static UBaseType_t uxCriticalNesting = 0xaaaaaaaa; StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, TaskFunction_t pxCode, void * pvParameters, - BaseType_t xRunPrivileged ) + BaseType_t xRunPrivileged, + xMPU_SETTINGS * xMPUSettings ) { - /* Simulate the stack frame as it would be created by a context switch - * interrupt. */ - pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ - *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ - pxTopOfStack--; - *pxTopOfStack = ( ( StackType_t ) pxCode ) & portSTART_ADDRESS_MASK; /* PC */ - pxTopOfStack--; - *pxTopOfStack = 0; /* LR */ - pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ - *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ - pxTopOfStack -= 9; /* R11, R10, R9, R8, R7, R6, R5 and R4. */ - if( xRunPrivileged == pdTRUE ) { - *pxTopOfStack = portINITIAL_CONTROL_IF_PRIVILEGED; + xMPUSettings->ulTaskFlags |= portTASK_IS_PRIVILEGED_FLAG; + xMPUSettings->ulContext[ 0 ] = portINITIAL_CONTROL_IF_PRIVILEGED; } else { - *pxTopOfStack = portINITIAL_CONTROL_IF_UNPRIVILEGED; + xMPUSettings->ulTaskFlags &= ( ~portTASK_IS_PRIVILEGED_FLAG ); + xMPUSettings->ulContext[ 0 ] = portINITIAL_CONTROL_IF_UNPRIVILEGED; } + xMPUSettings->ulContext[ 1 ] = 0x04040404; /* r4. */ + xMPUSettings->ulContext[ 2 ] = 0x05050505; /* r5. */ + xMPUSettings->ulContext[ 3 ] = 0x06060606; /* r6. */ + xMPUSettings->ulContext[ 4 ] = 0x07070707; /* r7. */ + xMPUSettings->ulContext[ 5 ] = 0x08080808; /* r8. */ + xMPUSettings->ulContext[ 6 ] = 0x09090909; /* r9. */ + xMPUSettings->ulContext[ 7 ] = 0x10101010; /* r10. */ + xMPUSettings->ulContext[ 8 ] = 0x11111111; /* r11. */ + xMPUSettings->ulContext[ 9 ] = portINITIAL_EXC_RETURN; /* EXC_RETURN. */ + + xMPUSettings->ulContext[ 10 ] = ( uint32_t ) ( pxTopOfStack - 8 ); /* PSP with the hardware saved stack. */ + xMPUSettings->ulContext[ 11 ] = ( uint32_t ) pvParameters; /* r0. */ + xMPUSettings->ulContext[ 12 ] = 0x01010101; /* r1. */ + xMPUSettings->ulContext[ 13 ] = 0x02020202; /* r2. */ + xMPUSettings->ulContext[ 14 ] = 0x03030303; /* r3. */ + xMPUSettings->ulContext[ 15 ] = 0x12121212; /* r12. */ + xMPUSettings->ulContext[ 16 ] = 0; /* LR. */ + xMPUSettings->ulContext[ 17 ] = ( ( uint32_t ) pxCode ) & portSTART_ADDRESS_MASK; /* PC. */ + xMPUSettings->ulContext[ 18 ] = portINITIAL_XPSR; /* xPSR. */ + + #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + { + /* Ensure that the system call stack is double word aligned. */ + xMPUSettings->xSystemCallStackInfo.pulSystemCallStack = &( xMPUSettings->xSystemCallStackInfo.ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE - 1 ] ); + xMPUSettings->xSystemCallStackInfo.pulSystemCallStack = ( uint32_t * ) ( ( uint32_t ) ( xMPUSettings->xSystemCallStackInfo.pulSystemCallStack ) & + ( uint32_t ) ( ~( portBYTE_ALIGNMENT_MASK ) ) ); - return pxTopOfStack; + /* This is not NULL only for the duration of a system call. */ + xMPUSettings->xSystemCallStackInfo.pulTaskStack = NULL; + } + #endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + + return &( xMPUSettings->ulContext[ 19 ] ); } /*-----------------------------------------------------------*/ -void vPortSVCHandler( void ) +#if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + +void vPortSVCHandler( void ) /* __attribute__( ( naked ) ) PRIVILEGED_FUNCTION */ +{ + __asm volatile + ( + ".syntax unified \n" + ".extern vSVCHandler_C \n" + ".extern vSystemCallEnter \n" + ".extern vSystemCallEnter_1 \n" + ".extern vSystemCallExit \n" + " \n" + "tst lr, #4 \n" + "ite eq \n" + "mrseq r0, msp \n" + "mrsne r0, psp \n" + " \n" + "ldr r1, [r0, #24] \n" + "ldrb r2, [r1, #-2] \n" + "cmp r2, %0 \n" + "beq vSystemCallEnter \n" + "cmp r2, %1 \n" + "beq vSystemCallEnter_1 \n" + "cmp r2, %2 \n" + "beq vSystemCallExit \n" + "b vSVCHandler_C \n" + " \n" + : /* No outputs. */ + :"i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_ENTER_1 ), "i" ( portSVC_SYSTEM_CALL_EXIT ) + : "r0", "r1", "r2", "memory" + ); +} + +#else /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + +void vPortSVCHandler( void ) /* __attribute__( ( naked ) ) PRIVILEGED_FUNCTION */ { /* Assumes psp was in use. */ __asm volatile @@ -248,12 +372,14 @@ void vPortSVCHandler( void ) " mrs r0, psp \n" #endif " b %0 \n" - ::"i" ( prvSVCHandler ) : "r0", "memory" + ::"i" ( vSVCHandler_C ) : "r0", "memory" ); } + +#endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ /*-----------------------------------------------------------*/ -static void prvSVCHandler( uint32_t * pulParam ) +void vSVCHandler_C( uint32_t * pulParam ) /* PRIVILEGED_FUNCTION */ { uint8_t ucSVCNumber; uint32_t ulPC; @@ -262,7 +388,7 @@ static void prvSVCHandler( uint32_t * pulParam ) #if defined( __ARMCC_VERSION ) /* Declaration when these variable are defined in code instead of being - * exported from linker scripts. */ + * exported from linker scripts. */ extern uint32_t * __syscalls_flash_start__; extern uint32_t * __syscalls_flash_end__; #else @@ -296,7 +422,6 @@ static void prvSVCHandler( uint32_t * pulParam ) break; - #if ( configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY == 1 ) case portSVC_RAISE_PRIVILEGE: /* Only raise the privilege, if the * svc was raised from any of the @@ -325,7 +450,7 @@ static void prvSVCHandler( uint32_t * pulParam ) ::: "r1", "memory" ); break; - #endif /* #if( configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY == 1 ) */ + #endif /* #if( configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY == 1 ) */ default: /* Unknown SVC call. */ break; @@ -333,45 +458,311 @@ static void prvSVCHandler( uint32_t * pulParam ) } /*-----------------------------------------------------------*/ +#if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + +void vSystemCallEnter( uint32_t * pulTaskStack ) /* PRIVILEGED_FUNCTION */ +{ + extern TaskHandle_t pxCurrentTCB; + xMPU_SETTINGS * pxMpuSettings; + uint32_t * pulSystemCallStack; + uint32_t ulSystemCallLocation, i; + const uint32_t ulStackFrameSize = 8; + #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being + * exported from linker scripts. */ + extern uint32_t * __syscalls_flash_start__; + extern uint32_t * __syscalls_flash_end__; + #else + /* Declaration when these variable are exported from linker scripts. */ + extern uint32_t __syscalls_flash_start__[]; + extern uint32_t __syscalls_flash_end__[]; + #endif /* #if defined( __ARMCC_VERSION ) */ + + ulSystemCallLocation = pulTaskStack[ portOFFSET_TO_PC ]; + + /* If the request did not come from the system call section, do nothing. */ + if( ( ulSystemCallLocation >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulSystemCallLocation <= ( uint32_t ) __syscalls_flash_end__ ) ) + { + pxMpuSettings = xTaskGetMPUSettings( pxCurrentTCB ); + pulSystemCallStack = pxMpuSettings->xSystemCallStackInfo.pulSystemCallStack; + + /* This is not NULL only for the duration of the system call. */ + configASSERT( pxMpuSettings->xSystemCallStackInfo.pulTaskStack == NULL ); + + /* Make space on the system call stack for the stack frame. */ + pulSystemCallStack = pulSystemCallStack - ulStackFrameSize; + + /* Copy the stack frame. */ + for( i = 0; i < ulStackFrameSize; i++ ) + { + pulSystemCallStack[ i ] = pulTaskStack[ i ]; + } + + /* Use the pulSystemCallStack in thread mode. */ + __asm volatile ( "msr psp, %0" : : "r" ( pulSystemCallStack ) ); + + /* Raise the privilege for the duration of the system call. */ + __asm volatile ( + " mrs r1, control \n" /* Obtain current control value. */ + " bic r1, #1 \n" /* Clear nPRIV bit. */ + " msr control, r1 \n" /* Write back new control value. */ + ::: "r1", "memory" + ); + + /* Remember the location where we should copy the stack frame when we exit from + * the system call. */ + pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulStackFrameSize; + + /* Store the value of the Link Register before the SVC was raised. We need to + * restore it when we exit from the system call. */ + pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; + + /* Record if the hardware used padding to force the stack pointer + * to be double word aligned. */ + if( ( pulTaskStack[ portOFFSET_TO_PSR ] & portPSR_STACK_PADDING_MASK ) == portPSR_STACK_PADDING_MASK ) + { + pxMpuSettings->ulTaskFlags |= portSTACK_FRAME_HAS_PADDING_FLAG; + } + else + { + pxMpuSettings->ulTaskFlags &= ( ~portSTACK_FRAME_HAS_PADDING_FLAG ); + } + + /* We ensure in pxPortInitialiseStack that the system call stack is + * double word aligned and therefore, there is no need of padding. + * Clear the bit[9] of stacked xPSR. */ + pulSystemCallStack[ portOFFSET_TO_PSR ] &= ( ~portPSR_STACK_PADDING_MASK ); + } +} + +#endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + +void vSystemCallEnter_1( uint32_t * pulTaskStack ) /* PRIVILEGED_FUNCTION */ +{ + extern TaskHandle_t pxCurrentTCB; + xMPU_SETTINGS * pxMpuSettings; + uint32_t * pulSystemCallStack; + uint32_t ulSystemCallLocation, i; + const uint32_t ulStackFrameSize = 8; + #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being + * exported from linker scripts. */ + extern uint32_t * __syscalls_flash_start__; + extern uint32_t * __syscalls_flash_end__; + #else + /* Declaration when these variable are exported from linker scripts. */ + extern uint32_t __syscalls_flash_start__[]; + extern uint32_t __syscalls_flash_end__[]; + #endif /* #if defined( __ARMCC_VERSION ) */ + + ulSystemCallLocation = pulTaskStack[ portOFFSET_TO_PC ]; + + /* If the request did not come from the system call section, do nothing. */ + if( ( ulSystemCallLocation >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulSystemCallLocation <= ( uint32_t ) __syscalls_flash_end__ ) ) + { + pxMpuSettings = xTaskGetMPUSettings( pxCurrentTCB ); + pulSystemCallStack = pxMpuSettings->xSystemCallStackInfo.pulSystemCallStack; + + /* This is not NULL only for the duration of the system call. */ + configASSERT( pxMpuSettings->xSystemCallStackInfo.pulTaskStack == NULL ); + + /* Make space on the system call stack for the stack frame and + * the parameter passed on the stack. We only need to copy one + * parameter but we still reserve 2 spaces to keep the stack + * double word aligned. */ + pulSystemCallStack = pulSystemCallStack - ulStackFrameSize - 2UL; + + /* Copy the stack frame. */ + for( i = 0; i < ulStackFrameSize; i++ ) + { + pulSystemCallStack[ i ] = pulTaskStack[ i ]; + } + + /* Copy the parameter which is passed the stack. */ + if( ( pulTaskStack[ portOFFSET_TO_PSR ] & portPSR_STACK_PADDING_MASK ) == portPSR_STACK_PADDING_MASK ) + { + pulSystemCallStack[ ulStackFrameSize ] = pulTaskStack[ ulStackFrameSize + 1 ]; + /* Record if the hardware used padding to force the stack pointer + * to be double word aligned. */ + pxMpuSettings->ulTaskFlags |= portSTACK_FRAME_HAS_PADDING_FLAG; + } + else + { + pulSystemCallStack[ ulStackFrameSize ] = pulTaskStack[ ulStackFrameSize ]; + /* Record if the hardware used padding to force the stack pointer + * to be double word aligned. */ + pxMpuSettings->ulTaskFlags &= ( ~portSTACK_FRAME_HAS_PADDING_FLAG ); + } + + /* Use the pulSystemCallStack in thread mode. */ + __asm volatile ( "msr psp, %0" : : "r" ( pulSystemCallStack ) ); + + /* Raise the privilege for the duration of the system call. */ + __asm volatile ( + " mrs r1, control \n" /* Obtain current control value. */ + " bic r1, #1 \n" /* Clear nPRIV bit. */ + " msr control, r1 \n" /* Write back new control value. */ + ::: "r1", "memory" + ); + + /* Remember the location where we should copy the stack frame when we exit from + * the system call. */ + pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulStackFrameSize; + + /* Store the value of the Link Register before the SVC was raised. We need to + * restore it when we exit from the system call. */ + pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; + + /* We ensure in pxPortInitialiseStack that the system call stack is + * double word aligned and therefore, there is no need of padding. + * Clear the bit[9] of stacked xPSR. */ + pulSystemCallStack[ portOFFSET_TO_PSR ] &= ( ~portPSR_STACK_PADDING_MASK ); + } +} + +#endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + +void vSystemCallExit( uint32_t * pulSystemCallStack ) /* PRIVILEGED_FUNCTION */ +{ + extern TaskHandle_t pxCurrentTCB; + xMPU_SETTINGS * pxMpuSettings; + uint32_t * pulTaskStack; + uint32_t ulSystemCallLocation, i; + const uint32_t ulStackFrameSize = 8; + #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being + * exported from linker scripts. */ + extern uint32_t * __syscalls_flash_start__; + extern uint32_t * __syscalls_flash_end__; + #else + /* Declaration when these variable are exported from linker scripts. */ + extern uint32_t __syscalls_flash_start__[]; + extern uint32_t __syscalls_flash_end__[]; + #endif /* #if defined( __ARMCC_VERSION ) */ + + ulSystemCallLocation = pulSystemCallStack[ portOFFSET_TO_PC ]; + + /* If the request did not come from the system call section, do nothing. */ + if( ( ulSystemCallLocation >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulSystemCallLocation <= ( uint32_t ) __syscalls_flash_end__ ) ) + { + pxMpuSettings = xTaskGetMPUSettings( pxCurrentTCB ); + pulTaskStack = pxMpuSettings->xSystemCallStackInfo.pulTaskStack; + + /* Make space on the task stack for the stack frame. */ + pulTaskStack = pulTaskStack - ulStackFrameSize; + + /* Copy the stack frame. */ + for( i = 0; i < ulStackFrameSize; i++ ) + { + pulTaskStack[ i ] = pulSystemCallStack[ i ]; + } + + /* Use the pulTaskStack in thread mode. */ + __asm volatile ( "msr psp, %0" : : "r" ( pulTaskStack ) ); + + /* Drop the privilege before returning to the thread mode. */ + __asm volatile ( + " mrs r1, control \n" /* Obtain current control value. */ + " orr r1, #1 \n" /* Set nPRIV bit. */ + " msr control, r1 \n" /* Write back new control value. */ + ::: "r1", "memory" + ); + + /* Restore the stacked link register to what it was at the time of + * system call entry. */ + pulTaskStack[ portOFFSET_TO_LR ] = pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry; + + /* If the hardware used padding to force the stack pointer + * to be double word aligned, set the stacked xPSR bit[9], + * otherwise clear it. */ + if( ( pxMpuSettings->ulTaskFlags & portSTACK_FRAME_HAS_PADDING_FLAG ) == portSTACK_FRAME_HAS_PADDING_FLAG ) + { + pulTaskStack[ portOFFSET_TO_PSR ] |= portPSR_STACK_PADDING_MASK; + } + else + { + pulTaskStack[ portOFFSET_TO_PSR ] &= ( ~portPSR_STACK_PADDING_MASK ); + } + + /* This is not NULL only for the duration of the system call. */ + pxMpuSettings->xSystemCallStackInfo.pulTaskStack = NULL; + } +} + +#endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ +/*-----------------------------------------------------------*/ + +BaseType_t xPortIsTaskPrivileged( void ) /* PRIVILEGED_FUNCTION */ +{ + BaseType_t xTaskIsPrivileged = pdFALSE; + const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */ + + if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) + { + xTaskIsPrivileged = pdTRUE; + } + + return xTaskIsPrivileged; +} +/*-----------------------------------------------------------*/ + static void prvRestoreContextOfFirstTask( void ) { __asm volatile ( - " ldr r0, =0xE000ED08 \n"/* Use the NVIC offset register to locate the stack. */ - " ldr r0, [r0] \n" - " ldr r0, [r0] \n" - " msr msp, r0 \n"/* Set the msp back to the start of the stack. */ - " ldr r3, pxCurrentTCBConst2 \n"/* Restore the context. */ - " ldr r1, [r3] \n" - " ldr r0, [r1] \n"/* The first item in the TCB is the task top of stack. */ - " add r1, r1, #4 \n"/* Move onto the second item in the TCB... */ - " \n" - " dmb \n"/* Complete outstanding transfers before disabling MPU. */ - " ldr r2, =0xe000ed94 \n"/* MPU_CTRL register. */ - " ldr r3, [r2] \n"/* Read the value of MPU_CTRL. */ - " bic r3, #1 \n"/* r3 = r3 & ~1 i.e. Clear the bit 0 in r3. */ - " str r3, [r2] \n"/* Disable MPU. */ - " \n" - " ldr r2, =0xe000ed9c \n"/* Region Base Address register. */ - " ldmia r1!, {r4-r11} \n"/* Read 4 sets of MPU registers. */ - " stmia r2!, {r4-r11} \n"/* Write 4 sets of MPU registers. */ - " \n" - " ldr r2, =0xe000ed94 \n"/* MPU_CTRL register. */ - " ldr r3, [r2] \n"/* Read the value of MPU_CTRL. */ - " orr r3, #1 \n"/* r3 = r3 | 1 i.e. Set the bit 0 in r3. */ - " str r3, [r2] \n"/* Enable MPU. */ - " dsb \n"/* Force memory writes before continuing. */ - " \n" - " ldmia r0!, {r3, r4-r11} \n"/* Pop the registers that are not automatically saved on exception entry. */ - " msr control, r3 \n" - " msr psp, r0 \n"/* Restore the task stack pointer. */ - " mov r0, #0 \n" - " msr basepri, r0 \n" - " ldr r14, =0xfffffffd \n"/* Load exec return code. */ - " bx r14 \n" - " \n" - " .ltorg \n"/* Assemble current literal pool to avoid offset-out-of-bound errors with lto. */ - " .align 4 \n" + " ldr r0, =0xE000ED08 \n" /* Use the NVIC offset register to locate the stack. */ + " ldr r0, [r0] \n" + " ldr r0, [r0] \n" + " msr msp, r0 \n" /* Set the msp back to the start of the stack. */ + " \n" + /*------------ Program MPU. ------------ */ + " ldr r3, pxCurrentTCBConst2 \n" /* r3 = pxCurrentTCBConst2. */ + " ldr r2, [r3] \n" /* r2 = pxCurrentTCB. */ + " add r2, r2, #4 \n" /* r2 = Second item in the TCB which is xMPUSettings. */ + " \n" + " dmb \n" /* Complete outstanding transfers before disabling MPU. */ + " ldr r0, =0xe000ed94 \n" /* MPU_CTRL register. */ + " ldr r3, [r0] \n" /* Read the value of MPU_CTRL. */ + " bic r3, #1 \n" /* r3 = r3 & ~1 i.e. Clear the bit 0 in r3. */ + " str r3, [r0] \n" /* Disable MPU. */ + " \n" + " ldr r0, =0xe000ed9c \n" /* Region Base Address register. */ + " ldmia r2!, {r4-r11} \n" /* Read 4 sets of MPU registers [MPU Region # 0 - 3]. */ + " stmia r0, {r4-r11} \n" /* Write 4 sets of MPU registers [MPU Region # 0 - 3]. */ + " \n" + " ldr r0, =0xe000ed94 \n" /* MPU_CTRL register. */ + " ldr r3, [r0] \n" /* Read the value of MPU_CTRL. */ + " orr r3, #1 \n" /* r3 = r3 | 1 i.e. Set the bit 0 in r3. */ + " str r3, [r0] \n" /* Enable MPU. */ + " dsb \n" /* Force memory writes before continuing. */ + " \n" + /*---------- Restore Context. ---------- */ + " ldr r3, pxCurrentTCBConst2 \n" /* r3 = pxCurrentTCBConst2. */ + " ldr r2, [r3] \n" /* r2 = pxCurrentTCB. */ + " ldr r1, [r2] \n" /* r1 = Location of saved context in TCB. */ + " \n" + " ldmdb r1!, {r0, r4-r11} \n" /* r0 contains PSP after the hardware had saved context. r4-r11 contain hardware saved context. */ + " msr psp, r0 \n" + " stmia r0, {r4-r11} \n" /* Copy the hardware saved context on the task stack. */ + " ldmdb r1!, {r3-r11, lr} \n" /* r3 contains CONTROL register. r4-r11 and LR restored. */ + " msr control, r3 \n" + " str r1, [r2] \n" /* Save the location where the context should be saved next as the first member of TCB. */ + " \n" + " mov r0, #0 \n" + " msr basepri, r0 \n" + " bx lr \n" + " \n" + " .ltorg \n" /* Assemble current literal pool to avoid offset-out-of-bound errors with lto. */ + " .align 4 \n" "pxCurrentTCBConst2: .word pxCurrentTCB \n" ); } @@ -415,6 +806,10 @@ BaseType_t xPortStartScheduler( void ) * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ configASSERT( ucMaxSysCallPriority ); + /* Check that the bits not implemented in hardware are zero in + * configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & ( ~ucMaxPriorityValue ) ) == 0U ); + /* Calculate the maximum acceptable priority group value for the number * of bits read back. */ @@ -451,28 +846,6 @@ BaseType_t xPortStartScheduler( void ) ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulImplementedPrioBits; } - #ifdef __NVIC_PRIO_BITS - { - /* - * Check that the number of implemented priority bits queried from - * hardware is at least as many as specified in the CMSIS - * __NVIC_PRIO_BITS configuration macro. - */ - configASSERT( ulImplementedPrioBits >= __NVIC_PRIO_BITS ); - } - #endif - - #ifdef configPRIO_BITS - { - /* - * Check that the number of implemented priority bits queried from - * hardware is at least as many as specified in the FreeRTOS - * configPRIO_BITS configuration macro. - */ - configASSERT( ulImplementedPrioBits >= configPRIO_BITS ); - } - #endif - /* Shift the priority group value back to its position within the AIRCR * register. */ ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT; @@ -603,53 +976,66 @@ void xPortPendSVHandler( void ) __asm volatile ( - " mrs r0, psp \n" + " ldr r3, pxCurrentTCBConst \n" /* r3 = pxCurrentTCBConst. */ + " ldr r2, [r3] \n" /* r2 = pxCurrentTCB. */ + " ldr r1, [r2] \n" /* r1 = Location where the context should be saved. */ " \n" - " ldr r3, pxCurrentTCBConst \n"/* Get the location of the current TCB. */ - " ldr r2, [r3] \n" + /*------------ Save Context. ----------- */ + " mrs r3, control \n" + " mrs r0, psp \n" + " isb \n" " \n" - " mrs r1, control \n" - " stmdb r0!, {r1, r4-r11} \n"/* Save the remaining registers. */ - " str r0, [r2] \n"/* Save the new top of stack into the first member of the TCB. */ + " stmia r1!, {r3-r11, lr} \n" /* Store CONTROL register, r4-r11 and LR. */ + " ldmia r0, {r4-r11} \n" /* Copy hardware saved context into r4-r11. */ + " stmia r1!, {r0, r4-r11} \n" /* Store original PSP (after hardware has saved context) and the hardware saved context. */ + " str r1, [r2] \n" /* Save the location from where the context should be restored as the first member of TCB. */ " \n" - " stmdb sp!, {r3, r14} \n" - " mov r0, %0 \n" - " msr basepri, r0 \n" - " dsb \n" - " isb \n" - " bl vTaskSwitchContext \n" - " mov r0, #0 \n" - " msr basepri, r0 \n" - " ldmia sp!, {r3, r14} \n" - " \n"/* Restore the context. */ - " ldr r1, [r3] \n" - " ldr r0, [r1] \n"/* The first item in the TCB is the task top of stack. */ - " add r1, r1, #4 \n"/* Move onto the second item in the TCB... */ + /*---------- Select next task. --------- */ + " mov r0, %0 \n" + " msr basepri, r0 \n" + " dsb \n" + " isb \n" + " bl vTaskSwitchContext \n" + " mov r0, #0 \n" + " msr basepri, r0 \n" " \n" - " dmb \n"/* Complete outstanding transfers before disabling MPU. */ - " ldr r2, =0xe000ed94 \n"/* MPU_CTRL register. */ - " ldr r3, [r2] \n"/* Read the value of MPU_CTRL. */ - " bic r3, #1 \n"/* r3 = r3 & ~1 i.e. Clear the bit 0 in r3. */ - " str r3, [r2] \n"/* Disable MPU. */ + /*------------ Program MPU. ------------ */ + " ldr r3, pxCurrentTCBConst \n" /* r3 = pxCurrentTCBConst. */ + " ldr r2, [r3] \n" /* r2 = pxCurrentTCB. */ + " add r2, r2, #4 \n" /* r2 = Second item in the TCB which is xMPUSettings. */ " \n" - " ldr r2, =0xe000ed9c \n"/* Region Base Address register. */ - " ldmia r1!, {r4-r11} \n"/* Read 4 sets of MPU registers. */ - " stmia r2!, {r4-r11} \n"/* Write 4 sets of MPU registers. */ + " dmb \n" /* Complete outstanding transfers before disabling MPU. */ + " ldr r0, =0xe000ed94 \n" /* MPU_CTRL register. */ + " ldr r3, [r0] \n" /* Read the value of MPU_CTRL. */ + " bic r3, #1 \n" /* r3 = r3 & ~1 i.e. Clear the bit 0 in r3. */ + " str r3, [r0] \n" /* Disable MPU. */ " \n" - " ldr r2, =0xe000ed94 \n"/* MPU_CTRL register. */ - " ldr r3, [r2] \n"/* Read the value of MPU_CTRL. */ - " orr r3, #1 \n"/* r3 = r3 | 1 i.e. Set the bit 0 in r3. */ - " str r3, [r2] \n"/* Enable MPU. */ - " dsb \n"/* Force memory writes before continuing. */ + " ldr r0, =0xe000ed9c \n" /* Region Base Address register. */ + " ldmia r2!, {r4-r11} \n" /* Read 4 sets of MPU registers [MPU Region # 0 - 3]. */ + " stmia r0, {r4-r11} \n" /* Write 4 sets of MPU registers [MPU Region # 0 - 3]. */ " \n" - " ldmia r0!, {r3, r4-r11} \n"/* Pop the registers that are not automatically saved on exception entry. */ - " msr control, r3 \n" + " ldr r0, =0xe000ed94 \n" /* MPU_CTRL register. */ + " ldr r3, [r0] \n" /* Read the value of MPU_CTRL. */ + " orr r3, #1 \n" /* r3 = r3 | 1 i.e. Set the bit 0 in r3. */ + " str r3, [r0] \n" /* Enable MPU. */ + " dsb \n" /* Force memory writes before continuing. */ " \n" - " msr psp, r0 \n" - " bx r14 \n" + /*---------- Restore Context. ---------- */ + " ldr r3, pxCurrentTCBConst \n" /* r3 = pxCurrentTCBConst. */ + " ldr r2, [r3] \n" /* r2 = pxCurrentTCB. */ + " ldr r1, [r2] \n" /* r1 = Location of saved context in TCB. */ " \n" - " .ltorg \n"/* Assemble current literal pool to avoid offset-out-of-bound errors with lto. */ - " .align 4 \n" + " ldmdb r1!, {r0, r4-r11} \n" /* r0 contains PSP after the hardware had saved context. r4-r11 contain hardware saved context. */ + " msr psp, r0 \n" + " stmia r0, {r4-r11} \n" /* Copy the hardware saved context on the task stack. */ + " ldmdb r1!, {r3-r11, lr} \n" /* r3 contains CONTROL register. r4-r11 and LR restored. */ + " msr control, r3 \n" + " \n" + " str r1, [r2] \n" /* Save the location where the context should be saved next as the first member of TCB. */ + " bx lr \n" + " \n" + " .ltorg \n" /* Assemble current literal pool to avoid offset-out-of-bound errors with lto. */ + " .align 4 \n" "pxCurrentTCBConst: .word pxCurrentTCB \n" ::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) ); @@ -834,11 +1220,19 @@ void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings, ( prvGetMPURegionSizeSetting( ( uint32_t ) __SRAM_segment_end__ - ( uint32_t ) __SRAM_segment_start__ ) ) | ( portMPU_REGION_ENABLE ); + xMPUSettings->xRegionSettings[ 0 ].ulRegionStartAddress = ( uint32_t ) __SRAM_segment_start__; + xMPUSettings->xRegionSettings[ 0 ].ulRegionEndAddress = ( uint32_t ) __SRAM_segment_end__; + xMPUSettings->xRegionSettings[ 0 ].ulRegionPermissions = ( tskMPU_READ_PERMISSION | + tskMPU_WRITE_PERMISSION ); + /* Invalidate user configurable regions. */ for( ul = 1UL; ul <= portNUM_CONFIGURABLE_REGIONS; ul++ ) { xMPUSettings->xRegion[ ul ].ulRegionBaseAddress = ( ( ul - 1UL ) | portMPU_REGION_VALID ); xMPUSettings->xRegion[ ul ].ulRegionAttribute = 0UL; + xMPUSettings->xRegionSettings[ ul ].ulRegionStartAddress = 0UL; + xMPUSettings->xRegionSettings[ ul ].ulRegionEndAddress = 0UL; + xMPUSettings->xRegionSettings[ ul ].ulRegionPermissions = 0UL; } } else @@ -861,6 +1255,11 @@ void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings, ( prvGetMPURegionSizeSetting( ulStackDepth * ( uint32_t ) sizeof( StackType_t ) ) ) | ( portMPU_REGION_CACHEABLE_BUFFERABLE ) | ( portMPU_REGION_ENABLE ); + xMPUSettings->xRegionSettings[ 0 ].ulRegionStartAddress = ( uint32_t ) pxBottomOfStack; + xMPUSettings->xRegionSettings[ 0 ].ulRegionEndAddress = ( uint32_t ) ( ( uint32_t ) ( pxBottomOfStack ) + + ( ulStackDepth * ( uint32_t ) sizeof( StackType_t ) ) - 1UL ); + xMPUSettings->xRegionSettings[ 0 ].ulRegionPermissions = ( tskMPU_READ_PERMISSION | + tskMPU_WRITE_PERMISSION ); } lIndex = 0; @@ -881,12 +1280,28 @@ void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings, ( prvGetMPURegionSizeSetting( xRegions[ lIndex ].ulLengthInBytes ) ) | ( xRegions[ lIndex ].ulParameters ) | ( portMPU_REGION_ENABLE ); + + xMPUSettings->xRegionSettings[ ul ].ulRegionStartAddress = ( uint32_t ) xRegions[ lIndex ].pvBaseAddress; + xMPUSettings->xRegionSettings[ ul ].ulRegionEndAddress = ( uint32_t ) ( ( uint32_t ) xRegions[ lIndex ].pvBaseAddress + xRegions[ lIndex ].ulLengthInBytes - 1UL ); + xMPUSettings->xRegionSettings[ ul ].ulRegionPermissions = 0UL; + if( ( ( xRegions[ lIndex ].ulParameters & portMPU_REGION_READ_ONLY ) == portMPU_REGION_READ_ONLY ) || + ( ( xRegions[ lIndex ].ulParameters & portMPU_REGION_PRIVILEGED_READ_WRITE_UNPRIV_READ_ONLY ) == portMPU_REGION_PRIVILEGED_READ_WRITE_UNPRIV_READ_ONLY ) ) + { + xMPUSettings->xRegionSettings[ ul ].ulRegionPermissions = tskMPU_READ_PERMISSION; + } + if( ( xRegions[ lIndex ].ulParameters & portMPU_REGION_READ_WRITE ) == portMPU_REGION_READ_WRITE ) + { + xMPUSettings->xRegionSettings[ ul ].ulRegionPermissions = ( tskMPU_READ_PERMISSION | tskMPU_WRITE_PERMISSION ); + } } else { /* Invalidate the region. */ xMPUSettings->xRegion[ ul ].ulRegionBaseAddress = ( ( ul - 1UL ) | portMPU_REGION_VALID ); xMPUSettings->xRegion[ ul ].ulRegionAttribute = 0UL; + xMPUSettings->xRegionSettings[ ul ].ulRegionStartAddress = 0UL; + xMPUSettings->xRegionSettings[ ul ].ulRegionEndAddress = 0UL; + xMPUSettings->xRegionSettings[ ul ].ulRegionPermissions = 0UL; } lIndex++; @@ -895,6 +1310,47 @@ void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings, } /*-----------------------------------------------------------*/ +BaseType_t xPortIsAuthorizedToAccessBuffer( const void * pvBuffer, + uint32_t ulBufferLength, + uint32_t ulAccessRequested ) /* PRIVILEGED_FUNCTION */ + +{ + uint32_t i, ulBufferStartAddress, ulBufferEndAddress; + BaseType_t xAccessGranted = pdFALSE; + const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */ + + if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) + { + xAccessGranted = pdTRUE; + } + else + { + if( portADD_UINT32_WILL_OVERFLOW( ( ( uint32_t ) pvBuffer ), ( ulBufferLength - 1UL ) ) == pdFALSE ) + { + ulBufferStartAddress = ( uint32_t ) pvBuffer; + ulBufferEndAddress = ( ( ( uint32_t ) pvBuffer ) + ulBufferLength - 1UL ); + + for( i = 0; i < portTOTAL_NUM_REGIONS_IN_TCB; i++ ) + { + if( portIS_ADDRESS_WITHIN_RANGE( ulBufferStartAddress, + xTaskMpuSettings->xRegionSettings[ i ].ulRegionStartAddress, + xTaskMpuSettings->xRegionSettings[ i ].ulRegionEndAddress ) && + portIS_ADDRESS_WITHIN_RANGE( ulBufferEndAddress, + xTaskMpuSettings->xRegionSettings[ i ].ulRegionStartAddress, + xTaskMpuSettings->xRegionSettings[ i ].ulRegionEndAddress ) && + portIS_AUTHORIZED( ulAccessRequested, xTaskMpuSettings->xRegionSettings[ i ].ulRegionPermissions ) ) + { + xAccessGranted = pdTRUE; + break; + } + } + } + } + + return xAccessGranted; +} +/*-----------------------------------------------------------*/ + #if ( configASSERT_DEFINED == 1 ) void vPortValidateInterruptPriority( void ) @@ -954,4 +1410,4 @@ void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings, } #endif /* configASSERT_DEFINED */ -/*-----------------------------------------------------------*/ \ No newline at end of file +/*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM3_MPU/portmacro.h b/portable/GCC/ARM_CM3_MPU/portmacro.h index b15193f1ee5..d1f659e3789 100644 --- a/portable/GCC/ARM_CM3_MPU/portmacro.h +++ b/portable/GCC/ARM_CM3_MPU/portmacro.h @@ -104,10 +104,45 @@ uint32_t ulRegionAttribute; } xMPU_REGION_REGISTERS; -/* Plus 1 to create space for the stack region. */ + typedef struct MPU_REGION_SETTINGS + { + uint32_t ulRegionStartAddress; + uint32_t ulRegionEndAddress; + uint32_t ulRegionPermissions; + } xMPU_REGION_SETTINGS; + + #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + + #ifndef configSYSTEM_CALL_STACK_SIZE + #error configSYSTEM_CALL_STACK_SIZE must be defined to the desired size of the system call stack in words for using MPU wrappers v2. + #endif + + typedef struct SYSTEM_CALL_STACK_INFO + { + uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ]; + uint32_t * pulSystemCallStack; + uint32_t * pulTaskStack; + uint32_t ulLinkRegisterAtSystemCallEntry; + } xSYSTEM_CALL_STACK_INFO; + + #endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + + #define MAX_CONTEXT_SIZE 20 + + /* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ + #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) + #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) + typedef struct MPU_SETTINGS { xMPU_REGION_REGISTERS xRegion[ portTOTAL_NUM_REGIONS_IN_TCB ]; + xMPU_REGION_SETTINGS xRegionSettings[ portTOTAL_NUM_REGIONS_IN_TCB ]; + uint32_t ulContext[ MAX_CONTEXT_SIZE ]; + uint32_t ulTaskFlags; + + #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo; + #endif } xMPU_SETTINGS; /* Architecture specifics. */ @@ -115,13 +150,15 @@ #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) #define portBYTE_ALIGNMENT 8 #define portDONT_DISCARD __attribute__( ( used ) ) - #define portNORETURN __attribute__( ( noreturn ) ) /*-----------------------------------------------------------*/ /* SVC numbers for various services. */ - #define portSVC_START_SCHEDULER 0 - #define portSVC_YIELD 1 - #define portSVC_RAISE_PRIVILEGE 2 + #define portSVC_START_SCHEDULER 0 + #define portSVC_YIELD 1 + #define portSVC_RAISE_PRIVILEGE 2 + #define portSVC_SYSTEM_CALL_ENTER 3 /* System calls with upto 4 parameters. */ + #define portSVC_SYSTEM_CALL_ENTER_1 4 /* System calls with 5 parameters. */ + #define portSVC_SYSTEM_CALL_EXIT 5 /* Scheduler utilities. */ @@ -233,6 +270,16 @@ #define portRESET_PRIVILEGE() vResetPrivilege() /*-----------------------------------------------------------*/ + extern BaseType_t xPortIsTaskPrivileged( void ); + +/** + * @brief Checks whether or not the calling task is privileged. + * + * @return pdTRUE if the calling task is privileged, pdFALSE otherwise. + */ + #define portIS_TASK_PRIVILEGED() xPortIsTaskPrivileged() +/*-----------------------------------------------------------*/ + portFORCE_INLINE static BaseType_t xPortIsInsideInterrupt( void ) { uint32_t ulCurrentInterrupt; diff --git a/portable/GCC/ARM_CM4F/port.c b/portable/GCC/ARM_CM4F/port.c old mode 100755 new mode 100644 index 88fc76db894..d18854e1beb --- a/portable/GCC/ARM_CM4F/port.c +++ b/portable/GCC/ARM_CM4F/port.c @@ -335,6 +335,10 @@ BaseType_t xPortStartScheduler( void ) * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ configASSERT( ucMaxSysCallPriority ); + /* Check that the bits not implemented in hardware are zero in + * configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & ( ~ucMaxPriorityValue ) ) == 0U ); + /* Calculate the maximum acceptable priority group value for the number * of bits read back. */ @@ -371,28 +375,6 @@ BaseType_t xPortStartScheduler( void ) ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulImplementedPrioBits; } - #ifdef __NVIC_PRIO_BITS - { - /* - * Check that the number of implemented priority bits queried from - * hardware is at least as many as specified in the CMSIS - * __NVIC_PRIO_BITS configuration macro. - */ - configASSERT( ulImplementedPrioBits >= __NVIC_PRIO_BITS ); - } - #endif - - #ifdef configPRIO_BITS - { - /* - * Check that the number of implemented priority bits queried from - * hardware is at least as many as specified in the FreeRTOS - * configPRIO_BITS configuration macro. - */ - configASSERT( ulImplementedPrioBits >= configPRIO_BITS ); - } - #endif - /* Shift the priority group value back to its position within the AIRCR * register. */ ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT; diff --git a/portable/GCC/ARM_CM4F/portmacro.h b/portable/GCC/ARM_CM4F/portmacro.h index 443661a6d3a..532eefa7405 100644 --- a/portable/GCC/ARM_CM4F/portmacro.h +++ b/portable/GCC/ARM_CM4F/portmacro.h @@ -82,7 +82,6 @@ #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) #define portBYTE_ALIGNMENT 8 #define portDONT_DISCARD __attribute__( ( used ) ) - #define portNORETURN __attribute__( ( noreturn ) ) /*-----------------------------------------------------------*/ /* Scheduler utilities. */ diff --git a/portable/GCC/ARM_CM4_MPU/mpu_wrappers_v2_asm.c b/portable/GCC/ARM_CM4_MPU/mpu_wrappers_v2_asm.c new file mode 100644 index 00000000000..df9239a41d6 --- /dev/null +++ b/portable/GCC/ARM_CM4_MPU/mpu_wrappers_v2_asm.c @@ -0,0 +1,2349 @@ +/* + * FreeRTOS Kernel + * Copyright (C) 2021 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 + * + */ + +/* 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. */ +#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +/* Scheduler includes. */ +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" +#include "timers.h" +#include "event_groups.h" +#include "stream_buffer.h" + +#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE +/*-----------------------------------------------------------*/ + +#if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + +#if ( INCLUDE_xTaskDelayUntil == 1 ) + +BaseType_t MPU_xTaskDelayUntil( TickType_t * const pxPreviousWakeTime, + const TickType_t xTimeIncrement ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskDelayUntil( TickType_t * const pxPreviousWakeTime, + const TickType_t xTimeIncrement ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskDelayUntilImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskDelayUntil_Unpriv \n" + " MPU_xTaskDelayUntil_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskDelayUntilImpl \n" + " MPU_xTaskDelayUntil_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskDelayUntilImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_xTaskDelayUntil == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_xTaskAbortDelay == 1 ) + +BaseType_t MPU_xTaskAbortDelay( TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskAbortDelay( TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskAbortDelayImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskAbortDelay_Unpriv \n" + " MPU_xTaskAbortDelay_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskAbortDelayImpl \n" + " MPU_xTaskAbortDelay_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskAbortDelayImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_xTaskAbortDelay == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskDelay == 1 ) + +void MPU_vTaskDelay( const TickType_t xTicksToDelay ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskDelay( const TickType_t xTicksToDelay ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskDelayImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vTaskDelay_Unpriv \n" + " MPU_vTaskDelay_Priv: \n" + " pop {r0} \n" + " b MPU_vTaskDelayImpl \n" + " MPU_vTaskDelay_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vTaskDelayImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_vTaskDelay == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_uxTaskPriorityGet == 1 ) + +UBaseType_t MPU_uxTaskPriorityGet( const TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxTaskPriorityGet( const TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxTaskPriorityGetImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_uxTaskPriorityGet_Unpriv \n" + " MPU_uxTaskPriorityGet_Priv: \n" + " pop {r0} \n" + " b MPU_uxTaskPriorityGetImpl \n" + " MPU_uxTaskPriorityGet_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_uxTaskPriorityGetImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_uxTaskPriorityGet == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_eTaskGetState == 1 ) + +eTaskState MPU_eTaskGetState( TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +eTaskState MPU_eTaskGetState( TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_eTaskGetStateImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_eTaskGetState_Unpriv \n" + " MPU_eTaskGetState_Priv: \n" + " pop {r0} \n" + " b MPU_eTaskGetStateImpl \n" + " MPU_eTaskGetState_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_eTaskGetStateImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_eTaskGetState == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + +void MPU_vTaskGetInfo( TaskHandle_t xTask, + TaskStatus_t * pxTaskStatus, + BaseType_t xGetFreeStackSpace, + eTaskState eState ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskGetInfo( TaskHandle_t xTask, + TaskStatus_t * pxTaskStatus, + BaseType_t xGetFreeStackSpace, + eTaskState eState ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskGetInfoImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vTaskGetInfo_Unpriv \n" + " MPU_vTaskGetInfo_Priv: \n" + " pop {r0} \n" + " b MPU_vTaskGetInfoImpl \n" + " MPU_vTaskGetInfo_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vTaskGetInfoImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TRACE_FACILITY == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) + +TaskHandle_t MPU_xTaskGetIdleTaskHandle( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TaskHandle_t MPU_xTaskGetIdleTaskHandle( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGetIdleTaskHandleImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskGetIdleTaskHandle_Unpriv \n" + " MPU_xTaskGetIdleTaskHandle_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskGetIdleTaskHandleImpl \n" + " MPU_xTaskGetIdleTaskHandle_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskGetIdleTaskHandleImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskSuspend == 1 ) + +void MPU_vTaskSuspend( TaskHandle_t xTaskToSuspend ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskSuspend( TaskHandle_t xTaskToSuspend ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskSuspendImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vTaskSuspend_Unpriv \n" + " MPU_vTaskSuspend_Priv: \n" + " pop {r0} \n" + " b MPU_vTaskSuspendImpl \n" + " MPU_vTaskSuspend_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vTaskSuspendImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_vTaskSuspend == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskSuspend == 1 ) + +void MPU_vTaskResume( TaskHandle_t xTaskToResume ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskResume( TaskHandle_t xTaskToResume ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskResumeImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vTaskResume_Unpriv \n" + " MPU_vTaskResume_Priv: \n" + " pop {r0} \n" + " b MPU_vTaskResumeImpl \n" + " MPU_vTaskResume_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vTaskResumeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_vTaskSuspend == 1 ) */ +/*-----------------------------------------------------------*/ + +TickType_t MPU_xTaskGetTickCount( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TickType_t MPU_xTaskGetTickCount( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGetTickCountImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskGetTickCount_Unpriv \n" + " MPU_xTaskGetTickCount_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskGetTickCountImpl \n" + " MPU_xTaskGetTickCount_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskGetTickCountImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +UBaseType_t MPU_uxTaskGetNumberOfTasks( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxTaskGetNumberOfTasks( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxTaskGetNumberOfTasksImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_uxTaskGetNumberOfTasks_Unpriv \n" + " MPU_uxTaskGetNumberOfTasks_Priv: \n" + " pop {r0} \n" + " b MPU_uxTaskGetNumberOfTasksImpl \n" + " MPU_uxTaskGetNumberOfTasks_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_uxTaskGetNumberOfTasksImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +char * MPU_pcTaskGetName( TaskHandle_t xTaskToQuery ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +char * MPU_pcTaskGetName( TaskHandle_t xTaskToQuery ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_pcTaskGetNameImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_pcTaskGetName_Unpriv \n" + " MPU_pcTaskGetName_Priv: \n" + " pop {r0} \n" + " b MPU_pcTaskGetNameImpl \n" + " MPU_pcTaskGetName_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_pcTaskGetNameImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +#if ( configGENERATE_RUN_TIME_STATS == 1 ) + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetRunTimeCounter( const TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetRunTimeCounter( const TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_ulTaskGetRunTimeCounterImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_ulTaskGetRunTimeCounter_Unpriv \n" + " MPU_ulTaskGetRunTimeCounter_Priv: \n" + " pop {r0} \n" + " b MPU_ulTaskGetRunTimeCounterImpl \n" + " MPU_ulTaskGetRunTimeCounter_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_ulTaskGetRunTimeCounterImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( ( configGENERATE_RUN_TIME_STATS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configGENERATE_RUN_TIME_STATS == 1 ) + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetRunTimePercent( const TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetRunTimePercent( const TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_ulTaskGetRunTimePercentImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_ulTaskGetRunTimePercent_Unpriv \n" + " MPU_ulTaskGetRunTimePercent_Priv: \n" + " pop {r0} \n" + " b MPU_ulTaskGetRunTimePercentImpl \n" + " MPU_ulTaskGetRunTimePercent_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_ulTaskGetRunTimePercentImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( ( configGENERATE_RUN_TIME_STATS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimePercent( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimePercent( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_ulTaskGetIdleRunTimePercentImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_ulTaskGetIdleRunTimePercent_Unpriv \n" + " MPU_ulTaskGetIdleRunTimePercent_Priv: \n" + " pop {r0} \n" + " b MPU_ulTaskGetIdleRunTimePercentImpl \n" + " MPU_ulTaskGetIdleRunTimePercent_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_ulTaskGetIdleRunTimePercentImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimeCounter( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimeCounter( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_ulTaskGetIdleRunTimeCounterImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_ulTaskGetIdleRunTimeCounter_Unpriv \n" + " MPU_ulTaskGetIdleRunTimeCounter_Priv: \n" + " pop {r0} \n" + " b MPU_ulTaskGetIdleRunTimeCounterImpl \n" + " MPU_ulTaskGetIdleRunTimeCounter_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_ulTaskGetIdleRunTimeCounterImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_APPLICATION_TASK_TAG == 1 ) + +void MPU_vTaskSetApplicationTaskTag( TaskHandle_t xTask, + TaskHookFunction_t pxHookFunction ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskSetApplicationTaskTag( TaskHandle_t xTask, + TaskHookFunction_t pxHookFunction ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskSetApplicationTaskTagImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vTaskSetApplicationTaskTag_Unpriv \n" + " MPU_vTaskSetApplicationTaskTag_Priv: \n" + " pop {r0} \n" + " b MPU_vTaskSetApplicationTaskTagImpl \n" + " MPU_vTaskSetApplicationTaskTag_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vTaskSetApplicationTaskTagImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_APPLICATION_TASK_TAG == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_APPLICATION_TASK_TAG == 1 ) + +TaskHookFunction_t MPU_xTaskGetApplicationTaskTag( TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TaskHookFunction_t MPU_xTaskGetApplicationTaskTag( TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGetApplicationTaskTagImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskGetApplicationTaskTag_Unpriv \n" + " MPU_xTaskGetApplicationTaskTag_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskGetApplicationTaskTagImpl \n" + " MPU_xTaskGetApplicationTaskTag_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskGetApplicationTaskTagImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_APPLICATION_TASK_TAG == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) + +void MPU_vTaskSetThreadLocalStoragePointer( TaskHandle_t xTaskToSet, + BaseType_t xIndex, + void * pvValue ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskSetThreadLocalStoragePointer( TaskHandle_t xTaskToSet, + BaseType_t xIndex, + void * pvValue ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskSetThreadLocalStoragePointerImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vTaskSetThreadLocalStoragePointer_Unpriv \n" + " MPU_vTaskSetThreadLocalStoragePointer_Priv: \n" + " pop {r0} \n" + " b MPU_vTaskSetThreadLocalStoragePointerImpl \n" + " MPU_vTaskSetThreadLocalStoragePointer_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vTaskSetThreadLocalStoragePointerImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) + +void * MPU_pvTaskGetThreadLocalStoragePointer( TaskHandle_t xTaskToQuery, + BaseType_t xIndex ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void * MPU_pvTaskGetThreadLocalStoragePointer( TaskHandle_t xTaskToQuery, + BaseType_t xIndex ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_pvTaskGetThreadLocalStoragePointerImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_pvTaskGetThreadLocalStoragePointer_Unpriv \n" + " MPU_pvTaskGetThreadLocalStoragePointer_Priv: \n" + " pop {r0} \n" + " b MPU_pvTaskGetThreadLocalStoragePointerImpl \n" + " MPU_pvTaskGetThreadLocalStoragePointer_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_pvTaskGetThreadLocalStoragePointerImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + +UBaseType_t MPU_uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray, + const UBaseType_t uxArraySize, + configRUN_TIME_COUNTER_TYPE * const pulTotalRunTime ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray, + const UBaseType_t uxArraySize, + configRUN_TIME_COUNTER_TYPE * const pulTotalRunTime ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxTaskGetSystemStateImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_uxTaskGetSystemState_Unpriv \n" + " MPU_uxTaskGetSystemState_Priv: \n" + " pop {r0} \n" + " b MPU_uxTaskGetSystemStateImpl \n" + " MPU_uxTaskGetSystemState_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_uxTaskGetSystemStateImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TRACE_FACILITY == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) + +UBaseType_t MPU_uxTaskGetStackHighWaterMark( TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxTaskGetStackHighWaterMark( TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxTaskGetStackHighWaterMarkImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_uxTaskGetStackHighWaterMark_Unpriv \n" + " MPU_uxTaskGetStackHighWaterMark_Priv: \n" + " pop {r0} \n" + " b MPU_uxTaskGetStackHighWaterMarkImpl \n" + " MPU_uxTaskGetStackHighWaterMark_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_uxTaskGetStackHighWaterMarkImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) + +configSTACK_DEPTH_TYPE MPU_uxTaskGetStackHighWaterMark2( TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +configSTACK_DEPTH_TYPE MPU_uxTaskGetStackHighWaterMark2( TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxTaskGetStackHighWaterMark2Impl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_uxTaskGetStackHighWaterMark2_Unpriv \n" + " MPU_uxTaskGetStackHighWaterMark2_Priv: \n" + " pop {r0} \n" + " b MPU_uxTaskGetStackHighWaterMark2Impl \n" + " MPU_uxTaskGetStackHighWaterMark2_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_uxTaskGetStackHighWaterMark2Impl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) ) + +TaskHandle_t MPU_xTaskGetCurrentTaskHandle( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TaskHandle_t MPU_xTaskGetCurrentTaskHandle( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGetCurrentTaskHandleImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskGetCurrentTaskHandle_Unpriv \n" + " MPU_xTaskGetCurrentTaskHandle_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskGetCurrentTaskHandleImpl \n" + " MPU_xTaskGetCurrentTaskHandle_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskGetCurrentTaskHandleImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_xTaskGetSchedulerState == 1 ) + +BaseType_t MPU_xTaskGetSchedulerState( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskGetSchedulerState( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGetSchedulerStateImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskGetSchedulerState_Unpriv \n" + " MPU_xTaskGetSchedulerState_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskGetSchedulerStateImpl \n" + " MPU_xTaskGetSchedulerState_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskGetSchedulerStateImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_xTaskGetSchedulerState == 1 ) */ +/*-----------------------------------------------------------*/ + +void MPU_vTaskSetTimeOutState( TimeOut_t * const pxTimeOut ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskSetTimeOutState( TimeOut_t * const pxTimeOut ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskSetTimeOutStateImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vTaskSetTimeOutState_Unpriv \n" + " MPU_vTaskSetTimeOutState_Priv: \n" + " pop {r0} \n" + " b MPU_vTaskSetTimeOutStateImpl \n" + " MPU_vTaskSetTimeOutState_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vTaskSetTimeOutStateImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut, + TickType_t * const pxTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut, + TickType_t * const pxTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskCheckForTimeOutImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskCheckForTimeOut_Unpriv \n" + " MPU_xTaskCheckForTimeOut_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskCheckForTimeOutImpl \n" + " MPU_xTaskCheckForTimeOut_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskCheckForTimeOutImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +#if ( configUSE_TASK_NOTIFICATIONS == 1 ) + +BaseType_t MPU_xTaskGenericNotify( TaskHandle_t xTaskToNotify, + UBaseType_t uxIndexToNotify, + uint32_t ulValue, + eNotifyAction eAction, + uint32_t * pulPreviousNotificationValue ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskGenericNotify( TaskHandle_t xTaskToNotify, + UBaseType_t uxIndexToNotify, + uint32_t ulValue, + eNotifyAction eAction, + uint32_t * pulPreviousNotificationValue ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGenericNotifyImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskGenericNotify_Unpriv \n" + " MPU_xTaskGenericNotify_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskGenericNotifyImpl \n" + " MPU_xTaskGenericNotify_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskGenericNotifyImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER_1 ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TASK_NOTIFICATIONS == 1 ) + +BaseType_t MPU_xTaskGenericNotifyWait( UBaseType_t uxIndexToWaitOn, + uint32_t ulBitsToClearOnEntry, + uint32_t ulBitsToClearOnExit, + uint32_t * pulNotificationValue, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskGenericNotifyWait( UBaseType_t uxIndexToWaitOn, + uint32_t ulBitsToClearOnEntry, + uint32_t ulBitsToClearOnExit, + uint32_t * pulNotificationValue, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGenericNotifyWaitImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskGenericNotifyWait_Unpriv \n" + " MPU_xTaskGenericNotifyWait_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskGenericNotifyWaitImpl \n" + " MPU_xTaskGenericNotifyWait_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskGenericNotifyWaitImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER_1 ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TASK_NOTIFICATIONS == 1 ) + +uint32_t MPU_ulTaskGenericNotifyTake( UBaseType_t uxIndexToWaitOn, + BaseType_t xClearCountOnExit, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +uint32_t MPU_ulTaskGenericNotifyTake( UBaseType_t uxIndexToWaitOn, + BaseType_t xClearCountOnExit, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_ulTaskGenericNotifyTakeImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_ulTaskGenericNotifyTake_Unpriv \n" + " MPU_ulTaskGenericNotifyTake_Priv: \n" + " pop {r0} \n" + " b MPU_ulTaskGenericNotifyTakeImpl \n" + " MPU_ulTaskGenericNotifyTake_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_ulTaskGenericNotifyTakeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TASK_NOTIFICATIONS == 1 ) + +BaseType_t MPU_xTaskGenericNotifyStateClear( TaskHandle_t xTask, + UBaseType_t uxIndexToClear ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskGenericNotifyStateClear( TaskHandle_t xTask, + UBaseType_t uxIndexToClear ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGenericNotifyStateClearImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskGenericNotifyStateClear_Unpriv \n" + " MPU_xTaskGenericNotifyStateClear_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskGenericNotifyStateClearImpl \n" + " MPU_xTaskGenericNotifyStateClear_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskGenericNotifyStateClearImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TASK_NOTIFICATIONS == 1 ) + +uint32_t MPU_ulTaskGenericNotifyValueClear( TaskHandle_t xTask, + UBaseType_t uxIndexToClear, + uint32_t ulBitsToClear ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +uint32_t MPU_ulTaskGenericNotifyValueClear( TaskHandle_t xTask, + UBaseType_t uxIndexToClear, + uint32_t ulBitsToClear ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_ulTaskGenericNotifyValueClearImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_ulTaskGenericNotifyValueClear_Unpriv \n" + " MPU_ulTaskGenericNotifyValueClear_Priv: \n" + " pop {r0} \n" + " b MPU_ulTaskGenericNotifyValueClearImpl \n" + " MPU_ulTaskGenericNotifyValueClear_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_ulTaskGenericNotifyValueClearImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xQueueGenericSend( QueueHandle_t xQueue, + const void * const pvItemToQueue, + TickType_t xTicksToWait, + const BaseType_t xCopyPosition ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueueGenericSend( QueueHandle_t xQueue, + const void * const pvItemToQueue, + TickType_t xTicksToWait, + const BaseType_t xCopyPosition ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueGenericSendImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xQueueGenericSend_Unpriv \n" + " MPU_xQueueGenericSend_Priv: \n" + " pop {r0} \n" + " b MPU_xQueueGenericSendImpl \n" + " MPU_xQueueGenericSend_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xQueueGenericSendImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +UBaseType_t MPU_uxQueueMessagesWaiting( const QueueHandle_t xQueue ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxQueueMessagesWaiting( const QueueHandle_t xQueue ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxQueueMessagesWaitingImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_uxQueueMessagesWaiting_Unpriv \n" + " MPU_uxQueueMessagesWaiting_Priv: \n" + " pop {r0} \n" + " b MPU_uxQueueMessagesWaitingImpl \n" + " MPU_uxQueueMessagesWaiting_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_uxQueueMessagesWaitingImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +UBaseType_t MPU_uxQueueSpacesAvailable( const QueueHandle_t xQueue ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxQueueSpacesAvailable( const QueueHandle_t xQueue ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxQueueSpacesAvailableImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_uxQueueSpacesAvailable_Unpriv \n" + " MPU_uxQueueSpacesAvailable_Priv: \n" + " pop {r0} \n" + " b MPU_uxQueueSpacesAvailableImpl \n" + " MPU_uxQueueSpacesAvailable_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_uxQueueSpacesAvailableImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xQueueReceive( QueueHandle_t xQueue, + void * const pvBuffer, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueueReceive( QueueHandle_t xQueue, + void * const pvBuffer, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueReceiveImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xQueueReceive_Unpriv \n" + " MPU_xQueueReceive_Priv: \n" + " pop {r0} \n" + " b MPU_xQueueReceiveImpl \n" + " MPU_xQueueReceive_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xQueueReceiveImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xQueuePeek( QueueHandle_t xQueue, + void * const pvBuffer, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueuePeek( QueueHandle_t xQueue, + void * const pvBuffer, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueuePeekImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xQueuePeek_Unpriv \n" + " MPU_xQueuePeek_Priv: \n" + " pop {r0} \n" + " b MPU_xQueuePeekImpl \n" + " MPU_xQueuePeek_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xQueuePeekImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xQueueSemaphoreTake( QueueHandle_t xQueue, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueueSemaphoreTake( QueueHandle_t xQueue, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueSemaphoreTakeImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xQueueSemaphoreTake_Unpriv \n" + " MPU_xQueueSemaphoreTake_Priv: \n" + " pop {r0} \n" + " b MPU_xQueueSemaphoreTakeImpl \n" + " MPU_xQueueSemaphoreTake_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xQueueSemaphoreTakeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +#if ( ( configUSE_MUTEXES == 1 ) && ( INCLUDE_xSemaphoreGetMutexHolder == 1 ) ) + +TaskHandle_t MPU_xQueueGetMutexHolder( QueueHandle_t xSemaphore ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TaskHandle_t MPU_xQueueGetMutexHolder( QueueHandle_t xSemaphore ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueGetMutexHolderImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xQueueGetMutexHolder_Unpriv \n" + " MPU_xQueueGetMutexHolder_Priv: \n" + " pop {r0} \n" + " b MPU_xQueueGetMutexHolderImpl \n" + " MPU_xQueueGetMutexHolder_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xQueueGetMutexHolderImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( ( configUSE_MUTEXES == 1 ) && ( INCLUDE_xSemaphoreGetMutexHolder == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_RECURSIVE_MUTEXES == 1 ) + +BaseType_t MPU_xQueueTakeMutexRecursive( QueueHandle_t xMutex, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueueTakeMutexRecursive( QueueHandle_t xMutex, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueTakeMutexRecursiveImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xQueueTakeMutexRecursive_Unpriv \n" + " MPU_xQueueTakeMutexRecursive_Priv: \n" + " pop {r0} \n" + " b MPU_xQueueTakeMutexRecursiveImpl \n" + " MPU_xQueueTakeMutexRecursive_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xQueueTakeMutexRecursiveImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_RECURSIVE_MUTEXES == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_RECURSIVE_MUTEXES == 1 ) + +BaseType_t MPU_xQueueGiveMutexRecursive( QueueHandle_t pxMutex ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueueGiveMutexRecursive( QueueHandle_t pxMutex ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueGiveMutexRecursiveImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xQueueGiveMutexRecursive_Unpriv \n" + " MPU_xQueueGiveMutexRecursive_Priv: \n" + " pop {r0} \n" + " b MPU_xQueueGiveMutexRecursiveImpl \n" + " MPU_xQueueGiveMutexRecursive_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xQueueGiveMutexRecursiveImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_RECURSIVE_MUTEXES == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_QUEUE_SETS == 1 ) + +QueueSetMemberHandle_t MPU_xQueueSelectFromSet( QueueSetHandle_t xQueueSet, + const TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +QueueSetMemberHandle_t MPU_xQueueSelectFromSet( QueueSetHandle_t xQueueSet, + const TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueSelectFromSetImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xQueueSelectFromSet_Unpriv \n" + " MPU_xQueueSelectFromSet_Priv: \n" + " pop {r0} \n" + " b MPU_xQueueSelectFromSetImpl \n" + " MPU_xQueueSelectFromSet_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xQueueSelectFromSetImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_QUEUE_SETS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_QUEUE_SETS == 1 ) + +BaseType_t MPU_xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore, + QueueSetHandle_t xQueueSet ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore, + QueueSetHandle_t xQueueSet ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueAddToSetImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xQueueAddToSet_Unpriv \n" + " MPU_xQueueAddToSet_Priv: \n" + " pop {r0} \n" + " b MPU_xQueueAddToSetImpl \n" + " MPU_xQueueAddToSet_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xQueueAddToSetImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_QUEUE_SETS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configQUEUE_REGISTRY_SIZE > 0 ) + +void MPU_vQueueAddToRegistry( QueueHandle_t xQueue, + const char * pcName ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vQueueAddToRegistry( QueueHandle_t xQueue, + const char * pcName ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vQueueAddToRegistryImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vQueueAddToRegistry_Unpriv \n" + " MPU_vQueueAddToRegistry_Priv: \n" + " pop {r0} \n" + " b MPU_vQueueAddToRegistryImpl \n" + " MPU_vQueueAddToRegistry_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vQueueAddToRegistryImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configQUEUE_REGISTRY_SIZE > 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configQUEUE_REGISTRY_SIZE > 0 ) + +void MPU_vQueueUnregisterQueue( QueueHandle_t xQueue ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vQueueUnregisterQueue( QueueHandle_t xQueue ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vQueueUnregisterQueueImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vQueueUnregisterQueue_Unpriv \n" + " MPU_vQueueUnregisterQueue_Priv: \n" + " pop {r0} \n" + " b MPU_vQueueUnregisterQueueImpl \n" + " MPU_vQueueUnregisterQueue_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vQueueUnregisterQueueImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configQUEUE_REGISTRY_SIZE > 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configQUEUE_REGISTRY_SIZE > 0 ) + +const char * MPU_pcQueueGetName( QueueHandle_t xQueue ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +const char * MPU_pcQueueGetName( QueueHandle_t xQueue ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_pcQueueGetNameImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_pcQueueGetName_Unpriv \n" + " MPU_pcQueueGetName_Priv: \n" + " pop {r0} \n" + " b MPU_pcQueueGetNameImpl \n" + " MPU_pcQueueGetName_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_pcQueueGetNameImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configQUEUE_REGISTRY_SIZE > 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +void * MPU_pvTimerGetTimerID( const TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void * MPU_pvTimerGetTimerID( const TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_pvTimerGetTimerIDImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_pvTimerGetTimerID_Unpriv \n" + " MPU_pvTimerGetTimerID_Priv: \n" + " pop {r0} \n" + " b MPU_pvTimerGetTimerIDImpl \n" + " MPU_pvTimerGetTimerID_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_pvTimerGetTimerIDImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +void MPU_vTimerSetTimerID( TimerHandle_t xTimer, + void * pvNewID ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTimerSetTimerID( TimerHandle_t xTimer, + void * pvNewID ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTimerSetTimerIDImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vTimerSetTimerID_Unpriv \n" + " MPU_vTimerSetTimerID_Priv: \n" + " pop {r0} \n" + " b MPU_vTimerSetTimerIDImpl \n" + " MPU_vTimerSetTimerID_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vTimerSetTimerIDImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +BaseType_t MPU_xTimerIsTimerActive( TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTimerIsTimerActive( TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTimerIsTimerActiveImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTimerIsTimerActive_Unpriv \n" + " MPU_xTimerIsTimerActive_Priv: \n" + " pop {r0} \n" + " b MPU_xTimerIsTimerActiveImpl \n" + " MPU_xTimerIsTimerActive_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTimerIsTimerActiveImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +TaskHandle_t MPU_xTimerGetTimerDaemonTaskHandle( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TaskHandle_t MPU_xTimerGetTimerDaemonTaskHandle( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTimerGetTimerDaemonTaskHandleImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTimerGetTimerDaemonTaskHandle_Unpriv \n" + " MPU_xTimerGetTimerDaemonTaskHandle_Priv: \n" + " pop {r0} \n" + " b MPU_xTimerGetTimerDaemonTaskHandleImpl \n" + " MPU_xTimerGetTimerDaemonTaskHandle_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTimerGetTimerDaemonTaskHandleImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +BaseType_t MPU_xTimerGenericCommand( TimerHandle_t xTimer, + const BaseType_t xCommandID, + const TickType_t xOptionalValue, + BaseType_t * const pxHigherPriorityTaskWoken, + const TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTimerGenericCommand( TimerHandle_t xTimer, + const BaseType_t xCommandID, + const TickType_t xOptionalValue, + BaseType_t * const pxHigherPriorityTaskWoken, + const TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTimerGenericCommandImpl \n" + " \n" + " push {r0} \n" + " mrs r0, ipsr \n" + " cmp r0, #0 \n" + " bne MPU_xTimerGenericCommand_Priv \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " beq MPU_xTimerGenericCommand_Priv \n" + " MPU_xTimerGenericCommand_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTimerGenericCommandImpl \n" + " svc %1 \n" + " bx lr \n" + " MPU_xTimerGenericCommand_Priv: \n" + " pop {r0} \n" + " b MPU_xTimerGenericCommandImpl \n" + " \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER_1 ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +const char * MPU_pcTimerGetName( TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +const char * MPU_pcTimerGetName( TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_pcTimerGetNameImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_pcTimerGetName_Unpriv \n" + " MPU_pcTimerGetName_Priv: \n" + " pop {r0} \n" + " b MPU_pcTimerGetNameImpl \n" + " MPU_pcTimerGetName_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_pcTimerGetNameImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, + const BaseType_t uxAutoReload ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, + const BaseType_t uxAutoReload ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTimerSetReloadModeImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vTimerSetReloadMode_Unpriv \n" + " MPU_vTimerSetReloadMode_Priv: \n" + " pop {r0} \n" + " b MPU_vTimerSetReloadModeImpl \n" + " MPU_vTimerSetReloadMode_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vTimerSetReloadModeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +BaseType_t MPU_xTimerGetReloadMode( TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTimerGetReloadMode( TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTimerGetReloadModeImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTimerGetReloadMode_Unpriv \n" + " MPU_xTimerGetReloadMode_Priv: \n" + " pop {r0} \n" + " b MPU_xTimerGetReloadModeImpl \n" + " MPU_xTimerGetReloadMode_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTimerGetReloadModeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +UBaseType_t MPU_uxTimerGetReloadMode( TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxTimerGetReloadMode( TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxTimerGetReloadModeImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_uxTimerGetReloadMode_Unpriv \n" + " MPU_uxTimerGetReloadMode_Priv: \n" + " pop {r0} \n" + " b MPU_uxTimerGetReloadModeImpl \n" + " MPU_uxTimerGetReloadMode_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_uxTimerGetReloadModeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +TickType_t MPU_xTimerGetPeriod( TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TickType_t MPU_xTimerGetPeriod( TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTimerGetPeriodImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTimerGetPeriod_Unpriv \n" + " MPU_xTimerGetPeriod_Priv: \n" + " pop {r0} \n" + " b MPU_xTimerGetPeriodImpl \n" + " MPU_xTimerGetPeriod_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTimerGetPeriodImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +TickType_t MPU_xTimerGetExpiryTime( TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TickType_t MPU_xTimerGetExpiryTime( TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTimerGetExpiryTimeImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTimerGetExpiryTime_Unpriv \n" + " MPU_xTimerGetExpiryTime_Priv: \n" + " pop {r0} \n" + " b MPU_xTimerGetExpiryTimeImpl \n" + " MPU_xTimerGetExpiryTime_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTimerGetExpiryTimeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +EventBits_t MPU_xEventGroupWaitBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToWaitFor, + const BaseType_t xClearOnExit, + const BaseType_t xWaitForAllBits, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +EventBits_t MPU_xEventGroupWaitBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToWaitFor, + const BaseType_t xClearOnExit, + const BaseType_t xWaitForAllBits, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupWaitBitsImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xEventGroupWaitBits_Unpriv \n" + " MPU_xEventGroupWaitBits_Priv: \n" + " pop {r0} \n" + " b MPU_xEventGroupWaitBitsImpl \n" + " MPU_xEventGroupWaitBits_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xEventGroupWaitBitsImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER_1 ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToClear ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToClear ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupClearBitsImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xEventGroupClearBits_Unpriv \n" + " MPU_xEventGroupClearBits_Priv: \n" + " pop {r0} \n" + " b MPU_xEventGroupClearBitsImpl \n" + " MPU_xEventGroupClearBits_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xEventGroupClearBitsImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupSetBitsImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xEventGroupSetBits_Unpriv \n" + " MPU_xEventGroupSetBits_Priv: \n" + " pop {r0} \n" + " b MPU_xEventGroupSetBitsImpl \n" + " MPU_xEventGroupSetBits_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xEventGroupSetBitsImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet, + const EventBits_t uxBitsToWaitFor, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet, + const EventBits_t uxBitsToWaitFor, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupSyncImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xEventGroupSync_Unpriv \n" + " MPU_xEventGroupSync_Priv: \n" + " pop {r0} \n" + " b MPU_xEventGroupSyncImpl \n" + " MPU_xEventGroupSync_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xEventGroupSyncImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + +UBaseType_t MPU_uxEventGroupGetNumber( void * xEventGroup ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxEventGroupGetNumber( void * xEventGroup ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxEventGroupGetNumberImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_uxEventGroupGetNumber_Unpriv \n" + " MPU_uxEventGroupGetNumber_Priv: \n" + " pop {r0} \n" + " b MPU_uxEventGroupGetNumberImpl \n" + " MPU_uxEventGroupGetNumber_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_uxEventGroupGetNumberImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /*( configUSE_TRACE_FACILITY == 1 )*/ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + +void MPU_vEventGroupSetNumber( void * xEventGroup, + UBaseType_t uxEventGroupNumber ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vEventGroupSetNumber( void * xEventGroup, + UBaseType_t uxEventGroupNumber ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vEventGroupSetNumberImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vEventGroupSetNumber_Unpriv \n" + " MPU_vEventGroupSetNumber_Priv: \n" + " pop {r0} \n" + " b MPU_vEventGroupSetNumberImpl \n" + " MPU_vEventGroupSetNumber_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vEventGroupSetNumberImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /*( configUSE_TRACE_FACILITY == 1 )*/ +/*-----------------------------------------------------------*/ + +size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, + const void * pvTxData, + size_t xDataLengthBytes, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, + const void * pvTxData, + size_t xDataLengthBytes, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferSendImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferSend_Unpriv \n" + " MPU_xStreamBufferSend_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferSendImpl \n" + " MPU_xStreamBufferSend_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xStreamBufferSendImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, + void * pvRxData, + size_t xBufferLengthBytes, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, + void * pvRxData, + size_t xBufferLengthBytes, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferReceiveImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferReceive_Unpriv \n" + " MPU_xStreamBufferReceive_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferReceiveImpl \n" + " MPU_xStreamBufferReceive_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xStreamBufferReceiveImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferIsFullImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferIsFull_Unpriv \n" + " MPU_xStreamBufferIsFull_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferIsFullImpl \n" + " MPU_xStreamBufferIsFull_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xStreamBufferIsFullImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferIsEmptyImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferIsEmpty_Unpriv \n" + " MPU_xStreamBufferIsEmpty_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferIsEmptyImpl \n" + " MPU_xStreamBufferIsEmpty_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xStreamBufferIsEmptyImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferSpacesAvailableImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferSpacesAvailable_Unpriv \n" + " MPU_xStreamBufferSpacesAvailable_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferSpacesAvailableImpl \n" + " MPU_xStreamBufferSpacesAvailable_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xStreamBufferSpacesAvailableImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferBytesAvailableImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferBytesAvailable_Unpriv \n" + " MPU_xStreamBufferBytesAvailable_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferBytesAvailableImpl \n" + " MPU_xStreamBufferBytesAvailable_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xStreamBufferBytesAvailableImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, + size_t xTriggerLevel ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, + size_t xTriggerLevel ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferSetTriggerLevelImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferSetTriggerLevel_Unpriv \n" + " MPU_xStreamBufferSetTriggerLevel_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferSetTriggerLevelImpl \n" + " MPU_xStreamBufferSetTriggerLevel_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xStreamBufferSetTriggerLevelImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferNextMessageLengthBytesImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferNextMessageLengthBytes_Unpriv \n" + " MPU_xStreamBufferNextMessageLengthBytes_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferNextMessageLengthBytesImpl \n" + " MPU_xStreamBufferNextMessageLengthBytes_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xStreamBufferNextMessageLengthBytesImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +#endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ diff --git a/portable/GCC/ARM_CM4_MPU/port.c b/portable/GCC/ARM_CM4_MPU/port.c old mode 100755 new mode 100644 index ab76ee84204..548187db351 --- a/portable/GCC/ARM_CM4_MPU/port.c +++ b/portable/GCC/ARM_CM4_MPU/port.c @@ -118,13 +118,35 @@ #define portPRIORITY_GROUP_MASK ( 0x07UL << 8UL ) #define portPRIGROUP_SHIFT ( 8UL ) +/* Constants used during system call enter and exit. */ +#define portPSR_STACK_PADDING_MASK ( 1UL << 9UL ) +#define portEXC_RETURN_STACK_FRAME_TYPE_MASK ( 1UL << 4UL ) + /* Offsets in the stack to the parameters when inside the SVC handler. */ +#define portOFFSET_TO_LR ( 5 ) #define portOFFSET_TO_PC ( 6 ) +#define portOFFSET_TO_PSR ( 7 ) + /* For strict compliance with the Cortex-M spec the task start address should * have bit-0 clear, as it is loaded into the PC on exit from an ISR. */ #define portSTART_ADDRESS_MASK ( ( StackType_t ) 0xfffffffeUL ) +/* Does addr lie within [start, end] address range? */ +#define portIS_ADDRESS_WITHIN_RANGE( addr, start, end ) \ + ( ( ( addr ) >= ( start ) ) && ( ( addr ) <= ( end ) ) ) + +/* Is the access request satisfied by the available permissions? */ +#define portIS_AUTHORIZED( accessRequest, permissions ) \ + ( ( ( permissions ) & ( accessRequest ) ) == accessRequest ) + +/* 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 ) ) ) +/*-----------------------------------------------------------*/ + /* * Configure a number of standard MPU regions that are used by all tasks. */ @@ -160,7 +182,7 @@ static void prvRestoreContextOfFirstTask( void ) __attribute__( ( naked ) ) PRIV * C portion of the SVC handler. The SVC handler is split between an asm entry * and a C wrapper for simplicity of coding and maintenance. */ -static void prvSVCHandler( uint32_t * pulRegisters ) __attribute__( ( noinline ) ) PRIVILEGED_FUNCTION; +void vSVCHandler_C( uint32_t * pulRegisters ) __attribute__( ( noinline ) ) PRIVILEGED_FUNCTION; /* * Function to enable the VFP. @@ -201,6 +223,56 @@ void vResetPrivilege( void ) __attribute__( ( naked ) ); #else void vPortExitCritical( void ) PRIVILEGED_FUNCTION; #endif + +#if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + + /** + * @brief Sets up the system call stack so that upon returning from + * SVC, the system call stack is used. + * + * It is used for the system calls with up to 4 parameters. + * + * @param pulTaskStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + */ + void vSystemCallEnter( uint32_t * pulTaskStack, uint32_t ulLR ) PRIVILEGED_FUNCTION; + +#endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + +#if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + + /** + * @brief Sets up the system call stack so that upon returning from + * SVC, the system call stack is used. + * + * It is used for the system calls with 5 parameters. + * + * @param pulTaskStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + */ + void vSystemCallEnter_1( uint32_t * pulTaskStack, uint32_t ulLR ) PRIVILEGED_FUNCTION; + +#endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + +#if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + + /** + * @brief Sets up the task stack so that upon returning from + * SVC, the task stack is used again. + * + * @param pulSystemCallStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + */ + void vSystemCallExit( uint32_t * pulSystemCallStack, uint32_t ulLR ) PRIVILEGED_FUNCTION; + +#endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + +/** + * @brief Checks whether or not the calling task is privileged. + * + * @return pdTRUE if the calling task is privileged, pdFALSE otherwise. + */ +BaseType_t xPortIsTaskPrivileged( void ) PRIVILEGED_FUNCTION; /*-----------------------------------------------------------*/ /* Each task maintains its own interrupt status in the critical nesting @@ -227,39 +299,102 @@ static UBaseType_t uxCriticalNesting = 0xaaaaaaaa; StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, TaskFunction_t pxCode, void * pvParameters, - BaseType_t xRunPrivileged ) + BaseType_t xRunPrivileged, + xMPU_SETTINGS * xMPUSettings ) { - /* Simulate the stack frame as it would be created by a context switch - * interrupt. */ - pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ - *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ - pxTopOfStack--; - *pxTopOfStack = ( ( StackType_t ) pxCode ) & portSTART_ADDRESS_MASK; /* PC */ - pxTopOfStack--; - *pxTopOfStack = 0; /* LR */ - pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ - *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ - - /* A save method is being used that requires each task to maintain its - * own exec return value. */ - pxTopOfStack--; - *pxTopOfStack = portINITIAL_EXC_RETURN; - - pxTopOfStack -= 9; /* R11, R10, R9, R8, R7, R6, R5 and R4. */ - if( xRunPrivileged == pdTRUE ) { - *pxTopOfStack = portINITIAL_CONTROL_IF_PRIVILEGED; + xMPUSettings->ulTaskFlags |= portTASK_IS_PRIVILEGED_FLAG; + xMPUSettings->ulContext[ 0 ] = portINITIAL_CONTROL_IF_PRIVILEGED; } else { - *pxTopOfStack = portINITIAL_CONTROL_IF_UNPRIVILEGED; + xMPUSettings->ulTaskFlags &= ( ~portTASK_IS_PRIVILEGED_FLAG ); + xMPUSettings->ulContext[ 0 ] = portINITIAL_CONTROL_IF_UNPRIVILEGED; } + xMPUSettings->ulContext[ 1 ] = 0x04040404; /* r4. */ + xMPUSettings->ulContext[ 2 ] = 0x05050505; /* r5. */ + xMPUSettings->ulContext[ 3 ] = 0x06060606; /* r6. */ + xMPUSettings->ulContext[ 4 ] = 0x07070707; /* r7. */ + xMPUSettings->ulContext[ 5 ] = 0x08080808; /* r8. */ + xMPUSettings->ulContext[ 6 ] = 0x09090909; /* r9. */ + xMPUSettings->ulContext[ 7 ] = 0x10101010; /* r10. */ + xMPUSettings->ulContext[ 8 ] = 0x11111111; /* r11. */ + xMPUSettings->ulContext[ 9 ] = portINITIAL_EXC_RETURN; /* EXC_RETURN. */ + + xMPUSettings->ulContext[ 10 ] = ( uint32_t ) ( pxTopOfStack - 8 ); /* PSP with the hardware saved stack. */ + xMPUSettings->ulContext[ 11 ] = ( uint32_t ) pvParameters; /* r0. */ + xMPUSettings->ulContext[ 12 ] = 0x01010101; /* r1. */ + xMPUSettings->ulContext[ 13 ] = 0x02020202; /* r2. */ + xMPUSettings->ulContext[ 14 ] = 0x03030303; /* r3. */ + xMPUSettings->ulContext[ 15 ] = 0x12121212; /* r12. */ + xMPUSettings->ulContext[ 16 ] = 0; /* LR. */ + xMPUSettings->ulContext[ 17 ] = ( ( uint32_t ) pxCode ) & portSTART_ADDRESS_MASK; /* PC. */ + xMPUSettings->ulContext[ 18 ] = portINITIAL_XPSR; /* xPSR. */ + + #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + { + /* Ensure that the system call stack is double word aligned. */ + xMPUSettings->xSystemCallStackInfo.pulSystemCallStack = &( xMPUSettings->xSystemCallStackInfo.ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE - 1 ] ); + xMPUSettings->xSystemCallStackInfo.pulSystemCallStack = ( uint32_t * ) ( ( uint32_t ) ( xMPUSettings->xSystemCallStackInfo.pulSystemCallStack ) & + ( uint32_t ) ( ~( portBYTE_ALIGNMENT_MASK ) ) ); + + /* This is not NULL only for the duration of a system call. */ + xMPUSettings->xSystemCallStackInfo.pulTaskStack = NULL; + } + #endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ - return pxTopOfStack; + return &( xMPUSettings->ulContext[ 19 ] ); } /*-----------------------------------------------------------*/ +#if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + +void vPortSVCHandler( void ) /* __attribute__( ( naked ) ) PRIVILEGED_FUNCTION */ +{ + __asm volatile + ( + ".syntax unified \n" + ".extern vSVCHandler_C \n" + ".extern vSystemCallEnter \n" + ".extern vSystemCallEnter_1 \n" + ".extern vSystemCallExit \n" + " \n" + "tst lr, #4 \n" + "ite eq \n" + "mrseq r0, msp \n" + "mrsne r0, psp \n" + " \n" + "ldr r1, [r0, #24] \n" + "ldrb r2, [r1, #-2] \n" + "cmp r2, %0 \n" + "beq syscall_enter \n" + "cmp r2, %1 \n" + "beq syscall_enter_1 \n" + "cmp r2, %2 \n" + "beq syscall_exit \n" + "b vSVCHandler_C \n" + " \n" + "syscall_enter: \n" + " mov r1, lr \n" + " b vSystemCallEnter \n" + " \n" + "syscall_enter_1: \n" + " mov r1, lr \n" + " b vSystemCallEnter_1 \n" + " \n" + "syscall_exit: \n" + " mov r1, lr \n" + " b vSystemCallExit \n" + " \n" + : /* No outputs. */ + :"i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_ENTER_1 ), "i" ( portSVC_SYSTEM_CALL_EXIT ) + : "r0", "r1", "r2", "memory" + ); +} + +#else /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + void vPortSVCHandler( void ) { /* Assumes psp was in use. */ @@ -274,12 +409,14 @@ void vPortSVCHandler( void ) " mrs r0, psp \n" #endif " b %0 \n" - ::"i" ( prvSVCHandler ) : "r0", "memory" + ::"i" ( vSVCHandler_C ) : "r0", "memory" ); } + +#endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ /*-----------------------------------------------------------*/ -static void prvSVCHandler( uint32_t * pulParam ) +void vSVCHandler_C( uint32_t * pulParam ) /* PRIVILEGED_FUNCTION */ { uint8_t ucSVCNumber; uint32_t ulPC; @@ -288,7 +425,7 @@ static void prvSVCHandler( uint32_t * pulParam ) #if defined( __ARMCC_VERSION ) /* Declaration when these variable are defined in code instead of being - * exported from linker scripts. */ + * exported from linker scripts. */ extern uint32_t * __syscalls_flash_start__; extern uint32_t * __syscalls_flash_end__; #else @@ -350,7 +487,7 @@ static void prvSVCHandler( uint32_t * pulParam ) ::: "r1", "memory" ); break; - #endif /* #if( configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY == 1 ) */ + #endif /* #if( configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY == 1 ) */ default: /* Unknown SVC call. */ break; @@ -358,52 +495,364 @@ static void prvSVCHandler( uint32_t * pulParam ) } /*-----------------------------------------------------------*/ +#if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + +void vSystemCallEnter( uint32_t * pulTaskStack, uint32_t ulLR ) /* PRIVILEGED_FUNCTION */ +{ + extern TaskHandle_t pxCurrentTCB; + xMPU_SETTINGS * pxMpuSettings; + uint32_t * pulSystemCallStack; + uint32_t ulStackFrameSize, ulSystemCallLocation, i; + #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being + * exported from linker scripts. */ + extern uint32_t * __syscalls_flash_start__; + extern uint32_t * __syscalls_flash_end__; + #else + /* Declaration when these variable are exported from linker scripts. */ + extern uint32_t __syscalls_flash_start__[]; + extern uint32_t __syscalls_flash_end__[]; + #endif /* #if defined( __ARMCC_VERSION ) */ + + ulSystemCallLocation = pulTaskStack[ portOFFSET_TO_PC ]; + + /* If the request did not come from the system call section, do nothing. */ + if( ( ulSystemCallLocation >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulSystemCallLocation <= ( uint32_t ) __syscalls_flash_end__ ) ) + { + pxMpuSettings = xTaskGetMPUSettings( pxCurrentTCB ); + pulSystemCallStack = pxMpuSettings->xSystemCallStackInfo.pulSystemCallStack; + + /* This is not NULL only for the duration of the system call. */ + configASSERT( pxMpuSettings->xSystemCallStackInfo.pulTaskStack == NULL ); + + if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) + { + /* Extended frame i.e. FPU in use. */ + ulStackFrameSize = 26; + __asm volatile ( + " vpush {s0} \n" /* Trigger lazy stacking. */ + " vpop {s0} \n" /* Nullify the affect of the above instruction. */ + ::: "memory" + ); + } + else + { + /* Standard frame i.e. FPU not in use. */ + ulStackFrameSize = 8; + } + + /* Make space on the system call stack for the stack frame. */ + pulSystemCallStack = pulSystemCallStack - ulStackFrameSize; + + /* Copy the stack frame. */ + for( i = 0; i < ulStackFrameSize; i++ ) + { + pulSystemCallStack[ i ] = pulTaskStack[ i ]; + } + + /* Use the pulSystemCallStack in thread mode. */ + __asm volatile ( "msr psp, %0" : : "r" ( pulSystemCallStack ) ); + + /* Raise the privilege for the duration of the system call. */ + __asm volatile ( + " mrs r1, control \n" /* Obtain current control value. */ + " bic r1, #1 \n" /* Clear nPRIV bit. */ + " msr control, r1 \n" /* Write back new control value. */ + ::: "r1", "memory" + ); + + /* Remember the location where we should copy the stack frame when we exit from + * the system call. */ + pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulStackFrameSize; + + /* Store the value of the Link Register before the SVC was raised. We need to + * restore it when we exit from the system call. */ + pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; + + /* Record if the hardware used padding to force the stack pointer + * to be double word aligned. */ + if( ( pulTaskStack[ portOFFSET_TO_PSR ] & portPSR_STACK_PADDING_MASK ) == portPSR_STACK_PADDING_MASK ) + { + pxMpuSettings->ulTaskFlags |= portSTACK_FRAME_HAS_PADDING_FLAG; + } + else + { + pxMpuSettings->ulTaskFlags &= ( ~portSTACK_FRAME_HAS_PADDING_FLAG ); + } + + /* We ensure in pxPortInitialiseStack that the system call stack is + * double word aligned and therefore, there is no need of padding. + * Clear the bit[9] of stacked xPSR. */ + pulSystemCallStack[ portOFFSET_TO_PSR ] &= ( ~portPSR_STACK_PADDING_MASK ); + } +} + +#endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + +void vSystemCallEnter_1( uint32_t * pulTaskStack, uint32_t ulLR ) /* PRIVILEGED_FUNCTION */ +{ + extern TaskHandle_t pxCurrentTCB; + xMPU_SETTINGS * pxMpuSettings; + uint32_t * pulSystemCallStack; + uint32_t ulStackFrameSize, ulSystemCallLocation, i; + #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being + * exported from linker scripts. */ + extern uint32_t * __syscalls_flash_start__; + extern uint32_t * __syscalls_flash_end__; + #else + /* Declaration when these variable are exported from linker scripts. */ + extern uint32_t __syscalls_flash_start__[]; + extern uint32_t __syscalls_flash_end__[]; + #endif /* #if defined( __ARMCC_VERSION ) */ + + ulSystemCallLocation = pulTaskStack[ portOFFSET_TO_PC ]; + + /* If the request did not come from the system call section, do nothing. */ + if( ( ulSystemCallLocation >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulSystemCallLocation <= ( uint32_t ) __syscalls_flash_end__ ) ) + { + pxMpuSettings = xTaskGetMPUSettings( pxCurrentTCB ); + pulSystemCallStack = pxMpuSettings->xSystemCallStackInfo.pulSystemCallStack; + + /* This is not NULL only for the duration of the system call. */ + configASSERT( pxMpuSettings->xSystemCallStackInfo.pulTaskStack == NULL ); + + if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) + { + /* Extended frame i.e. FPU in use. */ + ulStackFrameSize = 26; + __asm volatile ( + " vpush {s0} \n" /* Trigger lazy stacking. */ + " vpop {s0} \n" /* Nullify the affect of the above instruction. */ + ::: "memory" + ); + } + else + { + /* Standard frame i.e. FPU not in use. */ + ulStackFrameSize = 8; + } + + /* Make space on the system call stack for the stack frame and + * the parameter passed on the stack. We only need to copy one + * parameter but we still reserve 2 spaces to keep the stack + * double word aligned. */ + pulSystemCallStack = pulSystemCallStack - ulStackFrameSize - 2UL; + + /* Copy the stack frame. */ + for( i = 0; i < ulStackFrameSize; i++ ) + { + pulSystemCallStack[ i ] = pulTaskStack[ i ]; + } + + /* Copy the parameter which is passed the stack. */ + if( ( pulTaskStack[ portOFFSET_TO_PSR ] & portPSR_STACK_PADDING_MASK ) == portPSR_STACK_PADDING_MASK ) + { + pulSystemCallStack[ ulStackFrameSize ] = pulTaskStack[ ulStackFrameSize + 1 ]; + /* Record if the hardware used padding to force the stack pointer + * to be double word aligned. */ + pxMpuSettings->ulTaskFlags |= portSTACK_FRAME_HAS_PADDING_FLAG; + } + else + { + pulSystemCallStack[ ulStackFrameSize ] = pulTaskStack[ ulStackFrameSize ]; + /* Record if the hardware used padding to force the stack pointer + * to be double word aligned. */ + pxMpuSettings->ulTaskFlags &= ( ~portSTACK_FRAME_HAS_PADDING_FLAG ); + } + + /* Use the pulSystemCallStack in thread mode. */ + __asm volatile ( "msr psp, %0" : : "r" ( pulSystemCallStack ) ); + + /* Raise the privilege for the duration of the system call. */ + __asm volatile ( + " mrs r1, control \n" /* Obtain current control value. */ + " bic r1, #1 \n" /* Clear nPRIV bit. */ + " msr control, r1 \n" /* Write back new control value. */ + ::: "r1", "memory" + ); + + /* Remember the location where we should copy the stack frame when we exit from + * the system call. */ + pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulStackFrameSize; + + /* Store the value of the Link Register before the SVC was raised. We need to + * restore it when we exit from the system call. */ + pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; + + /* We ensure in pxPortInitialiseStack that the system call stack is + * double word aligned and therefore, there is no need of padding. + * Clear the bit[9] of stacked xPSR. */ + pulSystemCallStack[ portOFFSET_TO_PSR ] &= ( ~portPSR_STACK_PADDING_MASK ); + } +} + +#endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + +void vSystemCallExit( uint32_t * pulSystemCallStack, uint32_t ulLR ) /* PRIVILEGED_FUNCTION */ +{ + extern TaskHandle_t pxCurrentTCB; + xMPU_SETTINGS * pxMpuSettings; + uint32_t * pulTaskStack; + uint32_t ulStackFrameSize, ulSystemCallLocation, i; + #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being + * exported from linker scripts. */ + extern uint32_t * __syscalls_flash_start__; + extern uint32_t * __syscalls_flash_end__; + #else + /* Declaration when these variable are exported from linker scripts. */ + extern uint32_t __syscalls_flash_start__[]; + extern uint32_t __syscalls_flash_end__[]; + #endif /* #if defined( __ARMCC_VERSION ) */ + + ulSystemCallLocation = pulSystemCallStack[ portOFFSET_TO_PC ]; + + /* If the request did not come from the system call section, do nothing. */ + if( ( ulSystemCallLocation >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulSystemCallLocation <= ( uint32_t ) __syscalls_flash_end__ ) ) + { + pxMpuSettings = xTaskGetMPUSettings( pxCurrentTCB ); + pulTaskStack = pxMpuSettings->xSystemCallStackInfo.pulTaskStack; + + if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) + { + /* Extended frame i.e. FPU in use. */ + ulStackFrameSize = 26; + __asm volatile ( + " vpush {s0} \n" /* Trigger lazy stacking. */ + " vpop {s0} \n" /* Nullify the affect of the above instruction. */ + ::: "memory" + ); + } + else + { + /* Standard frame i.e. FPU not in use. */ + ulStackFrameSize = 8; + } + + /* Make space on the task stack for the stack frame. */ + pulTaskStack = pulTaskStack - ulStackFrameSize; + + /* Copy the stack frame. */ + for( i = 0; i < ulStackFrameSize; i++ ) + { + pulTaskStack[ i ] = pulSystemCallStack[ i ]; + } + + /* Use the pulTaskStack in thread mode. */ + __asm volatile ( "msr psp, %0" : : "r" ( pulTaskStack ) ); + + /* Drop the privilege before returning to the thread mode. */ + __asm volatile ( + " mrs r1, control \n" /* Obtain current control value. */ + " orr r1, #1 \n" /* Set nPRIV bit. */ + " msr control, r1 \n" /* Write back new control value. */ + ::: "r1", "memory" + ); + + /* Restore the stacked link register to what it was at the time of + * system call entry. */ + pulTaskStack[ portOFFSET_TO_LR ] = pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry; + + /* If the hardware used padding to force the stack pointer + * to be double word aligned, set the stacked xPSR bit[9], + * otherwise clear it. */ + if( ( pxMpuSettings->ulTaskFlags & portSTACK_FRAME_HAS_PADDING_FLAG ) == portSTACK_FRAME_HAS_PADDING_FLAG ) + { + pulTaskStack[ portOFFSET_TO_PSR ] |= portPSR_STACK_PADDING_MASK; + } + else + { + pulTaskStack[ portOFFSET_TO_PSR ] &= ( ~portPSR_STACK_PADDING_MASK ); + } + + /* This is not NULL only for the duration of the system call. */ + pxMpuSettings->xSystemCallStackInfo.pulTaskStack = NULL; + } +} + +#endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ +/*-----------------------------------------------------------*/ + +BaseType_t xPortIsTaskPrivileged( void ) /* PRIVILEGED_FUNCTION */ +{ + BaseType_t xTaskIsPrivileged = pdFALSE; + const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */ + + if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) + { + xTaskIsPrivileged = pdTRUE; + } + + return xTaskIsPrivileged; +} +/*-----------------------------------------------------------*/ + static void prvRestoreContextOfFirstTask( void ) { __asm volatile ( - " ldr r0, =0xE000ED08 \n"/* Use the NVIC offset register to locate the stack. */ - " ldr r0, [r0] \n" - " ldr r0, [r0] \n" - " msr msp, r0 \n"/* Set the msp back to the start of the stack. */ - " ldr r3, pxCurrentTCBConst2 \n"/* Restore the context. */ - " ldr r1, [r3] \n" - " ldr r0, [r1] \n"/* The first item in the TCB is the task top of stack. */ - " add r1, r1, #4 \n"/* Move onto the second item in the TCB... */ - " \n" - " dmb \n"/* Complete outstanding transfers before disabling MPU. */ - " ldr r2, =0xe000ed94 \n"/* MPU_CTRL register. */ - " ldr r3, [r2] \n"/* Read the value of MPU_CTRL. */ - " bic r3, #1 \n"/* r3 = r3 & ~1 i.e. Clear the bit 0 in r3. */ - " str r3, [r2] \n"/* Disable MPU. */ - " \n" - " ldr r2, =0xe000ed9c \n"/* Region Base Address register. */ - " ldmia r1!, {r4-r11} \n"/* Read 4 sets of MPU registers [MPU Region # 4 - 7]. */ - " stmia r2, {r4-r11} \n"/* Write 4 sets of MPU registers [MPU Region # 4 - 7]. */ - " \n" - #if ( configTOTAL_MPU_REGIONS == 16 ) - " ldmia r1!, {r4-r11} \n"/* Read 4 sets of MPU registers [MPU Region # 8 - 11]. */ - " stmia r2, {r4-r11} \n"/* Write 4 sets of MPU registers. [MPU Region # 8 - 11]. */ - " ldmia r1!, {r4-r11} \n"/* Read 4 sets of MPU registers [MPU Region # 12 - 15]. */ - " stmia r2, {r4-r11} \n"/* Write 4 sets of MPU registers. [MPU Region # 12 - 15]. */ - #endif /* configTOTAL_MPU_REGIONS == 16. */ - " \n" - " ldr r2, =0xe000ed94 \n"/* MPU_CTRL register. */ - " ldr r3, [r2] \n"/* Read the value of MPU_CTRL. */ - " orr r3, #1 \n"/* r3 = r3 | 1 i.e. Set the bit 0 in r3. */ - " str r3, [r2] \n"/* Enable MPU. */ - " dsb \n"/* Force memory writes before continuing. */ - " \n" - " ldmia r0!, {r3-r11, r14} \n"/* Pop the registers that are not automatically saved on exception entry. */ - " msr control, r3 \n" - " msr psp, r0 \n"/* Restore the task stack pointer. */ - " mov r0, #0 \n" - " msr basepri, r0 \n" - " bx r14 \n" - " \n" - " .ltorg \n"/* Assemble current literal pool to avoid offset-out-of-bound errors with lto. */ - " .align 4 \n" - "pxCurrentTCBConst2: .word pxCurrentTCB \n" + " ldr r0, =0xE000ED08 \n" /* Use the NVIC offset register to locate the stack. */ + " ldr r0, [r0] \n" + " ldr r0, [r0] \n" + " msr msp, r0 \n" /* Set the msp back to the start of the stack. */ + " \n" + /*------------ Program MPU. ------------ */ + " ldr r3, pxCurrentTCBConst2 \n" /* r3 = pxCurrentTCBConst2. */ + " ldr r2, [r3] \n" /* r2 = pxCurrentTCB. */ + " add r2, r2, #4 \n" /* r2 = Second item in the TCB which is xMPUSettings. */ + " \n" + " dmb \n" /* Complete outstanding transfers before disabling MPU. */ + " ldr r0, =0xe000ed94 \n" /* MPU_CTRL register. */ + " ldr r3, [r0] \n" /* Read the value of MPU_CTRL. */ + " bic r3, #1 \n" /* r3 = r3 & ~1 i.e. Clear the bit 0 in r3. */ + " str r3, [r0] \n" /* Disable MPU. */ + " \n" + " ldr r0, =0xe000ed9c \n" /* Region Base Address register. */ + " ldmia r2!, {r4-r11} \n" /* Read 4 sets of MPU registers [MPU Region # 0 - 3]. */ + " stmia r0, {r4-r11} \n" /* Write 4 sets of MPU registers [MPU Region # 0 - 3]. */ + " \n" + #if ( configTOTAL_MPU_REGIONS == 16 ) + " ldmia r2!, {r4-r11} \n" /* Read 4 sets of MPU registers [MPU Region # 4 - 8]. */ + " stmia r0, {r4-r11} \n" /* Write 4 sets of MPU registers. [MPU Region # 4 - 8]. */ + " ldmia r2!, {r4-r11} \n" /* Read 4 sets of MPU registers [MPU Region # 9 - 12]. */ + " stmia r0, {r4-r11} \n" /* Write 4 sets of MPU registers. [MPU Region # 9 - 12]. */ + #endif /* configTOTAL_MPU_REGIONS == 16. */ + " \n" + " ldr r0, =0xe000ed94 \n" /* MPU_CTRL register. */ + " ldr r3, [r0] \n" /* Read the value of MPU_CTRL. */ + " orr r3, #1 \n" /* r3 = r3 | 1 i.e. Set the bit 0 in r3. */ + " str r3, [r0] \n" /* Enable MPU. */ + " dsb \n" /* Force memory writes before continuing. */ + " \n" + /*---------- Restore Context. ---------- */ + " ldr r3, pxCurrentTCBConst2 \n" /* r3 = pxCurrentTCBConst2. */ + " ldr r2, [r3] \n" /* r2 = pxCurrentTCB. */ + " ldr r1, [r2] \n" /* r1 = Location of saved context in TCB. */ + " \n" + " ldmdb r1!, {r0, r4-r11} \n" /* r0 contains PSP after the hardware had saved context. r4-r11 contain hardware saved context. */ + " msr psp, r0 \n" + " stmia r0, {r4-r11} \n" /* Copy the hardware saved context on the task stack. */ + " ldmdb r1!, {r3-r11, lr} \n" /* r3 contains CONTROL register. r4-r11 and LR restored. */ + " msr control, r3 \n" + " str r1, [r2] \n" /* Save the location where the context should be saved next as the first member of TCB. */ + " \n" + " mov r0, #0 \n" + " msr basepri, r0 \n" + " bx lr \n" + " \n" + " .ltorg \n" /* Assemble current literal pool to avoid offset-out-of-bound errors with lto. */ + " .align 4 \n" + " pxCurrentTCBConst2: .word pxCurrentTCB\n" ); } /*-----------------------------------------------------------*/ @@ -458,6 +907,10 @@ BaseType_t xPortStartScheduler( void ) * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ configASSERT( ucMaxSysCallPriority ); + /* Check that the bits not implemented in hardware are zero in + * configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & ( ~ucMaxPriorityValue ) ) == 0U ); + /* Calculate the maximum acceptable priority group value for the number * of bits read back. */ @@ -494,28 +947,6 @@ BaseType_t xPortStartScheduler( void ) ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulImplementedPrioBits; } - #ifdef __NVIC_PRIO_BITS - { - /* - * Check that the number of implemented priority bits queried - * from hardware is at least as many as specified in the - * CMSIS __NVIC_PRIO_BITS configuration macro. - */ - configASSERT( ulImplementedPrioBits >= __NVIC_PRIO_BITS ); - } - #endif - - #ifdef configPRIO_BITS - { - /* - * Check that the number of implemented priority bits queried - * from hardware is at least as many as specified in the - * FreeRTOS configPRIO_BITS configuration macro. - */ - configASSERT( ulImplementedPrioBits >= configPRIO_BITS ); - } - #endif - /* Shift the priority group value back to its position within the AIRCR * register. */ ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT; @@ -657,76 +1088,94 @@ void xPortPendSVHandler( void ) __asm volatile ( - " mrs r0, psp \n" - " isb \n" + " ldr r3, pxCurrentTCBConst \n" /* r3 = pxCurrentTCBConst. */ + " ldr r2, [r3] \n" /* r2 = pxCurrentTCB. */ + " ldr r1, [r2] \n" /* r1 = Location where the context should be saved. */ " \n" - " ldr r3, pxCurrentTCBConst \n"/* Get the location of the current TCB. */ - " ldr r2, [r3] \n" + /*------------ Save Context. ----------- */ + " mrs r3, control \n" + " mrs r0, psp \n" + " isb \n" " \n" - " tst r14, #0x10 \n"/* Is the task using the FPU context? If so, push high vfp registers. */ - " it eq \n" - " vstmdbeq r0!, {s16-s31} \n" + " add r0, r0, #0x20 \n" /* Move r0 to location where s0 is saved. */ + " tst lr, #0x10 \n" + " ittt eq \n" + " vstmiaeq r1!, {s16-s31} \n" /* Store s16-s31. */ + " vldmiaeq r0, {s0-s16} \n" /* Copy hardware saved FP context into s0-s16. */ + " vstmiaeq r1!, {s0-s16} \n" /* Store hardware saved FP context. */ + " sub r0, r0, #0x20 \n" /* Set r0 back to the location of hardware saved context. */ " \n" - " mrs r1, control \n" - " stmdb r0!, {r1, r4-r11, r14} \n"/* Save the remaining registers. */ - " str r0, [r2] \n"/* Save the new top of stack into the first member of the TCB. */ + " stmia r1!, {r3-r11, lr} \n" /* Store CONTROL register, r4-r11 and LR. */ + " ldmia r0, {r4-r11} \n" /* Copy hardware saved context into r4-r11. */ + " stmia r1!, {r0, r4-r11} \n" /* Store original PSP (after hardware has saved context) and the hardware saved context. */ + " str r1, [r2] \n" /* Save the location from where the context should be restored as the first member of TCB. */ " \n" - " stmdb sp!, {r0, r3} \n" - " mov r0, %0 \n" - #if ( configENABLE_ERRATA_837070_WORKAROUND == 1 ) - " cpsid i \n"/* ARM Cortex-M7 r0p1 Errata 837070 workaround. */ - #endif - " msr basepri, r0 \n" - " dsb \n" - " isb \n" - #if ( configENABLE_ERRATA_837070_WORKAROUND == 1 ) - " cpsie i \n"/* ARM Cortex-M7 r0p1 Errata 837070 workaround. */ - #endif - " bl vTaskSwitchContext \n" - " mov r0, #0 \n" - " msr basepri, r0 \n" - " ldmia sp!, {r0, r3} \n" - " \n"/* Restore the context. */ - " ldr r1, [r3] \n" - " ldr r0, [r1] \n"/* The first item in the TCB is the task top of stack. */ - " add r1, r1, #4 \n"/* Move onto the second item in the TCB... */ + /*---------- Select next task. --------- */ + " mov r0, %0 \n" + #if ( configENABLE_ERRATA_837070_WORKAROUND == 1 ) + " cpsid i \n" /* ARM Cortex-M7 r0p1 Errata 837070 workaround. */ + #endif + " msr basepri, r0 \n" + " dsb \n" + " isb \n" + #if ( configENABLE_ERRATA_837070_WORKAROUND == 1 ) + " cpsie i \n" /* ARM Cortex-M7 r0p1 Errata 837070 workaround. */ + #endif + " bl vTaskSwitchContext \n" + " mov r0, #0 \n" + " msr basepri, r0 \n" " \n" - " dmb \n"/* Complete outstanding transfers before disabling MPU. */ - " ldr r2, =0xe000ed94 \n"/* MPU_CTRL register. */ - " ldr r3, [r2] \n"/* Read the value of MPU_CTRL. */ - " bic r3, #1 \n"/* r3 = r3 & ~1 i.e. Clear the bit 0 in r3. */ - " str r3, [r2] \n"/* Disable MPU. */ + /*------------ Program MPU. ------------ */ + " ldr r3, pxCurrentTCBConst \n" /* r3 = pxCurrentTCBConst. */ + " ldr r2, [r3] \n" /* r2 = pxCurrentTCB. */ + " add r2, r2, #4 \n" /* r2 = Second item in the TCB which is xMPUSettings. */ " \n" - " ldr r2, =0xe000ed9c \n"/* Region Base Address register. */ - " ldmia r1!, {r4-r11} \n"/* Read 4 sets of MPU registers [MPU Region # 4 - 7]. */ - " stmia r2, {r4-r11} \n"/* Write 4 sets of MPU registers [MPU Region # 4 - 7]. */ + " dmb \n" /* Complete outstanding transfers before disabling MPU. */ + " ldr r0, =0xe000ed94 \n" /* MPU_CTRL register. */ + " ldr r3, [r0] \n" /* Read the value of MPU_CTRL. */ + " bic r3, #1 \n" /* r3 = r3 & ~1 i.e. Clear the bit 0 in r3. */ + " str r3, [r0] \n" /* Disable MPU. */ " \n" - #if ( configTOTAL_MPU_REGIONS == 16 ) - " ldmia r1!, {r4-r11} \n"/* Read 4 sets of MPU registers [MPU Region # 8 - 11]. */ - " stmia r2, {r4-r11} \n"/* Write 4 sets of MPU registers. [MPU Region # 8 - 11]. */ - " ldmia r1!, {r4-r11} \n"/* Read 4 sets of MPU registers [MPU Region # 12 - 15]. */ - " stmia r2, {r4-r11} \n"/* Write 4 sets of MPU registers. [MPU Region # 12 - 15]. */ - #endif /* configTOTAL_MPU_REGIONS == 16. */ + " ldr r0, =0xe000ed9c \n" /* Region Base Address register. */ + " ldmia r2!, {r4-r11} \n" /* Read 4 sets of MPU registers [MPU Region # 0 - 3]. */ + " stmia r0, {r4-r11} \n" /* Write 4 sets of MPU registers [MPU Region # 0 - 3]. */ " \n" - " ldr r2, =0xe000ed94 \n"/* MPU_CTRL register. */ - " ldr r3, [r2] \n"/* Read the value of MPU_CTRL. */ - " orr r3, #1 \n"/* r3 = r3 | 1 i.e. Set the bit 0 in r3. */ - " str r3, [r2] \n"/* Enable MPU. */ - " dsb \n"/* Force memory writes before continuing. */ + #if ( configTOTAL_MPU_REGIONS == 16 ) + " ldmia r2!, {r4-r11} \n" /* Read 4 sets of MPU registers [MPU Region # 4 - 7]. */ + " stmia r0, {r4-r11} \n" /* Write 4 sets of MPU registers. [MPU Region # 4 - 7]. */ + " ldmia r2!, {r4-r11} \n" /* Read 4 sets of MPU registers [MPU Region # 8 - 11]. */ + " stmia r0, {r4-r11} \n" /* Write 4 sets of MPU registers. [MPU Region # 8 - 11]. */ + #endif /* configTOTAL_MPU_REGIONS == 16. */ " \n" - " ldmia r0!, {r3-r11, r14} \n"/* Pop the registers that are not automatically saved on exception entry. */ - " msr control, r3 \n" + " ldr r0, =0xe000ed94 \n" /* MPU_CTRL register. */ + " ldr r3, [r0] \n" /* Read the value of MPU_CTRL. */ + " orr r3, #1 \n" /* r3 = r3 | 1 i.e. Set the bit 0 in r3. */ + " str r3, [r0] \n" /* Enable MPU. */ + " dsb \n" /* Force memory writes before continuing. */ " \n" - " tst r14, #0x10 \n"/* Is the task using the FPU context? If so, pop the high vfp registers too. */ - " it eq \n" - " vldmiaeq r0!, {s16-s31} \n" + /*---------- Restore Context. ---------- */ + " ldr r3, pxCurrentTCBConst \n" /* r3 = pxCurrentTCBConst. */ + " ldr r2, [r3] \n" /* r2 = pxCurrentTCB. */ + " ldr r1, [r2] \n" /* r1 = Location of saved context in TCB. */ " \n" - " msr psp, r0 \n" - " bx r14 \n" + " ldmdb r1!, {r0, r4-r11} \n" /* r0 contains PSP after the hardware had saved context. r4-r11 contain hardware saved context. */ + " msr psp, r0 \n" + " stmia r0!, {r4-r11} \n" /* Copy the hardware saved context on the task stack. */ + " ldmdb r1!, {r3-r11, lr} \n" /* r3 contains CONTROL register. r4-r11 and LR restored. */ + " msr control, r3 \n" + + " tst lr, #0x10 \n" + " ittt eq \n" + " vldmdbeq r1!, {s0-s16} \n" /* s0-s16 contain hardware saved FP context. */ + " vstmiaeq r0!, {s0-s16} \n" /* Copy hardware saved FP context on the task stack. */ + " vldmdbeq r1!, {s16-s31} \n" /* Restore s16-s31. */ + + " str r1, [r2] \n" /* Save the location where the context should be saved next as the first member of TCB. */ + " bx lr \n" " \n" - " .ltorg \n"/* Assemble the current literal pool to avoid offset-out-of-bound errors with lto. */ - " .align 4 \n" - "pxCurrentTCBConst: .word pxCurrentTCB \n" + " .ltorg \n" /* Assemble the current literal pool to avoid offset-out-of-bound errors with lto. */ + " .align 4 \n" + " pxCurrentTCBConst: .word pxCurrentTCB \n" ::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) ); } @@ -957,11 +1406,19 @@ void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings, ( prvGetMPURegionSizeSetting( ( uint32_t ) __SRAM_segment_end__ - ( uint32_t ) __SRAM_segment_start__ ) ) | ( portMPU_REGION_ENABLE ); + xMPUSettings->xRegionSettings[ 0 ].ulRegionStartAddress = ( uint32_t ) __SRAM_segment_start__; + xMPUSettings->xRegionSettings[ 0 ].ulRegionEndAddress = ( uint32_t ) __SRAM_segment_end__; + xMPUSettings->xRegionSettings[ 0 ].ulRegionPermissions = ( tskMPU_READ_PERMISSION | + tskMPU_WRITE_PERMISSION ); + /* Invalidate user configurable regions. */ for( ul = 1UL; ul <= portNUM_CONFIGURABLE_REGIONS; ul++ ) { xMPUSettings->xRegion[ ul ].ulRegionBaseAddress = ( ( ul - 1UL ) | portMPU_REGION_VALID ); xMPUSettings->xRegion[ ul ].ulRegionAttribute = 0UL; + xMPUSettings->xRegionSettings[ ul ].ulRegionStartAddress = 0UL; + xMPUSettings->xRegionSettings[ ul ].ulRegionEndAddress = 0UL; + xMPUSettings->xRegionSettings[ ul ].ulRegionPermissions = 0UL; } } else @@ -984,6 +1441,12 @@ void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings, ( prvGetMPURegionSizeSetting( ulStackDepth * ( uint32_t ) sizeof( StackType_t ) ) ) | ( ( configTEX_S_C_B_SRAM & portMPU_RASR_TEX_S_C_B_MASK ) << portMPU_RASR_TEX_S_C_B_LOCATION ) | ( portMPU_REGION_ENABLE ); + + xMPUSettings->xRegionSettings[ 0 ].ulRegionStartAddress = ( uint32_t ) pxBottomOfStack; + xMPUSettings->xRegionSettings[ 0 ].ulRegionEndAddress = ( uint32_t ) ( ( uint32_t ) ( pxBottomOfStack ) + + ( ulStackDepth * ( uint32_t ) sizeof( StackType_t ) ) - 1UL ); + xMPUSettings->xRegionSettings[ 0 ].ulRegionPermissions = ( tskMPU_READ_PERMISSION | + tskMPU_WRITE_PERMISSION ); } lIndex = 0; @@ -1004,12 +1467,28 @@ void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings, ( prvGetMPURegionSizeSetting( xRegions[ lIndex ].ulLengthInBytes ) ) | ( xRegions[ lIndex ].ulParameters ) | ( portMPU_REGION_ENABLE ); + + xMPUSettings->xRegionSettings[ ul ].ulRegionStartAddress = ( uint32_t ) xRegions[ lIndex ].pvBaseAddress; + xMPUSettings->xRegionSettings[ ul ].ulRegionEndAddress = ( uint32_t ) ( ( uint32_t ) xRegions[ lIndex ].pvBaseAddress + xRegions[ lIndex ].ulLengthInBytes - 1UL ); + xMPUSettings->xRegionSettings[ ul ].ulRegionPermissions = 0UL; + if( ( ( xRegions[ lIndex ].ulParameters & portMPU_REGION_READ_ONLY ) == portMPU_REGION_READ_ONLY ) || + ( ( xRegions[ lIndex ].ulParameters & portMPU_REGION_PRIVILEGED_READ_WRITE_UNPRIV_READ_ONLY ) == portMPU_REGION_PRIVILEGED_READ_WRITE_UNPRIV_READ_ONLY ) ) + { + xMPUSettings->xRegionSettings[ ul ].ulRegionPermissions = tskMPU_READ_PERMISSION; + } + if( ( xRegions[ lIndex ].ulParameters & portMPU_REGION_READ_WRITE ) == portMPU_REGION_READ_WRITE ) + { + xMPUSettings->xRegionSettings[ ul ].ulRegionPermissions = ( tskMPU_READ_PERMISSION | tskMPU_WRITE_PERMISSION ); + } } else { /* Invalidate the region. */ xMPUSettings->xRegion[ ul ].ulRegionBaseAddress = ( ( ul - 1UL ) | portMPU_REGION_VALID ); xMPUSettings->xRegion[ ul ].ulRegionAttribute = 0UL; + xMPUSettings->xRegionSettings[ ul ].ulRegionStartAddress = 0UL; + xMPUSettings->xRegionSettings[ ul ].ulRegionEndAddress = 0UL; + xMPUSettings->xRegionSettings[ ul ].ulRegionPermissions = 0UL; } lIndex++; @@ -1018,6 +1497,47 @@ void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings, } /*-----------------------------------------------------------*/ +BaseType_t xPortIsAuthorizedToAccessBuffer( const void * pvBuffer, + uint32_t ulBufferLength, + uint32_t ulAccessRequested ) /* PRIVILEGED_FUNCTION */ + +{ + uint32_t i, ulBufferStartAddress, ulBufferEndAddress; + BaseType_t xAccessGranted = pdFALSE; + const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */ + + if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) + { + xAccessGranted = pdTRUE; + } + else + { + if( portADD_UINT32_WILL_OVERFLOW( ( ( uint32_t ) pvBuffer ), ( ulBufferLength - 1UL ) ) == pdFALSE ) + { + ulBufferStartAddress = ( uint32_t ) pvBuffer; + ulBufferEndAddress = ( ( ( uint32_t ) pvBuffer ) + ulBufferLength - 1UL ); + + for( i = 0; i < portTOTAL_NUM_REGIONS_IN_TCB; i++ ) + { + if( portIS_ADDRESS_WITHIN_RANGE( ulBufferStartAddress, + xTaskMpuSettings->xRegionSettings[ i ].ulRegionStartAddress, + xTaskMpuSettings->xRegionSettings[ i ].ulRegionEndAddress ) && + portIS_ADDRESS_WITHIN_RANGE( ulBufferEndAddress, + xTaskMpuSettings->xRegionSettings[ i ].ulRegionStartAddress, + xTaskMpuSettings->xRegionSettings[ i ].ulRegionEndAddress ) && + portIS_AUTHORIZED( ulAccessRequested, xTaskMpuSettings->xRegionSettings[ i ].ulRegionPermissions ) ) + { + xAccessGranted = pdTRUE; + break; + } + } + } + } + + return xAccessGranted; +} +/*-----------------------------------------------------------*/ + #if ( configASSERT_DEFINED == 1 ) void vPortValidateInterruptPriority( void ) @@ -1077,4 +1597,4 @@ void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings, } #endif /* configASSERT_DEFINED */ -/*-----------------------------------------------------------*/ \ No newline at end of file +/*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM4_MPU/portmacro.h b/portable/GCC/ARM_CM4_MPU/portmacro.h index df23d95381f..5417feaefd2 100644 --- a/portable/GCC/ARM_CM4_MPU/portmacro.h +++ b/portable/GCC/ARM_CM4_MPU/portmacro.h @@ -193,9 +193,45 @@ typedef struct MPU_REGION_REGISTERS uint32_t ulRegionAttribute; } xMPU_REGION_REGISTERS; +typedef struct MPU_REGION_SETTINGS +{ + uint32_t ulRegionStartAddress; + uint32_t ulRegionEndAddress; + uint32_t ulRegionPermissions; +} xMPU_REGION_SETTINGS; + +#if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + + #ifndef configSYSTEM_CALL_STACK_SIZE + #error configSYSTEM_CALL_STACK_SIZE must be defined to the desired size of the system call stack in words for using MPU wrappers v2. + #endif + + typedef struct SYSTEM_CALL_STACK_INFO + { + uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ]; + uint32_t * pulSystemCallStack; + uint32_t * pulTaskStack; + uint32_t ulLinkRegisterAtSystemCallEntry; + } xSYSTEM_CALL_STACK_INFO; + +#endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + +#define MAX_CONTEXT_SIZE 52 + +/* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ +#define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) +#define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) + typedef struct MPU_SETTINGS { xMPU_REGION_REGISTERS xRegion[ portTOTAL_NUM_REGIONS_IN_TCB ]; + xMPU_REGION_SETTINGS xRegionSettings[ portTOTAL_NUM_REGIONS_IN_TCB ]; + uint32_t ulContext[ MAX_CONTEXT_SIZE ]; + uint32_t ulTaskFlags; + + #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo; + #endif } xMPU_SETTINGS; /* Architecture specifics. */ @@ -203,13 +239,15 @@ typedef struct MPU_SETTINGS #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) #define portBYTE_ALIGNMENT 8 #define portDONT_DISCARD __attribute__( ( used ) ) -#define portNORETURN __attribute__( ( noreturn ) ) /*-----------------------------------------------------------*/ /* SVC numbers for various services. */ -#define portSVC_START_SCHEDULER 0 -#define portSVC_YIELD 1 -#define portSVC_RAISE_PRIVILEGE 2 +#define portSVC_START_SCHEDULER 0 +#define portSVC_YIELD 1 +#define portSVC_RAISE_PRIVILEGE 2 +#define portSVC_SYSTEM_CALL_ENTER 3 /* System calls with upto 4 parameters. */ +#define portSVC_SYSTEM_CALL_ENTER_1 4 /* System calls with 5 parameters. */ +#define portSVC_SYSTEM_CALL_EXIT 5 /* Scheduler utilities. */ @@ -321,6 +359,16 @@ extern void vResetPrivilege( void ); #define portRESET_PRIVILEGE() vResetPrivilege() /*-----------------------------------------------------------*/ +extern BaseType_t xPortIsTaskPrivileged( void ); + +/** + * @brief Checks whether or not the calling task is privileged. + * + * @return pdTRUE if the calling task is privileged, pdFALSE otherwise. + */ +#define portIS_TASK_PRIVILEGED() xPortIsTaskPrivileged() +/*-----------------------------------------------------------*/ + portFORCE_INLINE static BaseType_t xPortIsInsideInterrupt( void ) { uint32_t ulCurrentInterrupt; diff --git a/portable/GCC/ARM_CM55/non_secure/mpu_wrappers_v2_asm.c b/portable/GCC/ARM_CM55/non_secure/mpu_wrappers_v2_asm.c new file mode 100644 index 00000000000..6e2043427fe --- /dev/null +++ b/portable/GCC/ARM_CM55/non_secure/mpu_wrappers_v2_asm.c @@ -0,0 +1,2349 @@ +/* + * FreeRTOS Kernel + * Copyright (C) 2021 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 + * + */ + +/* 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. */ +#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +/* Scheduler includes. */ +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" +#include "timers.h" +#include "event_groups.h" +#include "stream_buffer.h" + +#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + +#if ( INCLUDE_xTaskDelayUntil == 1 ) + +BaseType_t MPU_xTaskDelayUntil( TickType_t * const pxPreviousWakeTime, + const TickType_t xTimeIncrement ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskDelayUntil( TickType_t * const pxPreviousWakeTime, + const TickType_t xTimeIncrement ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskDelayUntilImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskDelayUntil_Unpriv \n" + " MPU_xTaskDelayUntil_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskDelayUntilImpl \n" + " MPU_xTaskDelayUntil_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskDelayUntilImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_xTaskDelayUntil == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_xTaskAbortDelay == 1 ) + +BaseType_t MPU_xTaskAbortDelay( TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskAbortDelay( TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskAbortDelayImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskAbortDelay_Unpriv \n" + " MPU_xTaskAbortDelay_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskAbortDelayImpl \n" + " MPU_xTaskAbortDelay_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskAbortDelayImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_xTaskAbortDelay == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskDelay == 1 ) + +void MPU_vTaskDelay( const TickType_t xTicksToDelay ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskDelay( const TickType_t xTicksToDelay ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskDelayImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vTaskDelay_Unpriv \n" + " MPU_vTaskDelay_Priv: \n" + " pop {r0} \n" + " b MPU_vTaskDelayImpl \n" + " MPU_vTaskDelay_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vTaskDelayImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_vTaskDelay == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_uxTaskPriorityGet == 1 ) + +UBaseType_t MPU_uxTaskPriorityGet( const TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxTaskPriorityGet( const TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxTaskPriorityGetImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_uxTaskPriorityGet_Unpriv \n" + " MPU_uxTaskPriorityGet_Priv: \n" + " pop {r0} \n" + " b MPU_uxTaskPriorityGetImpl \n" + " MPU_uxTaskPriorityGet_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_uxTaskPriorityGetImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_uxTaskPriorityGet == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_eTaskGetState == 1 ) + +eTaskState MPU_eTaskGetState( TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +eTaskState MPU_eTaskGetState( TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_eTaskGetStateImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_eTaskGetState_Unpriv \n" + " MPU_eTaskGetState_Priv: \n" + " pop {r0} \n" + " b MPU_eTaskGetStateImpl \n" + " MPU_eTaskGetState_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_eTaskGetStateImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_eTaskGetState == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + +void MPU_vTaskGetInfo( TaskHandle_t xTask, + TaskStatus_t * pxTaskStatus, + BaseType_t xGetFreeStackSpace, + eTaskState eState ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskGetInfo( TaskHandle_t xTask, + TaskStatus_t * pxTaskStatus, + BaseType_t xGetFreeStackSpace, + eTaskState eState ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskGetInfoImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vTaskGetInfo_Unpriv \n" + " MPU_vTaskGetInfo_Priv: \n" + " pop {r0} \n" + " b MPU_vTaskGetInfoImpl \n" + " MPU_vTaskGetInfo_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vTaskGetInfoImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TRACE_FACILITY == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) + +TaskHandle_t MPU_xTaskGetIdleTaskHandle( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TaskHandle_t MPU_xTaskGetIdleTaskHandle( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGetIdleTaskHandleImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskGetIdleTaskHandle_Unpriv \n" + " MPU_xTaskGetIdleTaskHandle_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskGetIdleTaskHandleImpl \n" + " MPU_xTaskGetIdleTaskHandle_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskGetIdleTaskHandleImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskSuspend == 1 ) + +void MPU_vTaskSuspend( TaskHandle_t xTaskToSuspend ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskSuspend( TaskHandle_t xTaskToSuspend ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskSuspendImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vTaskSuspend_Unpriv \n" + " MPU_vTaskSuspend_Priv: \n" + " pop {r0} \n" + " b MPU_vTaskSuspendImpl \n" + " MPU_vTaskSuspend_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vTaskSuspendImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_vTaskSuspend == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskSuspend == 1 ) + +void MPU_vTaskResume( TaskHandle_t xTaskToResume ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskResume( TaskHandle_t xTaskToResume ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskResumeImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vTaskResume_Unpriv \n" + " MPU_vTaskResume_Priv: \n" + " pop {r0} \n" + " b MPU_vTaskResumeImpl \n" + " MPU_vTaskResume_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vTaskResumeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_vTaskSuspend == 1 ) */ +/*-----------------------------------------------------------*/ + +TickType_t MPU_xTaskGetTickCount( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TickType_t MPU_xTaskGetTickCount( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGetTickCountImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskGetTickCount_Unpriv \n" + " MPU_xTaskGetTickCount_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskGetTickCountImpl \n" + " MPU_xTaskGetTickCount_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskGetTickCountImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +UBaseType_t MPU_uxTaskGetNumberOfTasks( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxTaskGetNumberOfTasks( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxTaskGetNumberOfTasksImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_uxTaskGetNumberOfTasks_Unpriv \n" + " MPU_uxTaskGetNumberOfTasks_Priv: \n" + " pop {r0} \n" + " b MPU_uxTaskGetNumberOfTasksImpl \n" + " MPU_uxTaskGetNumberOfTasks_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_uxTaskGetNumberOfTasksImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +char * MPU_pcTaskGetName( TaskHandle_t xTaskToQuery ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +char * MPU_pcTaskGetName( TaskHandle_t xTaskToQuery ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_pcTaskGetNameImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_pcTaskGetName_Unpriv \n" + " MPU_pcTaskGetName_Priv: \n" + " pop {r0} \n" + " b MPU_pcTaskGetNameImpl \n" + " MPU_pcTaskGetName_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_pcTaskGetNameImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +#if ( configGENERATE_RUN_TIME_STATS == 1 ) + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetRunTimeCounter( const TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetRunTimeCounter( const TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_ulTaskGetRunTimeCounterImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_ulTaskGetRunTimeCounter_Unpriv \n" + " MPU_ulTaskGetRunTimeCounter_Priv: \n" + " pop {r0} \n" + " b MPU_ulTaskGetRunTimeCounterImpl \n" + " MPU_ulTaskGetRunTimeCounter_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_ulTaskGetRunTimeCounterImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( ( configGENERATE_RUN_TIME_STATS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configGENERATE_RUN_TIME_STATS == 1 ) + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetRunTimePercent( const TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetRunTimePercent( const TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_ulTaskGetRunTimePercentImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_ulTaskGetRunTimePercent_Unpriv \n" + " MPU_ulTaskGetRunTimePercent_Priv: \n" + " pop {r0} \n" + " b MPU_ulTaskGetRunTimePercentImpl \n" + " MPU_ulTaskGetRunTimePercent_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_ulTaskGetRunTimePercentImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( ( configGENERATE_RUN_TIME_STATS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimePercent( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimePercent( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_ulTaskGetIdleRunTimePercentImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_ulTaskGetIdleRunTimePercent_Unpriv \n" + " MPU_ulTaskGetIdleRunTimePercent_Priv: \n" + " pop {r0} \n" + " b MPU_ulTaskGetIdleRunTimePercentImpl \n" + " MPU_ulTaskGetIdleRunTimePercent_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_ulTaskGetIdleRunTimePercentImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimeCounter( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimeCounter( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_ulTaskGetIdleRunTimeCounterImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_ulTaskGetIdleRunTimeCounter_Unpriv \n" + " MPU_ulTaskGetIdleRunTimeCounter_Priv: \n" + " pop {r0} \n" + " b MPU_ulTaskGetIdleRunTimeCounterImpl \n" + " MPU_ulTaskGetIdleRunTimeCounter_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_ulTaskGetIdleRunTimeCounterImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_APPLICATION_TASK_TAG == 1 ) + +void MPU_vTaskSetApplicationTaskTag( TaskHandle_t xTask, + TaskHookFunction_t pxHookFunction ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskSetApplicationTaskTag( TaskHandle_t xTask, + TaskHookFunction_t pxHookFunction ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskSetApplicationTaskTagImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vTaskSetApplicationTaskTag_Unpriv \n" + " MPU_vTaskSetApplicationTaskTag_Priv: \n" + " pop {r0} \n" + " b MPU_vTaskSetApplicationTaskTagImpl \n" + " MPU_vTaskSetApplicationTaskTag_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vTaskSetApplicationTaskTagImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_APPLICATION_TASK_TAG == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_APPLICATION_TASK_TAG == 1 ) + +TaskHookFunction_t MPU_xTaskGetApplicationTaskTag( TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TaskHookFunction_t MPU_xTaskGetApplicationTaskTag( TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGetApplicationTaskTagImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskGetApplicationTaskTag_Unpriv \n" + " MPU_xTaskGetApplicationTaskTag_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskGetApplicationTaskTagImpl \n" + " MPU_xTaskGetApplicationTaskTag_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskGetApplicationTaskTagImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_APPLICATION_TASK_TAG == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) + +void MPU_vTaskSetThreadLocalStoragePointer( TaskHandle_t xTaskToSet, + BaseType_t xIndex, + void * pvValue ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskSetThreadLocalStoragePointer( TaskHandle_t xTaskToSet, + BaseType_t xIndex, + void * pvValue ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskSetThreadLocalStoragePointerImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vTaskSetThreadLocalStoragePointer_Unpriv \n" + " MPU_vTaskSetThreadLocalStoragePointer_Priv: \n" + " pop {r0} \n" + " b MPU_vTaskSetThreadLocalStoragePointerImpl \n" + " MPU_vTaskSetThreadLocalStoragePointer_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vTaskSetThreadLocalStoragePointerImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) + +void * MPU_pvTaskGetThreadLocalStoragePointer( TaskHandle_t xTaskToQuery, + BaseType_t xIndex ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void * MPU_pvTaskGetThreadLocalStoragePointer( TaskHandle_t xTaskToQuery, + BaseType_t xIndex ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_pvTaskGetThreadLocalStoragePointerImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_pvTaskGetThreadLocalStoragePointer_Unpriv \n" + " MPU_pvTaskGetThreadLocalStoragePointer_Priv: \n" + " pop {r0} \n" + " b MPU_pvTaskGetThreadLocalStoragePointerImpl \n" + " MPU_pvTaskGetThreadLocalStoragePointer_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_pvTaskGetThreadLocalStoragePointerImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + +UBaseType_t MPU_uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray, + const UBaseType_t uxArraySize, + configRUN_TIME_COUNTER_TYPE * const pulTotalRunTime ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray, + const UBaseType_t uxArraySize, + configRUN_TIME_COUNTER_TYPE * const pulTotalRunTime ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxTaskGetSystemStateImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_uxTaskGetSystemState_Unpriv \n" + " MPU_uxTaskGetSystemState_Priv: \n" + " pop {r0} \n" + " b MPU_uxTaskGetSystemStateImpl \n" + " MPU_uxTaskGetSystemState_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_uxTaskGetSystemStateImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TRACE_FACILITY == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) + +UBaseType_t MPU_uxTaskGetStackHighWaterMark( TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxTaskGetStackHighWaterMark( TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxTaskGetStackHighWaterMarkImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_uxTaskGetStackHighWaterMark_Unpriv \n" + " MPU_uxTaskGetStackHighWaterMark_Priv: \n" + " pop {r0} \n" + " b MPU_uxTaskGetStackHighWaterMarkImpl \n" + " MPU_uxTaskGetStackHighWaterMark_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_uxTaskGetStackHighWaterMarkImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) + +configSTACK_DEPTH_TYPE MPU_uxTaskGetStackHighWaterMark2( TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +configSTACK_DEPTH_TYPE MPU_uxTaskGetStackHighWaterMark2( TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxTaskGetStackHighWaterMark2Impl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_uxTaskGetStackHighWaterMark2_Unpriv \n" + " MPU_uxTaskGetStackHighWaterMark2_Priv: \n" + " pop {r0} \n" + " b MPU_uxTaskGetStackHighWaterMark2Impl \n" + " MPU_uxTaskGetStackHighWaterMark2_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_uxTaskGetStackHighWaterMark2Impl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) ) + +TaskHandle_t MPU_xTaskGetCurrentTaskHandle( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TaskHandle_t MPU_xTaskGetCurrentTaskHandle( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGetCurrentTaskHandleImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskGetCurrentTaskHandle_Unpriv \n" + " MPU_xTaskGetCurrentTaskHandle_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskGetCurrentTaskHandleImpl \n" + " MPU_xTaskGetCurrentTaskHandle_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskGetCurrentTaskHandleImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_xTaskGetSchedulerState == 1 ) + +BaseType_t MPU_xTaskGetSchedulerState( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskGetSchedulerState( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGetSchedulerStateImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskGetSchedulerState_Unpriv \n" + " MPU_xTaskGetSchedulerState_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskGetSchedulerStateImpl \n" + " MPU_xTaskGetSchedulerState_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskGetSchedulerStateImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_xTaskGetSchedulerState == 1 ) */ +/*-----------------------------------------------------------*/ + +void MPU_vTaskSetTimeOutState( TimeOut_t * const pxTimeOut ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskSetTimeOutState( TimeOut_t * const pxTimeOut ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskSetTimeOutStateImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vTaskSetTimeOutState_Unpriv \n" + " MPU_vTaskSetTimeOutState_Priv: \n" + " pop {r0} \n" + " b MPU_vTaskSetTimeOutStateImpl \n" + " MPU_vTaskSetTimeOutState_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vTaskSetTimeOutStateImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut, + TickType_t * const pxTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut, + TickType_t * const pxTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskCheckForTimeOutImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskCheckForTimeOut_Unpriv \n" + " MPU_xTaskCheckForTimeOut_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskCheckForTimeOutImpl \n" + " MPU_xTaskCheckForTimeOut_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskCheckForTimeOutImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +#if ( configUSE_TASK_NOTIFICATIONS == 1 ) + +BaseType_t MPU_xTaskGenericNotify( TaskHandle_t xTaskToNotify, + UBaseType_t uxIndexToNotify, + uint32_t ulValue, + eNotifyAction eAction, + uint32_t * pulPreviousNotificationValue ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskGenericNotify( TaskHandle_t xTaskToNotify, + UBaseType_t uxIndexToNotify, + uint32_t ulValue, + eNotifyAction eAction, + uint32_t * pulPreviousNotificationValue ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGenericNotifyImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskGenericNotify_Unpriv \n" + " MPU_xTaskGenericNotify_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskGenericNotifyImpl \n" + " MPU_xTaskGenericNotify_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskGenericNotifyImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER_1 ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TASK_NOTIFICATIONS == 1 ) + +BaseType_t MPU_xTaskGenericNotifyWait( UBaseType_t uxIndexToWaitOn, + uint32_t ulBitsToClearOnEntry, + uint32_t ulBitsToClearOnExit, + uint32_t * pulNotificationValue, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskGenericNotifyWait( UBaseType_t uxIndexToWaitOn, + uint32_t ulBitsToClearOnEntry, + uint32_t ulBitsToClearOnExit, + uint32_t * pulNotificationValue, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGenericNotifyWaitImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskGenericNotifyWait_Unpriv \n" + " MPU_xTaskGenericNotifyWait_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskGenericNotifyWaitImpl \n" + " MPU_xTaskGenericNotifyWait_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskGenericNotifyWaitImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER_1 ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TASK_NOTIFICATIONS == 1 ) + +uint32_t MPU_ulTaskGenericNotifyTake( UBaseType_t uxIndexToWaitOn, + BaseType_t xClearCountOnExit, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +uint32_t MPU_ulTaskGenericNotifyTake( UBaseType_t uxIndexToWaitOn, + BaseType_t xClearCountOnExit, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_ulTaskGenericNotifyTakeImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_ulTaskGenericNotifyTake_Unpriv \n" + " MPU_ulTaskGenericNotifyTake_Priv: \n" + " pop {r0} \n" + " b MPU_ulTaskGenericNotifyTakeImpl \n" + " MPU_ulTaskGenericNotifyTake_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_ulTaskGenericNotifyTakeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TASK_NOTIFICATIONS == 1 ) + +BaseType_t MPU_xTaskGenericNotifyStateClear( TaskHandle_t xTask, + UBaseType_t uxIndexToClear ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskGenericNotifyStateClear( TaskHandle_t xTask, + UBaseType_t uxIndexToClear ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGenericNotifyStateClearImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskGenericNotifyStateClear_Unpriv \n" + " MPU_xTaskGenericNotifyStateClear_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskGenericNotifyStateClearImpl \n" + " MPU_xTaskGenericNotifyStateClear_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskGenericNotifyStateClearImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TASK_NOTIFICATIONS == 1 ) + +uint32_t MPU_ulTaskGenericNotifyValueClear( TaskHandle_t xTask, + UBaseType_t uxIndexToClear, + uint32_t ulBitsToClear ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +uint32_t MPU_ulTaskGenericNotifyValueClear( TaskHandle_t xTask, + UBaseType_t uxIndexToClear, + uint32_t ulBitsToClear ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_ulTaskGenericNotifyValueClearImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_ulTaskGenericNotifyValueClear_Unpriv \n" + " MPU_ulTaskGenericNotifyValueClear_Priv: \n" + " pop {r0} \n" + " b MPU_ulTaskGenericNotifyValueClearImpl \n" + " MPU_ulTaskGenericNotifyValueClear_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_ulTaskGenericNotifyValueClearImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xQueueGenericSend( QueueHandle_t xQueue, + const void * const pvItemToQueue, + TickType_t xTicksToWait, + const BaseType_t xCopyPosition ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueueGenericSend( QueueHandle_t xQueue, + const void * const pvItemToQueue, + TickType_t xTicksToWait, + const BaseType_t xCopyPosition ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueGenericSendImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xQueueGenericSend_Unpriv \n" + " MPU_xQueueGenericSend_Priv: \n" + " pop {r0} \n" + " b MPU_xQueueGenericSendImpl \n" + " MPU_xQueueGenericSend_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xQueueGenericSendImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +UBaseType_t MPU_uxQueueMessagesWaiting( const QueueHandle_t xQueue ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxQueueMessagesWaiting( const QueueHandle_t xQueue ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxQueueMessagesWaitingImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_uxQueueMessagesWaiting_Unpriv \n" + " MPU_uxQueueMessagesWaiting_Priv: \n" + " pop {r0} \n" + " b MPU_uxQueueMessagesWaitingImpl \n" + " MPU_uxQueueMessagesWaiting_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_uxQueueMessagesWaitingImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +UBaseType_t MPU_uxQueueSpacesAvailable( const QueueHandle_t xQueue ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxQueueSpacesAvailable( const QueueHandle_t xQueue ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxQueueSpacesAvailableImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_uxQueueSpacesAvailable_Unpriv \n" + " MPU_uxQueueSpacesAvailable_Priv: \n" + " pop {r0} \n" + " b MPU_uxQueueSpacesAvailableImpl \n" + " MPU_uxQueueSpacesAvailable_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_uxQueueSpacesAvailableImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xQueueReceive( QueueHandle_t xQueue, + void * const pvBuffer, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueueReceive( QueueHandle_t xQueue, + void * const pvBuffer, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueReceiveImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xQueueReceive_Unpriv \n" + " MPU_xQueueReceive_Priv: \n" + " pop {r0} \n" + " b MPU_xQueueReceiveImpl \n" + " MPU_xQueueReceive_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xQueueReceiveImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xQueuePeek( QueueHandle_t xQueue, + void * const pvBuffer, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueuePeek( QueueHandle_t xQueue, + void * const pvBuffer, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueuePeekImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xQueuePeek_Unpriv \n" + " MPU_xQueuePeek_Priv: \n" + " pop {r0} \n" + " b MPU_xQueuePeekImpl \n" + " MPU_xQueuePeek_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xQueuePeekImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xQueueSemaphoreTake( QueueHandle_t xQueue, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueueSemaphoreTake( QueueHandle_t xQueue, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueSemaphoreTakeImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xQueueSemaphoreTake_Unpriv \n" + " MPU_xQueueSemaphoreTake_Priv: \n" + " pop {r0} \n" + " b MPU_xQueueSemaphoreTakeImpl \n" + " MPU_xQueueSemaphoreTake_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xQueueSemaphoreTakeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +#if ( ( configUSE_MUTEXES == 1 ) && ( INCLUDE_xSemaphoreGetMutexHolder == 1 ) ) + +TaskHandle_t MPU_xQueueGetMutexHolder( QueueHandle_t xSemaphore ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TaskHandle_t MPU_xQueueGetMutexHolder( QueueHandle_t xSemaphore ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueGetMutexHolderImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xQueueGetMutexHolder_Unpriv \n" + " MPU_xQueueGetMutexHolder_Priv: \n" + " pop {r0} \n" + " b MPU_xQueueGetMutexHolderImpl \n" + " MPU_xQueueGetMutexHolder_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xQueueGetMutexHolderImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( ( configUSE_MUTEXES == 1 ) && ( INCLUDE_xSemaphoreGetMutexHolder == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_RECURSIVE_MUTEXES == 1 ) + +BaseType_t MPU_xQueueTakeMutexRecursive( QueueHandle_t xMutex, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueueTakeMutexRecursive( QueueHandle_t xMutex, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueTakeMutexRecursiveImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xQueueTakeMutexRecursive_Unpriv \n" + " MPU_xQueueTakeMutexRecursive_Priv: \n" + " pop {r0} \n" + " b MPU_xQueueTakeMutexRecursiveImpl \n" + " MPU_xQueueTakeMutexRecursive_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xQueueTakeMutexRecursiveImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_RECURSIVE_MUTEXES == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_RECURSIVE_MUTEXES == 1 ) + +BaseType_t MPU_xQueueGiveMutexRecursive( QueueHandle_t pxMutex ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueueGiveMutexRecursive( QueueHandle_t pxMutex ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueGiveMutexRecursiveImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xQueueGiveMutexRecursive_Unpriv \n" + " MPU_xQueueGiveMutexRecursive_Priv: \n" + " pop {r0} \n" + " b MPU_xQueueGiveMutexRecursiveImpl \n" + " MPU_xQueueGiveMutexRecursive_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xQueueGiveMutexRecursiveImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_RECURSIVE_MUTEXES == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_QUEUE_SETS == 1 ) + +QueueSetMemberHandle_t MPU_xQueueSelectFromSet( QueueSetHandle_t xQueueSet, + const TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +QueueSetMemberHandle_t MPU_xQueueSelectFromSet( QueueSetHandle_t xQueueSet, + const TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueSelectFromSetImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xQueueSelectFromSet_Unpriv \n" + " MPU_xQueueSelectFromSet_Priv: \n" + " pop {r0} \n" + " b MPU_xQueueSelectFromSetImpl \n" + " MPU_xQueueSelectFromSet_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xQueueSelectFromSetImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_QUEUE_SETS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_QUEUE_SETS == 1 ) + +BaseType_t MPU_xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore, + QueueSetHandle_t xQueueSet ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore, + QueueSetHandle_t xQueueSet ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueAddToSetImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xQueueAddToSet_Unpriv \n" + " MPU_xQueueAddToSet_Priv: \n" + " pop {r0} \n" + " b MPU_xQueueAddToSetImpl \n" + " MPU_xQueueAddToSet_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xQueueAddToSetImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_QUEUE_SETS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configQUEUE_REGISTRY_SIZE > 0 ) + +void MPU_vQueueAddToRegistry( QueueHandle_t xQueue, + const char * pcName ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vQueueAddToRegistry( QueueHandle_t xQueue, + const char * pcName ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vQueueAddToRegistryImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vQueueAddToRegistry_Unpriv \n" + " MPU_vQueueAddToRegistry_Priv: \n" + " pop {r0} \n" + " b MPU_vQueueAddToRegistryImpl \n" + " MPU_vQueueAddToRegistry_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vQueueAddToRegistryImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configQUEUE_REGISTRY_SIZE > 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configQUEUE_REGISTRY_SIZE > 0 ) + +void MPU_vQueueUnregisterQueue( QueueHandle_t xQueue ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vQueueUnregisterQueue( QueueHandle_t xQueue ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vQueueUnregisterQueueImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vQueueUnregisterQueue_Unpriv \n" + " MPU_vQueueUnregisterQueue_Priv: \n" + " pop {r0} \n" + " b MPU_vQueueUnregisterQueueImpl \n" + " MPU_vQueueUnregisterQueue_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vQueueUnregisterQueueImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configQUEUE_REGISTRY_SIZE > 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configQUEUE_REGISTRY_SIZE > 0 ) + +const char * MPU_pcQueueGetName( QueueHandle_t xQueue ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +const char * MPU_pcQueueGetName( QueueHandle_t xQueue ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_pcQueueGetNameImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_pcQueueGetName_Unpriv \n" + " MPU_pcQueueGetName_Priv: \n" + " pop {r0} \n" + " b MPU_pcQueueGetNameImpl \n" + " MPU_pcQueueGetName_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_pcQueueGetNameImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configQUEUE_REGISTRY_SIZE > 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +void * MPU_pvTimerGetTimerID( const TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void * MPU_pvTimerGetTimerID( const TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_pvTimerGetTimerIDImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_pvTimerGetTimerID_Unpriv \n" + " MPU_pvTimerGetTimerID_Priv: \n" + " pop {r0} \n" + " b MPU_pvTimerGetTimerIDImpl \n" + " MPU_pvTimerGetTimerID_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_pvTimerGetTimerIDImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +void MPU_vTimerSetTimerID( TimerHandle_t xTimer, + void * pvNewID ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTimerSetTimerID( TimerHandle_t xTimer, + void * pvNewID ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTimerSetTimerIDImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vTimerSetTimerID_Unpriv \n" + " MPU_vTimerSetTimerID_Priv: \n" + " pop {r0} \n" + " b MPU_vTimerSetTimerIDImpl \n" + " MPU_vTimerSetTimerID_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vTimerSetTimerIDImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +BaseType_t MPU_xTimerIsTimerActive( TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTimerIsTimerActive( TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTimerIsTimerActiveImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTimerIsTimerActive_Unpriv \n" + " MPU_xTimerIsTimerActive_Priv: \n" + " pop {r0} \n" + " b MPU_xTimerIsTimerActiveImpl \n" + " MPU_xTimerIsTimerActive_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTimerIsTimerActiveImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +TaskHandle_t MPU_xTimerGetTimerDaemonTaskHandle( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TaskHandle_t MPU_xTimerGetTimerDaemonTaskHandle( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTimerGetTimerDaemonTaskHandleImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTimerGetTimerDaemonTaskHandle_Unpriv \n" + " MPU_xTimerGetTimerDaemonTaskHandle_Priv: \n" + " pop {r0} \n" + " b MPU_xTimerGetTimerDaemonTaskHandleImpl \n" + " MPU_xTimerGetTimerDaemonTaskHandle_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTimerGetTimerDaemonTaskHandleImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +BaseType_t MPU_xTimerGenericCommand( TimerHandle_t xTimer, + const BaseType_t xCommandID, + const TickType_t xOptionalValue, + BaseType_t * const pxHigherPriorityTaskWoken, + const TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTimerGenericCommand( TimerHandle_t xTimer, + const BaseType_t xCommandID, + const TickType_t xOptionalValue, + BaseType_t * const pxHigherPriorityTaskWoken, + const TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTimerGenericCommandImpl \n" + " \n" + " push {r0} \n" + " mrs r0, ipsr \n" + " cmp r0, #0 \n" + " bne MPU_xTimerGenericCommand_Priv \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " beq MPU_xTimerGenericCommand_Priv \n" + " MPU_xTimerGenericCommand_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTimerGenericCommandImpl \n" + " svc %1 \n" + " bx lr \n" + " MPU_xTimerGenericCommand_Priv: \n" + " pop {r0} \n" + " b MPU_xTimerGenericCommandImpl \n" + " \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER_1 ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +const char * MPU_pcTimerGetName( TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +const char * MPU_pcTimerGetName( TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_pcTimerGetNameImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_pcTimerGetName_Unpriv \n" + " MPU_pcTimerGetName_Priv: \n" + " pop {r0} \n" + " b MPU_pcTimerGetNameImpl \n" + " MPU_pcTimerGetName_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_pcTimerGetNameImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, + const BaseType_t uxAutoReload ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, + const BaseType_t uxAutoReload ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTimerSetReloadModeImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vTimerSetReloadMode_Unpriv \n" + " MPU_vTimerSetReloadMode_Priv: \n" + " pop {r0} \n" + " b MPU_vTimerSetReloadModeImpl \n" + " MPU_vTimerSetReloadMode_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vTimerSetReloadModeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +BaseType_t MPU_xTimerGetReloadMode( TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTimerGetReloadMode( TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTimerGetReloadModeImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTimerGetReloadMode_Unpriv \n" + " MPU_xTimerGetReloadMode_Priv: \n" + " pop {r0} \n" + " b MPU_xTimerGetReloadModeImpl \n" + " MPU_xTimerGetReloadMode_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTimerGetReloadModeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +UBaseType_t MPU_uxTimerGetReloadMode( TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxTimerGetReloadMode( TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxTimerGetReloadModeImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_uxTimerGetReloadMode_Unpriv \n" + " MPU_uxTimerGetReloadMode_Priv: \n" + " pop {r0} \n" + " b MPU_uxTimerGetReloadModeImpl \n" + " MPU_uxTimerGetReloadMode_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_uxTimerGetReloadModeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +TickType_t MPU_xTimerGetPeriod( TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TickType_t MPU_xTimerGetPeriod( TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTimerGetPeriodImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTimerGetPeriod_Unpriv \n" + " MPU_xTimerGetPeriod_Priv: \n" + " pop {r0} \n" + " b MPU_xTimerGetPeriodImpl \n" + " MPU_xTimerGetPeriod_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTimerGetPeriodImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +TickType_t MPU_xTimerGetExpiryTime( TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TickType_t MPU_xTimerGetExpiryTime( TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTimerGetExpiryTimeImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTimerGetExpiryTime_Unpriv \n" + " MPU_xTimerGetExpiryTime_Priv: \n" + " pop {r0} \n" + " b MPU_xTimerGetExpiryTimeImpl \n" + " MPU_xTimerGetExpiryTime_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTimerGetExpiryTimeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +EventBits_t MPU_xEventGroupWaitBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToWaitFor, + const BaseType_t xClearOnExit, + const BaseType_t xWaitForAllBits, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +EventBits_t MPU_xEventGroupWaitBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToWaitFor, + const BaseType_t xClearOnExit, + const BaseType_t xWaitForAllBits, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupWaitBitsImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xEventGroupWaitBits_Unpriv \n" + " MPU_xEventGroupWaitBits_Priv: \n" + " pop {r0} \n" + " b MPU_xEventGroupWaitBitsImpl \n" + " MPU_xEventGroupWaitBits_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xEventGroupWaitBitsImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER_1 ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToClear ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToClear ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupClearBitsImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xEventGroupClearBits_Unpriv \n" + " MPU_xEventGroupClearBits_Priv: \n" + " pop {r0} \n" + " b MPU_xEventGroupClearBitsImpl \n" + " MPU_xEventGroupClearBits_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xEventGroupClearBitsImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupSetBitsImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xEventGroupSetBits_Unpriv \n" + " MPU_xEventGroupSetBits_Priv: \n" + " pop {r0} \n" + " b MPU_xEventGroupSetBitsImpl \n" + " MPU_xEventGroupSetBits_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xEventGroupSetBitsImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet, + const EventBits_t uxBitsToWaitFor, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet, + const EventBits_t uxBitsToWaitFor, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupSyncImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xEventGroupSync_Unpriv \n" + " MPU_xEventGroupSync_Priv: \n" + " pop {r0} \n" + " b MPU_xEventGroupSyncImpl \n" + " MPU_xEventGroupSync_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xEventGroupSyncImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + +UBaseType_t MPU_uxEventGroupGetNumber( void * xEventGroup ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxEventGroupGetNumber( void * xEventGroup ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxEventGroupGetNumberImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_uxEventGroupGetNumber_Unpriv \n" + " MPU_uxEventGroupGetNumber_Priv: \n" + " pop {r0} \n" + " b MPU_uxEventGroupGetNumberImpl \n" + " MPU_uxEventGroupGetNumber_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_uxEventGroupGetNumberImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /*( configUSE_TRACE_FACILITY == 1 )*/ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + +void MPU_vEventGroupSetNumber( void * xEventGroup, + UBaseType_t uxEventGroupNumber ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vEventGroupSetNumber( void * xEventGroup, + UBaseType_t uxEventGroupNumber ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vEventGroupSetNumberImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vEventGroupSetNumber_Unpriv \n" + " MPU_vEventGroupSetNumber_Priv: \n" + " pop {r0} \n" + " b MPU_vEventGroupSetNumberImpl \n" + " MPU_vEventGroupSetNumber_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vEventGroupSetNumberImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /*( configUSE_TRACE_FACILITY == 1 )*/ +/*-----------------------------------------------------------*/ + +size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, + const void * pvTxData, + size_t xDataLengthBytes, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, + const void * pvTxData, + size_t xDataLengthBytes, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferSendImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferSend_Unpriv \n" + " MPU_xStreamBufferSend_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferSendImpl \n" + " MPU_xStreamBufferSend_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xStreamBufferSendImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, + void * pvRxData, + size_t xBufferLengthBytes, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, + void * pvRxData, + size_t xBufferLengthBytes, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferReceiveImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferReceive_Unpriv \n" + " MPU_xStreamBufferReceive_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferReceiveImpl \n" + " MPU_xStreamBufferReceive_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xStreamBufferReceiveImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferIsFullImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferIsFull_Unpriv \n" + " MPU_xStreamBufferIsFull_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferIsFullImpl \n" + " MPU_xStreamBufferIsFull_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xStreamBufferIsFullImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferIsEmptyImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferIsEmpty_Unpriv \n" + " MPU_xStreamBufferIsEmpty_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferIsEmptyImpl \n" + " MPU_xStreamBufferIsEmpty_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xStreamBufferIsEmptyImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferSpacesAvailableImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferSpacesAvailable_Unpriv \n" + " MPU_xStreamBufferSpacesAvailable_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferSpacesAvailableImpl \n" + " MPU_xStreamBufferSpacesAvailable_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xStreamBufferSpacesAvailableImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferBytesAvailableImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferBytesAvailable_Unpriv \n" + " MPU_xStreamBufferBytesAvailable_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferBytesAvailableImpl \n" + " MPU_xStreamBufferBytesAvailable_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xStreamBufferBytesAvailableImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, + size_t xTriggerLevel ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, + size_t xTriggerLevel ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferSetTriggerLevelImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferSetTriggerLevel_Unpriv \n" + " MPU_xStreamBufferSetTriggerLevel_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferSetTriggerLevelImpl \n" + " MPU_xStreamBufferSetTriggerLevel_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xStreamBufferSetTriggerLevelImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferNextMessageLengthBytesImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferNextMessageLengthBytes_Unpriv \n" + " MPU_xStreamBufferNextMessageLengthBytes_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferNextMessageLengthBytesImpl \n" + " MPU_xStreamBufferNextMessageLengthBytes_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xStreamBufferNextMessageLengthBytesImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ diff --git a/portable/GCC/ARM_CM55/non_secure/port.c b/portable/GCC/ARM_CM55/non_secure/port.c index 7bbe1b7bc53..cab1b3668bf 100644 --- a/portable/GCC/ARM_CM55/non_secure/port.c +++ b/portable/GCC/ARM_CM55/non_secure/port.c @@ -107,6 +107,13 @@ #define portPRIGROUP_SHIFT ( 8UL ) /*-----------------------------------------------------------*/ +/** + * @brief Constants used during system call enter and exit. + */ +#define portPSR_STACK_PADDING_MASK ( 1UL << 9UL ) +#define portEXC_RETURN_STACK_FRAME_TYPE_MASK ( 1UL << 4UL ) +/*-----------------------------------------------------------*/ + /** * @brief Constants required to manipulate the FPU. */ @@ -123,6 +130,14 @@ #define portFPCCR_LSPEN_MASK ( 1UL << portFPCCR_LSPEN_POS ) /*-----------------------------------------------------------*/ +/** + * @brief Offsets in the stack to the parameters when inside the SVC handler. + */ +#define portOFFSET_TO_LR ( 5 ) +#define portOFFSET_TO_PC ( 6 ) +#define portOFFSET_TO_PSR ( 7 ) +/*-----------------------------------------------------------*/ + /** * @brief Constants required to manipulate the MPU. */ @@ -148,6 +163,8 @@ #define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ #define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ +#define portMPU_RBAR_ACCESS_PERMISSIONS_MASK ( 3UL << 1UL ) + #define portMPU_MAIR_ATTR0_POS ( 0UL ) #define portMPU_MAIR_ATTR0_MASK ( 0x000000ff ) @@ -191,6 +208,30 @@ /* Expected value of the portMPU_TYPE register. */ #define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) + +/* Extract first address of the MPU region as encoded in the + * RBAR (Region Base Address Register) value. */ +#define portEXTRACT_FIRST_ADDRESS_FROM_RBAR( rbar ) \ + ( ( rbar ) & portMPU_RBAR_ADDRESS_MASK ) + +/* Extract last address of the MPU region as encoded in the + * RLAR (Region Limit Address Register) value. */ +#define portEXTRACT_LAST_ADDRESS_FROM_RLAR( rlar ) \ + ( ( ( rlar ) & portMPU_RLAR_ADDRESS_MASK ) | ~portMPU_RLAR_ADDRESS_MASK ) + +/* Does addr lies within [start, end] address range? */ +#define portIS_ADDRESS_WITHIN_RANGE( addr, start, end ) \ + ( ( ( addr ) >= ( start ) ) && ( ( addr ) <= ( end ) ) ) + +/* Is the access request satisfied by the available permissions? */ +#define portIS_AUTHORIZED( accessRequest, permissions ) \ + ( ( ( permissions ) & ( accessRequest ) ) == accessRequest ) + +/* 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 ) ) ) /*-----------------------------------------------------------*/ /** @@ -311,6 +352,19 @@ static void prvTaskExitError( void ); #if ( configENABLE_MPU == 1 ) +/** + * @brief Extract MPU region's access permissions from the Region Base Address + * Register (RBAR) value. + * + * @param ulRBARValue RBAR value for the MPU region. + * + * @return uint32_t Access permissions. + */ + static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) PRIVILEGED_FUNCTION; +#endif /* configENABLE_MPU */ + +#if ( configENABLE_MPU == 1 ) + /** * @brief Setup the Memory Protection Unit (MPU). */ @@ -365,6 +419,60 @@ void SysTick_Handler( void ) PRIVILEGED_FUNCTION; * @brief C part of SVC handler. */ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIVILEGED_FUNCTION; + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + + /** + * @brief Sets up the system call stack so that upon returning from + * SVC, the system call stack is used. + * + * It is used for the system calls with up to 4 parameters. + * + * @param pulTaskStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + */ + void vSystemCallEnter( uint32_t * pulTaskStack, uint32_t ulLR ) PRIVILEGED_FUNCTION; + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + + /** + * @brief Sets up the system call stack so that upon returning from + * SVC, the system call stack is used. + * + * It is used for the system calls with 5 parameters. + * + * @param pulTaskStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + */ + void vSystemCallEnter_1( uint32_t * pulTaskStack, uint32_t ulLR ) PRIVILEGED_FUNCTION; + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + + /** + * @brief Sets up the task stack so that upon returning from + * SVC, the task stack is used again. + * + * @param pulSystemCallStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + */ + void vSystemCallExit( uint32_t * pulSystemCallStack, uint32_t ulLR ) PRIVILEGED_FUNCTION; + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + +#if ( configENABLE_MPU == 1 ) + + /** + * @brief Checks whether or not the calling task is privileged. + * + * @return pdTRUE if the calling task is privileged, pdFALSE otherwise. + */ + BaseType_t xPortIsTaskPrivileged( void ) PRIVILEGED_FUNCTION; + +#endif /* configENABLE_MPU == 1 */ /*-----------------------------------------------------------*/ /** @@ -681,6 +789,26 @@ static void prvTaskExitError( void ) } /*-----------------------------------------------------------*/ +#if ( configENABLE_MPU == 1 ) + static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) /* PRIVILEGED_FUNCTION */ + { + uint32_t ulAccessPermissions = 0; + + if( ( ulRBARValue & portMPU_RBAR_ACCESS_PERMISSIONS_MASK ) == portMPU_REGION_READ_ONLY ) + { + ulAccessPermissions = tskMPU_READ_PERMISSION; + } + + if( ( ulRBARValue & portMPU_RBAR_ACCESS_PERMISSIONS_MASK ) == portMPU_REGION_READ_WRITE ) + { + ulAccessPermissions = ( tskMPU_READ_PERMISSION | tskMPU_WRITE_PERMISSION ); + } + + return ulAccessPermissions; + } +#endif /* configENABLE_MPU */ +/*-----------------------------------------------------------*/ + #if ( configENABLE_MPU == 1 ) static void prvSetupMPU( void ) /* PRIVILEGED_FUNCTION */ { @@ -853,7 +981,7 @@ void SysTick_Handler( void ) /* PRIVILEGED_FUNCTION */ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTION portDONT_DISCARD */ { - #if ( configENABLE_MPU == 1 ) + #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) ) #if defined( __ARMCC_VERSION ) /* Declaration when these variable are defined in code instead of being @@ -865,7 +993,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO extern uint32_t __syscalls_flash_start__[]; extern uint32_t __syscalls_flash_end__[]; #endif /* defined( __ARMCC_VERSION ) */ - #endif /* configENABLE_MPU */ + #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */ uint32_t ulPC; @@ -880,7 +1008,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO /* Register are stored on the stack in the following order - R0, R1, R2, R3, * R12, LR, PC, xPSR. */ - ulPC = pulCallerStackAddress[ 6 ]; + ulPC = pulCallerStackAddress[ portOFFSET_TO_PC ]; ucSVCNumber = ( ( uint8_t * ) ulPC )[ -2 ]; switch( ucSVCNumber ) @@ -951,18 +1079,18 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO vRestoreContextOfFirstTask(); break; - #if ( configENABLE_MPU == 1 ) - case portSVC_RAISE_PRIVILEGE: + #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) ) + case portSVC_RAISE_PRIVILEGE: - /* Only raise the privilege, if the svc was raised from any of - * the system calls. */ - if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) && - ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ) - { - vRaisePrivilege(); - } - break; - #endif /* configENABLE_MPU */ + /* Only raise the privilege, if the svc was raised from any of + * the system calls. */ + if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ) + { + vRaisePrivilege(); + } + break; + #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */ default: /* Incorrect SVC call. */ @@ -971,51 +1099,455 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } /*-----------------------------------------------------------*/ -/* *INDENT-OFF* */ -#if ( configENABLE_MPU == 1 ) - StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, - StackType_t * pxEndOfStack, - TaskFunction_t pxCode, - void * pvParameters, - BaseType_t xRunPrivileged ) /* PRIVILEGED_FUNCTION */ -#else - StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, - StackType_t * pxEndOfStack, - TaskFunction_t pxCode, - void * pvParameters ) /* PRIVILEGED_FUNCTION */ -#endif /* configENABLE_MPU */ -/* *INDENT-ON* */ +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + +void vSystemCallEnter( uint32_t * pulTaskStack, uint32_t ulLR ) /* PRIVILEGED_FUNCTION */ { - /* Simulate the stack frame as it would be created by a context switch - * interrupt. */ - #if ( portPRELOAD_REGISTERS == 0 ) + extern TaskHandle_t pxCurrentTCB; + xMPU_SETTINGS * pxMpuSettings; + uint32_t * pulSystemCallStack; + uint32_t ulStackFrameSize, ulSystemCallLocation, i; + #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being + * exported from linker scripts. */ + extern uint32_t * __syscalls_flash_start__; + extern uint32_t * __syscalls_flash_end__; + #else + /* Declaration when these variable are exported from linker scripts. */ + extern uint32_t __syscalls_flash_start__[]; + extern uint32_t __syscalls_flash_end__[]; + #endif /* #if defined( __ARMCC_VERSION ) */ + + ulSystemCallLocation = pulTaskStack[ portOFFSET_TO_PC ]; + + /* If the request did not come from the system call section, do nothing. */ + if( ( ulSystemCallLocation >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulSystemCallLocation <= ( uint32_t ) __syscalls_flash_end__ ) ) { - pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ - *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ - pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pxCode; /* PC */ - pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR */ - pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ - *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ - pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */ - *pxTopOfStack = portINITIAL_EXC_RETURN; + pxMpuSettings = xTaskGetMPUSettings( pxCurrentTCB ); + pulSystemCallStack = pxMpuSettings->xSystemCallStackInfo.pulSystemCallStack; - #if ( configENABLE_MPU == 1 ) + /* This is not NULL only for the duration of the system call. */ + configASSERT( pxMpuSettings->xSystemCallStackInfo.pulTaskStack == NULL ); + + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) { - pxTopOfStack--; + if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) + { + /* Extended frame i.e. FPU in use. */ + ulStackFrameSize = 26; + __asm volatile ( + " vpush {s0} \n" /* Trigger lazy stacking. */ + " vpop {s0} \n" /* Nullify the affect of the above instruction. */ + ::: "memory" + ); + } + else + { + /* Standard frame i.e. FPU not in use. */ + ulStackFrameSize = 8; + } + } + #else + { + ulStackFrameSize = 8; + } + #endif /* configENABLE_FPU || configENABLE_MVE */ + + /* Make space on the system call stack for the stack frame. */ + pulSystemCallStack = pulSystemCallStack - ulStackFrameSize; + + /* Copy the stack frame. */ + for( i = 0; i < ulStackFrameSize; i++ ) + { + pulSystemCallStack[ i ] = pulTaskStack[ i ]; + } + + /* Store the value of the LR and PSPLIM registers before the SVC was raised. We need to + * restore it when we exit from the system call. */ + pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; + __asm volatile ( "mrs %0, psplim" : "=r" ( pxMpuSettings->xSystemCallStackInfo.ulStackLimitRegisterAtSystemCallEntry ) ); + + /* Use the pulSystemCallStack in thread mode. */ + __asm volatile ( "msr psp, %0" : : "r" ( pulSystemCallStack ) ); + __asm volatile ( "msr psplim, %0" : : "r" ( pxMpuSettings->xSystemCallStackInfo.pulSystemCallStackLimit ) ); + + /* Remember the location where we should copy the stack frame when we exit from + * the system call. */ + pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulStackFrameSize; + + /* Record if the hardware used padding to force the stack pointer + * to be double word aligned. */ + if( ( pulTaskStack[ portOFFSET_TO_PSR ] & portPSR_STACK_PADDING_MASK ) == portPSR_STACK_PADDING_MASK ) + { + pxMpuSettings->ulTaskFlags |= portSTACK_FRAME_HAS_PADDING_FLAG; + } + else + { + pxMpuSettings->ulTaskFlags &= ( ~portSTACK_FRAME_HAS_PADDING_FLAG ); + } + + /* We ensure in pxPortInitialiseStack that the system call stack is + * double word aligned and therefore, there is no need of padding. + * Clear the bit[9] of stacked xPSR. */ + pulSystemCallStack[ portOFFSET_TO_PSR ] &= ( ~portPSR_STACK_PADDING_MASK ); + + /* Raise the privilege for the duration of the system call. */ + __asm volatile ( + " mrs r0, control \n" /* Obtain current control value. */ + " movs r1, #1 \n" /* r1 = 1. */ + " bics r0, r1 \n" /* Clear nPRIV bit. */ + " msr control, r0 \n" /* Write back new control value. */ + ::: "r0", "r1", "memory" + ); + } +} - if( xRunPrivileged == pdTRUE ) +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + +void vSystemCallEnter_1( uint32_t * pulTaskStack, uint32_t ulLR ) /* PRIVILEGED_FUNCTION */ +{ + extern TaskHandle_t pxCurrentTCB; + xMPU_SETTINGS * pxMpuSettings; + uint32_t * pulSystemCallStack; + uint32_t ulStackFrameSize, ulSystemCallLocation, i; + #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being + * exported from linker scripts. */ + extern uint32_t * __syscalls_flash_start__; + extern uint32_t * __syscalls_flash_end__; + #else + /* Declaration when these variable are exported from linker scripts. */ + extern uint32_t __syscalls_flash_start__[]; + extern uint32_t __syscalls_flash_end__[]; + #endif /* #if defined( __ARMCC_VERSION ) */ + + ulSystemCallLocation = pulTaskStack[ portOFFSET_TO_PC ]; + + /* If the request did not come from the system call section, do nothing. */ + if( ( ulSystemCallLocation >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulSystemCallLocation <= ( uint32_t ) __syscalls_flash_end__ ) ) + { + pxMpuSettings = xTaskGetMPUSettings( pxCurrentTCB ); + pulSystemCallStack = pxMpuSettings->xSystemCallStackInfo.pulSystemCallStack; + + /* This is not NULL only for the duration of the system call. */ + configASSERT( pxMpuSettings->xSystemCallStackInfo.pulTaskStack == NULL ); + + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + { + if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) { - *pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */ + /* Extended frame i.e. FPU in use. */ + ulStackFrameSize = 26; + __asm volatile ( + " vpush {s0} \n" /* Trigger lazy stacking. */ + " vpop {s0} \n" /* Nullify the affect of the above instruction. */ + ::: "memory" + ); } else { - *pxTopOfStack = portINITIAL_CONTROL_UNPRIVILEGED; /* Slot used to hold this task's CONTROL value. */ + /* Standard frame i.e. FPU not in use. */ + ulStackFrameSize = 8; } } - #endif /* configENABLE_MPU */ + #else + { + ulStackFrameSize = 8; + } + #endif /* configENABLE_FPU || configENABLE_MVE */ + + /* Make space on the system call stack for the stack frame and + * the parameter passed on the stack. We only need to copy one + * parameter but we still reserve 2 spaces to keep the stack + * double word aligned. */ + pulSystemCallStack = pulSystemCallStack - ulStackFrameSize - 2UL; + + /* Copy the stack frame. */ + for( i = 0; i < ulStackFrameSize; i++ ) + { + pulSystemCallStack[ i ] = pulTaskStack[ i ]; + } + + /* Copy the parameter which is passed the stack. */ + if( ( pulTaskStack[ portOFFSET_TO_PSR ] & portPSR_STACK_PADDING_MASK ) == portPSR_STACK_PADDING_MASK ) + { + pulSystemCallStack[ ulStackFrameSize ] = pulTaskStack[ ulStackFrameSize + 1 ]; + /* Record if the hardware used padding to force the stack pointer + * to be double word aligned. */ + pxMpuSettings->ulTaskFlags |= portSTACK_FRAME_HAS_PADDING_FLAG; + } + else + { + pulSystemCallStack[ ulStackFrameSize ] = pulTaskStack[ ulStackFrameSize ]; + /* Record if the hardware used padding to force the stack pointer + * to be double word aligned. */ + pxMpuSettings->ulTaskFlags &= ( ~portSTACK_FRAME_HAS_PADDING_FLAG ); + } + + /* Store the value of the LR and PSPLIM registers before the SVC was raised. + * We need to restore it when we exit from the system call. */ + pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; + __asm volatile ( "mrs %0, psplim" : "=r" ( pxMpuSettings->xSystemCallStackInfo.ulStackLimitRegisterAtSystemCallEntry ) ); + + /* Use the pulSystemCallStack in thread mode. */ + __asm volatile ( "msr psp, %0" : : "r" ( pulSystemCallStack ) ); + __asm volatile ( "msr psplim, %0" : : "r" ( pxMpuSettings->xSystemCallStackInfo.pulSystemCallStackLimit ) ); + + /* Remember the location where we should copy the stack frame when we exit from + * the system call. */ + pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulStackFrameSize; + + /* We ensure in pxPortInitialiseStack that the system call stack is + * double word aligned and therefore, there is no need of padding. + * Clear the bit[9] of stacked xPSR. */ + pulSystemCallStack[ portOFFSET_TO_PSR ] &= ( ~portPSR_STACK_PADDING_MASK ); + + /* Raise the privilege for the duration of the system call. */ + __asm volatile ( + " mrs r0, control \n" /* Obtain current control value. */ + " movs r1, #1 \n" /* r1 = 1. */ + " bics r0, r1 \n" /* Clear nPRIV bit. */ + " msr control, r0 \n" /* Write back new control value. */ + ::: "r0", "r1", "memory" + ); + } +} + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) +void vSystemCallExit( uint32_t * pulSystemCallStack, uint32_t ulLR ) /* PRIVILEGED_FUNCTION */ +{ + extern TaskHandle_t pxCurrentTCB; + xMPU_SETTINGS * pxMpuSettings; + uint32_t * pulTaskStack; + uint32_t ulStackFrameSize, ulSystemCallLocation, i; + #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being + * exported from linker scripts. */ + extern uint32_t * __syscalls_flash_start__; + extern uint32_t * __syscalls_flash_end__; + #else + /* Declaration when these variable are exported from linker scripts. */ + extern uint32_t __syscalls_flash_start__[]; + extern uint32_t __syscalls_flash_end__[]; + #endif /* #if defined( __ARMCC_VERSION ) */ + + ulSystemCallLocation = pulSystemCallStack[ portOFFSET_TO_PC ]; + + /* If the request did not come from the system call section, do nothing. */ + if( ( ulSystemCallLocation >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulSystemCallLocation <= ( uint32_t ) __syscalls_flash_end__ ) ) + { + pxMpuSettings = xTaskGetMPUSettings( pxCurrentTCB ); + pulTaskStack = pxMpuSettings->xSystemCallStackInfo.pulTaskStack; + + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + { + if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) + { + /* Extended frame i.e. FPU in use. */ + ulStackFrameSize = 26; + __asm volatile ( + " vpush {s0} \n" /* Trigger lazy stacking. */ + " vpop {s0} \n" /* Nullify the affect of the above instruction. */ + ::: "memory" + ); + } + else + { + /* Standard frame i.e. FPU not in use. */ + ulStackFrameSize = 8; + } + } + #else + { + ulStackFrameSize = 8; + } + #endif /* configENABLE_FPU || configENABLE_MVE */ + + /* Make space on the task stack for the stack frame. */ + pulTaskStack = pulTaskStack - ulStackFrameSize; + + /* Copy the stack frame. */ + for( i = 0; i < ulStackFrameSize; i++ ) + { + pulTaskStack[ i ] = pulSystemCallStack[ i ]; + } + + /* Use the pulTaskStack in thread mode. */ + __asm volatile ( "msr psp, %0" : : "r" ( pulTaskStack ) ); + + /* Restore the LR and PSPLIM to what they were at the time of + * system call entry. */ + pulTaskStack[ portOFFSET_TO_LR ] = pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry; + __asm volatile ( "msr psplim, %0" : : "r" ( pxMpuSettings->xSystemCallStackInfo.ulStackLimitRegisterAtSystemCallEntry ) ); + + /* If the hardware used padding to force the stack pointer + * to be double word aligned, set the stacked xPSR bit[9], + * otherwise clear it. */ + if( ( pxMpuSettings->ulTaskFlags & portSTACK_FRAME_HAS_PADDING_FLAG ) == portSTACK_FRAME_HAS_PADDING_FLAG ) + { + pulTaskStack[ portOFFSET_TO_PSR ] |= portPSR_STACK_PADDING_MASK; + } + else + { + pulTaskStack[ portOFFSET_TO_PSR ] &= ( ~portPSR_STACK_PADDING_MASK ); + } + + /* This is not NULL only for the duration of the system call. */ + pxMpuSettings->xSystemCallStackInfo.pulTaskStack = NULL; + + /* Drop the privilege before returning to the thread mode. */ + __asm volatile ( + " mrs r0, control \n" /* Obtain current control value. */ + " movs r1, #1 \n" /* r1 = 1. */ + " orrs r0, r1 \n" /* Set nPRIV bit. */ + " msr control, r0 \n" /* Write back new control value. */ + ::: "r0", "r1", "memory" + ); + } +} + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configENABLE_MPU == 1 ) + +BaseType_t xPortIsTaskPrivileged( void ) /* PRIVILEGED_FUNCTION */ +{ + BaseType_t xTaskIsPrivileged = pdFALSE; + const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */ + + if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) + { + xTaskIsPrivileged = pdTRUE; + } + + return xTaskIsPrivileged; +} + +#endif /* configENABLE_MPU == 1 */ +/*-----------------------------------------------------------*/ + +#if( configENABLE_MPU == 1 ) + +StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, + StackType_t * pxEndOfStack, + TaskFunction_t pxCode, + void * pvParameters, + BaseType_t xRunPrivileged, + xMPU_SETTINGS * xMPUSettings ) /* PRIVILEGED_FUNCTION */ +{ + uint32_t ulIndex = 0; + + xMPUSettings->ulContext[ ulIndex ] = 0x04040404; /* r4. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x05050505; /* r5. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x06060606; /* r6. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x07070707; /* r7. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x08080808; /* r8. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x09090909; /* r9. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x10101010; /* r10. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x11111111; /* r11. */ + ulIndex++; + + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pvParameters; /* r0. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x01010101; /* r1. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x02020202; /* r2. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x03030303; /* r3. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x12121212; /* r12. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portTASK_RETURN_ADDRESS; /* LR. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxCode; /* PC. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = portINITIAL_XPSR; /* xPSR. */ + ulIndex++; + + #if ( configENABLE_TRUSTZONE == 1 ) + { + xMPUSettings->ulContext[ ulIndex ] = portNO_SECURE_CONTEXT; /* xSecureContext. */ + ulIndex++; + } + #endif /* configENABLE_TRUSTZONE */ + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) ( pxTopOfStack - 8 ); /* PSP with the hardware saved stack. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */ + ulIndex++; + if( xRunPrivileged == pdTRUE ) + { + xMPUSettings->ulTaskFlags |= portTASK_IS_PRIVILEGED_FLAG; + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_PRIVILEGED; /* CONTROL. */ + ulIndex++; + } + else + { + xMPUSettings->ulTaskFlags &= ( ~portTASK_IS_PRIVILEGED_FLAG ); + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_UNPRIVILEGED; /* CONTROL. */ + ulIndex++; + } + xMPUSettings->ulContext[ ulIndex ] = portINITIAL_EXC_RETURN; /* LR (EXC_RETURN). */ + ulIndex++; + + #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + { + /* Ensure that the system call stack is double word aligned. */ + xMPUSettings->xSystemCallStackInfo.pulSystemCallStack = &( xMPUSettings->xSystemCallStackInfo.ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE - 1 ] ); + xMPUSettings->xSystemCallStackInfo.pulSystemCallStack = ( uint32_t * ) ( ( uint32_t ) ( xMPUSettings->xSystemCallStackInfo.pulSystemCallStack ) & + ( uint32_t ) ( ~( portBYTE_ALIGNMENT_MASK ) ) ); + + xMPUSettings->xSystemCallStackInfo.pulSystemCallStackLimit = &( xMPUSettings->xSystemCallStackInfo.ulSystemCallStackBuffer[ 0 ] ); + xMPUSettings->xSystemCallStackInfo.pulSystemCallStackLimit = ( uint32_t * ) ( ( ( uint32_t ) ( xMPUSettings->xSystemCallStackInfo.pulSystemCallStackLimit ) + + ( uint32_t ) ( portBYTE_ALIGNMENT - 1 ) ) & + ( uint32_t ) ( ~( portBYTE_ALIGNMENT_MASK ) ) ); + + /* This is not NULL only for the duration of a system call. */ + xMPUSettings->xSystemCallStackInfo.pulTaskStack = NULL; + } + #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + + return &( xMPUSettings->ulContext[ ulIndex ] ); +} + +#else /* configENABLE_MPU */ + +StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, + StackType_t * pxEndOfStack, + TaskFunction_t pxCode, + void * pvParameters ) /* PRIVILEGED_FUNCTION */ +{ + /* Simulate the stack frame as it would be created by a context switch + * interrupt. */ + #if ( portPRELOAD_REGISTERS == 0 ) + { + pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ + *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR. */ + pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ + pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */ + *pxTopOfStack = portINITIAL_EXC_RETURN; pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ @@ -1029,55 +1561,39 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO #else /* portPRELOAD_REGISTERS */ { pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ - *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ + *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pxCode; /* PC */ + *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR */ + *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x12121212UL; /* R12 */ + *pxTopOfStack = ( StackType_t ) 0x12121212UL; /* R12. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x03030303UL; /* R3 */ + *pxTopOfStack = ( StackType_t ) 0x03030303UL; /* R3. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x02020202UL; /* R2 */ + *pxTopOfStack = ( StackType_t ) 0x02020202UL; /* R2. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x01010101UL; /* R1 */ + *pxTopOfStack = ( StackType_t ) 0x01010101UL; /* R1. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x11111111UL; /* R11 */ + *pxTopOfStack = ( StackType_t ) 0x11111111UL; /* R11. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x10101010UL; /* R10 */ + *pxTopOfStack = ( StackType_t ) 0x10101010UL; /* R10. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x09090909UL; /* R09 */ + *pxTopOfStack = ( StackType_t ) 0x09090909UL; /* R09. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x08080808UL; /* R08 */ + *pxTopOfStack = ( StackType_t ) 0x08080808UL; /* R08. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x07070707UL; /* R07 */ + *pxTopOfStack = ( StackType_t ) 0x07070707UL; /* R07. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x06060606UL; /* R06 */ + *pxTopOfStack = ( StackType_t ) 0x06060606UL; /* R06. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x05050505UL; /* R05 */ + *pxTopOfStack = ( StackType_t ) 0x05050505UL; /* R05. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x04040404UL; /* R04 */ + *pxTopOfStack = ( StackType_t ) 0x04040404UL; /* R04. */ pxTopOfStack--; - *pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN */ - - #if ( configENABLE_MPU == 1 ) - { - pxTopOfStack--; - - if( xRunPrivileged == pdTRUE ) - { - *pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */ - } - else - { - *pxTopOfStack = portINITIAL_CONTROL_UNPRIVILEGED; /* Slot used to hold this task's CONTROL value. */ - } - } - #endif /* configENABLE_MPU */ - + *pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN. */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ @@ -1092,6 +1608,8 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO return pxTopOfStack; } + +#endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ @@ -1128,6 +1646,10 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ configASSERT( ucMaxSysCallPriority ); + /* Check that the bits not implemented in hardware are zero in + * configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & ( ~ucMaxPriorityValue ) ) == 0U ); + /* Calculate the maximum acceptable priority group value for the number * of bits read back. */ @@ -1164,35 +1686,6 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulImplementedPrioBits; } - /* The interrupt priority bits are not modelled in QEMU and the assert that - * checks the number of implemented bits and __NVIC_PRIO_BITS will always fail. - * Therefore, this assert is not adding any value for QEMU targets. The config - * option `configDISABLE_INTERRUPT_PRIO_BITS_CHECK` should be defined in the - * `FreeRTOSConfig.h` for QEMU targets. */ - #ifndef configDISABLE_INTERRUPT_PRIO_BITS_CHECK - { - #ifdef __NVIC_PRIO_BITS - { - /* - * Check that the number of implemented priority bits queried from - * hardware is equal to the CMSIS __NVIC_PRIO_BITS configuration macro. - */ - configASSERT( ulImplementedPrioBits == __NVIC_PRIO_BITS ); - } - #endif /* __NVIC_PRIO_BITS */ - - #ifdef configPRIO_BITS - { - /* - * Check that the number of implemented priority bits queried from - * hardware is equal to the FreeRTOS configPRIO_BITS configuration macro. - */ - configASSERT( ulImplementedPrioBits == configPRIO_BITS ); - } - #endif /* configPRIO_BITS */ - } - #endif /* #ifndef configDISABLE_INTERRUPT_PRIO_BITS_CHECK */ - /* Shift the priority group value back to its position within the AIRCR * register. */ ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT; @@ -1372,6 +1865,54 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ +#if ( configENABLE_MPU == 1 ) + BaseType_t xPortIsAuthorizedToAccessBuffer( const void * pvBuffer, + uint32_t ulBufferLength, + uint32_t ulAccessRequested ) /* PRIVILEGED_FUNCTION */ + + { + uint32_t i, ulBufferStartAddress, ulBufferEndAddress; + BaseType_t xAccessGranted = pdFALSE; + const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */ + + if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) + { + xAccessGranted = pdTRUE; + } + else + { + if( portADD_UINT32_WILL_OVERFLOW( ( ( uint32_t ) pvBuffer ), ( ulBufferLength - 1UL ) ) == pdFALSE ) + { + ulBufferStartAddress = ( uint32_t ) pvBuffer; + ulBufferEndAddress = ( ( ( uint32_t ) pvBuffer ) + ulBufferLength - 1UL ); + + for( i = 0; i < portTOTAL_NUM_REGIONS; i++ ) + { + /* Is the MPU region enabled? */ + if( ( xTaskMpuSettings->xRegionsSettings[ i ].ulRLAR & portMPU_RLAR_REGION_ENABLE ) == portMPU_RLAR_REGION_ENABLE ) + { + if( portIS_ADDRESS_WITHIN_RANGE( ulBufferStartAddress, + portEXTRACT_FIRST_ADDRESS_FROM_RBAR( xTaskMpuSettings->xRegionsSettings[ i ].ulRBAR ), + portEXTRACT_LAST_ADDRESS_FROM_RLAR( xTaskMpuSettings->xRegionsSettings[ i ].ulRLAR ) ) && + portIS_ADDRESS_WITHIN_RANGE( ulBufferEndAddress, + portEXTRACT_FIRST_ADDRESS_FROM_RBAR( xTaskMpuSettings->xRegionsSettings[ i ].ulRBAR ), + portEXTRACT_LAST_ADDRESS_FROM_RLAR( xTaskMpuSettings->xRegionsSettings[ i ].ulRLAR ) ) && + portIS_AUTHORIZED( ulAccessRequested, + prvGetRegionAccessPermissions( xTaskMpuSettings->xRegionsSettings[ i ].ulRBAR ) ) ) + { + xAccessGranted = pdTRUE; + break; + } + } + } + } + } + + return xAccessGranted; + } +#endif /* configENABLE_MPU */ +/*-----------------------------------------------------------*/ + BaseType_t xPortIsInsideInterrupt( void ) { uint32_t ulCurrentInterrupt; diff --git a/portable/GCC/ARM_CM55/non_secure/portasm.c b/portable/GCC/ARM_CM55/non_secure/portasm.c index 9f9b2e68d39..f7ec7d9c072 100644 --- a/portable/GCC/ARM_CM55/non_secure/portasm.c +++ b/portable/GCC/ARM_CM55/non_secure/portasm.c @@ -40,95 +40,120 @@ * header files. */ #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE +#if ( configENABLE_MPU == 1 ) + void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ { __asm volatile ( - " .syntax unified \n" - " \n" - " ldr r2, pxCurrentTCBConst2 \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - " ldr r3, [r2] \n"/* Read pxCurrentTCB. */ - " ldr r0, [r3] \n"/* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ - " \n" - #if ( configENABLE_MPU == 1 ) - " dmb \n"/* Complete outstanding transfers before disabling MPU. */ - " ldr r2, xMPUCTRLConst2 \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ - " ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */ - " bic r4, #1 \n"/* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */ - " str r4, [r2] \n"/* Disable MPU. */ - " \n" - " adds r3, #4 \n"/* r3 = r3 + 4. r3 now points to MAIR0 in TCB. */ - " ldr r4, [r3] \n"/* r4 = *r3 i.e. r4 = MAIR0. */ - " ldr r2, xMAIR0Const2 \n"/* r2 = 0xe000edc0 [Location of MAIR0]. */ - " str r4, [r2] \n"/* Program MAIR0. */ - " ldr r2, xRNRConst2 \n"/* r2 = 0xe000ed98 [Location of RNR]. */ - " movs r4, #4 \n"/* r4 = 4. */ - " str r4, [r2] \n"/* Program RNR = 4. */ - " adds r3, #4 \n"/* r3 = r3 + 4. r3 now points to first RBAR in TCB. */ - " ldr r2, xRBARConst2 \n"/* r2 = 0xe000ed9c [Location of RBAR]. */ - " ldmia r3!, {r4-r11} \n"/* Read 4 set of RBAR/RLAR registers from TCB. */ - " stmia r2!, {r4-r11} \n"/* Write 4 set of RBAR/RLAR registers using alias registers. */ - " \n" + " .syntax unified \n" + " \n" + " program_mpu_first_task: \n" + " ldr r3, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r0, [r3] \n" /* r0 = pxCurrentTCB. */ + " \n" + " dmb \n" /* Complete outstanding transfers before disabling MPU. */ + " ldr r1, xMPUCTRLConst2 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ + " bic r2, #1 \n" /* r2 = r2 & ~1 i.e. Clear the bit 0 in r2. */ + " str r2, [r1] \n" /* Disable MPU. */ + " \n" + " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */ + " ldr r1, [r0] \n" /* r1 = *r0 i.e. r1 = MAIR0. */ + " ldr r2, xMAIR0Const2 \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */ + " str r1, [r2] \n" /* Program MAIR0. */ + " \n" + " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */ + " ldr r1, xRNRConst2 \n" /* r1 = 0xe000ed98 [Location of RNR]. */ + " ldr r2, xRBARConst2 \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ + " \n" + " movs r3, #4 \n" /* r3 = 4. */ + " str r3, [r1] \n" /* Program RNR = 4. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + " \n" #if ( configTOTAL_MPU_REGIONS == 16 ) - " ldr r2, xRNRConst2 \n"/* r2 = 0xe000ed98 [Location of RNR]. */ - " movs r4, #8 \n"/* r4 = 8. */ - " str r4, [r2] \n"/* Program RNR = 8. */ - " ldr r2, xRBARConst2 \n"/* r2 = 0xe000ed9c [Location of RBAR]. */ - " ldmia r3!, {r4-r11} \n"/* Read 4 set of RBAR/RLAR registers from TCB. */ - " stmia r2!, {r4-r11} \n"/* Write 4 set of RBAR/RLAR registers using alias registers. */ - " ldr r2, xRNRConst2 \n"/* r2 = 0xe000ed98 [Location of RNR]. */ - " movs r4, #12 \n"/* r4 = 12. */ - " str r4, [r2] \n"/* Program RNR = 12. */ - " ldr r2, xRBARConst2 \n"/* r2 = 0xe000ed9c [Location of RBAR]. */ - " ldmia r3!, {r4-r11} \n"/* Read 4 set of RBAR/RLAR registers from TCB. */ - " stmia r2!, {r4-r11} \n"/* Write 4 set of RBAR/RLAR registers using alias registers. */ + " movs r3, #8 \n" /* r3 = 8. */ + " str r3, [r1] \n" /* Program RNR = 8. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + " movs r3, #12 \n" /* r3 = 12. */ + " str r3, [r1] \n" /* Program RNR = 12. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ #endif /* configTOTAL_MPU_REGIONS == 16 */ - " \n" - " ldr r2, xMPUCTRLConst2 \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ - " ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */ - " orr r4, #1 \n"/* r4 = r4 | 1 i.e. Set the bit 0 in r4. */ - " str r4, [r2] \n"/* Enable MPU. */ - " dsb \n"/* Force memory writes before continuing. */ - #endif /* configENABLE_MPU */ + " \n" + " ldr r1, xMPUCTRLConst2 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ + " orr r2, #1 \n" /* r2 = r1 | 1 i.e. Set the bit 0 in r2. */ + " str r2, [r1] \n" /* Enable MPU. */ + " dsb \n" /* Force memory writes before continuing. */ + " \n" + " restore_context_first_task: \n" + " ldr r3, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r1, [r3] \n" /* r1 = pxCurrentTCB.*/ + " ldr r2, [r1] \n" /* r2 = Location of saved context in TCB. */ + " \n" + " restore_special_regs_first_task: \n" + " ldmdb r2!, {r0, r3-r5, lr} \n" /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */ + " msr psp, r3 \n" + " msr psplim, r4 \n" + " msr control, r5 \n" + " ldr r4, xSecureContextConst2 \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ + " str r0, [r4] \n" /* Restore xSecureContext. */ + " \n" + " restore_general_regs_first_task: \n" + " ldmdb r2!, {r4-r11} \n" /* r4-r11 contain hardware saved context. */ + " stmia r3!, {r4-r11} \n" /* Copy the hardware saved context on the task stack. */ + " ldmdb r2!, {r4-r11} \n" /* r4-r11 restored. */ + " \n" + " restore_context_done_first_task: \n" + " str r2, [r1] \n" /* Save the location where the context should be saved next as the first member of TCB. */ + " mov r0, #0 \n" + " msr basepri, r0 \n" /* Ensure that interrupts are enabled when the first task starts. */ + " bx lr \n" + " \n" + " .align 4 \n" + " pxCurrentTCBConst2: .word pxCurrentTCB \n" + " xSecureContextConst2: .word xSecureContext \n" + " xMPUCTRLConst2: .word 0xe000ed94 \n" + " xMAIR0Const2: .word 0xe000edc0 \n" + " xRNRConst2: .word 0xe000ed98 \n" + " xRBARConst2: .word 0xe000ed9c \n" + ); +} + +#else /* configENABLE_MPU */ + +void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ +{ + __asm volatile + ( + " .syntax unified \n" " \n" - #if ( configENABLE_MPU == 1 ) - " ldm r0!, {r1-r4} \n"/* Read from stack - r1 = xSecureContext, r2 = PSPLIM, r3 = CONTROL and r4 = EXC_RETURN. */ - " ldr r5, xSecureContextConst2 \n" - " str r1, [r5] \n"/* Set xSecureContext to this task's value for the same. */ - " msr psplim, r2 \n"/* Set this task's PSPLIM value. */ - " msr control, r3 \n"/* Set this task's CONTROL value. */ - " adds r0, #32 \n"/* Discard everything up to r0. */ - " msr psp, r0 \n"/* This is now the new top of stack to use in the task. */ - " isb \n" - " mov r0, #0 \n" - " msr basepri, r0 \n"/* Ensure that interrupts are enabled when the first task starts. */ - " bx r4 \n"/* Finally, branch to EXC_RETURN. */ - #else /* configENABLE_MPU */ - " ldm r0!, {r1-r3} \n"/* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */ - " ldr r4, xSecureContextConst2 \n" - " str r1, [r4] \n"/* Set xSecureContext to this task's value for the same. */ - " msr psplim, r2 \n"/* Set this task's PSPLIM value. */ - " movs r1, #2 \n"/* r1 = 2. */ - " msr CONTROL, r1 \n"/* Switch to use PSP in the thread mode. */ - " adds r0, #32 \n"/* Discard everything up to r0. */ - " msr psp, r0 \n"/* This is now the new top of stack to use in the task. */ - " isb \n" - " mov r0, #0 \n" - " msr basepri, r0 \n"/* Ensure that interrupts are enabled when the first task starts. */ - " bx r3 \n"/* Finally, branch to EXC_RETURN. */ - #endif /* configENABLE_MPU */ + " ldr r2, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r3, [r2] \n" /* Read pxCurrentTCB. */ + " ldr r0, [r3] \n" /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ " \n" + " ldm r0!, {r1-r3} \n" /* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */ + " ldr r4, xSecureContextConst2 \n" + " str r1, [r4] \n" /* Set xSecureContext to this task's value for the same. */ + " msr psplim, r2 \n" /* Set this task's PSPLIM value. */ + " movs r1, #2 \n" /* r1 = 2. */ + " msr CONTROL, r1 \n" /* Switch to use PSP in the thread mode. */ + " adds r0, #32 \n" /* Discard everything up to r0. */ + " msr psp, r0 \n" /* This is now the new top of stack to use in the task. */ + " isb \n" + " mov r0, #0 \n" + " msr basepri, r0 \n" /* Ensure that interrupts are enabled when the first task starts. */ + " bx r3 \n" /* Finally, branch to EXC_RETURN. */ " .align 4 \n" "pxCurrentTCBConst2: .word pxCurrentTCB \n" "xSecureContextConst2: .word xSecureContext \n" - #if ( configENABLE_MPU == 1 ) - "xMPUCTRLConst2: .word 0xe000ed94 \n" - "xMAIR0Const2: .word 0xe000edc0 \n" - "xRNRConst2: .word 0xe000ed98 \n" - "xRBARConst2: .word 0xe000ed9c \n" - #endif /* configENABLE_MPU */ ); } + +#endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */ @@ -236,6 +261,160 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att } /*-----------------------------------------------------------*/ +#if ( configENABLE_MPU == 1 ) + +void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern SecureContext_SaveContext \n" + " .extern SecureContext_LoadContext \n" + " \n" + " ldr r3, xSecureContextConst \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ + " ldr r0, [r3] \n" /* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */ + " ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r1, [r3] \n" /* Read pxCurrentTCB - Value of pxCurrentTCB must be in r1 as it is used as a parameter later. */ + " ldr r2, [r1] \n" /* r2 = Location in TCB where the context should be saved. */ + " \n" + " cbz r0, save_ns_context \n" /* No secure context to save. */ + " save_s_context: \n" + " push {r0-r2, lr} \n" + " bl SecureContext_SaveContext \n" /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ + " pop {r0-r2, lr} \n" + " \n" + " save_ns_context: \n" + " mov r3, lr \n" /* r3 = LR (EXC_RETURN). */ + " lsls r3, r3, #25 \n" /* r3 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ + " bmi save_special_regs \n" /* r3 < 0 ==> Bit[6] in EXC_RETURN is 1 ==> secure stack was used to store the stack frame. */ + " \n" + " save_general_regs: \n" + " mrs r3, psp \n" + " \n" + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + " add r3, r3, #0x20 \n" /* Move r3 to location where s0 is saved. */ + " tst lr, #0x10 \n" + " ittt eq \n" + " vstmiaeq r2!, {s16-s31} \n" /* Store s16-s31. */ + " vldmiaeq r3, {s0-s16} \n" /* Copy hardware saved FP context into s0-s16. */ + " vstmiaeq r2!, {s0-s16} \n" /* Store hardware saved FP context. */ + " sub r3, r3, #0x20 \n" /* Set r3 back to the location of hardware saved context. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ + " \n" + " stmia r2!, {r4-r11} \n" /* Store r4-r11. */ + " ldmia r3, {r4-r11} \n" /* Copy the hardware saved context into r4-r11. */ + " stmia r2!, {r4-r11} \n" /* Store the hardware saved context. */ + " \n" + " save_special_regs: \n" + " mrs r3, psp \n" /* r3 = PSP. */ + " mrs r4, psplim \n" /* r4 = PSPLIM. */ + " mrs r5, control \n" /* r5 = CONTROL. */ + " stmia r2!, {r0, r3-r5, lr} \n" /* Store xSecureContext, original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */ + " str r2, [r1] \n" /* Save the location from where the context should be restored as the first member of TCB. */ + " \n" + " select_next_task: \n" + " mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */ + " msr basepri, r0 \n" /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + " dsb \n" + " isb \n" + " bl vTaskSwitchContext \n" + " mov r0, #0 \n" /* r0 = 0. */ + " msr basepri, r0 \n" /* Enable interrupts. */ + " \n" + " program_mpu: \n" + " ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r0, [r3] \n" /* r0 = pxCurrentTCB.*/ + " \n" + " dmb \n" /* Complete outstanding transfers before disabling MPU. */ + " ldr r1, xMPUCTRLConst \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ + " bic r2, #1 \n" /* r2 = r2 & ~1 i.e. Clear the bit 0 in r2. */ + " str r2, [r1] \n" /* Disable MPU. */ + " \n" + " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */ + " ldr r1, [r0] \n" /* r1 = *r0 i.e. r1 = MAIR0. */ + " ldr r2, xMAIR0Const \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */ + " str r1, [r2] \n" /* Program MAIR0. */ + " \n" + " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */ + " ldr r1, xRNRConst \n" /* r1 = 0xe000ed98 [Location of RNR]. */ + " ldr r2, xRBARConst \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ + " \n" + " movs r3, #4 \n" /* r3 = 4. */ + " str r3, [r1] \n" /* Program RNR = 4. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + " \n" + #if ( configTOTAL_MPU_REGIONS == 16 ) + " movs r3, #8 \n" /* r3 = 8. */ + " str r3, [r1] \n" /* Program RNR = 8. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + " movs r3, #12 \n" /* r3 = 12. */ + " str r3, [r1] \n" /* Program RNR = 12. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + #endif /* configTOTAL_MPU_REGIONS == 16 */ + " \n" + " ldr r1, xMPUCTRLConst \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ + " orr r2, #1 \n" /* r2 = r2 | 1 i.e. Set the bit 0 in r2. */ + " str r2, [r1] \n" /* Enable MPU. */ + " dsb \n" /* Force memory writes before continuing. */ + " \n" + " restore_context: \n" + " ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r1, [r3] \n" /* r1 = pxCurrentTCB.*/ + " ldr r2, [r1] \n" /* r2 = Location of saved context in TCB. */ + " \n" + " restore_special_regs: \n" + " ldmdb r2!, {r0, r3-r5, lr} \n" /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */ + " msr psp, r3 \n" + " msr psplim, r4 \n" + " msr control, r5 \n" + " ldr r4, xSecureContextConst \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ + " str r0, [r4] \n" /* Restore xSecureContext. */ + " cbz r0, restore_ns_context \n" /* No secure context to restore. */ + " \n" + " restore_s_context: \n" + " push {r1-r3, lr} \n" + " bl SecureContext_LoadContext \n" /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ + " pop {r1-r3, lr} \n" + " \n" + " restore_ns_context: \n" + " mov r0, lr \n" /* r0 = LR (EXC_RETURN). */ + " lsls r0, r0, #25 \n" /* r0 = r0 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ + " bmi restore_context_done \n" /* r0 < 0 ==> Bit[6] in EXC_RETURN is 1 ==> secure stack was used to store the stack frame. */ + " \n" + " restore_general_regs: \n" + " ldmdb r2!, {r4-r11} \n" /* r4-r11 contain hardware saved context. */ + " stmia r3!, {r4-r11} \n" /* Copy the hardware saved context on the task stack. */ + " ldmdb r2!, {r4-r11} \n" /* r4-r11 restored. */ + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + " tst lr, #0x10 \n" + " ittt eq \n" + " vldmdbeq r2!, {s0-s16} \n" /* s0-s16 contain hardware saved FP context. */ + " vstmiaeq r3!, {s0-s16} \n" /* Copy hardware saved FP context on the task stack. */ + " vldmdbeq r2!, {s16-s31} \n" /* Restore s16-s31. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ + " \n" + " restore_context_done: \n" + " str r2, [r1] \n" /* Save the location where the context should be saved next as the first member of TCB. */ + " bx lr \n" + " \n" + " .align 4 \n" + " pxCurrentTCBConst: .word pxCurrentTCB \n" + " xSecureContextConst: .word xSecureContext \n" + " xMPUCTRLConst: .word 0xe000ed94 \n" + " xMAIR0Const: .word 0xe000edc0 \n" + " xRNRConst: .word 0xe000ed98 \n" + " xRBARConst: .word 0xe000ed9c \n" + ::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) + ); +} + +#else /* configENABLE_MPU */ + void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ { __asm volatile @@ -260,20 +439,11 @@ void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ " \n" " ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r3] \n"/* Read pxCurrentTCB.*/ - #if ( configENABLE_MPU == 1 ) - " subs r2, r2, #16 \n"/* Make space for xSecureContext, PSPLIM, CONTROL and LR on the stack. */ - " str r2, [r1] \n"/* Save the new top of stack in TCB. */ - " mrs r1, psplim \n"/* r1 = PSPLIM. */ - " mrs r3, control \n"/* r3 = CONTROL. */ - " mov r4, lr \n"/* r4 = LR/EXC_RETURN. */ - " stmia r2!, {r0, r1, r3, r4} \n"/* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */ - #else /* configENABLE_MPU */ - " subs r2, r2, #12 \n"/* Make space for xSecureContext, PSPLIM and LR on the stack. */ - " str r2, [r1] \n"/* Save the new top of stack in TCB. */ - " mrs r1, psplim \n"/* r1 = PSPLIM. */ - " mov r3, lr \n"/* r3 = LR/EXC_RETURN. */ - " stmia r2!, {r0, r1, r3} \n"/* Store xSecureContext, PSPLIM and LR on the stack. */ - #endif /* configENABLE_MPU */ + " subs r2, r2, #12 \n"/* Make space for xSecureContext, PSPLIM and LR on the stack. */ + " str r2, [r1] \n"/* Save the new top of stack in TCB. */ + " mrs r1, psplim \n"/* r1 = PSPLIM. */ + " mov r3, lr \n"/* r3 = LR/EXC_RETURN. */ + " stmia r2!, {r0, r1, r3} \n"/* Store xSecureContext, PSPLIM and LR on the stack. */ " b select_next_task \n" " \n" " save_ns_context: \n" @@ -284,26 +454,14 @@ void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ " it eq \n" " vstmdbeq r2!, {s16-s31} \n"/* Store the additional FP context registers which are not saved automatically. */ #endif /* configENABLE_FPU || configENABLE_MVE */ - #if ( configENABLE_MPU == 1 ) - " subs r2, r2, #48 \n"/* Make space for xSecureContext, PSPLIM, CONTROL, LR and the remaining registers on the stack. */ - " str r2, [r1] \n"/* Save the new top of stack in TCB. */ - " adds r2, r2, #16 \n"/* r2 = r2 + 16. */ - " stm r2, {r4-r11} \n"/* Store the registers that are not saved automatically. */ - " mrs r1, psplim \n"/* r1 = PSPLIM. */ - " mrs r3, control \n"/* r3 = CONTROL. */ - " mov r4, lr \n"/* r4 = LR/EXC_RETURN. */ - " subs r2, r2, #16 \n"/* r2 = r2 - 16. */ - " stmia r2!, {r0, r1, r3, r4} \n"/* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */ - #else /* configENABLE_MPU */ - " subs r2, r2, #44 \n"/* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */ - " str r2, [r1] \n"/* Save the new top of stack in TCB. */ - " adds r2, r2, #12 \n"/* r2 = r2 + 12. */ - " stm r2, {r4-r11} \n"/* Store the registers that are not saved automatically. */ - " mrs r1, psplim \n"/* r1 = PSPLIM. */ - " mov r3, lr \n"/* r3 = LR/EXC_RETURN. */ - " subs r2, r2, #12 \n"/* r2 = r2 - 12. */ - " stmia r2!, {r0, r1, r3} \n"/* Store xSecureContext, PSPLIM and LR on the stack. */ - #endif /* configENABLE_MPU */ + " subs r2, r2, #44 \n"/* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */ + " str r2, [r1] \n"/* Save the new top of stack in TCB. */ + " adds r2, r2, #12 \n"/* r2 = r2 + 12. */ + " stm r2, {r4-r11} \n"/* Store the registers that are not saved automatically. */ + " mrs r1, psplim \n"/* r1 = PSPLIM. */ + " mov r3, lr \n"/* r3 = LR/EXC_RETURN. */ + " subs r2, r2, #12 \n"/* r2 = r2 - 12. */ + " stmia r2!, {r0, r1, r3} \n"/* Store xSecureContext, PSPLIM and LR on the stack. */ " \n" " select_next_task: \n" " mov r0, %0 \n"/* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */ @@ -318,83 +476,22 @@ void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ " ldr r1, [r3] \n"/* Read pxCurrentTCB. */ " ldr r2, [r1] \n"/* The first item in pxCurrentTCB is the task top of stack. r2 now points to the top of stack. */ " \n" - #if ( configENABLE_MPU == 1 ) - " dmb \n"/* Complete outstanding transfers before disabling MPU. */ - " ldr r3, xMPUCTRLConst \n"/* r3 = 0xe000ed94 [Location of MPU_CTRL]. */ - " ldr r4, [r3] \n"/* Read the value of MPU_CTRL. */ - " bic r4, #1 \n"/* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */ - " str r4, [r3] \n"/* Disable MPU. */ - " \n" - " adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */ - " ldr r4, [r1] \n"/* r4 = *r1 i.e. r4 = MAIR0. */ - " ldr r3, xMAIR0Const \n"/* r3 = 0xe000edc0 [Location of MAIR0]. */ - " str r4, [r3] \n"/* Program MAIR0. */ - " ldr r3, xRNRConst \n"/* r3 = 0xe000ed98 [Location of RNR]. */ - " movs r4, #4 \n"/* r4 = 4. */ - " str r4, [r3] \n"/* Program RNR = 4. */ - " adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to first RBAR in TCB. */ - " ldr r3, xRBARConst \n"/* r3 = 0xe000ed9c [Location of RBAR]. */ - " ldmia r1!, {r4-r11} \n"/* Read 4 sets of RBAR/RLAR registers from TCB. */ - " stmia r3!, {r4-r11} \n"/* Write 4 set of RBAR/RLAR registers using alias registers. */ - " \n" - #if ( configTOTAL_MPU_REGIONS == 16 ) - " ldr r3, xRNRConst \n"/* r3 = 0xe000ed98 [Location of RNR]. */ - " movs r4, #8 \n"/* r4 = 8. */ - " str r4, [r3] \n"/* Program RNR = 8. */ - " ldr r3, xRBARConst \n"/* r3 = 0xe000ed9c [Location of RBAR]. */ - " ldmia r1!, {r4-r11} \n"/* Read 4 sets of RBAR/RLAR registers from TCB. */ - " stmia r3!, {r4-r11} \n"/* Write 4 set of RBAR/RLAR registers using alias registers. */ - " ldr r3, xRNRConst \n"/* r3 = 0xe000ed98 [Location of RNR]. */ - " movs r4, #12 \n"/* r4 = 12. */ - " str r4, [r3] \n"/* Program RNR = 12. */ - " ldr r3, xRBARConst \n"/* r3 = 0xe000ed9c [Location of RBAR]. */ - " ldmia r1!, {r4-r11} \n"/* Read 4 sets of RBAR/RLAR registers from TCB. */ - " stmia r3!, {r4-r11} \n"/* Write 4 set of RBAR/RLAR registers using alias registers. */ - #endif /* configTOTAL_MPU_REGIONS == 16 */ - " \n" - " ldr r3, xMPUCTRLConst \n"/* r3 = 0xe000ed94 [Location of MPU_CTRL]. */ - " ldr r4, [r3] \n"/* Read the value of MPU_CTRL. */ - " orr r4, #1 \n"/* r4 = r4 | 1 i.e. Set the bit 0 in r4. */ - " str r4, [r3] \n"/* Enable MPU. */ - " dsb \n"/* Force memory writes before continuing. */ - #endif /* configENABLE_MPU */ - " \n" - #if ( configENABLE_MPU == 1 ) - " ldmia r2!, {r0, r1, r3, r4} \n"/* Read from stack - r0 = xSecureContext, r1 = PSPLIM, r3 = CONTROL and r4 = LR. */ - " msr psplim, r1 \n"/* Restore the PSPLIM register value for the task. */ - " msr control, r3 \n"/* Restore the CONTROL register value for the task. */ - " mov lr, r4 \n"/* LR = r4. */ - " ldr r3, xSecureContextConst \n"/* Read the location of xSecureContext i.e. &( xSecureContext ). */ - " str r0, [r3] \n"/* Restore the task's xSecureContext. */ - " cbz r0, restore_ns_context \n"/* If there is no secure context for the task, restore the non-secure context. */ - " ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - " ldr r1, [r3] \n"/* Read pxCurrentTCB. */ - " push {r2, r4} \n" - " bl SecureContext_LoadContext \n"/* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ - " pop {r2, r4} \n" - " mov lr, r4 \n"/* LR = r4. */ - " lsls r1, r4, #25 \n"/* r1 = r4 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ - " bpl restore_ns_context \n"/* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ - " msr psp, r2 \n"/* Remember the new top of stack for the task. */ - " bx lr \n" - #else /* configENABLE_MPU */ - " ldmia r2!, {r0, r1, r4} \n"/* Read from stack - r0 = xSecureContext, r1 = PSPLIM and r4 = LR. */ - " msr psplim, r1 \n"/* Restore the PSPLIM register value for the task. */ - " mov lr, r4 \n"/* LR = r4. */ - " ldr r3, xSecureContextConst \n"/* Read the location of xSecureContext i.e. &( xSecureContext ). */ - " str r0, [r3] \n"/* Restore the task's xSecureContext. */ - " cbz r0, restore_ns_context \n"/* If there is no secure context for the task, restore the non-secure context. */ - " ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - " ldr r1, [r3] \n"/* Read pxCurrentTCB. */ - " push {r2, r4} \n" - " bl SecureContext_LoadContext \n"/* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ - " pop {r2, r4} \n" - " mov lr, r4 \n"/* LR = r4. */ - " lsls r1, r4, #25 \n"/* r1 = r4 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ - " bpl restore_ns_context \n"/* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ - " msr psp, r2 \n"/* Remember the new top of stack for the task. */ - " bx lr \n" - #endif /* configENABLE_MPU */ + " ldmia r2!, {r0, r1, r4} \n"/* Read from stack - r0 = xSecureContext, r1 = PSPLIM and r4 = LR. */ + " msr psplim, r1 \n"/* Restore the PSPLIM register value for the task. */ + " mov lr, r4 \n"/* LR = r4. */ + " ldr r3, xSecureContextConst \n"/* Read the location of xSecureContext i.e. &( xSecureContext ). */ + " str r0, [r3] \n"/* Restore the task's xSecureContext. */ + " cbz r0, restore_ns_context \n"/* If there is no secure context for the task, restore the non-secure context. */ + " ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r1, [r3] \n"/* Read pxCurrentTCB. */ + " push {r2, r4} \n" + " bl SecureContext_LoadContext \n"/* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ + " pop {r2, r4} \n" + " mov lr, r4 \n"/* LR = r4. */ + " lsls r1, r4, #25 \n"/* r1 = r4 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ + " bpl restore_ns_context \n"/* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ + " msr psp, r2 \n"/* Remember the new top of stack for the task. */ + " bx lr \n" " \n" " restore_ns_context: \n" " ldmia r2!, {r4-r11} \n"/* Restore the registers that are not automatically restored. */ @@ -409,17 +506,60 @@ void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ " .align 4 \n" "pxCurrentTCBConst: .word pxCurrentTCB \n" "xSecureContextConst: .word xSecureContext \n" - #if ( configENABLE_MPU == 1 ) - "xMPUCTRLConst: .word 0xe000ed94 \n" - "xMAIR0Const: .word 0xe000edc0 \n" - "xRNRConst: .word 0xe000ed98 \n" - "xRBARConst: .word 0xe000ed9c \n" - #endif /* configENABLE_MPU */ ::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) ); } + +#endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + +void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ +{ + __asm volatile + ( + ".syntax unified \n" + ".extern vPortSVCHandler_C \n" + ".extern vSystemCallEnter \n" + ".extern vSystemCallEnter_1 \n" + ".extern vSystemCallExit \n" + " \n" + "tst lr, #4 \n" + "ite eq \n" + "mrseq r0, msp \n" + "mrsne r0, psp \n" + " \n" + "ldr r1, [r0, #24] \n" + "ldrb r2, [r1, #-2] \n" + "cmp r2, %0 \n" + "beq syscall_enter \n" + "cmp r2, %1 \n" + "beq syscall_enter_1 \n" + "cmp r2, %2 \n" + "beq syscall_exit \n" + "b vPortSVCHandler_C \n" + " \n" + "syscall_enter: \n" + " mov r1, lr \n" + " b vSystemCallEnter \n" + " \n" + "syscall_enter_1: \n" + " mov r1, lr \n" + " b vSystemCallEnter_1 \n" + " \n" + "syscall_exit: \n" + " mov r1, lr \n" + " b vSystemCallExit \n" + " \n" + : /* No outputs. */ + :"i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_ENTER_1 ), "i" ( portSVC_SYSTEM_CALL_EXIT ) + : "r0", "r1", "r2", "memory" + ); +} + +#else /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ { __asm volatile @@ -437,6 +577,8 @@ void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ "svchandler_address_const: .word vPortSVCHandler_C \n" ); } + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ /*-----------------------------------------------------------*/ void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) /* __attribute__ (( naked )) */ diff --git a/portable/GCC/ARM_CM55/non_secure/portmacro.h b/portable/GCC/ARM_CM55/non_secure/portmacro.h index c9bad40cf98..12bb5e7c4b9 100644 --- a/portable/GCC/ARM_CM55/non_secure/portmacro.h +++ b/portable/GCC/ARM_CM55/non_secure/portmacro.h @@ -56,7 +56,6 @@ #define portARCH_NAME "Cortex-M55" #define portHAS_BASEPRI 1 #define portDONT_DISCARD __attribute__( ( used ) ) -#define portNORETURN __attribute__( ( noreturn ) ) /*-----------------------------------------------------------*/ /* ARMv8-M common port configurations. */ diff --git a/portable/GCC/ARM_CM55/non_secure/portmacrocommon.h b/portable/GCC/ARM_CM55/non_secure/portmacrocommon.h index c2ca5fa7730..65ac109c802 100644 --- a/portable/GCC/ARM_CM55/non_secure/portmacrocommon.h +++ b/portable/GCC/ARM_CM55/non_secure/portmacrocommon.h @@ -186,23 +186,120 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #define portMPU_REGION_EXECUTE_NEVER ( 1UL ) /*-----------------------------------------------------------*/ -/** - * @brief Settings to define an MPU region. - */ -typedef struct MPURegionSettings -{ - uint32_t ulRBAR; /**< RBAR for the region. */ - uint32_t ulRLAR; /**< RLAR for the region. */ -} MPURegionSettings_t; +#if ( configENABLE_MPU == 1 ) -/** - * @brief MPU settings as stored in the TCB. - */ -typedef struct MPU_SETTINGS -{ - uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ - MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */ -} xMPU_SETTINGS; + /** + * @brief Settings to define an MPU region. + */ + typedef struct MPURegionSettings + { + uint32_t ulRBAR; /**< RBAR for the region. */ + uint32_t ulRLAR; /**< RLAR for the region. */ + } MPURegionSettings_t; + + #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + + #ifndef configSYSTEM_CALL_STACK_SIZE + #error configSYSTEM_CALL_STACK_SIZE must be defined to the desired size of the system call stack in words for using MPU wrappers v2. + #endif + + /** + * @brief System call stack. + */ + typedef struct SYSTEM_CALL_STACK_INFO + { + uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ]; + uint32_t * pulSystemCallStack; + uint32_t * pulSystemCallStackLimit; + uint32_t * pulTaskStack; + uint32_t ulLinkRegisterAtSystemCallEntry; + uint32_t ulStackLimitRegisterAtSystemCallEntry; + } xSYSTEM_CALL_STACK_INFO; + + #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + + /** + * @brief MPU settings as stored in the TCB. + */ + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + + #if( configENABLE_TRUSTZONE == 1 ) + + /* + * +-----------+---------------+----------+-----------------+------------------------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | + * | | | | PC, xPSR | CONTROL, EXC_RETURN | | + * +-----------+---------------+----------+-----------------+------------------------------+-----+ + * + * <-----------><--------------><---------><----------------><-----------------------------><----> + * 16 16 8 8 5 1 + */ + #define MAX_CONTEXT_SIZE 54 + + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ + + /* + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | + * | | | | PC, xPSR | EXC_RETURN | | + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * + * <-----------><--------------><---------><----------------><---------------------><----> + * 16 16 8 8 4 1 + */ + #define MAX_CONTEXT_SIZE 53 + + #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + + #else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ + + #if( configENABLE_TRUSTZONE == 1 ) + + /* + * +----------+-----------------+------------------------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | + * | | PC, xPSR | CONTROL, EXC_RETURN | | + * +----------+-----------------+------------------------------+-----+ + * + * <---------><----------------><------------------------------><----> + * 8 8 5 1 + */ + #define MAX_CONTEXT_SIZE 22 + + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ + + /* + * +----------+-----------------+----------------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | + * | | PC, xPSR | EXC_RETURN | | + * +----------+-----------------+----------------------+-----+ + * + * <---------><----------------><----------------------><----> + * 8 8 4 1 + */ + #define MAX_CONTEXT_SIZE 21 + + #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + + #endif /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ + + /* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ + #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) + #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) + + typedef struct MPU_SETTINGS + { + uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ + MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */ + uint32_t ulContext[ MAX_CONTEXT_SIZE ]; + uint32_t ulTaskFlags; + + #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo; + #endif + } xMPU_SETTINGS; + +#endif /* configENABLE_MPU == 1 */ /*-----------------------------------------------------------*/ /** @@ -223,6 +320,9 @@ typedef struct MPU_SETTINGS #define portSVC_FREE_SECURE_CONTEXT 1 #define portSVC_START_SCHEDULER 2 #define portSVC_RAISE_PRIVILEGE 3 +#define portSVC_SYSTEM_CALL_ENTER 4 /* System calls with upto 4 parameters. */ +#define portSVC_SYSTEM_CALL_ENTER_1 5 /* System calls with 5 parameters. */ +#define portSVC_SYSTEM_CALL_EXIT 6 /*-----------------------------------------------------------*/ /** @@ -315,6 +415,20 @@ typedef struct MPU_SETTINGS #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ +#if ( configENABLE_MPU == 1 ) + + extern BaseType_t xPortIsTaskPrivileged( void ); + + /** + * @brief Checks whether or not the calling task is privileged. + * + * @return pdTRUE if the calling task is privileged, pdFALSE otherwise. + */ + #define portIS_TASK_PRIVILEGED() xPortIsTaskPrivileged() + +#endif /* configENABLE_MPU == 1 */ +/*-----------------------------------------------------------*/ + /** * @brief Barriers. */ diff --git a/portable/GCC/ARM_CM55_NTZ/non_secure/mpu_wrappers_v2_asm.c b/portable/GCC/ARM_CM55_NTZ/non_secure/mpu_wrappers_v2_asm.c new file mode 100644 index 00000000000..6e2043427fe --- /dev/null +++ b/portable/GCC/ARM_CM55_NTZ/non_secure/mpu_wrappers_v2_asm.c @@ -0,0 +1,2349 @@ +/* + * FreeRTOS Kernel + * Copyright (C) 2021 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 + * + */ + +/* 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. */ +#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +/* Scheduler includes. */ +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" +#include "timers.h" +#include "event_groups.h" +#include "stream_buffer.h" + +#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + +#if ( INCLUDE_xTaskDelayUntil == 1 ) + +BaseType_t MPU_xTaskDelayUntil( TickType_t * const pxPreviousWakeTime, + const TickType_t xTimeIncrement ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskDelayUntil( TickType_t * const pxPreviousWakeTime, + const TickType_t xTimeIncrement ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskDelayUntilImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskDelayUntil_Unpriv \n" + " MPU_xTaskDelayUntil_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskDelayUntilImpl \n" + " MPU_xTaskDelayUntil_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskDelayUntilImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_xTaskDelayUntil == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_xTaskAbortDelay == 1 ) + +BaseType_t MPU_xTaskAbortDelay( TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskAbortDelay( TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskAbortDelayImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskAbortDelay_Unpriv \n" + " MPU_xTaskAbortDelay_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskAbortDelayImpl \n" + " MPU_xTaskAbortDelay_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskAbortDelayImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_xTaskAbortDelay == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskDelay == 1 ) + +void MPU_vTaskDelay( const TickType_t xTicksToDelay ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskDelay( const TickType_t xTicksToDelay ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskDelayImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vTaskDelay_Unpriv \n" + " MPU_vTaskDelay_Priv: \n" + " pop {r0} \n" + " b MPU_vTaskDelayImpl \n" + " MPU_vTaskDelay_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vTaskDelayImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_vTaskDelay == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_uxTaskPriorityGet == 1 ) + +UBaseType_t MPU_uxTaskPriorityGet( const TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxTaskPriorityGet( const TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxTaskPriorityGetImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_uxTaskPriorityGet_Unpriv \n" + " MPU_uxTaskPriorityGet_Priv: \n" + " pop {r0} \n" + " b MPU_uxTaskPriorityGetImpl \n" + " MPU_uxTaskPriorityGet_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_uxTaskPriorityGetImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_uxTaskPriorityGet == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_eTaskGetState == 1 ) + +eTaskState MPU_eTaskGetState( TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +eTaskState MPU_eTaskGetState( TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_eTaskGetStateImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_eTaskGetState_Unpriv \n" + " MPU_eTaskGetState_Priv: \n" + " pop {r0} \n" + " b MPU_eTaskGetStateImpl \n" + " MPU_eTaskGetState_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_eTaskGetStateImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_eTaskGetState == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + +void MPU_vTaskGetInfo( TaskHandle_t xTask, + TaskStatus_t * pxTaskStatus, + BaseType_t xGetFreeStackSpace, + eTaskState eState ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskGetInfo( TaskHandle_t xTask, + TaskStatus_t * pxTaskStatus, + BaseType_t xGetFreeStackSpace, + eTaskState eState ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskGetInfoImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vTaskGetInfo_Unpriv \n" + " MPU_vTaskGetInfo_Priv: \n" + " pop {r0} \n" + " b MPU_vTaskGetInfoImpl \n" + " MPU_vTaskGetInfo_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vTaskGetInfoImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TRACE_FACILITY == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) + +TaskHandle_t MPU_xTaskGetIdleTaskHandle( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TaskHandle_t MPU_xTaskGetIdleTaskHandle( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGetIdleTaskHandleImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskGetIdleTaskHandle_Unpriv \n" + " MPU_xTaskGetIdleTaskHandle_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskGetIdleTaskHandleImpl \n" + " MPU_xTaskGetIdleTaskHandle_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskGetIdleTaskHandleImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskSuspend == 1 ) + +void MPU_vTaskSuspend( TaskHandle_t xTaskToSuspend ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskSuspend( TaskHandle_t xTaskToSuspend ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskSuspendImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vTaskSuspend_Unpriv \n" + " MPU_vTaskSuspend_Priv: \n" + " pop {r0} \n" + " b MPU_vTaskSuspendImpl \n" + " MPU_vTaskSuspend_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vTaskSuspendImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_vTaskSuspend == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskSuspend == 1 ) + +void MPU_vTaskResume( TaskHandle_t xTaskToResume ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskResume( TaskHandle_t xTaskToResume ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskResumeImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vTaskResume_Unpriv \n" + " MPU_vTaskResume_Priv: \n" + " pop {r0} \n" + " b MPU_vTaskResumeImpl \n" + " MPU_vTaskResume_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vTaskResumeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_vTaskSuspend == 1 ) */ +/*-----------------------------------------------------------*/ + +TickType_t MPU_xTaskGetTickCount( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TickType_t MPU_xTaskGetTickCount( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGetTickCountImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskGetTickCount_Unpriv \n" + " MPU_xTaskGetTickCount_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskGetTickCountImpl \n" + " MPU_xTaskGetTickCount_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskGetTickCountImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +UBaseType_t MPU_uxTaskGetNumberOfTasks( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxTaskGetNumberOfTasks( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxTaskGetNumberOfTasksImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_uxTaskGetNumberOfTasks_Unpriv \n" + " MPU_uxTaskGetNumberOfTasks_Priv: \n" + " pop {r0} \n" + " b MPU_uxTaskGetNumberOfTasksImpl \n" + " MPU_uxTaskGetNumberOfTasks_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_uxTaskGetNumberOfTasksImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +char * MPU_pcTaskGetName( TaskHandle_t xTaskToQuery ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +char * MPU_pcTaskGetName( TaskHandle_t xTaskToQuery ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_pcTaskGetNameImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_pcTaskGetName_Unpriv \n" + " MPU_pcTaskGetName_Priv: \n" + " pop {r0} \n" + " b MPU_pcTaskGetNameImpl \n" + " MPU_pcTaskGetName_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_pcTaskGetNameImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +#if ( configGENERATE_RUN_TIME_STATS == 1 ) + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetRunTimeCounter( const TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetRunTimeCounter( const TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_ulTaskGetRunTimeCounterImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_ulTaskGetRunTimeCounter_Unpriv \n" + " MPU_ulTaskGetRunTimeCounter_Priv: \n" + " pop {r0} \n" + " b MPU_ulTaskGetRunTimeCounterImpl \n" + " MPU_ulTaskGetRunTimeCounter_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_ulTaskGetRunTimeCounterImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( ( configGENERATE_RUN_TIME_STATS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configGENERATE_RUN_TIME_STATS == 1 ) + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetRunTimePercent( const TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetRunTimePercent( const TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_ulTaskGetRunTimePercentImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_ulTaskGetRunTimePercent_Unpriv \n" + " MPU_ulTaskGetRunTimePercent_Priv: \n" + " pop {r0} \n" + " b MPU_ulTaskGetRunTimePercentImpl \n" + " MPU_ulTaskGetRunTimePercent_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_ulTaskGetRunTimePercentImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( ( configGENERATE_RUN_TIME_STATS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimePercent( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimePercent( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_ulTaskGetIdleRunTimePercentImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_ulTaskGetIdleRunTimePercent_Unpriv \n" + " MPU_ulTaskGetIdleRunTimePercent_Priv: \n" + " pop {r0} \n" + " b MPU_ulTaskGetIdleRunTimePercentImpl \n" + " MPU_ulTaskGetIdleRunTimePercent_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_ulTaskGetIdleRunTimePercentImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimeCounter( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimeCounter( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_ulTaskGetIdleRunTimeCounterImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_ulTaskGetIdleRunTimeCounter_Unpriv \n" + " MPU_ulTaskGetIdleRunTimeCounter_Priv: \n" + " pop {r0} \n" + " b MPU_ulTaskGetIdleRunTimeCounterImpl \n" + " MPU_ulTaskGetIdleRunTimeCounter_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_ulTaskGetIdleRunTimeCounterImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_APPLICATION_TASK_TAG == 1 ) + +void MPU_vTaskSetApplicationTaskTag( TaskHandle_t xTask, + TaskHookFunction_t pxHookFunction ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskSetApplicationTaskTag( TaskHandle_t xTask, + TaskHookFunction_t pxHookFunction ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskSetApplicationTaskTagImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vTaskSetApplicationTaskTag_Unpriv \n" + " MPU_vTaskSetApplicationTaskTag_Priv: \n" + " pop {r0} \n" + " b MPU_vTaskSetApplicationTaskTagImpl \n" + " MPU_vTaskSetApplicationTaskTag_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vTaskSetApplicationTaskTagImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_APPLICATION_TASK_TAG == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_APPLICATION_TASK_TAG == 1 ) + +TaskHookFunction_t MPU_xTaskGetApplicationTaskTag( TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TaskHookFunction_t MPU_xTaskGetApplicationTaskTag( TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGetApplicationTaskTagImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskGetApplicationTaskTag_Unpriv \n" + " MPU_xTaskGetApplicationTaskTag_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskGetApplicationTaskTagImpl \n" + " MPU_xTaskGetApplicationTaskTag_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskGetApplicationTaskTagImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_APPLICATION_TASK_TAG == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) + +void MPU_vTaskSetThreadLocalStoragePointer( TaskHandle_t xTaskToSet, + BaseType_t xIndex, + void * pvValue ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskSetThreadLocalStoragePointer( TaskHandle_t xTaskToSet, + BaseType_t xIndex, + void * pvValue ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskSetThreadLocalStoragePointerImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vTaskSetThreadLocalStoragePointer_Unpriv \n" + " MPU_vTaskSetThreadLocalStoragePointer_Priv: \n" + " pop {r0} \n" + " b MPU_vTaskSetThreadLocalStoragePointerImpl \n" + " MPU_vTaskSetThreadLocalStoragePointer_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vTaskSetThreadLocalStoragePointerImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) + +void * MPU_pvTaskGetThreadLocalStoragePointer( TaskHandle_t xTaskToQuery, + BaseType_t xIndex ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void * MPU_pvTaskGetThreadLocalStoragePointer( TaskHandle_t xTaskToQuery, + BaseType_t xIndex ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_pvTaskGetThreadLocalStoragePointerImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_pvTaskGetThreadLocalStoragePointer_Unpriv \n" + " MPU_pvTaskGetThreadLocalStoragePointer_Priv: \n" + " pop {r0} \n" + " b MPU_pvTaskGetThreadLocalStoragePointerImpl \n" + " MPU_pvTaskGetThreadLocalStoragePointer_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_pvTaskGetThreadLocalStoragePointerImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + +UBaseType_t MPU_uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray, + const UBaseType_t uxArraySize, + configRUN_TIME_COUNTER_TYPE * const pulTotalRunTime ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray, + const UBaseType_t uxArraySize, + configRUN_TIME_COUNTER_TYPE * const pulTotalRunTime ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxTaskGetSystemStateImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_uxTaskGetSystemState_Unpriv \n" + " MPU_uxTaskGetSystemState_Priv: \n" + " pop {r0} \n" + " b MPU_uxTaskGetSystemStateImpl \n" + " MPU_uxTaskGetSystemState_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_uxTaskGetSystemStateImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TRACE_FACILITY == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) + +UBaseType_t MPU_uxTaskGetStackHighWaterMark( TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxTaskGetStackHighWaterMark( TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxTaskGetStackHighWaterMarkImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_uxTaskGetStackHighWaterMark_Unpriv \n" + " MPU_uxTaskGetStackHighWaterMark_Priv: \n" + " pop {r0} \n" + " b MPU_uxTaskGetStackHighWaterMarkImpl \n" + " MPU_uxTaskGetStackHighWaterMark_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_uxTaskGetStackHighWaterMarkImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) + +configSTACK_DEPTH_TYPE MPU_uxTaskGetStackHighWaterMark2( TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +configSTACK_DEPTH_TYPE MPU_uxTaskGetStackHighWaterMark2( TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxTaskGetStackHighWaterMark2Impl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_uxTaskGetStackHighWaterMark2_Unpriv \n" + " MPU_uxTaskGetStackHighWaterMark2_Priv: \n" + " pop {r0} \n" + " b MPU_uxTaskGetStackHighWaterMark2Impl \n" + " MPU_uxTaskGetStackHighWaterMark2_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_uxTaskGetStackHighWaterMark2Impl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) ) + +TaskHandle_t MPU_xTaskGetCurrentTaskHandle( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TaskHandle_t MPU_xTaskGetCurrentTaskHandle( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGetCurrentTaskHandleImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskGetCurrentTaskHandle_Unpriv \n" + " MPU_xTaskGetCurrentTaskHandle_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskGetCurrentTaskHandleImpl \n" + " MPU_xTaskGetCurrentTaskHandle_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskGetCurrentTaskHandleImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_xTaskGetSchedulerState == 1 ) + +BaseType_t MPU_xTaskGetSchedulerState( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskGetSchedulerState( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGetSchedulerStateImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskGetSchedulerState_Unpriv \n" + " MPU_xTaskGetSchedulerState_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskGetSchedulerStateImpl \n" + " MPU_xTaskGetSchedulerState_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskGetSchedulerStateImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_xTaskGetSchedulerState == 1 ) */ +/*-----------------------------------------------------------*/ + +void MPU_vTaskSetTimeOutState( TimeOut_t * const pxTimeOut ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskSetTimeOutState( TimeOut_t * const pxTimeOut ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskSetTimeOutStateImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vTaskSetTimeOutState_Unpriv \n" + " MPU_vTaskSetTimeOutState_Priv: \n" + " pop {r0} \n" + " b MPU_vTaskSetTimeOutStateImpl \n" + " MPU_vTaskSetTimeOutState_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vTaskSetTimeOutStateImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut, + TickType_t * const pxTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut, + TickType_t * const pxTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskCheckForTimeOutImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskCheckForTimeOut_Unpriv \n" + " MPU_xTaskCheckForTimeOut_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskCheckForTimeOutImpl \n" + " MPU_xTaskCheckForTimeOut_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskCheckForTimeOutImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +#if ( configUSE_TASK_NOTIFICATIONS == 1 ) + +BaseType_t MPU_xTaskGenericNotify( TaskHandle_t xTaskToNotify, + UBaseType_t uxIndexToNotify, + uint32_t ulValue, + eNotifyAction eAction, + uint32_t * pulPreviousNotificationValue ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskGenericNotify( TaskHandle_t xTaskToNotify, + UBaseType_t uxIndexToNotify, + uint32_t ulValue, + eNotifyAction eAction, + uint32_t * pulPreviousNotificationValue ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGenericNotifyImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskGenericNotify_Unpriv \n" + " MPU_xTaskGenericNotify_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskGenericNotifyImpl \n" + " MPU_xTaskGenericNotify_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskGenericNotifyImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER_1 ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TASK_NOTIFICATIONS == 1 ) + +BaseType_t MPU_xTaskGenericNotifyWait( UBaseType_t uxIndexToWaitOn, + uint32_t ulBitsToClearOnEntry, + uint32_t ulBitsToClearOnExit, + uint32_t * pulNotificationValue, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskGenericNotifyWait( UBaseType_t uxIndexToWaitOn, + uint32_t ulBitsToClearOnEntry, + uint32_t ulBitsToClearOnExit, + uint32_t * pulNotificationValue, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGenericNotifyWaitImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskGenericNotifyWait_Unpriv \n" + " MPU_xTaskGenericNotifyWait_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskGenericNotifyWaitImpl \n" + " MPU_xTaskGenericNotifyWait_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskGenericNotifyWaitImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER_1 ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TASK_NOTIFICATIONS == 1 ) + +uint32_t MPU_ulTaskGenericNotifyTake( UBaseType_t uxIndexToWaitOn, + BaseType_t xClearCountOnExit, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +uint32_t MPU_ulTaskGenericNotifyTake( UBaseType_t uxIndexToWaitOn, + BaseType_t xClearCountOnExit, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_ulTaskGenericNotifyTakeImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_ulTaskGenericNotifyTake_Unpriv \n" + " MPU_ulTaskGenericNotifyTake_Priv: \n" + " pop {r0} \n" + " b MPU_ulTaskGenericNotifyTakeImpl \n" + " MPU_ulTaskGenericNotifyTake_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_ulTaskGenericNotifyTakeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TASK_NOTIFICATIONS == 1 ) + +BaseType_t MPU_xTaskGenericNotifyStateClear( TaskHandle_t xTask, + UBaseType_t uxIndexToClear ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskGenericNotifyStateClear( TaskHandle_t xTask, + UBaseType_t uxIndexToClear ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGenericNotifyStateClearImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskGenericNotifyStateClear_Unpriv \n" + " MPU_xTaskGenericNotifyStateClear_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskGenericNotifyStateClearImpl \n" + " MPU_xTaskGenericNotifyStateClear_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskGenericNotifyStateClearImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TASK_NOTIFICATIONS == 1 ) + +uint32_t MPU_ulTaskGenericNotifyValueClear( TaskHandle_t xTask, + UBaseType_t uxIndexToClear, + uint32_t ulBitsToClear ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +uint32_t MPU_ulTaskGenericNotifyValueClear( TaskHandle_t xTask, + UBaseType_t uxIndexToClear, + uint32_t ulBitsToClear ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_ulTaskGenericNotifyValueClearImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_ulTaskGenericNotifyValueClear_Unpriv \n" + " MPU_ulTaskGenericNotifyValueClear_Priv: \n" + " pop {r0} \n" + " b MPU_ulTaskGenericNotifyValueClearImpl \n" + " MPU_ulTaskGenericNotifyValueClear_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_ulTaskGenericNotifyValueClearImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xQueueGenericSend( QueueHandle_t xQueue, + const void * const pvItemToQueue, + TickType_t xTicksToWait, + const BaseType_t xCopyPosition ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueueGenericSend( QueueHandle_t xQueue, + const void * const pvItemToQueue, + TickType_t xTicksToWait, + const BaseType_t xCopyPosition ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueGenericSendImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xQueueGenericSend_Unpriv \n" + " MPU_xQueueGenericSend_Priv: \n" + " pop {r0} \n" + " b MPU_xQueueGenericSendImpl \n" + " MPU_xQueueGenericSend_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xQueueGenericSendImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +UBaseType_t MPU_uxQueueMessagesWaiting( const QueueHandle_t xQueue ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxQueueMessagesWaiting( const QueueHandle_t xQueue ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxQueueMessagesWaitingImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_uxQueueMessagesWaiting_Unpriv \n" + " MPU_uxQueueMessagesWaiting_Priv: \n" + " pop {r0} \n" + " b MPU_uxQueueMessagesWaitingImpl \n" + " MPU_uxQueueMessagesWaiting_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_uxQueueMessagesWaitingImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +UBaseType_t MPU_uxQueueSpacesAvailable( const QueueHandle_t xQueue ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxQueueSpacesAvailable( const QueueHandle_t xQueue ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxQueueSpacesAvailableImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_uxQueueSpacesAvailable_Unpriv \n" + " MPU_uxQueueSpacesAvailable_Priv: \n" + " pop {r0} \n" + " b MPU_uxQueueSpacesAvailableImpl \n" + " MPU_uxQueueSpacesAvailable_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_uxQueueSpacesAvailableImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xQueueReceive( QueueHandle_t xQueue, + void * const pvBuffer, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueueReceive( QueueHandle_t xQueue, + void * const pvBuffer, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueReceiveImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xQueueReceive_Unpriv \n" + " MPU_xQueueReceive_Priv: \n" + " pop {r0} \n" + " b MPU_xQueueReceiveImpl \n" + " MPU_xQueueReceive_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xQueueReceiveImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xQueuePeek( QueueHandle_t xQueue, + void * const pvBuffer, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueuePeek( QueueHandle_t xQueue, + void * const pvBuffer, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueuePeekImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xQueuePeek_Unpriv \n" + " MPU_xQueuePeek_Priv: \n" + " pop {r0} \n" + " b MPU_xQueuePeekImpl \n" + " MPU_xQueuePeek_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xQueuePeekImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xQueueSemaphoreTake( QueueHandle_t xQueue, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueueSemaphoreTake( QueueHandle_t xQueue, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueSemaphoreTakeImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xQueueSemaphoreTake_Unpriv \n" + " MPU_xQueueSemaphoreTake_Priv: \n" + " pop {r0} \n" + " b MPU_xQueueSemaphoreTakeImpl \n" + " MPU_xQueueSemaphoreTake_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xQueueSemaphoreTakeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +#if ( ( configUSE_MUTEXES == 1 ) && ( INCLUDE_xSemaphoreGetMutexHolder == 1 ) ) + +TaskHandle_t MPU_xQueueGetMutexHolder( QueueHandle_t xSemaphore ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TaskHandle_t MPU_xQueueGetMutexHolder( QueueHandle_t xSemaphore ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueGetMutexHolderImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xQueueGetMutexHolder_Unpriv \n" + " MPU_xQueueGetMutexHolder_Priv: \n" + " pop {r0} \n" + " b MPU_xQueueGetMutexHolderImpl \n" + " MPU_xQueueGetMutexHolder_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xQueueGetMutexHolderImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( ( configUSE_MUTEXES == 1 ) && ( INCLUDE_xSemaphoreGetMutexHolder == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_RECURSIVE_MUTEXES == 1 ) + +BaseType_t MPU_xQueueTakeMutexRecursive( QueueHandle_t xMutex, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueueTakeMutexRecursive( QueueHandle_t xMutex, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueTakeMutexRecursiveImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xQueueTakeMutexRecursive_Unpriv \n" + " MPU_xQueueTakeMutexRecursive_Priv: \n" + " pop {r0} \n" + " b MPU_xQueueTakeMutexRecursiveImpl \n" + " MPU_xQueueTakeMutexRecursive_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xQueueTakeMutexRecursiveImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_RECURSIVE_MUTEXES == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_RECURSIVE_MUTEXES == 1 ) + +BaseType_t MPU_xQueueGiveMutexRecursive( QueueHandle_t pxMutex ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueueGiveMutexRecursive( QueueHandle_t pxMutex ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueGiveMutexRecursiveImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xQueueGiveMutexRecursive_Unpriv \n" + " MPU_xQueueGiveMutexRecursive_Priv: \n" + " pop {r0} \n" + " b MPU_xQueueGiveMutexRecursiveImpl \n" + " MPU_xQueueGiveMutexRecursive_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xQueueGiveMutexRecursiveImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_RECURSIVE_MUTEXES == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_QUEUE_SETS == 1 ) + +QueueSetMemberHandle_t MPU_xQueueSelectFromSet( QueueSetHandle_t xQueueSet, + const TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +QueueSetMemberHandle_t MPU_xQueueSelectFromSet( QueueSetHandle_t xQueueSet, + const TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueSelectFromSetImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xQueueSelectFromSet_Unpriv \n" + " MPU_xQueueSelectFromSet_Priv: \n" + " pop {r0} \n" + " b MPU_xQueueSelectFromSetImpl \n" + " MPU_xQueueSelectFromSet_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xQueueSelectFromSetImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_QUEUE_SETS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_QUEUE_SETS == 1 ) + +BaseType_t MPU_xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore, + QueueSetHandle_t xQueueSet ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore, + QueueSetHandle_t xQueueSet ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueAddToSetImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xQueueAddToSet_Unpriv \n" + " MPU_xQueueAddToSet_Priv: \n" + " pop {r0} \n" + " b MPU_xQueueAddToSetImpl \n" + " MPU_xQueueAddToSet_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xQueueAddToSetImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_QUEUE_SETS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configQUEUE_REGISTRY_SIZE > 0 ) + +void MPU_vQueueAddToRegistry( QueueHandle_t xQueue, + const char * pcName ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vQueueAddToRegistry( QueueHandle_t xQueue, + const char * pcName ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vQueueAddToRegistryImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vQueueAddToRegistry_Unpriv \n" + " MPU_vQueueAddToRegistry_Priv: \n" + " pop {r0} \n" + " b MPU_vQueueAddToRegistryImpl \n" + " MPU_vQueueAddToRegistry_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vQueueAddToRegistryImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configQUEUE_REGISTRY_SIZE > 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configQUEUE_REGISTRY_SIZE > 0 ) + +void MPU_vQueueUnregisterQueue( QueueHandle_t xQueue ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vQueueUnregisterQueue( QueueHandle_t xQueue ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vQueueUnregisterQueueImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vQueueUnregisterQueue_Unpriv \n" + " MPU_vQueueUnregisterQueue_Priv: \n" + " pop {r0} \n" + " b MPU_vQueueUnregisterQueueImpl \n" + " MPU_vQueueUnregisterQueue_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vQueueUnregisterQueueImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configQUEUE_REGISTRY_SIZE > 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configQUEUE_REGISTRY_SIZE > 0 ) + +const char * MPU_pcQueueGetName( QueueHandle_t xQueue ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +const char * MPU_pcQueueGetName( QueueHandle_t xQueue ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_pcQueueGetNameImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_pcQueueGetName_Unpriv \n" + " MPU_pcQueueGetName_Priv: \n" + " pop {r0} \n" + " b MPU_pcQueueGetNameImpl \n" + " MPU_pcQueueGetName_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_pcQueueGetNameImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configQUEUE_REGISTRY_SIZE > 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +void * MPU_pvTimerGetTimerID( const TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void * MPU_pvTimerGetTimerID( const TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_pvTimerGetTimerIDImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_pvTimerGetTimerID_Unpriv \n" + " MPU_pvTimerGetTimerID_Priv: \n" + " pop {r0} \n" + " b MPU_pvTimerGetTimerIDImpl \n" + " MPU_pvTimerGetTimerID_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_pvTimerGetTimerIDImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +void MPU_vTimerSetTimerID( TimerHandle_t xTimer, + void * pvNewID ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTimerSetTimerID( TimerHandle_t xTimer, + void * pvNewID ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTimerSetTimerIDImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vTimerSetTimerID_Unpriv \n" + " MPU_vTimerSetTimerID_Priv: \n" + " pop {r0} \n" + " b MPU_vTimerSetTimerIDImpl \n" + " MPU_vTimerSetTimerID_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vTimerSetTimerIDImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +BaseType_t MPU_xTimerIsTimerActive( TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTimerIsTimerActive( TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTimerIsTimerActiveImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTimerIsTimerActive_Unpriv \n" + " MPU_xTimerIsTimerActive_Priv: \n" + " pop {r0} \n" + " b MPU_xTimerIsTimerActiveImpl \n" + " MPU_xTimerIsTimerActive_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTimerIsTimerActiveImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +TaskHandle_t MPU_xTimerGetTimerDaemonTaskHandle( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TaskHandle_t MPU_xTimerGetTimerDaemonTaskHandle( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTimerGetTimerDaemonTaskHandleImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTimerGetTimerDaemonTaskHandle_Unpriv \n" + " MPU_xTimerGetTimerDaemonTaskHandle_Priv: \n" + " pop {r0} \n" + " b MPU_xTimerGetTimerDaemonTaskHandleImpl \n" + " MPU_xTimerGetTimerDaemonTaskHandle_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTimerGetTimerDaemonTaskHandleImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +BaseType_t MPU_xTimerGenericCommand( TimerHandle_t xTimer, + const BaseType_t xCommandID, + const TickType_t xOptionalValue, + BaseType_t * const pxHigherPriorityTaskWoken, + const TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTimerGenericCommand( TimerHandle_t xTimer, + const BaseType_t xCommandID, + const TickType_t xOptionalValue, + BaseType_t * const pxHigherPriorityTaskWoken, + const TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTimerGenericCommandImpl \n" + " \n" + " push {r0} \n" + " mrs r0, ipsr \n" + " cmp r0, #0 \n" + " bne MPU_xTimerGenericCommand_Priv \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " beq MPU_xTimerGenericCommand_Priv \n" + " MPU_xTimerGenericCommand_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTimerGenericCommandImpl \n" + " svc %1 \n" + " bx lr \n" + " MPU_xTimerGenericCommand_Priv: \n" + " pop {r0} \n" + " b MPU_xTimerGenericCommandImpl \n" + " \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER_1 ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +const char * MPU_pcTimerGetName( TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +const char * MPU_pcTimerGetName( TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_pcTimerGetNameImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_pcTimerGetName_Unpriv \n" + " MPU_pcTimerGetName_Priv: \n" + " pop {r0} \n" + " b MPU_pcTimerGetNameImpl \n" + " MPU_pcTimerGetName_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_pcTimerGetNameImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, + const BaseType_t uxAutoReload ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, + const BaseType_t uxAutoReload ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTimerSetReloadModeImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vTimerSetReloadMode_Unpriv \n" + " MPU_vTimerSetReloadMode_Priv: \n" + " pop {r0} \n" + " b MPU_vTimerSetReloadModeImpl \n" + " MPU_vTimerSetReloadMode_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vTimerSetReloadModeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +BaseType_t MPU_xTimerGetReloadMode( TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTimerGetReloadMode( TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTimerGetReloadModeImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTimerGetReloadMode_Unpriv \n" + " MPU_xTimerGetReloadMode_Priv: \n" + " pop {r0} \n" + " b MPU_xTimerGetReloadModeImpl \n" + " MPU_xTimerGetReloadMode_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTimerGetReloadModeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +UBaseType_t MPU_uxTimerGetReloadMode( TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxTimerGetReloadMode( TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxTimerGetReloadModeImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_uxTimerGetReloadMode_Unpriv \n" + " MPU_uxTimerGetReloadMode_Priv: \n" + " pop {r0} \n" + " b MPU_uxTimerGetReloadModeImpl \n" + " MPU_uxTimerGetReloadMode_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_uxTimerGetReloadModeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +TickType_t MPU_xTimerGetPeriod( TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TickType_t MPU_xTimerGetPeriod( TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTimerGetPeriodImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTimerGetPeriod_Unpriv \n" + " MPU_xTimerGetPeriod_Priv: \n" + " pop {r0} \n" + " b MPU_xTimerGetPeriodImpl \n" + " MPU_xTimerGetPeriod_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTimerGetPeriodImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +TickType_t MPU_xTimerGetExpiryTime( TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TickType_t MPU_xTimerGetExpiryTime( TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTimerGetExpiryTimeImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTimerGetExpiryTime_Unpriv \n" + " MPU_xTimerGetExpiryTime_Priv: \n" + " pop {r0} \n" + " b MPU_xTimerGetExpiryTimeImpl \n" + " MPU_xTimerGetExpiryTime_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTimerGetExpiryTimeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +EventBits_t MPU_xEventGroupWaitBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToWaitFor, + const BaseType_t xClearOnExit, + const BaseType_t xWaitForAllBits, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +EventBits_t MPU_xEventGroupWaitBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToWaitFor, + const BaseType_t xClearOnExit, + const BaseType_t xWaitForAllBits, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupWaitBitsImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xEventGroupWaitBits_Unpriv \n" + " MPU_xEventGroupWaitBits_Priv: \n" + " pop {r0} \n" + " b MPU_xEventGroupWaitBitsImpl \n" + " MPU_xEventGroupWaitBits_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xEventGroupWaitBitsImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER_1 ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToClear ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToClear ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupClearBitsImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xEventGroupClearBits_Unpriv \n" + " MPU_xEventGroupClearBits_Priv: \n" + " pop {r0} \n" + " b MPU_xEventGroupClearBitsImpl \n" + " MPU_xEventGroupClearBits_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xEventGroupClearBitsImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupSetBitsImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xEventGroupSetBits_Unpriv \n" + " MPU_xEventGroupSetBits_Priv: \n" + " pop {r0} \n" + " b MPU_xEventGroupSetBitsImpl \n" + " MPU_xEventGroupSetBits_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xEventGroupSetBitsImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet, + const EventBits_t uxBitsToWaitFor, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet, + const EventBits_t uxBitsToWaitFor, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupSyncImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xEventGroupSync_Unpriv \n" + " MPU_xEventGroupSync_Priv: \n" + " pop {r0} \n" + " b MPU_xEventGroupSyncImpl \n" + " MPU_xEventGroupSync_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xEventGroupSyncImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + +UBaseType_t MPU_uxEventGroupGetNumber( void * xEventGroup ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxEventGroupGetNumber( void * xEventGroup ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxEventGroupGetNumberImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_uxEventGroupGetNumber_Unpriv \n" + " MPU_uxEventGroupGetNumber_Priv: \n" + " pop {r0} \n" + " b MPU_uxEventGroupGetNumberImpl \n" + " MPU_uxEventGroupGetNumber_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_uxEventGroupGetNumberImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /*( configUSE_TRACE_FACILITY == 1 )*/ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + +void MPU_vEventGroupSetNumber( void * xEventGroup, + UBaseType_t uxEventGroupNumber ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vEventGroupSetNumber( void * xEventGroup, + UBaseType_t uxEventGroupNumber ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vEventGroupSetNumberImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vEventGroupSetNumber_Unpriv \n" + " MPU_vEventGroupSetNumber_Priv: \n" + " pop {r0} \n" + " b MPU_vEventGroupSetNumberImpl \n" + " MPU_vEventGroupSetNumber_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vEventGroupSetNumberImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /*( configUSE_TRACE_FACILITY == 1 )*/ +/*-----------------------------------------------------------*/ + +size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, + const void * pvTxData, + size_t xDataLengthBytes, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, + const void * pvTxData, + size_t xDataLengthBytes, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferSendImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferSend_Unpriv \n" + " MPU_xStreamBufferSend_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferSendImpl \n" + " MPU_xStreamBufferSend_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xStreamBufferSendImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, + void * pvRxData, + size_t xBufferLengthBytes, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, + void * pvRxData, + size_t xBufferLengthBytes, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferReceiveImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferReceive_Unpriv \n" + " MPU_xStreamBufferReceive_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferReceiveImpl \n" + " MPU_xStreamBufferReceive_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xStreamBufferReceiveImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferIsFullImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferIsFull_Unpriv \n" + " MPU_xStreamBufferIsFull_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferIsFullImpl \n" + " MPU_xStreamBufferIsFull_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xStreamBufferIsFullImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferIsEmptyImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferIsEmpty_Unpriv \n" + " MPU_xStreamBufferIsEmpty_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferIsEmptyImpl \n" + " MPU_xStreamBufferIsEmpty_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xStreamBufferIsEmptyImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferSpacesAvailableImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferSpacesAvailable_Unpriv \n" + " MPU_xStreamBufferSpacesAvailable_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferSpacesAvailableImpl \n" + " MPU_xStreamBufferSpacesAvailable_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xStreamBufferSpacesAvailableImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferBytesAvailableImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferBytesAvailable_Unpriv \n" + " MPU_xStreamBufferBytesAvailable_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferBytesAvailableImpl \n" + " MPU_xStreamBufferBytesAvailable_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xStreamBufferBytesAvailableImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, + size_t xTriggerLevel ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, + size_t xTriggerLevel ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferSetTriggerLevelImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferSetTriggerLevel_Unpriv \n" + " MPU_xStreamBufferSetTriggerLevel_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferSetTriggerLevelImpl \n" + " MPU_xStreamBufferSetTriggerLevel_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xStreamBufferSetTriggerLevelImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferNextMessageLengthBytesImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferNextMessageLengthBytes_Unpriv \n" + " MPU_xStreamBufferNextMessageLengthBytes_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferNextMessageLengthBytesImpl \n" + " MPU_xStreamBufferNextMessageLengthBytes_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xStreamBufferNextMessageLengthBytesImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ diff --git a/portable/GCC/ARM_CM55_NTZ/non_secure/port.c b/portable/GCC/ARM_CM55_NTZ/non_secure/port.c index 7bbe1b7bc53..cab1b3668bf 100644 --- a/portable/GCC/ARM_CM55_NTZ/non_secure/port.c +++ b/portable/GCC/ARM_CM55_NTZ/non_secure/port.c @@ -107,6 +107,13 @@ #define portPRIGROUP_SHIFT ( 8UL ) /*-----------------------------------------------------------*/ +/** + * @brief Constants used during system call enter and exit. + */ +#define portPSR_STACK_PADDING_MASK ( 1UL << 9UL ) +#define portEXC_RETURN_STACK_FRAME_TYPE_MASK ( 1UL << 4UL ) +/*-----------------------------------------------------------*/ + /** * @brief Constants required to manipulate the FPU. */ @@ -123,6 +130,14 @@ #define portFPCCR_LSPEN_MASK ( 1UL << portFPCCR_LSPEN_POS ) /*-----------------------------------------------------------*/ +/** + * @brief Offsets in the stack to the parameters when inside the SVC handler. + */ +#define portOFFSET_TO_LR ( 5 ) +#define portOFFSET_TO_PC ( 6 ) +#define portOFFSET_TO_PSR ( 7 ) +/*-----------------------------------------------------------*/ + /** * @brief Constants required to manipulate the MPU. */ @@ -148,6 +163,8 @@ #define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ #define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ +#define portMPU_RBAR_ACCESS_PERMISSIONS_MASK ( 3UL << 1UL ) + #define portMPU_MAIR_ATTR0_POS ( 0UL ) #define portMPU_MAIR_ATTR0_MASK ( 0x000000ff ) @@ -191,6 +208,30 @@ /* Expected value of the portMPU_TYPE register. */ #define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) + +/* Extract first address of the MPU region as encoded in the + * RBAR (Region Base Address Register) value. */ +#define portEXTRACT_FIRST_ADDRESS_FROM_RBAR( rbar ) \ + ( ( rbar ) & portMPU_RBAR_ADDRESS_MASK ) + +/* Extract last address of the MPU region as encoded in the + * RLAR (Region Limit Address Register) value. */ +#define portEXTRACT_LAST_ADDRESS_FROM_RLAR( rlar ) \ + ( ( ( rlar ) & portMPU_RLAR_ADDRESS_MASK ) | ~portMPU_RLAR_ADDRESS_MASK ) + +/* Does addr lies within [start, end] address range? */ +#define portIS_ADDRESS_WITHIN_RANGE( addr, start, end ) \ + ( ( ( addr ) >= ( start ) ) && ( ( addr ) <= ( end ) ) ) + +/* Is the access request satisfied by the available permissions? */ +#define portIS_AUTHORIZED( accessRequest, permissions ) \ + ( ( ( permissions ) & ( accessRequest ) ) == accessRequest ) + +/* 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 ) ) ) /*-----------------------------------------------------------*/ /** @@ -311,6 +352,19 @@ static void prvTaskExitError( void ); #if ( configENABLE_MPU == 1 ) +/** + * @brief Extract MPU region's access permissions from the Region Base Address + * Register (RBAR) value. + * + * @param ulRBARValue RBAR value for the MPU region. + * + * @return uint32_t Access permissions. + */ + static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) PRIVILEGED_FUNCTION; +#endif /* configENABLE_MPU */ + +#if ( configENABLE_MPU == 1 ) + /** * @brief Setup the Memory Protection Unit (MPU). */ @@ -365,6 +419,60 @@ void SysTick_Handler( void ) PRIVILEGED_FUNCTION; * @brief C part of SVC handler. */ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIVILEGED_FUNCTION; + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + + /** + * @brief Sets up the system call stack so that upon returning from + * SVC, the system call stack is used. + * + * It is used for the system calls with up to 4 parameters. + * + * @param pulTaskStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + */ + void vSystemCallEnter( uint32_t * pulTaskStack, uint32_t ulLR ) PRIVILEGED_FUNCTION; + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + + /** + * @brief Sets up the system call stack so that upon returning from + * SVC, the system call stack is used. + * + * It is used for the system calls with 5 parameters. + * + * @param pulTaskStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + */ + void vSystemCallEnter_1( uint32_t * pulTaskStack, uint32_t ulLR ) PRIVILEGED_FUNCTION; + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + + /** + * @brief Sets up the task stack so that upon returning from + * SVC, the task stack is used again. + * + * @param pulSystemCallStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + */ + void vSystemCallExit( uint32_t * pulSystemCallStack, uint32_t ulLR ) PRIVILEGED_FUNCTION; + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + +#if ( configENABLE_MPU == 1 ) + + /** + * @brief Checks whether or not the calling task is privileged. + * + * @return pdTRUE if the calling task is privileged, pdFALSE otherwise. + */ + BaseType_t xPortIsTaskPrivileged( void ) PRIVILEGED_FUNCTION; + +#endif /* configENABLE_MPU == 1 */ /*-----------------------------------------------------------*/ /** @@ -681,6 +789,26 @@ static void prvTaskExitError( void ) } /*-----------------------------------------------------------*/ +#if ( configENABLE_MPU == 1 ) + static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) /* PRIVILEGED_FUNCTION */ + { + uint32_t ulAccessPermissions = 0; + + if( ( ulRBARValue & portMPU_RBAR_ACCESS_PERMISSIONS_MASK ) == portMPU_REGION_READ_ONLY ) + { + ulAccessPermissions = tskMPU_READ_PERMISSION; + } + + if( ( ulRBARValue & portMPU_RBAR_ACCESS_PERMISSIONS_MASK ) == portMPU_REGION_READ_WRITE ) + { + ulAccessPermissions = ( tskMPU_READ_PERMISSION | tskMPU_WRITE_PERMISSION ); + } + + return ulAccessPermissions; + } +#endif /* configENABLE_MPU */ +/*-----------------------------------------------------------*/ + #if ( configENABLE_MPU == 1 ) static void prvSetupMPU( void ) /* PRIVILEGED_FUNCTION */ { @@ -853,7 +981,7 @@ void SysTick_Handler( void ) /* PRIVILEGED_FUNCTION */ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTION portDONT_DISCARD */ { - #if ( configENABLE_MPU == 1 ) + #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) ) #if defined( __ARMCC_VERSION ) /* Declaration when these variable are defined in code instead of being @@ -865,7 +993,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO extern uint32_t __syscalls_flash_start__[]; extern uint32_t __syscalls_flash_end__[]; #endif /* defined( __ARMCC_VERSION ) */ - #endif /* configENABLE_MPU */ + #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */ uint32_t ulPC; @@ -880,7 +1008,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO /* Register are stored on the stack in the following order - R0, R1, R2, R3, * R12, LR, PC, xPSR. */ - ulPC = pulCallerStackAddress[ 6 ]; + ulPC = pulCallerStackAddress[ portOFFSET_TO_PC ]; ucSVCNumber = ( ( uint8_t * ) ulPC )[ -2 ]; switch( ucSVCNumber ) @@ -951,18 +1079,18 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO vRestoreContextOfFirstTask(); break; - #if ( configENABLE_MPU == 1 ) - case portSVC_RAISE_PRIVILEGE: + #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) ) + case portSVC_RAISE_PRIVILEGE: - /* Only raise the privilege, if the svc was raised from any of - * the system calls. */ - if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) && - ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ) - { - vRaisePrivilege(); - } - break; - #endif /* configENABLE_MPU */ + /* Only raise the privilege, if the svc was raised from any of + * the system calls. */ + if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ) + { + vRaisePrivilege(); + } + break; + #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */ default: /* Incorrect SVC call. */ @@ -971,51 +1099,455 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } /*-----------------------------------------------------------*/ -/* *INDENT-OFF* */ -#if ( configENABLE_MPU == 1 ) - StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, - StackType_t * pxEndOfStack, - TaskFunction_t pxCode, - void * pvParameters, - BaseType_t xRunPrivileged ) /* PRIVILEGED_FUNCTION */ -#else - StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, - StackType_t * pxEndOfStack, - TaskFunction_t pxCode, - void * pvParameters ) /* PRIVILEGED_FUNCTION */ -#endif /* configENABLE_MPU */ -/* *INDENT-ON* */ +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + +void vSystemCallEnter( uint32_t * pulTaskStack, uint32_t ulLR ) /* PRIVILEGED_FUNCTION */ { - /* Simulate the stack frame as it would be created by a context switch - * interrupt. */ - #if ( portPRELOAD_REGISTERS == 0 ) + extern TaskHandle_t pxCurrentTCB; + xMPU_SETTINGS * pxMpuSettings; + uint32_t * pulSystemCallStack; + uint32_t ulStackFrameSize, ulSystemCallLocation, i; + #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being + * exported from linker scripts. */ + extern uint32_t * __syscalls_flash_start__; + extern uint32_t * __syscalls_flash_end__; + #else + /* Declaration when these variable are exported from linker scripts. */ + extern uint32_t __syscalls_flash_start__[]; + extern uint32_t __syscalls_flash_end__[]; + #endif /* #if defined( __ARMCC_VERSION ) */ + + ulSystemCallLocation = pulTaskStack[ portOFFSET_TO_PC ]; + + /* If the request did not come from the system call section, do nothing. */ + if( ( ulSystemCallLocation >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulSystemCallLocation <= ( uint32_t ) __syscalls_flash_end__ ) ) { - pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ - *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ - pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pxCode; /* PC */ - pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR */ - pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ - *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ - pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */ - *pxTopOfStack = portINITIAL_EXC_RETURN; + pxMpuSettings = xTaskGetMPUSettings( pxCurrentTCB ); + pulSystemCallStack = pxMpuSettings->xSystemCallStackInfo.pulSystemCallStack; - #if ( configENABLE_MPU == 1 ) + /* This is not NULL only for the duration of the system call. */ + configASSERT( pxMpuSettings->xSystemCallStackInfo.pulTaskStack == NULL ); + + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) { - pxTopOfStack--; + if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) + { + /* Extended frame i.e. FPU in use. */ + ulStackFrameSize = 26; + __asm volatile ( + " vpush {s0} \n" /* Trigger lazy stacking. */ + " vpop {s0} \n" /* Nullify the affect of the above instruction. */ + ::: "memory" + ); + } + else + { + /* Standard frame i.e. FPU not in use. */ + ulStackFrameSize = 8; + } + } + #else + { + ulStackFrameSize = 8; + } + #endif /* configENABLE_FPU || configENABLE_MVE */ + + /* Make space on the system call stack for the stack frame. */ + pulSystemCallStack = pulSystemCallStack - ulStackFrameSize; + + /* Copy the stack frame. */ + for( i = 0; i < ulStackFrameSize; i++ ) + { + pulSystemCallStack[ i ] = pulTaskStack[ i ]; + } + + /* Store the value of the LR and PSPLIM registers before the SVC was raised. We need to + * restore it when we exit from the system call. */ + pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; + __asm volatile ( "mrs %0, psplim" : "=r" ( pxMpuSettings->xSystemCallStackInfo.ulStackLimitRegisterAtSystemCallEntry ) ); + + /* Use the pulSystemCallStack in thread mode. */ + __asm volatile ( "msr psp, %0" : : "r" ( pulSystemCallStack ) ); + __asm volatile ( "msr psplim, %0" : : "r" ( pxMpuSettings->xSystemCallStackInfo.pulSystemCallStackLimit ) ); + + /* Remember the location where we should copy the stack frame when we exit from + * the system call. */ + pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulStackFrameSize; + + /* Record if the hardware used padding to force the stack pointer + * to be double word aligned. */ + if( ( pulTaskStack[ portOFFSET_TO_PSR ] & portPSR_STACK_PADDING_MASK ) == portPSR_STACK_PADDING_MASK ) + { + pxMpuSettings->ulTaskFlags |= portSTACK_FRAME_HAS_PADDING_FLAG; + } + else + { + pxMpuSettings->ulTaskFlags &= ( ~portSTACK_FRAME_HAS_PADDING_FLAG ); + } + + /* We ensure in pxPortInitialiseStack that the system call stack is + * double word aligned and therefore, there is no need of padding. + * Clear the bit[9] of stacked xPSR. */ + pulSystemCallStack[ portOFFSET_TO_PSR ] &= ( ~portPSR_STACK_PADDING_MASK ); + + /* Raise the privilege for the duration of the system call. */ + __asm volatile ( + " mrs r0, control \n" /* Obtain current control value. */ + " movs r1, #1 \n" /* r1 = 1. */ + " bics r0, r1 \n" /* Clear nPRIV bit. */ + " msr control, r0 \n" /* Write back new control value. */ + ::: "r0", "r1", "memory" + ); + } +} - if( xRunPrivileged == pdTRUE ) +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + +void vSystemCallEnter_1( uint32_t * pulTaskStack, uint32_t ulLR ) /* PRIVILEGED_FUNCTION */ +{ + extern TaskHandle_t pxCurrentTCB; + xMPU_SETTINGS * pxMpuSettings; + uint32_t * pulSystemCallStack; + uint32_t ulStackFrameSize, ulSystemCallLocation, i; + #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being + * exported from linker scripts. */ + extern uint32_t * __syscalls_flash_start__; + extern uint32_t * __syscalls_flash_end__; + #else + /* Declaration when these variable are exported from linker scripts. */ + extern uint32_t __syscalls_flash_start__[]; + extern uint32_t __syscalls_flash_end__[]; + #endif /* #if defined( __ARMCC_VERSION ) */ + + ulSystemCallLocation = pulTaskStack[ portOFFSET_TO_PC ]; + + /* If the request did not come from the system call section, do nothing. */ + if( ( ulSystemCallLocation >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulSystemCallLocation <= ( uint32_t ) __syscalls_flash_end__ ) ) + { + pxMpuSettings = xTaskGetMPUSettings( pxCurrentTCB ); + pulSystemCallStack = pxMpuSettings->xSystemCallStackInfo.pulSystemCallStack; + + /* This is not NULL only for the duration of the system call. */ + configASSERT( pxMpuSettings->xSystemCallStackInfo.pulTaskStack == NULL ); + + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + { + if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) { - *pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */ + /* Extended frame i.e. FPU in use. */ + ulStackFrameSize = 26; + __asm volatile ( + " vpush {s0} \n" /* Trigger lazy stacking. */ + " vpop {s0} \n" /* Nullify the affect of the above instruction. */ + ::: "memory" + ); } else { - *pxTopOfStack = portINITIAL_CONTROL_UNPRIVILEGED; /* Slot used to hold this task's CONTROL value. */ + /* Standard frame i.e. FPU not in use. */ + ulStackFrameSize = 8; } } - #endif /* configENABLE_MPU */ + #else + { + ulStackFrameSize = 8; + } + #endif /* configENABLE_FPU || configENABLE_MVE */ + + /* Make space on the system call stack for the stack frame and + * the parameter passed on the stack. We only need to copy one + * parameter but we still reserve 2 spaces to keep the stack + * double word aligned. */ + pulSystemCallStack = pulSystemCallStack - ulStackFrameSize - 2UL; + + /* Copy the stack frame. */ + for( i = 0; i < ulStackFrameSize; i++ ) + { + pulSystemCallStack[ i ] = pulTaskStack[ i ]; + } + + /* Copy the parameter which is passed the stack. */ + if( ( pulTaskStack[ portOFFSET_TO_PSR ] & portPSR_STACK_PADDING_MASK ) == portPSR_STACK_PADDING_MASK ) + { + pulSystemCallStack[ ulStackFrameSize ] = pulTaskStack[ ulStackFrameSize + 1 ]; + /* Record if the hardware used padding to force the stack pointer + * to be double word aligned. */ + pxMpuSettings->ulTaskFlags |= portSTACK_FRAME_HAS_PADDING_FLAG; + } + else + { + pulSystemCallStack[ ulStackFrameSize ] = pulTaskStack[ ulStackFrameSize ]; + /* Record if the hardware used padding to force the stack pointer + * to be double word aligned. */ + pxMpuSettings->ulTaskFlags &= ( ~portSTACK_FRAME_HAS_PADDING_FLAG ); + } + + /* Store the value of the LR and PSPLIM registers before the SVC was raised. + * We need to restore it when we exit from the system call. */ + pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; + __asm volatile ( "mrs %0, psplim" : "=r" ( pxMpuSettings->xSystemCallStackInfo.ulStackLimitRegisterAtSystemCallEntry ) ); + + /* Use the pulSystemCallStack in thread mode. */ + __asm volatile ( "msr psp, %0" : : "r" ( pulSystemCallStack ) ); + __asm volatile ( "msr psplim, %0" : : "r" ( pxMpuSettings->xSystemCallStackInfo.pulSystemCallStackLimit ) ); + + /* Remember the location where we should copy the stack frame when we exit from + * the system call. */ + pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulStackFrameSize; + + /* We ensure in pxPortInitialiseStack that the system call stack is + * double word aligned and therefore, there is no need of padding. + * Clear the bit[9] of stacked xPSR. */ + pulSystemCallStack[ portOFFSET_TO_PSR ] &= ( ~portPSR_STACK_PADDING_MASK ); + + /* Raise the privilege for the duration of the system call. */ + __asm volatile ( + " mrs r0, control \n" /* Obtain current control value. */ + " movs r1, #1 \n" /* r1 = 1. */ + " bics r0, r1 \n" /* Clear nPRIV bit. */ + " msr control, r0 \n" /* Write back new control value. */ + ::: "r0", "r1", "memory" + ); + } +} + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) +void vSystemCallExit( uint32_t * pulSystemCallStack, uint32_t ulLR ) /* PRIVILEGED_FUNCTION */ +{ + extern TaskHandle_t pxCurrentTCB; + xMPU_SETTINGS * pxMpuSettings; + uint32_t * pulTaskStack; + uint32_t ulStackFrameSize, ulSystemCallLocation, i; + #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being + * exported from linker scripts. */ + extern uint32_t * __syscalls_flash_start__; + extern uint32_t * __syscalls_flash_end__; + #else + /* Declaration when these variable are exported from linker scripts. */ + extern uint32_t __syscalls_flash_start__[]; + extern uint32_t __syscalls_flash_end__[]; + #endif /* #if defined( __ARMCC_VERSION ) */ + + ulSystemCallLocation = pulSystemCallStack[ portOFFSET_TO_PC ]; + + /* If the request did not come from the system call section, do nothing. */ + if( ( ulSystemCallLocation >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulSystemCallLocation <= ( uint32_t ) __syscalls_flash_end__ ) ) + { + pxMpuSettings = xTaskGetMPUSettings( pxCurrentTCB ); + pulTaskStack = pxMpuSettings->xSystemCallStackInfo.pulTaskStack; + + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + { + if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) + { + /* Extended frame i.e. FPU in use. */ + ulStackFrameSize = 26; + __asm volatile ( + " vpush {s0} \n" /* Trigger lazy stacking. */ + " vpop {s0} \n" /* Nullify the affect of the above instruction. */ + ::: "memory" + ); + } + else + { + /* Standard frame i.e. FPU not in use. */ + ulStackFrameSize = 8; + } + } + #else + { + ulStackFrameSize = 8; + } + #endif /* configENABLE_FPU || configENABLE_MVE */ + + /* Make space on the task stack for the stack frame. */ + pulTaskStack = pulTaskStack - ulStackFrameSize; + + /* Copy the stack frame. */ + for( i = 0; i < ulStackFrameSize; i++ ) + { + pulTaskStack[ i ] = pulSystemCallStack[ i ]; + } + + /* Use the pulTaskStack in thread mode. */ + __asm volatile ( "msr psp, %0" : : "r" ( pulTaskStack ) ); + + /* Restore the LR and PSPLIM to what they were at the time of + * system call entry. */ + pulTaskStack[ portOFFSET_TO_LR ] = pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry; + __asm volatile ( "msr psplim, %0" : : "r" ( pxMpuSettings->xSystemCallStackInfo.ulStackLimitRegisterAtSystemCallEntry ) ); + + /* If the hardware used padding to force the stack pointer + * to be double word aligned, set the stacked xPSR bit[9], + * otherwise clear it. */ + if( ( pxMpuSettings->ulTaskFlags & portSTACK_FRAME_HAS_PADDING_FLAG ) == portSTACK_FRAME_HAS_PADDING_FLAG ) + { + pulTaskStack[ portOFFSET_TO_PSR ] |= portPSR_STACK_PADDING_MASK; + } + else + { + pulTaskStack[ portOFFSET_TO_PSR ] &= ( ~portPSR_STACK_PADDING_MASK ); + } + + /* This is not NULL only for the duration of the system call. */ + pxMpuSettings->xSystemCallStackInfo.pulTaskStack = NULL; + + /* Drop the privilege before returning to the thread mode. */ + __asm volatile ( + " mrs r0, control \n" /* Obtain current control value. */ + " movs r1, #1 \n" /* r1 = 1. */ + " orrs r0, r1 \n" /* Set nPRIV bit. */ + " msr control, r0 \n" /* Write back new control value. */ + ::: "r0", "r1", "memory" + ); + } +} + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configENABLE_MPU == 1 ) + +BaseType_t xPortIsTaskPrivileged( void ) /* PRIVILEGED_FUNCTION */ +{ + BaseType_t xTaskIsPrivileged = pdFALSE; + const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */ + + if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) + { + xTaskIsPrivileged = pdTRUE; + } + + return xTaskIsPrivileged; +} + +#endif /* configENABLE_MPU == 1 */ +/*-----------------------------------------------------------*/ + +#if( configENABLE_MPU == 1 ) + +StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, + StackType_t * pxEndOfStack, + TaskFunction_t pxCode, + void * pvParameters, + BaseType_t xRunPrivileged, + xMPU_SETTINGS * xMPUSettings ) /* PRIVILEGED_FUNCTION */ +{ + uint32_t ulIndex = 0; + + xMPUSettings->ulContext[ ulIndex ] = 0x04040404; /* r4. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x05050505; /* r5. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x06060606; /* r6. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x07070707; /* r7. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x08080808; /* r8. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x09090909; /* r9. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x10101010; /* r10. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x11111111; /* r11. */ + ulIndex++; + + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pvParameters; /* r0. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x01010101; /* r1. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x02020202; /* r2. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x03030303; /* r3. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x12121212; /* r12. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portTASK_RETURN_ADDRESS; /* LR. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxCode; /* PC. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = portINITIAL_XPSR; /* xPSR. */ + ulIndex++; + + #if ( configENABLE_TRUSTZONE == 1 ) + { + xMPUSettings->ulContext[ ulIndex ] = portNO_SECURE_CONTEXT; /* xSecureContext. */ + ulIndex++; + } + #endif /* configENABLE_TRUSTZONE */ + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) ( pxTopOfStack - 8 ); /* PSP with the hardware saved stack. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */ + ulIndex++; + if( xRunPrivileged == pdTRUE ) + { + xMPUSettings->ulTaskFlags |= portTASK_IS_PRIVILEGED_FLAG; + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_PRIVILEGED; /* CONTROL. */ + ulIndex++; + } + else + { + xMPUSettings->ulTaskFlags &= ( ~portTASK_IS_PRIVILEGED_FLAG ); + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_UNPRIVILEGED; /* CONTROL. */ + ulIndex++; + } + xMPUSettings->ulContext[ ulIndex ] = portINITIAL_EXC_RETURN; /* LR (EXC_RETURN). */ + ulIndex++; + + #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + { + /* Ensure that the system call stack is double word aligned. */ + xMPUSettings->xSystemCallStackInfo.pulSystemCallStack = &( xMPUSettings->xSystemCallStackInfo.ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE - 1 ] ); + xMPUSettings->xSystemCallStackInfo.pulSystemCallStack = ( uint32_t * ) ( ( uint32_t ) ( xMPUSettings->xSystemCallStackInfo.pulSystemCallStack ) & + ( uint32_t ) ( ~( portBYTE_ALIGNMENT_MASK ) ) ); + + xMPUSettings->xSystemCallStackInfo.pulSystemCallStackLimit = &( xMPUSettings->xSystemCallStackInfo.ulSystemCallStackBuffer[ 0 ] ); + xMPUSettings->xSystemCallStackInfo.pulSystemCallStackLimit = ( uint32_t * ) ( ( ( uint32_t ) ( xMPUSettings->xSystemCallStackInfo.pulSystemCallStackLimit ) + + ( uint32_t ) ( portBYTE_ALIGNMENT - 1 ) ) & + ( uint32_t ) ( ~( portBYTE_ALIGNMENT_MASK ) ) ); + + /* This is not NULL only for the duration of a system call. */ + xMPUSettings->xSystemCallStackInfo.pulTaskStack = NULL; + } + #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + + return &( xMPUSettings->ulContext[ ulIndex ] ); +} + +#else /* configENABLE_MPU */ + +StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, + StackType_t * pxEndOfStack, + TaskFunction_t pxCode, + void * pvParameters ) /* PRIVILEGED_FUNCTION */ +{ + /* Simulate the stack frame as it would be created by a context switch + * interrupt. */ + #if ( portPRELOAD_REGISTERS == 0 ) + { + pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ + *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR. */ + pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ + pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */ + *pxTopOfStack = portINITIAL_EXC_RETURN; pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ @@ -1029,55 +1561,39 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO #else /* portPRELOAD_REGISTERS */ { pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ - *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ + *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pxCode; /* PC */ + *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR */ + *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x12121212UL; /* R12 */ + *pxTopOfStack = ( StackType_t ) 0x12121212UL; /* R12. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x03030303UL; /* R3 */ + *pxTopOfStack = ( StackType_t ) 0x03030303UL; /* R3. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x02020202UL; /* R2 */ + *pxTopOfStack = ( StackType_t ) 0x02020202UL; /* R2. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x01010101UL; /* R1 */ + *pxTopOfStack = ( StackType_t ) 0x01010101UL; /* R1. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x11111111UL; /* R11 */ + *pxTopOfStack = ( StackType_t ) 0x11111111UL; /* R11. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x10101010UL; /* R10 */ + *pxTopOfStack = ( StackType_t ) 0x10101010UL; /* R10. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x09090909UL; /* R09 */ + *pxTopOfStack = ( StackType_t ) 0x09090909UL; /* R09. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x08080808UL; /* R08 */ + *pxTopOfStack = ( StackType_t ) 0x08080808UL; /* R08. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x07070707UL; /* R07 */ + *pxTopOfStack = ( StackType_t ) 0x07070707UL; /* R07. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x06060606UL; /* R06 */ + *pxTopOfStack = ( StackType_t ) 0x06060606UL; /* R06. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x05050505UL; /* R05 */ + *pxTopOfStack = ( StackType_t ) 0x05050505UL; /* R05. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x04040404UL; /* R04 */ + *pxTopOfStack = ( StackType_t ) 0x04040404UL; /* R04. */ pxTopOfStack--; - *pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN */ - - #if ( configENABLE_MPU == 1 ) - { - pxTopOfStack--; - - if( xRunPrivileged == pdTRUE ) - { - *pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */ - } - else - { - *pxTopOfStack = portINITIAL_CONTROL_UNPRIVILEGED; /* Slot used to hold this task's CONTROL value. */ - } - } - #endif /* configENABLE_MPU */ - + *pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN. */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ @@ -1092,6 +1608,8 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO return pxTopOfStack; } + +#endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ @@ -1128,6 +1646,10 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ configASSERT( ucMaxSysCallPriority ); + /* Check that the bits not implemented in hardware are zero in + * configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & ( ~ucMaxPriorityValue ) ) == 0U ); + /* Calculate the maximum acceptable priority group value for the number * of bits read back. */ @@ -1164,35 +1686,6 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulImplementedPrioBits; } - /* The interrupt priority bits are not modelled in QEMU and the assert that - * checks the number of implemented bits and __NVIC_PRIO_BITS will always fail. - * Therefore, this assert is not adding any value for QEMU targets. The config - * option `configDISABLE_INTERRUPT_PRIO_BITS_CHECK` should be defined in the - * `FreeRTOSConfig.h` for QEMU targets. */ - #ifndef configDISABLE_INTERRUPT_PRIO_BITS_CHECK - { - #ifdef __NVIC_PRIO_BITS - { - /* - * Check that the number of implemented priority bits queried from - * hardware is equal to the CMSIS __NVIC_PRIO_BITS configuration macro. - */ - configASSERT( ulImplementedPrioBits == __NVIC_PRIO_BITS ); - } - #endif /* __NVIC_PRIO_BITS */ - - #ifdef configPRIO_BITS - { - /* - * Check that the number of implemented priority bits queried from - * hardware is equal to the FreeRTOS configPRIO_BITS configuration macro. - */ - configASSERT( ulImplementedPrioBits == configPRIO_BITS ); - } - #endif /* configPRIO_BITS */ - } - #endif /* #ifndef configDISABLE_INTERRUPT_PRIO_BITS_CHECK */ - /* Shift the priority group value back to its position within the AIRCR * register. */ ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT; @@ -1372,6 +1865,54 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ +#if ( configENABLE_MPU == 1 ) + BaseType_t xPortIsAuthorizedToAccessBuffer( const void * pvBuffer, + uint32_t ulBufferLength, + uint32_t ulAccessRequested ) /* PRIVILEGED_FUNCTION */ + + { + uint32_t i, ulBufferStartAddress, ulBufferEndAddress; + BaseType_t xAccessGranted = pdFALSE; + const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */ + + if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) + { + xAccessGranted = pdTRUE; + } + else + { + if( portADD_UINT32_WILL_OVERFLOW( ( ( uint32_t ) pvBuffer ), ( ulBufferLength - 1UL ) ) == pdFALSE ) + { + ulBufferStartAddress = ( uint32_t ) pvBuffer; + ulBufferEndAddress = ( ( ( uint32_t ) pvBuffer ) + ulBufferLength - 1UL ); + + for( i = 0; i < portTOTAL_NUM_REGIONS; i++ ) + { + /* Is the MPU region enabled? */ + if( ( xTaskMpuSettings->xRegionsSettings[ i ].ulRLAR & portMPU_RLAR_REGION_ENABLE ) == portMPU_RLAR_REGION_ENABLE ) + { + if( portIS_ADDRESS_WITHIN_RANGE( ulBufferStartAddress, + portEXTRACT_FIRST_ADDRESS_FROM_RBAR( xTaskMpuSettings->xRegionsSettings[ i ].ulRBAR ), + portEXTRACT_LAST_ADDRESS_FROM_RLAR( xTaskMpuSettings->xRegionsSettings[ i ].ulRLAR ) ) && + portIS_ADDRESS_WITHIN_RANGE( ulBufferEndAddress, + portEXTRACT_FIRST_ADDRESS_FROM_RBAR( xTaskMpuSettings->xRegionsSettings[ i ].ulRBAR ), + portEXTRACT_LAST_ADDRESS_FROM_RLAR( xTaskMpuSettings->xRegionsSettings[ i ].ulRLAR ) ) && + portIS_AUTHORIZED( ulAccessRequested, + prvGetRegionAccessPermissions( xTaskMpuSettings->xRegionsSettings[ i ].ulRBAR ) ) ) + { + xAccessGranted = pdTRUE; + break; + } + } + } + } + } + + return xAccessGranted; + } +#endif /* configENABLE_MPU */ +/*-----------------------------------------------------------*/ + BaseType_t xPortIsInsideInterrupt( void ) { uint32_t ulCurrentInterrupt; diff --git a/portable/GCC/ARM_CM55_NTZ/non_secure/portasm.c b/portable/GCC/ARM_CM55_NTZ/non_secure/portasm.c index a78529d04d9..504b6bf3be3 100644 --- a/portable/GCC/ARM_CM55_NTZ/non_secure/portasm.c +++ b/portable/GCC/ARM_CM55_NTZ/non_secure/portasm.c @@ -40,6 +40,88 @@ * header files. */ #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE +#if ( configENABLE_MPU == 1 ) + +void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ +{ + __asm volatile + ( + " .syntax unified \n" + " \n" + " program_mpu_first_task: \n" + " ldr r2, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r0, [r2] \n" /* r0 = pxCurrentTCB. */ + " \n" + " dmb \n" /* Complete outstanding transfers before disabling MPU. */ + " ldr r1, xMPUCTRLConst2 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ + " bic r2, #1 \n" /* r2 = r2 & ~1 i.e. Clear the bit 0 in r2. */ + " str r2, [r1] \n" /* Disable MPU. */ + " \n" + " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */ + " ldr r1, [r0] \n" /* r1 = *r0 i.e. r1 = MAIR0. */ + " ldr r2, xMAIR0Const2 \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */ + " str r1, [r2] \n" /* Program MAIR0. */ + " \n" + " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */ + " ldr r1, xRNRConst2 \n" /* r1 = 0xe000ed98 [Location of RNR]. */ + " ldr r2, xRBARConst2 \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ + " \n" + " movs r3, #4 \n" /* r3 = 4. */ + " str r3, [r1] \n" /* Program RNR = 4. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + " \n" + #if ( configTOTAL_MPU_REGIONS == 16 ) + " movs r3, #8 \n" /* r3 = 8. */ + " str r3, [r1] \n" /* Program RNR = 8. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + " movs r3, #12 \n" /* r3 = 12. */ + " str r3, [r1] \n" /* Program RNR = 12. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + #endif /* configTOTAL_MPU_REGIONS == 16 */ + " \n" + " ldr r1, xMPUCTRLConst2 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ + " orr r2, #1 \n" /* r2 = r2 | 1 i.e. Set the bit 0 in r2. */ + " str r2, [r1] \n" /* Enable MPU. */ + " dsb \n" /* Force memory writes before continuing. */ + " \n" + " restore_context_first_task: \n" + " ldr r2, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r0, [r2] \n" /* r0 = pxCurrentTCB.*/ + " ldr r1, [r0] \n" /* r1 = Location of saved context in TCB. */ + " \n" + " restore_special_regs_first_task: \n" + " ldmdb r1!, {r2-r4, lr} \n" /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */ + " msr psp, r2 \n" + " msr psplim, r3 \n" + " msr control, r4 \n" + " \n" + " restore_general_regs_first_task: \n" + " ldmdb r1!, {r4-r11} \n" /* r4-r11 contain hardware saved context. */ + " stmia r2!, {r4-r11} \n" /* Copy the hardware saved context on the task stack. */ + " ldmdb r1!, {r4-r11} \n" /* r4-r11 restored. */ + " \n" + " restore_context_done_first_task: \n" + " str r1, [r0] \n" /* Save the location where the context should be saved next as the first member of TCB. */ + " mov r0, #0 \n" + " msr basepri, r0 \n" /* Ensure that interrupts are enabled when the first task starts. */ + " bx lr \n" + " \n" + " .align 4 \n" + " pxCurrentTCBConst2: .word pxCurrentTCB \n" + " xMPUCTRLConst2: .word 0xe000ed94 \n" + " xMAIR0Const2: .word 0xe000edc0 \n" + " xRNRConst2: .word 0xe000ed98 \n" + " xRBARConst2: .word 0xe000ed9c \n" + ); +} + +#else /* configENABLE_MPU */ + void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ { __asm volatile @@ -50,80 +132,23 @@ void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_ " ldr r1, [r2] \n"/* Read pxCurrentTCB. */ " ldr r0, [r1] \n"/* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ " \n" - #if ( configENABLE_MPU == 1 ) - " dmb \n"/* Complete outstanding transfers before disabling MPU. */ - " ldr r2, xMPUCTRLConst2 \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ - " ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */ - " bic r4, #1 \n"/* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */ - " str r4, [r2] \n"/* Disable MPU. */ - " \n" - " adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */ - " ldr r3, [r1] \n"/* r3 = *r1 i.e. r3 = MAIR0. */ - " ldr r2, xMAIR0Const2 \n"/* r2 = 0xe000edc0 [Location of MAIR0]. */ - " str r3, [r2] \n"/* Program MAIR0. */ - " ldr r2, xRNRConst2 \n"/* r2 = 0xe000ed98 [Location of RNR]. */ - " movs r3, #4 \n"/* r3 = 4. */ - " str r3, [r2] \n"/* Program RNR = 4. */ - " adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to first RBAR in TCB. */ - " ldr r2, xRBARConst2 \n"/* r2 = 0xe000ed9c [Location of RBAR]. */ - " ldmia r1!, {r4-r11} \n"/* Read 4 set of RBAR/RLAR registers from TCB. */ - " stmia r2!, {r4-r11} \n"/* Write 4 set of RBAR/RLAR registers using alias registers. */ - " \n" - #if ( configTOTAL_MPU_REGIONS == 16 ) - " ldr r2, xRNRConst2 \n"/* r2 = 0xe000ed98 [Location of RNR]. */ - " movs r3, #8 \n"/* r3 = 8. */ - " str r3, [r2] \n"/* Program RNR = 8. */ - " ldr r2, xRBARConst2 \n"/* r2 = 0xe000ed9c [Location of RBAR]. */ - " ldmia r1!, {r4-r11} \n"/* Read 4 set of RBAR/RLAR registers from TCB. */ - " stmia r2!, {r4-r11} \n"/* Write 4 set of RBAR/RLAR registers using alias registers. */ - " ldr r2, xRNRConst2 \n"/* r2 = 0xe000ed98 [Location of RNR]. */ - " movs r3, #12 \n"/* r3 = 12. */ - " str r3, [r2] \n"/* Program RNR = 12. */ - " ldr r2, xRBARConst2 \n"/* r2 = 0xe000ed9c [Location of RBAR]. */ - " ldmia r1!, {r4-r11} \n"/* Read 4 set of RBAR/RLAR registers from TCB. */ - " stmia r2!, {r4-r11} \n"/* Write 4 set of RBAR/RLAR registers using alias registers. */ - #endif /* configTOTAL_MPU_REGIONS == 16 */ - " \n" - " ldr r2, xMPUCTRLConst2 \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ - " ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */ - " orr r4, #1 \n"/* r4 = r4 | 1 i.e. Set the bit 0 in r4. */ - " str r4, [r2] \n"/* Enable MPU. */ - " dsb \n"/* Force memory writes before continuing. */ - #endif /* configENABLE_MPU */ - " \n" - #if ( configENABLE_MPU == 1 ) - " ldm r0!, {r1-r3} \n"/* Read from stack - r1 = PSPLIM, r2 = CONTROL and r3 = EXC_RETURN. */ - " msr psplim, r1 \n"/* Set this task's PSPLIM value. */ - " msr control, r2 \n"/* Set this task's CONTROL value. */ - " adds r0, #32 \n"/* Discard everything up to r0. */ - " msr psp, r0 \n"/* This is now the new top of stack to use in the task. */ - " isb \n" - " mov r0, #0 \n" - " msr basepri, r0 \n"/* Ensure that interrupts are enabled when the first task starts. */ - " bx r3 \n"/* Finally, branch to EXC_RETURN. */ - #else /* configENABLE_MPU */ - " ldm r0!, {r1-r2} \n"/* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */ - " msr psplim, r1 \n"/* Set this task's PSPLIM value. */ - " movs r1, #2 \n"/* r1 = 2. */ - " msr CONTROL, r1 \n"/* Switch to use PSP in the thread mode. */ - " adds r0, #32 \n"/* Discard everything up to r0. */ - " msr psp, r0 \n"/* This is now the new top of stack to use in the task. */ - " isb \n" - " mov r0, #0 \n" - " msr basepri, r0 \n"/* Ensure that interrupts are enabled when the first task starts. */ - " bx r2 \n"/* Finally, branch to EXC_RETURN. */ - #endif /* configENABLE_MPU */ + " ldm r0!, {r1-r2} \n"/* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */ + " msr psplim, r1 \n"/* Set this task's PSPLIM value. */ + " movs r1, #2 \n"/* r1 = 2. */ + " msr CONTROL, r1 \n"/* Switch to use PSP in the thread mode. */ + " adds r0, #32 \n"/* Discard everything up to r0. */ + " msr psp, r0 \n"/* This is now the new top of stack to use in the task. */ + " isb \n" + " mov r0, #0 \n" + " msr basepri, r0 \n"/* Ensure that interrupts are enabled when the first task starts. */ + " bx r2 \n"/* Finally, branch to EXC_RETURN. */ " \n" " .align 4 \n" "pxCurrentTCBConst2: .word pxCurrentTCB \n" - #if ( configENABLE_MPU == 1 ) - "xMPUCTRLConst2: .word 0xe000ed94 \n" - "xMAIR0Const2: .word 0xe000edc0 \n" - "xRNRConst2: .word 0xe000ed98 \n" - "xRBARConst2: .word 0xe000ed9c \n" - #endif /* configENABLE_MPU */ ); } + +#endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */ @@ -231,6 +256,129 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att } /*-----------------------------------------------------------*/ +#if ( configENABLE_MPU == 1 ) + +void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ +{ + __asm volatile + ( + " .syntax unified \n" + " \n" + " ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r0, [r2] \n" /* r0 = pxCurrentTCB. */ + " ldr r1, [r0] \n" /* r1 = Location in TCB where the context should be saved. */ + " mrs r2, psp \n" /* r2 = PSP. */ + " \n" + " save_general_regs: \n" + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + " add r2, r2, #0x20 \n" /* Move r2 to location where s0 is saved. */ + " tst lr, #0x10 \n" + " ittt eq \n" + " vstmiaeq r1!, {s16-s31} \n" /* Store s16-s31. */ + " vldmiaeq r2, {s0-s16} \n" /* Copy hardware saved FP context into s0-s16. */ + " vstmiaeq r1!, {s0-s16} \n" /* Store hardware saved FP context. */ + " sub r2, r2, #0x20 \n" /* Set r2 back to the location of hardware saved context. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ + " \n" + " stmia r1!, {r4-r11} \n" /* Store r4-r11. */ + " ldmia r2, {r4-r11} \n" /* Copy the hardware saved context into r4-r11. */ + " stmia r1!, {r4-r11} \n" /* Store the hardware saved context. */ + " \n" + " save_special_regs: \n" + " mrs r3, psplim \n" /* r3 = PSPLIM. */ + " mrs r4, control \n" /* r4 = CONTROL. */ + " stmia r1!, {r2-r4, lr} \n" /* Store original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */ + " str r1, [r0] \n" /* Save the location from where the context should be restored as the first member of TCB. */ + " \n" + " select_next_task: \n" + " mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */ + " msr basepri, r0 \n" /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + " dsb \n" + " isb \n" + " bl vTaskSwitchContext \n" + " mov r0, #0 \n" /* r0 = 0. */ + " msr basepri, r0 \n" /* Enable interrupts. */ + " \n" + " program_mpu: \n" + " ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r0, [r2] \n" /* r0 = pxCurrentTCB. */ + " \n" + " dmb \n" /* Complete outstanding transfers before disabling MPU. */ + " ldr r1, xMPUCTRLConst \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ + " bic r2, #1 \n" /* r2 = r2 & ~1 i.e. Clear the bit 0 in r2. */ + " str r2, [r1] \n" /* Disable MPU. */ + " \n" + " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */ + " ldr r1, [r0] \n" /* r1 = *r0 i.e. r1 = MAIR0. */ + " ldr r2, xMAIR0Const \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */ + " str r1, [r2] \n" /* Program MAIR0. */ + " \n" + " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */ + " ldr r1, xRNRConst \n" /* r1 = 0xe000ed98 [Location of RNR]. */ + " ldr r2, xRBARConst \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ + " \n" + " movs r3, #4 \n" /* r3 = 4. */ + " str r3, [r1] \n" /* Program RNR = 4. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + " \n" + #if ( configTOTAL_MPU_REGIONS == 16 ) + " movs r3, #8 \n" /* r3 = 8. */ + " str r3, [r1] \n" /* Program RNR = 8. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + " movs r3, #12 \n" /* r3 = 12. */ + " str r3, [r1] \n" /* Program RNR = 12. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + #endif /* configTOTAL_MPU_REGIONS == 16 */ + " \n" + " ldr r1, xMPUCTRLConst \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ + " orr r2, #1 \n" /* r2 = r2 | 1 i.e. Set the bit 0 in r2. */ + " str r2, [r1] \n" /* Enable MPU. */ + " dsb \n" /* Force memory writes before continuing. */ + " \n" + " restore_context: \n" + " ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r0, [r2] \n" /* r0 = pxCurrentTCB.*/ + " ldr r1, [r0] \n" /* r1 = Location of saved context in TCB. */ + " \n" + " restore_special_regs: \n" + " ldmdb r1!, {r2-r4, lr} \n" /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */ + " msr psp, r2 \n" + " msr psplim, r3 \n" + " msr control, r4 \n" + " \n" + " restore_general_regs: \n" + " ldmdb r1!, {r4-r11} \n" /* r4-r11 contain hardware saved context. */ + " stmia r2!, {r4-r11} \n" /* Copy the hardware saved context on the task stack. */ + " ldmdb r1!, {r4-r11} \n" /* r4-r11 restored. */ + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + " tst lr, #0x10 \n" + " ittt eq \n" + " vldmdbeq r1!, {s0-s16} \n" /* s0-s16 contain hardware saved FP context. */ + " vstmiaeq r2!, {s0-s16} \n" /* Copy hardware saved FP context on the task stack. */ + " vldmdbeq r1!, {s16-s31} \n" /* Restore s16-s31. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ + " \n" + " restore_context_done: \n" + " str r1, [r0] \n" /* Save the location where the context should be saved next as the first member of TCB. */ + " bx lr \n" + " \n" + " .align 4 \n" + " pxCurrentTCBConst: .word pxCurrentTCB \n" + " xMPUCTRLConst: .word 0xe000ed94 \n" + " xMAIR0Const: .word 0xe000edc0 \n" + " xRNRConst: .word 0xe000ed98 \n" + " xRBARConst: .word 0xe000ed9c \n" + ::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) + ); +} + +#else /* configENABLE_MPU */ + void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ { __asm volatile @@ -238,21 +386,16 @@ void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ " .syntax unified \n" " \n" " mrs r0, psp \n"/* Read PSP in r0. */ + " \n" #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) " tst lr, #0x10 \n"/* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ " it eq \n" " vstmdbeq r0!, {s16-s31} \n"/* Store the additional FP context registers which are not saved automatically. */ #endif /* configENABLE_FPU || configENABLE_MVE */ - #if ( configENABLE_MPU == 1 ) - " mrs r1, psplim \n"/* r1 = PSPLIM. */ - " mrs r2, control \n"/* r2 = CONTROL. */ - " mov r3, lr \n"/* r3 = LR/EXC_RETURN. */ - " stmdb r0!, {r1-r11} \n"/* Store on the stack - PSPLIM, CONTROL, LR and registers that are not automatically saved. */ - #else /* configENABLE_MPU */ - " mrs r2, psplim \n"/* r2 = PSPLIM. */ - " mov r3, lr \n"/* r3 = LR/EXC_RETURN. */ - " stmdb r0!, {r2-r11} \n"/* Store on the stack - PSPLIM, LR and registers that are not automatically saved. */ - #endif /* configENABLE_MPU */ + " \n" + " mrs r2, psplim \n"/* r2 = PSPLIM. */ + " mov r3, lr \n"/* r3 = LR/EXC_RETURN. */ + " stmdb r0!, {r2-r11} \n"/* Store on the stack - PSPLIM, LR and registers that are not automatically saved. */ " \n" " ldr r2, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r2] \n"/* Read pxCurrentTCB. */ @@ -270,52 +413,7 @@ void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ " ldr r1, [r2] \n"/* Read pxCurrentTCB. */ " ldr r0, [r1] \n"/* The first item in pxCurrentTCB is the task top of stack. r0 now points to the top of stack. */ " \n" - #if ( configENABLE_MPU == 1 ) - " dmb \n"/* Complete outstanding transfers before disabling MPU. */ - " ldr r2, xMPUCTRLConst \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ - " ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */ - " bic r4, #1 \n"/* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */ - " str r4, [r2] \n"/* Disable MPU. */ - " \n" - " adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */ - " ldr r3, [r1] \n"/* r3 = *r1 i.e. r3 = MAIR0. */ - " ldr r2, xMAIR0Const \n"/* r2 = 0xe000edc0 [Location of MAIR0]. */ - " str r3, [r2] \n"/* Program MAIR0. */ - " ldr r2, xRNRConst \n"/* r2 = 0xe000ed98 [Location of RNR]. */ - " movs r3, #4 \n"/* r3 = 4. */ - " str r3, [r2] \n"/* Program RNR = 4. */ - " adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to first RBAR in TCB. */ - " ldr r2, xRBARConst \n"/* r2 = 0xe000ed9c [Location of RBAR]. */ - " ldmia r1!, {r4-r11} \n"/* Read 4 sets of RBAR/RLAR registers from TCB. */ - " stmia r2!, {r4-r11} \n"/* Write 4 set of RBAR/RLAR registers using alias registers. */ - " \n" - #if ( configTOTAL_MPU_REGIONS == 16 ) - " ldr r2, xRNRConst \n"/* r2 = 0xe000ed98 [Location of RNR]. */ - " movs r3, #8 \n"/* r3 = 8. */ - " str r3, [r2] \n"/* Program RNR = 8. */ - " ldr r2, xRBARConst \n"/* r2 = 0xe000ed9c [Location of RBAR]. */ - " ldmia r1!, {r4-r11} \n"/* Read 4 sets of RBAR/RLAR registers from TCB. */ - " stmia r2!, {r4-r11} \n"/* Write 4 set of RBAR/RLAR registers using alias registers. */ - " ldr r2, xRNRConst \n"/* r2 = 0xe000ed98 [Location of RNR]. */ - " movs r3, #12 \n"/* r3 = 12. */ - " str r3, [r2] \n"/* Program RNR = 12. */ - " ldr r2, xRBARConst \n"/* r2 = 0xe000ed9c [Location of RBAR]. */ - " ldmia r1!, {r4-r11} \n"/* Read 4 sets of RBAR/RLAR registers from TCB. */ - " stmia r2!, {r4-r11} \n"/* Write 4 set of RBAR/RLAR registers using alias registers. */ - #endif /* configTOTAL_MPU_REGIONS == 16 */ - " \n" - " ldr r2, xMPUCTRLConst \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ - " ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */ - " orr r4, #1 \n"/* r4 = r4 | 1 i.e. Set the bit 0 in r4. */ - " str r4, [r2] \n"/* Enable MPU. */ - " dsb \n"/* Force memory writes before continuing. */ - #endif /* configENABLE_MPU */ - " \n" - #if ( configENABLE_MPU == 1 ) - " ldmia r0!, {r1-r11} \n"/* Read from stack - r1 = PSPLIM, r2 = CONTROL, r3 = LR and r4-r11 restored. */ - #else /* configENABLE_MPU */ - " ldmia r0!, {r2-r11} \n"/* Read from stack - r2 = PSPLIM, r3 = LR and r4-r11 restored. */ - #endif /* configENABLE_MPU */ + " ldmia r0!, {r2-r11} \n"/* Read from stack - r2 = PSPLIM, r3 = LR and r4-r11 restored. */ " \n" #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) " tst r3, #0x10 \n"/* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ @@ -323,28 +421,66 @@ void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ " vldmiaeq r0!, {s16-s31} \n"/* Restore the additional FP context registers which are not restored automatically. */ #endif /* configENABLE_FPU || configENABLE_MVE */ " \n" - #if ( configENABLE_MPU == 1 ) - " msr psplim, r1 \n"/* Restore the PSPLIM register value for the task. */ - " msr control, r2 \n"/* Restore the CONTROL register value for the task. */ - #else /* configENABLE_MPU */ - " msr psplim, r2 \n"/* Restore the PSPLIM register value for the task. */ - #endif /* configENABLE_MPU */ + " msr psplim, r2 \n"/* Restore the PSPLIM register value for the task. */ " msr psp, r0 \n"/* Remember the new top of stack for the task. */ " bx r3 \n" " \n" " .align 4 \n" "pxCurrentTCBConst: .word pxCurrentTCB \n" - #if ( configENABLE_MPU == 1 ) - "xMPUCTRLConst: .word 0xe000ed94 \n" - "xMAIR0Const: .word 0xe000edc0 \n" - "xRNRConst: .word 0xe000ed98 \n" - "xRBARConst: .word 0xe000ed9c \n" - #endif /* configENABLE_MPU */ ::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) ); } + +#endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + +void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ +{ + __asm volatile + ( + ".syntax unified \n" + ".extern vPortSVCHandler_C \n" + ".extern vSystemCallEnter \n" + ".extern vSystemCallEnter_1 \n" + ".extern vSystemCallExit \n" + " \n" + "tst lr, #4 \n" + "ite eq \n" + "mrseq r0, msp \n" + "mrsne r0, psp \n" + " \n" + "ldr r1, [r0, #24] \n" + "ldrb r2, [r1, #-2] \n" + "cmp r2, %0 \n" + "beq syscall_enter \n" + "cmp r2, %1 \n" + "beq syscall_enter_1 \n" + "cmp r2, %2 \n" + "beq syscall_exit \n" + "b vPortSVCHandler_C \n" + " \n" + "syscall_enter: \n" + " mov r1, lr \n" + " b vSystemCallEnter \n" + " \n" + "syscall_enter_1: \n" + " mov r1, lr \n" + " b vSystemCallEnter_1 \n" + " \n" + "syscall_exit: \n" + " mov r1, lr \n" + " b vSystemCallExit \n" + " \n" + : /* No outputs. */ + :"i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_ENTER_1 ), "i" ( portSVC_SYSTEM_CALL_EXIT ) + : "r0", "r1", "r2", "memory" + ); +} + +#else /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ { __asm volatile @@ -362,4 +498,6 @@ void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ "svchandler_address_const: .word vPortSVCHandler_C \n" ); } + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ /*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM55_NTZ/non_secure/portmacro.h b/portable/GCC/ARM_CM55_NTZ/non_secure/portmacro.h index c9bad40cf98..12bb5e7c4b9 100644 --- a/portable/GCC/ARM_CM55_NTZ/non_secure/portmacro.h +++ b/portable/GCC/ARM_CM55_NTZ/non_secure/portmacro.h @@ -56,7 +56,6 @@ #define portARCH_NAME "Cortex-M55" #define portHAS_BASEPRI 1 #define portDONT_DISCARD __attribute__( ( used ) ) -#define portNORETURN __attribute__( ( noreturn ) ) /*-----------------------------------------------------------*/ /* ARMv8-M common port configurations. */ diff --git a/portable/GCC/ARM_CM55_NTZ/non_secure/portmacrocommon.h b/portable/GCC/ARM_CM55_NTZ/non_secure/portmacrocommon.h index c2ca5fa7730..65ac109c802 100644 --- a/portable/GCC/ARM_CM55_NTZ/non_secure/portmacrocommon.h +++ b/portable/GCC/ARM_CM55_NTZ/non_secure/portmacrocommon.h @@ -186,23 +186,120 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #define portMPU_REGION_EXECUTE_NEVER ( 1UL ) /*-----------------------------------------------------------*/ -/** - * @brief Settings to define an MPU region. - */ -typedef struct MPURegionSettings -{ - uint32_t ulRBAR; /**< RBAR for the region. */ - uint32_t ulRLAR; /**< RLAR for the region. */ -} MPURegionSettings_t; +#if ( configENABLE_MPU == 1 ) -/** - * @brief MPU settings as stored in the TCB. - */ -typedef struct MPU_SETTINGS -{ - uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ - MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */ -} xMPU_SETTINGS; + /** + * @brief Settings to define an MPU region. + */ + typedef struct MPURegionSettings + { + uint32_t ulRBAR; /**< RBAR for the region. */ + uint32_t ulRLAR; /**< RLAR for the region. */ + } MPURegionSettings_t; + + #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + + #ifndef configSYSTEM_CALL_STACK_SIZE + #error configSYSTEM_CALL_STACK_SIZE must be defined to the desired size of the system call stack in words for using MPU wrappers v2. + #endif + + /** + * @brief System call stack. + */ + typedef struct SYSTEM_CALL_STACK_INFO + { + uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ]; + uint32_t * pulSystemCallStack; + uint32_t * pulSystemCallStackLimit; + uint32_t * pulTaskStack; + uint32_t ulLinkRegisterAtSystemCallEntry; + uint32_t ulStackLimitRegisterAtSystemCallEntry; + } xSYSTEM_CALL_STACK_INFO; + + #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + + /** + * @brief MPU settings as stored in the TCB. + */ + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + + #if( configENABLE_TRUSTZONE == 1 ) + + /* + * +-----------+---------------+----------+-----------------+------------------------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | + * | | | | PC, xPSR | CONTROL, EXC_RETURN | | + * +-----------+---------------+----------+-----------------+------------------------------+-----+ + * + * <-----------><--------------><---------><----------------><-----------------------------><----> + * 16 16 8 8 5 1 + */ + #define MAX_CONTEXT_SIZE 54 + + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ + + /* + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | + * | | | | PC, xPSR | EXC_RETURN | | + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * + * <-----------><--------------><---------><----------------><---------------------><----> + * 16 16 8 8 4 1 + */ + #define MAX_CONTEXT_SIZE 53 + + #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + + #else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ + + #if( configENABLE_TRUSTZONE == 1 ) + + /* + * +----------+-----------------+------------------------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | + * | | PC, xPSR | CONTROL, EXC_RETURN | | + * +----------+-----------------+------------------------------+-----+ + * + * <---------><----------------><------------------------------><----> + * 8 8 5 1 + */ + #define MAX_CONTEXT_SIZE 22 + + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ + + /* + * +----------+-----------------+----------------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | + * | | PC, xPSR | EXC_RETURN | | + * +----------+-----------------+----------------------+-----+ + * + * <---------><----------------><----------------------><----> + * 8 8 4 1 + */ + #define MAX_CONTEXT_SIZE 21 + + #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + + #endif /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ + + /* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ + #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) + #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) + + typedef struct MPU_SETTINGS + { + uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ + MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */ + uint32_t ulContext[ MAX_CONTEXT_SIZE ]; + uint32_t ulTaskFlags; + + #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo; + #endif + } xMPU_SETTINGS; + +#endif /* configENABLE_MPU == 1 */ /*-----------------------------------------------------------*/ /** @@ -223,6 +320,9 @@ typedef struct MPU_SETTINGS #define portSVC_FREE_SECURE_CONTEXT 1 #define portSVC_START_SCHEDULER 2 #define portSVC_RAISE_PRIVILEGE 3 +#define portSVC_SYSTEM_CALL_ENTER 4 /* System calls with upto 4 parameters. */ +#define portSVC_SYSTEM_CALL_ENTER_1 5 /* System calls with 5 parameters. */ +#define portSVC_SYSTEM_CALL_EXIT 6 /*-----------------------------------------------------------*/ /** @@ -315,6 +415,20 @@ typedef struct MPU_SETTINGS #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ +#if ( configENABLE_MPU == 1 ) + + extern BaseType_t xPortIsTaskPrivileged( void ); + + /** + * @brief Checks whether or not the calling task is privileged. + * + * @return pdTRUE if the calling task is privileged, pdFALSE otherwise. + */ + #define portIS_TASK_PRIVILEGED() xPortIsTaskPrivileged() + +#endif /* configENABLE_MPU == 1 */ +/*-----------------------------------------------------------*/ + /** * @brief Barriers. */ diff --git a/portable/GCC/ARM_CM7/r0p1/port.c b/portable/GCC/ARM_CM7/r0p1/port.c index 2be4f27704d..aab077d7639 100755 --- a/portable/GCC/ARM_CM7/r0p1/port.c +++ b/portable/GCC/ARM_CM7/r0p1/port.c @@ -323,6 +323,10 @@ BaseType_t xPortStartScheduler( void ) * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ configASSERT( ucMaxSysCallPriority ); + /* Check that the bits not implemented in hardware are zero in + * configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & ( ~ucMaxPriorityValue ) ) == 0U ); + /* Calculate the maximum acceptable priority group value for the number * of bits read back. */ @@ -359,28 +363,6 @@ BaseType_t xPortStartScheduler( void ) ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulImplementedPrioBits; } - #ifdef __NVIC_PRIO_BITS - { - /* - * Check that the number of implemented priority bits queried from - * hardware is at least as many as specified in the CMSIS - * __NVIC_PRIO_BITS configuration macro. - */ - configASSERT( ulImplementedPrioBits >= __NVIC_PRIO_BITS ); - } - #endif - - #ifdef configPRIO_BITS - { - /* - * Check that the number of implemented priority bits queried from - * hardware is at least as many as specified in the FreeRTOS - * configPRIO_BITS configuration macro. - */ - configASSERT( ulImplementedPrioBits >= configPRIO_BITS ); - } - #endif - /* Shift the priority group value back to its position within the AIRCR * register. */ ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT; diff --git a/portable/GCC/ARM_CM7/r0p1/portmacro.h b/portable/GCC/ARM_CM7/r0p1/portmacro.h index 82529f998ad..f433beb52d0 100644 --- a/portable/GCC/ARM_CM7/r0p1/portmacro.h +++ b/portable/GCC/ARM_CM7/r0p1/portmacro.h @@ -79,7 +79,6 @@ #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) #define portBYTE_ALIGNMENT 8 #define portDONT_DISCARD __attribute__( ( used ) ) - #define portNORETURN __attribute__( ( noreturn ) ) /*-----------------------------------------------------------*/ /* Scheduler utilities. */ diff --git a/portable/GCC/ARM_CM85/non_secure/mpu_wrappers_v2_asm.c b/portable/GCC/ARM_CM85/non_secure/mpu_wrappers_v2_asm.c new file mode 100644 index 00000000000..6e2043427fe --- /dev/null +++ b/portable/GCC/ARM_CM85/non_secure/mpu_wrappers_v2_asm.c @@ -0,0 +1,2349 @@ +/* + * FreeRTOS Kernel + * Copyright (C) 2021 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 + * + */ + +/* 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. */ +#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +/* Scheduler includes. */ +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" +#include "timers.h" +#include "event_groups.h" +#include "stream_buffer.h" + +#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + +#if ( INCLUDE_xTaskDelayUntil == 1 ) + +BaseType_t MPU_xTaskDelayUntil( TickType_t * const pxPreviousWakeTime, + const TickType_t xTimeIncrement ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskDelayUntil( TickType_t * const pxPreviousWakeTime, + const TickType_t xTimeIncrement ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskDelayUntilImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskDelayUntil_Unpriv \n" + " MPU_xTaskDelayUntil_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskDelayUntilImpl \n" + " MPU_xTaskDelayUntil_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskDelayUntilImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_xTaskDelayUntil == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_xTaskAbortDelay == 1 ) + +BaseType_t MPU_xTaskAbortDelay( TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskAbortDelay( TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskAbortDelayImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskAbortDelay_Unpriv \n" + " MPU_xTaskAbortDelay_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskAbortDelayImpl \n" + " MPU_xTaskAbortDelay_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskAbortDelayImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_xTaskAbortDelay == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskDelay == 1 ) + +void MPU_vTaskDelay( const TickType_t xTicksToDelay ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskDelay( const TickType_t xTicksToDelay ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskDelayImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vTaskDelay_Unpriv \n" + " MPU_vTaskDelay_Priv: \n" + " pop {r0} \n" + " b MPU_vTaskDelayImpl \n" + " MPU_vTaskDelay_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vTaskDelayImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_vTaskDelay == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_uxTaskPriorityGet == 1 ) + +UBaseType_t MPU_uxTaskPriorityGet( const TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxTaskPriorityGet( const TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxTaskPriorityGetImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_uxTaskPriorityGet_Unpriv \n" + " MPU_uxTaskPriorityGet_Priv: \n" + " pop {r0} \n" + " b MPU_uxTaskPriorityGetImpl \n" + " MPU_uxTaskPriorityGet_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_uxTaskPriorityGetImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_uxTaskPriorityGet == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_eTaskGetState == 1 ) + +eTaskState MPU_eTaskGetState( TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +eTaskState MPU_eTaskGetState( TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_eTaskGetStateImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_eTaskGetState_Unpriv \n" + " MPU_eTaskGetState_Priv: \n" + " pop {r0} \n" + " b MPU_eTaskGetStateImpl \n" + " MPU_eTaskGetState_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_eTaskGetStateImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_eTaskGetState == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + +void MPU_vTaskGetInfo( TaskHandle_t xTask, + TaskStatus_t * pxTaskStatus, + BaseType_t xGetFreeStackSpace, + eTaskState eState ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskGetInfo( TaskHandle_t xTask, + TaskStatus_t * pxTaskStatus, + BaseType_t xGetFreeStackSpace, + eTaskState eState ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskGetInfoImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vTaskGetInfo_Unpriv \n" + " MPU_vTaskGetInfo_Priv: \n" + " pop {r0} \n" + " b MPU_vTaskGetInfoImpl \n" + " MPU_vTaskGetInfo_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vTaskGetInfoImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TRACE_FACILITY == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) + +TaskHandle_t MPU_xTaskGetIdleTaskHandle( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TaskHandle_t MPU_xTaskGetIdleTaskHandle( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGetIdleTaskHandleImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskGetIdleTaskHandle_Unpriv \n" + " MPU_xTaskGetIdleTaskHandle_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskGetIdleTaskHandleImpl \n" + " MPU_xTaskGetIdleTaskHandle_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskGetIdleTaskHandleImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskSuspend == 1 ) + +void MPU_vTaskSuspend( TaskHandle_t xTaskToSuspend ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskSuspend( TaskHandle_t xTaskToSuspend ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskSuspendImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vTaskSuspend_Unpriv \n" + " MPU_vTaskSuspend_Priv: \n" + " pop {r0} \n" + " b MPU_vTaskSuspendImpl \n" + " MPU_vTaskSuspend_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vTaskSuspendImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_vTaskSuspend == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskSuspend == 1 ) + +void MPU_vTaskResume( TaskHandle_t xTaskToResume ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskResume( TaskHandle_t xTaskToResume ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskResumeImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vTaskResume_Unpriv \n" + " MPU_vTaskResume_Priv: \n" + " pop {r0} \n" + " b MPU_vTaskResumeImpl \n" + " MPU_vTaskResume_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vTaskResumeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_vTaskSuspend == 1 ) */ +/*-----------------------------------------------------------*/ + +TickType_t MPU_xTaskGetTickCount( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TickType_t MPU_xTaskGetTickCount( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGetTickCountImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskGetTickCount_Unpriv \n" + " MPU_xTaskGetTickCount_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskGetTickCountImpl \n" + " MPU_xTaskGetTickCount_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskGetTickCountImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +UBaseType_t MPU_uxTaskGetNumberOfTasks( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxTaskGetNumberOfTasks( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxTaskGetNumberOfTasksImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_uxTaskGetNumberOfTasks_Unpriv \n" + " MPU_uxTaskGetNumberOfTasks_Priv: \n" + " pop {r0} \n" + " b MPU_uxTaskGetNumberOfTasksImpl \n" + " MPU_uxTaskGetNumberOfTasks_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_uxTaskGetNumberOfTasksImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +char * MPU_pcTaskGetName( TaskHandle_t xTaskToQuery ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +char * MPU_pcTaskGetName( TaskHandle_t xTaskToQuery ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_pcTaskGetNameImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_pcTaskGetName_Unpriv \n" + " MPU_pcTaskGetName_Priv: \n" + " pop {r0} \n" + " b MPU_pcTaskGetNameImpl \n" + " MPU_pcTaskGetName_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_pcTaskGetNameImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +#if ( configGENERATE_RUN_TIME_STATS == 1 ) + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetRunTimeCounter( const TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetRunTimeCounter( const TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_ulTaskGetRunTimeCounterImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_ulTaskGetRunTimeCounter_Unpriv \n" + " MPU_ulTaskGetRunTimeCounter_Priv: \n" + " pop {r0} \n" + " b MPU_ulTaskGetRunTimeCounterImpl \n" + " MPU_ulTaskGetRunTimeCounter_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_ulTaskGetRunTimeCounterImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( ( configGENERATE_RUN_TIME_STATS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configGENERATE_RUN_TIME_STATS == 1 ) + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetRunTimePercent( const TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetRunTimePercent( const TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_ulTaskGetRunTimePercentImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_ulTaskGetRunTimePercent_Unpriv \n" + " MPU_ulTaskGetRunTimePercent_Priv: \n" + " pop {r0} \n" + " b MPU_ulTaskGetRunTimePercentImpl \n" + " MPU_ulTaskGetRunTimePercent_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_ulTaskGetRunTimePercentImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( ( configGENERATE_RUN_TIME_STATS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimePercent( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimePercent( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_ulTaskGetIdleRunTimePercentImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_ulTaskGetIdleRunTimePercent_Unpriv \n" + " MPU_ulTaskGetIdleRunTimePercent_Priv: \n" + " pop {r0} \n" + " b MPU_ulTaskGetIdleRunTimePercentImpl \n" + " MPU_ulTaskGetIdleRunTimePercent_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_ulTaskGetIdleRunTimePercentImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimeCounter( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimeCounter( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_ulTaskGetIdleRunTimeCounterImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_ulTaskGetIdleRunTimeCounter_Unpriv \n" + " MPU_ulTaskGetIdleRunTimeCounter_Priv: \n" + " pop {r0} \n" + " b MPU_ulTaskGetIdleRunTimeCounterImpl \n" + " MPU_ulTaskGetIdleRunTimeCounter_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_ulTaskGetIdleRunTimeCounterImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_APPLICATION_TASK_TAG == 1 ) + +void MPU_vTaskSetApplicationTaskTag( TaskHandle_t xTask, + TaskHookFunction_t pxHookFunction ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskSetApplicationTaskTag( TaskHandle_t xTask, + TaskHookFunction_t pxHookFunction ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskSetApplicationTaskTagImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vTaskSetApplicationTaskTag_Unpriv \n" + " MPU_vTaskSetApplicationTaskTag_Priv: \n" + " pop {r0} \n" + " b MPU_vTaskSetApplicationTaskTagImpl \n" + " MPU_vTaskSetApplicationTaskTag_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vTaskSetApplicationTaskTagImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_APPLICATION_TASK_TAG == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_APPLICATION_TASK_TAG == 1 ) + +TaskHookFunction_t MPU_xTaskGetApplicationTaskTag( TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TaskHookFunction_t MPU_xTaskGetApplicationTaskTag( TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGetApplicationTaskTagImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskGetApplicationTaskTag_Unpriv \n" + " MPU_xTaskGetApplicationTaskTag_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskGetApplicationTaskTagImpl \n" + " MPU_xTaskGetApplicationTaskTag_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskGetApplicationTaskTagImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_APPLICATION_TASK_TAG == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) + +void MPU_vTaskSetThreadLocalStoragePointer( TaskHandle_t xTaskToSet, + BaseType_t xIndex, + void * pvValue ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskSetThreadLocalStoragePointer( TaskHandle_t xTaskToSet, + BaseType_t xIndex, + void * pvValue ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskSetThreadLocalStoragePointerImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vTaskSetThreadLocalStoragePointer_Unpriv \n" + " MPU_vTaskSetThreadLocalStoragePointer_Priv: \n" + " pop {r0} \n" + " b MPU_vTaskSetThreadLocalStoragePointerImpl \n" + " MPU_vTaskSetThreadLocalStoragePointer_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vTaskSetThreadLocalStoragePointerImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) + +void * MPU_pvTaskGetThreadLocalStoragePointer( TaskHandle_t xTaskToQuery, + BaseType_t xIndex ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void * MPU_pvTaskGetThreadLocalStoragePointer( TaskHandle_t xTaskToQuery, + BaseType_t xIndex ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_pvTaskGetThreadLocalStoragePointerImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_pvTaskGetThreadLocalStoragePointer_Unpriv \n" + " MPU_pvTaskGetThreadLocalStoragePointer_Priv: \n" + " pop {r0} \n" + " b MPU_pvTaskGetThreadLocalStoragePointerImpl \n" + " MPU_pvTaskGetThreadLocalStoragePointer_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_pvTaskGetThreadLocalStoragePointerImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + +UBaseType_t MPU_uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray, + const UBaseType_t uxArraySize, + configRUN_TIME_COUNTER_TYPE * const pulTotalRunTime ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray, + const UBaseType_t uxArraySize, + configRUN_TIME_COUNTER_TYPE * const pulTotalRunTime ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxTaskGetSystemStateImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_uxTaskGetSystemState_Unpriv \n" + " MPU_uxTaskGetSystemState_Priv: \n" + " pop {r0} \n" + " b MPU_uxTaskGetSystemStateImpl \n" + " MPU_uxTaskGetSystemState_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_uxTaskGetSystemStateImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TRACE_FACILITY == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) + +UBaseType_t MPU_uxTaskGetStackHighWaterMark( TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxTaskGetStackHighWaterMark( TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxTaskGetStackHighWaterMarkImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_uxTaskGetStackHighWaterMark_Unpriv \n" + " MPU_uxTaskGetStackHighWaterMark_Priv: \n" + " pop {r0} \n" + " b MPU_uxTaskGetStackHighWaterMarkImpl \n" + " MPU_uxTaskGetStackHighWaterMark_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_uxTaskGetStackHighWaterMarkImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) + +configSTACK_DEPTH_TYPE MPU_uxTaskGetStackHighWaterMark2( TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +configSTACK_DEPTH_TYPE MPU_uxTaskGetStackHighWaterMark2( TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxTaskGetStackHighWaterMark2Impl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_uxTaskGetStackHighWaterMark2_Unpriv \n" + " MPU_uxTaskGetStackHighWaterMark2_Priv: \n" + " pop {r0} \n" + " b MPU_uxTaskGetStackHighWaterMark2Impl \n" + " MPU_uxTaskGetStackHighWaterMark2_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_uxTaskGetStackHighWaterMark2Impl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) ) + +TaskHandle_t MPU_xTaskGetCurrentTaskHandle( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TaskHandle_t MPU_xTaskGetCurrentTaskHandle( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGetCurrentTaskHandleImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskGetCurrentTaskHandle_Unpriv \n" + " MPU_xTaskGetCurrentTaskHandle_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskGetCurrentTaskHandleImpl \n" + " MPU_xTaskGetCurrentTaskHandle_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskGetCurrentTaskHandleImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_xTaskGetSchedulerState == 1 ) + +BaseType_t MPU_xTaskGetSchedulerState( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskGetSchedulerState( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGetSchedulerStateImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskGetSchedulerState_Unpriv \n" + " MPU_xTaskGetSchedulerState_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskGetSchedulerStateImpl \n" + " MPU_xTaskGetSchedulerState_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskGetSchedulerStateImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_xTaskGetSchedulerState == 1 ) */ +/*-----------------------------------------------------------*/ + +void MPU_vTaskSetTimeOutState( TimeOut_t * const pxTimeOut ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskSetTimeOutState( TimeOut_t * const pxTimeOut ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskSetTimeOutStateImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vTaskSetTimeOutState_Unpriv \n" + " MPU_vTaskSetTimeOutState_Priv: \n" + " pop {r0} \n" + " b MPU_vTaskSetTimeOutStateImpl \n" + " MPU_vTaskSetTimeOutState_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vTaskSetTimeOutStateImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut, + TickType_t * const pxTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut, + TickType_t * const pxTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskCheckForTimeOutImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskCheckForTimeOut_Unpriv \n" + " MPU_xTaskCheckForTimeOut_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskCheckForTimeOutImpl \n" + " MPU_xTaskCheckForTimeOut_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskCheckForTimeOutImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +#if ( configUSE_TASK_NOTIFICATIONS == 1 ) + +BaseType_t MPU_xTaskGenericNotify( TaskHandle_t xTaskToNotify, + UBaseType_t uxIndexToNotify, + uint32_t ulValue, + eNotifyAction eAction, + uint32_t * pulPreviousNotificationValue ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskGenericNotify( TaskHandle_t xTaskToNotify, + UBaseType_t uxIndexToNotify, + uint32_t ulValue, + eNotifyAction eAction, + uint32_t * pulPreviousNotificationValue ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGenericNotifyImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskGenericNotify_Unpriv \n" + " MPU_xTaskGenericNotify_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskGenericNotifyImpl \n" + " MPU_xTaskGenericNotify_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskGenericNotifyImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER_1 ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TASK_NOTIFICATIONS == 1 ) + +BaseType_t MPU_xTaskGenericNotifyWait( UBaseType_t uxIndexToWaitOn, + uint32_t ulBitsToClearOnEntry, + uint32_t ulBitsToClearOnExit, + uint32_t * pulNotificationValue, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskGenericNotifyWait( UBaseType_t uxIndexToWaitOn, + uint32_t ulBitsToClearOnEntry, + uint32_t ulBitsToClearOnExit, + uint32_t * pulNotificationValue, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGenericNotifyWaitImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskGenericNotifyWait_Unpriv \n" + " MPU_xTaskGenericNotifyWait_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskGenericNotifyWaitImpl \n" + " MPU_xTaskGenericNotifyWait_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskGenericNotifyWaitImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER_1 ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TASK_NOTIFICATIONS == 1 ) + +uint32_t MPU_ulTaskGenericNotifyTake( UBaseType_t uxIndexToWaitOn, + BaseType_t xClearCountOnExit, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +uint32_t MPU_ulTaskGenericNotifyTake( UBaseType_t uxIndexToWaitOn, + BaseType_t xClearCountOnExit, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_ulTaskGenericNotifyTakeImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_ulTaskGenericNotifyTake_Unpriv \n" + " MPU_ulTaskGenericNotifyTake_Priv: \n" + " pop {r0} \n" + " b MPU_ulTaskGenericNotifyTakeImpl \n" + " MPU_ulTaskGenericNotifyTake_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_ulTaskGenericNotifyTakeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TASK_NOTIFICATIONS == 1 ) + +BaseType_t MPU_xTaskGenericNotifyStateClear( TaskHandle_t xTask, + UBaseType_t uxIndexToClear ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskGenericNotifyStateClear( TaskHandle_t xTask, + UBaseType_t uxIndexToClear ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGenericNotifyStateClearImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskGenericNotifyStateClear_Unpriv \n" + " MPU_xTaskGenericNotifyStateClear_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskGenericNotifyStateClearImpl \n" + " MPU_xTaskGenericNotifyStateClear_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskGenericNotifyStateClearImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TASK_NOTIFICATIONS == 1 ) + +uint32_t MPU_ulTaskGenericNotifyValueClear( TaskHandle_t xTask, + UBaseType_t uxIndexToClear, + uint32_t ulBitsToClear ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +uint32_t MPU_ulTaskGenericNotifyValueClear( TaskHandle_t xTask, + UBaseType_t uxIndexToClear, + uint32_t ulBitsToClear ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_ulTaskGenericNotifyValueClearImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_ulTaskGenericNotifyValueClear_Unpriv \n" + " MPU_ulTaskGenericNotifyValueClear_Priv: \n" + " pop {r0} \n" + " b MPU_ulTaskGenericNotifyValueClearImpl \n" + " MPU_ulTaskGenericNotifyValueClear_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_ulTaskGenericNotifyValueClearImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xQueueGenericSend( QueueHandle_t xQueue, + const void * const pvItemToQueue, + TickType_t xTicksToWait, + const BaseType_t xCopyPosition ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueueGenericSend( QueueHandle_t xQueue, + const void * const pvItemToQueue, + TickType_t xTicksToWait, + const BaseType_t xCopyPosition ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueGenericSendImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xQueueGenericSend_Unpriv \n" + " MPU_xQueueGenericSend_Priv: \n" + " pop {r0} \n" + " b MPU_xQueueGenericSendImpl \n" + " MPU_xQueueGenericSend_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xQueueGenericSendImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +UBaseType_t MPU_uxQueueMessagesWaiting( const QueueHandle_t xQueue ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxQueueMessagesWaiting( const QueueHandle_t xQueue ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxQueueMessagesWaitingImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_uxQueueMessagesWaiting_Unpriv \n" + " MPU_uxQueueMessagesWaiting_Priv: \n" + " pop {r0} \n" + " b MPU_uxQueueMessagesWaitingImpl \n" + " MPU_uxQueueMessagesWaiting_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_uxQueueMessagesWaitingImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +UBaseType_t MPU_uxQueueSpacesAvailable( const QueueHandle_t xQueue ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxQueueSpacesAvailable( const QueueHandle_t xQueue ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxQueueSpacesAvailableImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_uxQueueSpacesAvailable_Unpriv \n" + " MPU_uxQueueSpacesAvailable_Priv: \n" + " pop {r0} \n" + " b MPU_uxQueueSpacesAvailableImpl \n" + " MPU_uxQueueSpacesAvailable_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_uxQueueSpacesAvailableImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xQueueReceive( QueueHandle_t xQueue, + void * const pvBuffer, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueueReceive( QueueHandle_t xQueue, + void * const pvBuffer, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueReceiveImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xQueueReceive_Unpriv \n" + " MPU_xQueueReceive_Priv: \n" + " pop {r0} \n" + " b MPU_xQueueReceiveImpl \n" + " MPU_xQueueReceive_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xQueueReceiveImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xQueuePeek( QueueHandle_t xQueue, + void * const pvBuffer, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueuePeek( QueueHandle_t xQueue, + void * const pvBuffer, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueuePeekImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xQueuePeek_Unpriv \n" + " MPU_xQueuePeek_Priv: \n" + " pop {r0} \n" + " b MPU_xQueuePeekImpl \n" + " MPU_xQueuePeek_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xQueuePeekImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xQueueSemaphoreTake( QueueHandle_t xQueue, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueueSemaphoreTake( QueueHandle_t xQueue, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueSemaphoreTakeImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xQueueSemaphoreTake_Unpriv \n" + " MPU_xQueueSemaphoreTake_Priv: \n" + " pop {r0} \n" + " b MPU_xQueueSemaphoreTakeImpl \n" + " MPU_xQueueSemaphoreTake_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xQueueSemaphoreTakeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +#if ( ( configUSE_MUTEXES == 1 ) && ( INCLUDE_xSemaphoreGetMutexHolder == 1 ) ) + +TaskHandle_t MPU_xQueueGetMutexHolder( QueueHandle_t xSemaphore ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TaskHandle_t MPU_xQueueGetMutexHolder( QueueHandle_t xSemaphore ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueGetMutexHolderImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xQueueGetMutexHolder_Unpriv \n" + " MPU_xQueueGetMutexHolder_Priv: \n" + " pop {r0} \n" + " b MPU_xQueueGetMutexHolderImpl \n" + " MPU_xQueueGetMutexHolder_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xQueueGetMutexHolderImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( ( configUSE_MUTEXES == 1 ) && ( INCLUDE_xSemaphoreGetMutexHolder == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_RECURSIVE_MUTEXES == 1 ) + +BaseType_t MPU_xQueueTakeMutexRecursive( QueueHandle_t xMutex, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueueTakeMutexRecursive( QueueHandle_t xMutex, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueTakeMutexRecursiveImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xQueueTakeMutexRecursive_Unpriv \n" + " MPU_xQueueTakeMutexRecursive_Priv: \n" + " pop {r0} \n" + " b MPU_xQueueTakeMutexRecursiveImpl \n" + " MPU_xQueueTakeMutexRecursive_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xQueueTakeMutexRecursiveImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_RECURSIVE_MUTEXES == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_RECURSIVE_MUTEXES == 1 ) + +BaseType_t MPU_xQueueGiveMutexRecursive( QueueHandle_t pxMutex ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueueGiveMutexRecursive( QueueHandle_t pxMutex ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueGiveMutexRecursiveImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xQueueGiveMutexRecursive_Unpriv \n" + " MPU_xQueueGiveMutexRecursive_Priv: \n" + " pop {r0} \n" + " b MPU_xQueueGiveMutexRecursiveImpl \n" + " MPU_xQueueGiveMutexRecursive_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xQueueGiveMutexRecursiveImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_RECURSIVE_MUTEXES == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_QUEUE_SETS == 1 ) + +QueueSetMemberHandle_t MPU_xQueueSelectFromSet( QueueSetHandle_t xQueueSet, + const TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +QueueSetMemberHandle_t MPU_xQueueSelectFromSet( QueueSetHandle_t xQueueSet, + const TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueSelectFromSetImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xQueueSelectFromSet_Unpriv \n" + " MPU_xQueueSelectFromSet_Priv: \n" + " pop {r0} \n" + " b MPU_xQueueSelectFromSetImpl \n" + " MPU_xQueueSelectFromSet_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xQueueSelectFromSetImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_QUEUE_SETS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_QUEUE_SETS == 1 ) + +BaseType_t MPU_xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore, + QueueSetHandle_t xQueueSet ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore, + QueueSetHandle_t xQueueSet ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueAddToSetImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xQueueAddToSet_Unpriv \n" + " MPU_xQueueAddToSet_Priv: \n" + " pop {r0} \n" + " b MPU_xQueueAddToSetImpl \n" + " MPU_xQueueAddToSet_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xQueueAddToSetImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_QUEUE_SETS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configQUEUE_REGISTRY_SIZE > 0 ) + +void MPU_vQueueAddToRegistry( QueueHandle_t xQueue, + const char * pcName ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vQueueAddToRegistry( QueueHandle_t xQueue, + const char * pcName ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vQueueAddToRegistryImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vQueueAddToRegistry_Unpriv \n" + " MPU_vQueueAddToRegistry_Priv: \n" + " pop {r0} \n" + " b MPU_vQueueAddToRegistryImpl \n" + " MPU_vQueueAddToRegistry_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vQueueAddToRegistryImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configQUEUE_REGISTRY_SIZE > 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configQUEUE_REGISTRY_SIZE > 0 ) + +void MPU_vQueueUnregisterQueue( QueueHandle_t xQueue ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vQueueUnregisterQueue( QueueHandle_t xQueue ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vQueueUnregisterQueueImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vQueueUnregisterQueue_Unpriv \n" + " MPU_vQueueUnregisterQueue_Priv: \n" + " pop {r0} \n" + " b MPU_vQueueUnregisterQueueImpl \n" + " MPU_vQueueUnregisterQueue_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vQueueUnregisterQueueImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configQUEUE_REGISTRY_SIZE > 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configQUEUE_REGISTRY_SIZE > 0 ) + +const char * MPU_pcQueueGetName( QueueHandle_t xQueue ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +const char * MPU_pcQueueGetName( QueueHandle_t xQueue ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_pcQueueGetNameImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_pcQueueGetName_Unpriv \n" + " MPU_pcQueueGetName_Priv: \n" + " pop {r0} \n" + " b MPU_pcQueueGetNameImpl \n" + " MPU_pcQueueGetName_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_pcQueueGetNameImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configQUEUE_REGISTRY_SIZE > 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +void * MPU_pvTimerGetTimerID( const TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void * MPU_pvTimerGetTimerID( const TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_pvTimerGetTimerIDImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_pvTimerGetTimerID_Unpriv \n" + " MPU_pvTimerGetTimerID_Priv: \n" + " pop {r0} \n" + " b MPU_pvTimerGetTimerIDImpl \n" + " MPU_pvTimerGetTimerID_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_pvTimerGetTimerIDImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +void MPU_vTimerSetTimerID( TimerHandle_t xTimer, + void * pvNewID ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTimerSetTimerID( TimerHandle_t xTimer, + void * pvNewID ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTimerSetTimerIDImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vTimerSetTimerID_Unpriv \n" + " MPU_vTimerSetTimerID_Priv: \n" + " pop {r0} \n" + " b MPU_vTimerSetTimerIDImpl \n" + " MPU_vTimerSetTimerID_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vTimerSetTimerIDImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +BaseType_t MPU_xTimerIsTimerActive( TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTimerIsTimerActive( TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTimerIsTimerActiveImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTimerIsTimerActive_Unpriv \n" + " MPU_xTimerIsTimerActive_Priv: \n" + " pop {r0} \n" + " b MPU_xTimerIsTimerActiveImpl \n" + " MPU_xTimerIsTimerActive_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTimerIsTimerActiveImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +TaskHandle_t MPU_xTimerGetTimerDaemonTaskHandle( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TaskHandle_t MPU_xTimerGetTimerDaemonTaskHandle( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTimerGetTimerDaemonTaskHandleImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTimerGetTimerDaemonTaskHandle_Unpriv \n" + " MPU_xTimerGetTimerDaemonTaskHandle_Priv: \n" + " pop {r0} \n" + " b MPU_xTimerGetTimerDaemonTaskHandleImpl \n" + " MPU_xTimerGetTimerDaemonTaskHandle_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTimerGetTimerDaemonTaskHandleImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +BaseType_t MPU_xTimerGenericCommand( TimerHandle_t xTimer, + const BaseType_t xCommandID, + const TickType_t xOptionalValue, + BaseType_t * const pxHigherPriorityTaskWoken, + const TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTimerGenericCommand( TimerHandle_t xTimer, + const BaseType_t xCommandID, + const TickType_t xOptionalValue, + BaseType_t * const pxHigherPriorityTaskWoken, + const TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTimerGenericCommandImpl \n" + " \n" + " push {r0} \n" + " mrs r0, ipsr \n" + " cmp r0, #0 \n" + " bne MPU_xTimerGenericCommand_Priv \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " beq MPU_xTimerGenericCommand_Priv \n" + " MPU_xTimerGenericCommand_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTimerGenericCommandImpl \n" + " svc %1 \n" + " bx lr \n" + " MPU_xTimerGenericCommand_Priv: \n" + " pop {r0} \n" + " b MPU_xTimerGenericCommandImpl \n" + " \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER_1 ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +const char * MPU_pcTimerGetName( TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +const char * MPU_pcTimerGetName( TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_pcTimerGetNameImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_pcTimerGetName_Unpriv \n" + " MPU_pcTimerGetName_Priv: \n" + " pop {r0} \n" + " b MPU_pcTimerGetNameImpl \n" + " MPU_pcTimerGetName_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_pcTimerGetNameImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, + const BaseType_t uxAutoReload ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, + const BaseType_t uxAutoReload ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTimerSetReloadModeImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vTimerSetReloadMode_Unpriv \n" + " MPU_vTimerSetReloadMode_Priv: \n" + " pop {r0} \n" + " b MPU_vTimerSetReloadModeImpl \n" + " MPU_vTimerSetReloadMode_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vTimerSetReloadModeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +BaseType_t MPU_xTimerGetReloadMode( TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTimerGetReloadMode( TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTimerGetReloadModeImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTimerGetReloadMode_Unpriv \n" + " MPU_xTimerGetReloadMode_Priv: \n" + " pop {r0} \n" + " b MPU_xTimerGetReloadModeImpl \n" + " MPU_xTimerGetReloadMode_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTimerGetReloadModeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +UBaseType_t MPU_uxTimerGetReloadMode( TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxTimerGetReloadMode( TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxTimerGetReloadModeImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_uxTimerGetReloadMode_Unpriv \n" + " MPU_uxTimerGetReloadMode_Priv: \n" + " pop {r0} \n" + " b MPU_uxTimerGetReloadModeImpl \n" + " MPU_uxTimerGetReloadMode_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_uxTimerGetReloadModeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +TickType_t MPU_xTimerGetPeriod( TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TickType_t MPU_xTimerGetPeriod( TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTimerGetPeriodImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTimerGetPeriod_Unpriv \n" + " MPU_xTimerGetPeriod_Priv: \n" + " pop {r0} \n" + " b MPU_xTimerGetPeriodImpl \n" + " MPU_xTimerGetPeriod_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTimerGetPeriodImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +TickType_t MPU_xTimerGetExpiryTime( TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TickType_t MPU_xTimerGetExpiryTime( TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTimerGetExpiryTimeImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTimerGetExpiryTime_Unpriv \n" + " MPU_xTimerGetExpiryTime_Priv: \n" + " pop {r0} \n" + " b MPU_xTimerGetExpiryTimeImpl \n" + " MPU_xTimerGetExpiryTime_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTimerGetExpiryTimeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +EventBits_t MPU_xEventGroupWaitBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToWaitFor, + const BaseType_t xClearOnExit, + const BaseType_t xWaitForAllBits, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +EventBits_t MPU_xEventGroupWaitBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToWaitFor, + const BaseType_t xClearOnExit, + const BaseType_t xWaitForAllBits, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupWaitBitsImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xEventGroupWaitBits_Unpriv \n" + " MPU_xEventGroupWaitBits_Priv: \n" + " pop {r0} \n" + " b MPU_xEventGroupWaitBitsImpl \n" + " MPU_xEventGroupWaitBits_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xEventGroupWaitBitsImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER_1 ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToClear ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToClear ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupClearBitsImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xEventGroupClearBits_Unpriv \n" + " MPU_xEventGroupClearBits_Priv: \n" + " pop {r0} \n" + " b MPU_xEventGroupClearBitsImpl \n" + " MPU_xEventGroupClearBits_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xEventGroupClearBitsImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupSetBitsImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xEventGroupSetBits_Unpriv \n" + " MPU_xEventGroupSetBits_Priv: \n" + " pop {r0} \n" + " b MPU_xEventGroupSetBitsImpl \n" + " MPU_xEventGroupSetBits_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xEventGroupSetBitsImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet, + const EventBits_t uxBitsToWaitFor, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet, + const EventBits_t uxBitsToWaitFor, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupSyncImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xEventGroupSync_Unpriv \n" + " MPU_xEventGroupSync_Priv: \n" + " pop {r0} \n" + " b MPU_xEventGroupSyncImpl \n" + " MPU_xEventGroupSync_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xEventGroupSyncImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + +UBaseType_t MPU_uxEventGroupGetNumber( void * xEventGroup ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxEventGroupGetNumber( void * xEventGroup ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxEventGroupGetNumberImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_uxEventGroupGetNumber_Unpriv \n" + " MPU_uxEventGroupGetNumber_Priv: \n" + " pop {r0} \n" + " b MPU_uxEventGroupGetNumberImpl \n" + " MPU_uxEventGroupGetNumber_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_uxEventGroupGetNumberImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /*( configUSE_TRACE_FACILITY == 1 )*/ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + +void MPU_vEventGroupSetNumber( void * xEventGroup, + UBaseType_t uxEventGroupNumber ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vEventGroupSetNumber( void * xEventGroup, + UBaseType_t uxEventGroupNumber ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vEventGroupSetNumberImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vEventGroupSetNumber_Unpriv \n" + " MPU_vEventGroupSetNumber_Priv: \n" + " pop {r0} \n" + " b MPU_vEventGroupSetNumberImpl \n" + " MPU_vEventGroupSetNumber_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vEventGroupSetNumberImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /*( configUSE_TRACE_FACILITY == 1 )*/ +/*-----------------------------------------------------------*/ + +size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, + const void * pvTxData, + size_t xDataLengthBytes, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, + const void * pvTxData, + size_t xDataLengthBytes, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferSendImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferSend_Unpriv \n" + " MPU_xStreamBufferSend_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferSendImpl \n" + " MPU_xStreamBufferSend_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xStreamBufferSendImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, + void * pvRxData, + size_t xBufferLengthBytes, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, + void * pvRxData, + size_t xBufferLengthBytes, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferReceiveImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferReceive_Unpriv \n" + " MPU_xStreamBufferReceive_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferReceiveImpl \n" + " MPU_xStreamBufferReceive_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xStreamBufferReceiveImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferIsFullImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferIsFull_Unpriv \n" + " MPU_xStreamBufferIsFull_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferIsFullImpl \n" + " MPU_xStreamBufferIsFull_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xStreamBufferIsFullImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferIsEmptyImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferIsEmpty_Unpriv \n" + " MPU_xStreamBufferIsEmpty_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferIsEmptyImpl \n" + " MPU_xStreamBufferIsEmpty_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xStreamBufferIsEmptyImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferSpacesAvailableImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferSpacesAvailable_Unpriv \n" + " MPU_xStreamBufferSpacesAvailable_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferSpacesAvailableImpl \n" + " MPU_xStreamBufferSpacesAvailable_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xStreamBufferSpacesAvailableImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferBytesAvailableImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferBytesAvailable_Unpriv \n" + " MPU_xStreamBufferBytesAvailable_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferBytesAvailableImpl \n" + " MPU_xStreamBufferBytesAvailable_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xStreamBufferBytesAvailableImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, + size_t xTriggerLevel ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, + size_t xTriggerLevel ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferSetTriggerLevelImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferSetTriggerLevel_Unpriv \n" + " MPU_xStreamBufferSetTriggerLevel_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferSetTriggerLevelImpl \n" + " MPU_xStreamBufferSetTriggerLevel_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xStreamBufferSetTriggerLevelImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferNextMessageLengthBytesImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferNextMessageLengthBytes_Unpriv \n" + " MPU_xStreamBufferNextMessageLengthBytes_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferNextMessageLengthBytesImpl \n" + " MPU_xStreamBufferNextMessageLengthBytes_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xStreamBufferNextMessageLengthBytesImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ diff --git a/portable/GCC/ARM_CM85/non_secure/port.c b/portable/GCC/ARM_CM85/non_secure/port.c index 7bbe1b7bc53..cab1b3668bf 100644 --- a/portable/GCC/ARM_CM85/non_secure/port.c +++ b/portable/GCC/ARM_CM85/non_secure/port.c @@ -107,6 +107,13 @@ #define portPRIGROUP_SHIFT ( 8UL ) /*-----------------------------------------------------------*/ +/** + * @brief Constants used during system call enter and exit. + */ +#define portPSR_STACK_PADDING_MASK ( 1UL << 9UL ) +#define portEXC_RETURN_STACK_FRAME_TYPE_MASK ( 1UL << 4UL ) +/*-----------------------------------------------------------*/ + /** * @brief Constants required to manipulate the FPU. */ @@ -123,6 +130,14 @@ #define portFPCCR_LSPEN_MASK ( 1UL << portFPCCR_LSPEN_POS ) /*-----------------------------------------------------------*/ +/** + * @brief Offsets in the stack to the parameters when inside the SVC handler. + */ +#define portOFFSET_TO_LR ( 5 ) +#define portOFFSET_TO_PC ( 6 ) +#define portOFFSET_TO_PSR ( 7 ) +/*-----------------------------------------------------------*/ + /** * @brief Constants required to manipulate the MPU. */ @@ -148,6 +163,8 @@ #define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ #define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ +#define portMPU_RBAR_ACCESS_PERMISSIONS_MASK ( 3UL << 1UL ) + #define portMPU_MAIR_ATTR0_POS ( 0UL ) #define portMPU_MAIR_ATTR0_MASK ( 0x000000ff ) @@ -191,6 +208,30 @@ /* Expected value of the portMPU_TYPE register. */ #define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) + +/* Extract first address of the MPU region as encoded in the + * RBAR (Region Base Address Register) value. */ +#define portEXTRACT_FIRST_ADDRESS_FROM_RBAR( rbar ) \ + ( ( rbar ) & portMPU_RBAR_ADDRESS_MASK ) + +/* Extract last address of the MPU region as encoded in the + * RLAR (Region Limit Address Register) value. */ +#define portEXTRACT_LAST_ADDRESS_FROM_RLAR( rlar ) \ + ( ( ( rlar ) & portMPU_RLAR_ADDRESS_MASK ) | ~portMPU_RLAR_ADDRESS_MASK ) + +/* Does addr lies within [start, end] address range? */ +#define portIS_ADDRESS_WITHIN_RANGE( addr, start, end ) \ + ( ( ( addr ) >= ( start ) ) && ( ( addr ) <= ( end ) ) ) + +/* Is the access request satisfied by the available permissions? */ +#define portIS_AUTHORIZED( accessRequest, permissions ) \ + ( ( ( permissions ) & ( accessRequest ) ) == accessRequest ) + +/* 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 ) ) ) /*-----------------------------------------------------------*/ /** @@ -311,6 +352,19 @@ static void prvTaskExitError( void ); #if ( configENABLE_MPU == 1 ) +/** + * @brief Extract MPU region's access permissions from the Region Base Address + * Register (RBAR) value. + * + * @param ulRBARValue RBAR value for the MPU region. + * + * @return uint32_t Access permissions. + */ + static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) PRIVILEGED_FUNCTION; +#endif /* configENABLE_MPU */ + +#if ( configENABLE_MPU == 1 ) + /** * @brief Setup the Memory Protection Unit (MPU). */ @@ -365,6 +419,60 @@ void SysTick_Handler( void ) PRIVILEGED_FUNCTION; * @brief C part of SVC handler. */ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIVILEGED_FUNCTION; + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + + /** + * @brief Sets up the system call stack so that upon returning from + * SVC, the system call stack is used. + * + * It is used for the system calls with up to 4 parameters. + * + * @param pulTaskStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + */ + void vSystemCallEnter( uint32_t * pulTaskStack, uint32_t ulLR ) PRIVILEGED_FUNCTION; + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + + /** + * @brief Sets up the system call stack so that upon returning from + * SVC, the system call stack is used. + * + * It is used for the system calls with 5 parameters. + * + * @param pulTaskStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + */ + void vSystemCallEnter_1( uint32_t * pulTaskStack, uint32_t ulLR ) PRIVILEGED_FUNCTION; + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + + /** + * @brief Sets up the task stack so that upon returning from + * SVC, the task stack is used again. + * + * @param pulSystemCallStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + */ + void vSystemCallExit( uint32_t * pulSystemCallStack, uint32_t ulLR ) PRIVILEGED_FUNCTION; + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + +#if ( configENABLE_MPU == 1 ) + + /** + * @brief Checks whether or not the calling task is privileged. + * + * @return pdTRUE if the calling task is privileged, pdFALSE otherwise. + */ + BaseType_t xPortIsTaskPrivileged( void ) PRIVILEGED_FUNCTION; + +#endif /* configENABLE_MPU == 1 */ /*-----------------------------------------------------------*/ /** @@ -681,6 +789,26 @@ static void prvTaskExitError( void ) } /*-----------------------------------------------------------*/ +#if ( configENABLE_MPU == 1 ) + static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) /* PRIVILEGED_FUNCTION */ + { + uint32_t ulAccessPermissions = 0; + + if( ( ulRBARValue & portMPU_RBAR_ACCESS_PERMISSIONS_MASK ) == portMPU_REGION_READ_ONLY ) + { + ulAccessPermissions = tskMPU_READ_PERMISSION; + } + + if( ( ulRBARValue & portMPU_RBAR_ACCESS_PERMISSIONS_MASK ) == portMPU_REGION_READ_WRITE ) + { + ulAccessPermissions = ( tskMPU_READ_PERMISSION | tskMPU_WRITE_PERMISSION ); + } + + return ulAccessPermissions; + } +#endif /* configENABLE_MPU */ +/*-----------------------------------------------------------*/ + #if ( configENABLE_MPU == 1 ) static void prvSetupMPU( void ) /* PRIVILEGED_FUNCTION */ { @@ -853,7 +981,7 @@ void SysTick_Handler( void ) /* PRIVILEGED_FUNCTION */ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTION portDONT_DISCARD */ { - #if ( configENABLE_MPU == 1 ) + #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) ) #if defined( __ARMCC_VERSION ) /* Declaration when these variable are defined in code instead of being @@ -865,7 +993,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO extern uint32_t __syscalls_flash_start__[]; extern uint32_t __syscalls_flash_end__[]; #endif /* defined( __ARMCC_VERSION ) */ - #endif /* configENABLE_MPU */ + #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */ uint32_t ulPC; @@ -880,7 +1008,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO /* Register are stored on the stack in the following order - R0, R1, R2, R3, * R12, LR, PC, xPSR. */ - ulPC = pulCallerStackAddress[ 6 ]; + ulPC = pulCallerStackAddress[ portOFFSET_TO_PC ]; ucSVCNumber = ( ( uint8_t * ) ulPC )[ -2 ]; switch( ucSVCNumber ) @@ -951,18 +1079,18 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO vRestoreContextOfFirstTask(); break; - #if ( configENABLE_MPU == 1 ) - case portSVC_RAISE_PRIVILEGE: + #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) ) + case portSVC_RAISE_PRIVILEGE: - /* Only raise the privilege, if the svc was raised from any of - * the system calls. */ - if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) && - ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ) - { - vRaisePrivilege(); - } - break; - #endif /* configENABLE_MPU */ + /* Only raise the privilege, if the svc was raised from any of + * the system calls. */ + if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ) + { + vRaisePrivilege(); + } + break; + #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */ default: /* Incorrect SVC call. */ @@ -971,51 +1099,455 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } /*-----------------------------------------------------------*/ -/* *INDENT-OFF* */ -#if ( configENABLE_MPU == 1 ) - StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, - StackType_t * pxEndOfStack, - TaskFunction_t pxCode, - void * pvParameters, - BaseType_t xRunPrivileged ) /* PRIVILEGED_FUNCTION */ -#else - StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, - StackType_t * pxEndOfStack, - TaskFunction_t pxCode, - void * pvParameters ) /* PRIVILEGED_FUNCTION */ -#endif /* configENABLE_MPU */ -/* *INDENT-ON* */ +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + +void vSystemCallEnter( uint32_t * pulTaskStack, uint32_t ulLR ) /* PRIVILEGED_FUNCTION */ { - /* Simulate the stack frame as it would be created by a context switch - * interrupt. */ - #if ( portPRELOAD_REGISTERS == 0 ) + extern TaskHandle_t pxCurrentTCB; + xMPU_SETTINGS * pxMpuSettings; + uint32_t * pulSystemCallStack; + uint32_t ulStackFrameSize, ulSystemCallLocation, i; + #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being + * exported from linker scripts. */ + extern uint32_t * __syscalls_flash_start__; + extern uint32_t * __syscalls_flash_end__; + #else + /* Declaration when these variable are exported from linker scripts. */ + extern uint32_t __syscalls_flash_start__[]; + extern uint32_t __syscalls_flash_end__[]; + #endif /* #if defined( __ARMCC_VERSION ) */ + + ulSystemCallLocation = pulTaskStack[ portOFFSET_TO_PC ]; + + /* If the request did not come from the system call section, do nothing. */ + if( ( ulSystemCallLocation >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulSystemCallLocation <= ( uint32_t ) __syscalls_flash_end__ ) ) { - pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ - *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ - pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pxCode; /* PC */ - pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR */ - pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ - *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ - pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */ - *pxTopOfStack = portINITIAL_EXC_RETURN; + pxMpuSettings = xTaskGetMPUSettings( pxCurrentTCB ); + pulSystemCallStack = pxMpuSettings->xSystemCallStackInfo.pulSystemCallStack; - #if ( configENABLE_MPU == 1 ) + /* This is not NULL only for the duration of the system call. */ + configASSERT( pxMpuSettings->xSystemCallStackInfo.pulTaskStack == NULL ); + + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) { - pxTopOfStack--; + if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) + { + /* Extended frame i.e. FPU in use. */ + ulStackFrameSize = 26; + __asm volatile ( + " vpush {s0} \n" /* Trigger lazy stacking. */ + " vpop {s0} \n" /* Nullify the affect of the above instruction. */ + ::: "memory" + ); + } + else + { + /* Standard frame i.e. FPU not in use. */ + ulStackFrameSize = 8; + } + } + #else + { + ulStackFrameSize = 8; + } + #endif /* configENABLE_FPU || configENABLE_MVE */ + + /* Make space on the system call stack for the stack frame. */ + pulSystemCallStack = pulSystemCallStack - ulStackFrameSize; + + /* Copy the stack frame. */ + for( i = 0; i < ulStackFrameSize; i++ ) + { + pulSystemCallStack[ i ] = pulTaskStack[ i ]; + } + + /* Store the value of the LR and PSPLIM registers before the SVC was raised. We need to + * restore it when we exit from the system call. */ + pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; + __asm volatile ( "mrs %0, psplim" : "=r" ( pxMpuSettings->xSystemCallStackInfo.ulStackLimitRegisterAtSystemCallEntry ) ); + + /* Use the pulSystemCallStack in thread mode. */ + __asm volatile ( "msr psp, %0" : : "r" ( pulSystemCallStack ) ); + __asm volatile ( "msr psplim, %0" : : "r" ( pxMpuSettings->xSystemCallStackInfo.pulSystemCallStackLimit ) ); + + /* Remember the location where we should copy the stack frame when we exit from + * the system call. */ + pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulStackFrameSize; + + /* Record if the hardware used padding to force the stack pointer + * to be double word aligned. */ + if( ( pulTaskStack[ portOFFSET_TO_PSR ] & portPSR_STACK_PADDING_MASK ) == portPSR_STACK_PADDING_MASK ) + { + pxMpuSettings->ulTaskFlags |= portSTACK_FRAME_HAS_PADDING_FLAG; + } + else + { + pxMpuSettings->ulTaskFlags &= ( ~portSTACK_FRAME_HAS_PADDING_FLAG ); + } + + /* We ensure in pxPortInitialiseStack that the system call stack is + * double word aligned and therefore, there is no need of padding. + * Clear the bit[9] of stacked xPSR. */ + pulSystemCallStack[ portOFFSET_TO_PSR ] &= ( ~portPSR_STACK_PADDING_MASK ); + + /* Raise the privilege for the duration of the system call. */ + __asm volatile ( + " mrs r0, control \n" /* Obtain current control value. */ + " movs r1, #1 \n" /* r1 = 1. */ + " bics r0, r1 \n" /* Clear nPRIV bit. */ + " msr control, r0 \n" /* Write back new control value. */ + ::: "r0", "r1", "memory" + ); + } +} - if( xRunPrivileged == pdTRUE ) +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + +void vSystemCallEnter_1( uint32_t * pulTaskStack, uint32_t ulLR ) /* PRIVILEGED_FUNCTION */ +{ + extern TaskHandle_t pxCurrentTCB; + xMPU_SETTINGS * pxMpuSettings; + uint32_t * pulSystemCallStack; + uint32_t ulStackFrameSize, ulSystemCallLocation, i; + #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being + * exported from linker scripts. */ + extern uint32_t * __syscalls_flash_start__; + extern uint32_t * __syscalls_flash_end__; + #else + /* Declaration when these variable are exported from linker scripts. */ + extern uint32_t __syscalls_flash_start__[]; + extern uint32_t __syscalls_flash_end__[]; + #endif /* #if defined( __ARMCC_VERSION ) */ + + ulSystemCallLocation = pulTaskStack[ portOFFSET_TO_PC ]; + + /* If the request did not come from the system call section, do nothing. */ + if( ( ulSystemCallLocation >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulSystemCallLocation <= ( uint32_t ) __syscalls_flash_end__ ) ) + { + pxMpuSettings = xTaskGetMPUSettings( pxCurrentTCB ); + pulSystemCallStack = pxMpuSettings->xSystemCallStackInfo.pulSystemCallStack; + + /* This is not NULL only for the duration of the system call. */ + configASSERT( pxMpuSettings->xSystemCallStackInfo.pulTaskStack == NULL ); + + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + { + if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) { - *pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */ + /* Extended frame i.e. FPU in use. */ + ulStackFrameSize = 26; + __asm volatile ( + " vpush {s0} \n" /* Trigger lazy stacking. */ + " vpop {s0} \n" /* Nullify the affect of the above instruction. */ + ::: "memory" + ); } else { - *pxTopOfStack = portINITIAL_CONTROL_UNPRIVILEGED; /* Slot used to hold this task's CONTROL value. */ + /* Standard frame i.e. FPU not in use. */ + ulStackFrameSize = 8; } } - #endif /* configENABLE_MPU */ + #else + { + ulStackFrameSize = 8; + } + #endif /* configENABLE_FPU || configENABLE_MVE */ + + /* Make space on the system call stack for the stack frame and + * the parameter passed on the stack. We only need to copy one + * parameter but we still reserve 2 spaces to keep the stack + * double word aligned. */ + pulSystemCallStack = pulSystemCallStack - ulStackFrameSize - 2UL; + + /* Copy the stack frame. */ + for( i = 0; i < ulStackFrameSize; i++ ) + { + pulSystemCallStack[ i ] = pulTaskStack[ i ]; + } + + /* Copy the parameter which is passed the stack. */ + if( ( pulTaskStack[ portOFFSET_TO_PSR ] & portPSR_STACK_PADDING_MASK ) == portPSR_STACK_PADDING_MASK ) + { + pulSystemCallStack[ ulStackFrameSize ] = pulTaskStack[ ulStackFrameSize + 1 ]; + /* Record if the hardware used padding to force the stack pointer + * to be double word aligned. */ + pxMpuSettings->ulTaskFlags |= portSTACK_FRAME_HAS_PADDING_FLAG; + } + else + { + pulSystemCallStack[ ulStackFrameSize ] = pulTaskStack[ ulStackFrameSize ]; + /* Record if the hardware used padding to force the stack pointer + * to be double word aligned. */ + pxMpuSettings->ulTaskFlags &= ( ~portSTACK_FRAME_HAS_PADDING_FLAG ); + } + + /* Store the value of the LR and PSPLIM registers before the SVC was raised. + * We need to restore it when we exit from the system call. */ + pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; + __asm volatile ( "mrs %0, psplim" : "=r" ( pxMpuSettings->xSystemCallStackInfo.ulStackLimitRegisterAtSystemCallEntry ) ); + + /* Use the pulSystemCallStack in thread mode. */ + __asm volatile ( "msr psp, %0" : : "r" ( pulSystemCallStack ) ); + __asm volatile ( "msr psplim, %0" : : "r" ( pxMpuSettings->xSystemCallStackInfo.pulSystemCallStackLimit ) ); + + /* Remember the location where we should copy the stack frame when we exit from + * the system call. */ + pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulStackFrameSize; + + /* We ensure in pxPortInitialiseStack that the system call stack is + * double word aligned and therefore, there is no need of padding. + * Clear the bit[9] of stacked xPSR. */ + pulSystemCallStack[ portOFFSET_TO_PSR ] &= ( ~portPSR_STACK_PADDING_MASK ); + + /* Raise the privilege for the duration of the system call. */ + __asm volatile ( + " mrs r0, control \n" /* Obtain current control value. */ + " movs r1, #1 \n" /* r1 = 1. */ + " bics r0, r1 \n" /* Clear nPRIV bit. */ + " msr control, r0 \n" /* Write back new control value. */ + ::: "r0", "r1", "memory" + ); + } +} + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) +void vSystemCallExit( uint32_t * pulSystemCallStack, uint32_t ulLR ) /* PRIVILEGED_FUNCTION */ +{ + extern TaskHandle_t pxCurrentTCB; + xMPU_SETTINGS * pxMpuSettings; + uint32_t * pulTaskStack; + uint32_t ulStackFrameSize, ulSystemCallLocation, i; + #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being + * exported from linker scripts. */ + extern uint32_t * __syscalls_flash_start__; + extern uint32_t * __syscalls_flash_end__; + #else + /* Declaration when these variable are exported from linker scripts. */ + extern uint32_t __syscalls_flash_start__[]; + extern uint32_t __syscalls_flash_end__[]; + #endif /* #if defined( __ARMCC_VERSION ) */ + + ulSystemCallLocation = pulSystemCallStack[ portOFFSET_TO_PC ]; + + /* If the request did not come from the system call section, do nothing. */ + if( ( ulSystemCallLocation >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulSystemCallLocation <= ( uint32_t ) __syscalls_flash_end__ ) ) + { + pxMpuSettings = xTaskGetMPUSettings( pxCurrentTCB ); + pulTaskStack = pxMpuSettings->xSystemCallStackInfo.pulTaskStack; + + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + { + if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) + { + /* Extended frame i.e. FPU in use. */ + ulStackFrameSize = 26; + __asm volatile ( + " vpush {s0} \n" /* Trigger lazy stacking. */ + " vpop {s0} \n" /* Nullify the affect of the above instruction. */ + ::: "memory" + ); + } + else + { + /* Standard frame i.e. FPU not in use. */ + ulStackFrameSize = 8; + } + } + #else + { + ulStackFrameSize = 8; + } + #endif /* configENABLE_FPU || configENABLE_MVE */ + + /* Make space on the task stack for the stack frame. */ + pulTaskStack = pulTaskStack - ulStackFrameSize; + + /* Copy the stack frame. */ + for( i = 0; i < ulStackFrameSize; i++ ) + { + pulTaskStack[ i ] = pulSystemCallStack[ i ]; + } + + /* Use the pulTaskStack in thread mode. */ + __asm volatile ( "msr psp, %0" : : "r" ( pulTaskStack ) ); + + /* Restore the LR and PSPLIM to what they were at the time of + * system call entry. */ + pulTaskStack[ portOFFSET_TO_LR ] = pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry; + __asm volatile ( "msr psplim, %0" : : "r" ( pxMpuSettings->xSystemCallStackInfo.ulStackLimitRegisterAtSystemCallEntry ) ); + + /* If the hardware used padding to force the stack pointer + * to be double word aligned, set the stacked xPSR bit[9], + * otherwise clear it. */ + if( ( pxMpuSettings->ulTaskFlags & portSTACK_FRAME_HAS_PADDING_FLAG ) == portSTACK_FRAME_HAS_PADDING_FLAG ) + { + pulTaskStack[ portOFFSET_TO_PSR ] |= portPSR_STACK_PADDING_MASK; + } + else + { + pulTaskStack[ portOFFSET_TO_PSR ] &= ( ~portPSR_STACK_PADDING_MASK ); + } + + /* This is not NULL only for the duration of the system call. */ + pxMpuSettings->xSystemCallStackInfo.pulTaskStack = NULL; + + /* Drop the privilege before returning to the thread mode. */ + __asm volatile ( + " mrs r0, control \n" /* Obtain current control value. */ + " movs r1, #1 \n" /* r1 = 1. */ + " orrs r0, r1 \n" /* Set nPRIV bit. */ + " msr control, r0 \n" /* Write back new control value. */ + ::: "r0", "r1", "memory" + ); + } +} + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configENABLE_MPU == 1 ) + +BaseType_t xPortIsTaskPrivileged( void ) /* PRIVILEGED_FUNCTION */ +{ + BaseType_t xTaskIsPrivileged = pdFALSE; + const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */ + + if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) + { + xTaskIsPrivileged = pdTRUE; + } + + return xTaskIsPrivileged; +} + +#endif /* configENABLE_MPU == 1 */ +/*-----------------------------------------------------------*/ + +#if( configENABLE_MPU == 1 ) + +StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, + StackType_t * pxEndOfStack, + TaskFunction_t pxCode, + void * pvParameters, + BaseType_t xRunPrivileged, + xMPU_SETTINGS * xMPUSettings ) /* PRIVILEGED_FUNCTION */ +{ + uint32_t ulIndex = 0; + + xMPUSettings->ulContext[ ulIndex ] = 0x04040404; /* r4. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x05050505; /* r5. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x06060606; /* r6. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x07070707; /* r7. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x08080808; /* r8. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x09090909; /* r9. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x10101010; /* r10. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x11111111; /* r11. */ + ulIndex++; + + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pvParameters; /* r0. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x01010101; /* r1. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x02020202; /* r2. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x03030303; /* r3. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x12121212; /* r12. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portTASK_RETURN_ADDRESS; /* LR. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxCode; /* PC. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = portINITIAL_XPSR; /* xPSR. */ + ulIndex++; + + #if ( configENABLE_TRUSTZONE == 1 ) + { + xMPUSettings->ulContext[ ulIndex ] = portNO_SECURE_CONTEXT; /* xSecureContext. */ + ulIndex++; + } + #endif /* configENABLE_TRUSTZONE */ + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) ( pxTopOfStack - 8 ); /* PSP with the hardware saved stack. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */ + ulIndex++; + if( xRunPrivileged == pdTRUE ) + { + xMPUSettings->ulTaskFlags |= portTASK_IS_PRIVILEGED_FLAG; + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_PRIVILEGED; /* CONTROL. */ + ulIndex++; + } + else + { + xMPUSettings->ulTaskFlags &= ( ~portTASK_IS_PRIVILEGED_FLAG ); + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_UNPRIVILEGED; /* CONTROL. */ + ulIndex++; + } + xMPUSettings->ulContext[ ulIndex ] = portINITIAL_EXC_RETURN; /* LR (EXC_RETURN). */ + ulIndex++; + + #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + { + /* Ensure that the system call stack is double word aligned. */ + xMPUSettings->xSystemCallStackInfo.pulSystemCallStack = &( xMPUSettings->xSystemCallStackInfo.ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE - 1 ] ); + xMPUSettings->xSystemCallStackInfo.pulSystemCallStack = ( uint32_t * ) ( ( uint32_t ) ( xMPUSettings->xSystemCallStackInfo.pulSystemCallStack ) & + ( uint32_t ) ( ~( portBYTE_ALIGNMENT_MASK ) ) ); + + xMPUSettings->xSystemCallStackInfo.pulSystemCallStackLimit = &( xMPUSettings->xSystemCallStackInfo.ulSystemCallStackBuffer[ 0 ] ); + xMPUSettings->xSystemCallStackInfo.pulSystemCallStackLimit = ( uint32_t * ) ( ( ( uint32_t ) ( xMPUSettings->xSystemCallStackInfo.pulSystemCallStackLimit ) + + ( uint32_t ) ( portBYTE_ALIGNMENT - 1 ) ) & + ( uint32_t ) ( ~( portBYTE_ALIGNMENT_MASK ) ) ); + + /* This is not NULL only for the duration of a system call. */ + xMPUSettings->xSystemCallStackInfo.pulTaskStack = NULL; + } + #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + + return &( xMPUSettings->ulContext[ ulIndex ] ); +} + +#else /* configENABLE_MPU */ + +StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, + StackType_t * pxEndOfStack, + TaskFunction_t pxCode, + void * pvParameters ) /* PRIVILEGED_FUNCTION */ +{ + /* Simulate the stack frame as it would be created by a context switch + * interrupt. */ + #if ( portPRELOAD_REGISTERS == 0 ) + { + pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ + *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR. */ + pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ + pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */ + *pxTopOfStack = portINITIAL_EXC_RETURN; pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ @@ -1029,55 +1561,39 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO #else /* portPRELOAD_REGISTERS */ { pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ - *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ + *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pxCode; /* PC */ + *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR */ + *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x12121212UL; /* R12 */ + *pxTopOfStack = ( StackType_t ) 0x12121212UL; /* R12. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x03030303UL; /* R3 */ + *pxTopOfStack = ( StackType_t ) 0x03030303UL; /* R3. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x02020202UL; /* R2 */ + *pxTopOfStack = ( StackType_t ) 0x02020202UL; /* R2. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x01010101UL; /* R1 */ + *pxTopOfStack = ( StackType_t ) 0x01010101UL; /* R1. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x11111111UL; /* R11 */ + *pxTopOfStack = ( StackType_t ) 0x11111111UL; /* R11. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x10101010UL; /* R10 */ + *pxTopOfStack = ( StackType_t ) 0x10101010UL; /* R10. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x09090909UL; /* R09 */ + *pxTopOfStack = ( StackType_t ) 0x09090909UL; /* R09. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x08080808UL; /* R08 */ + *pxTopOfStack = ( StackType_t ) 0x08080808UL; /* R08. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x07070707UL; /* R07 */ + *pxTopOfStack = ( StackType_t ) 0x07070707UL; /* R07. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x06060606UL; /* R06 */ + *pxTopOfStack = ( StackType_t ) 0x06060606UL; /* R06. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x05050505UL; /* R05 */ + *pxTopOfStack = ( StackType_t ) 0x05050505UL; /* R05. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x04040404UL; /* R04 */ + *pxTopOfStack = ( StackType_t ) 0x04040404UL; /* R04. */ pxTopOfStack--; - *pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN */ - - #if ( configENABLE_MPU == 1 ) - { - pxTopOfStack--; - - if( xRunPrivileged == pdTRUE ) - { - *pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */ - } - else - { - *pxTopOfStack = portINITIAL_CONTROL_UNPRIVILEGED; /* Slot used to hold this task's CONTROL value. */ - } - } - #endif /* configENABLE_MPU */ - + *pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN. */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ @@ -1092,6 +1608,8 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO return pxTopOfStack; } + +#endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ @@ -1128,6 +1646,10 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ configASSERT( ucMaxSysCallPriority ); + /* Check that the bits not implemented in hardware are zero in + * configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & ( ~ucMaxPriorityValue ) ) == 0U ); + /* Calculate the maximum acceptable priority group value for the number * of bits read back. */ @@ -1164,35 +1686,6 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulImplementedPrioBits; } - /* The interrupt priority bits are not modelled in QEMU and the assert that - * checks the number of implemented bits and __NVIC_PRIO_BITS will always fail. - * Therefore, this assert is not adding any value for QEMU targets. The config - * option `configDISABLE_INTERRUPT_PRIO_BITS_CHECK` should be defined in the - * `FreeRTOSConfig.h` for QEMU targets. */ - #ifndef configDISABLE_INTERRUPT_PRIO_BITS_CHECK - { - #ifdef __NVIC_PRIO_BITS - { - /* - * Check that the number of implemented priority bits queried from - * hardware is equal to the CMSIS __NVIC_PRIO_BITS configuration macro. - */ - configASSERT( ulImplementedPrioBits == __NVIC_PRIO_BITS ); - } - #endif /* __NVIC_PRIO_BITS */ - - #ifdef configPRIO_BITS - { - /* - * Check that the number of implemented priority bits queried from - * hardware is equal to the FreeRTOS configPRIO_BITS configuration macro. - */ - configASSERT( ulImplementedPrioBits == configPRIO_BITS ); - } - #endif /* configPRIO_BITS */ - } - #endif /* #ifndef configDISABLE_INTERRUPT_PRIO_BITS_CHECK */ - /* Shift the priority group value back to its position within the AIRCR * register. */ ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT; @@ -1372,6 +1865,54 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ +#if ( configENABLE_MPU == 1 ) + BaseType_t xPortIsAuthorizedToAccessBuffer( const void * pvBuffer, + uint32_t ulBufferLength, + uint32_t ulAccessRequested ) /* PRIVILEGED_FUNCTION */ + + { + uint32_t i, ulBufferStartAddress, ulBufferEndAddress; + BaseType_t xAccessGranted = pdFALSE; + const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */ + + if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) + { + xAccessGranted = pdTRUE; + } + else + { + if( portADD_UINT32_WILL_OVERFLOW( ( ( uint32_t ) pvBuffer ), ( ulBufferLength - 1UL ) ) == pdFALSE ) + { + ulBufferStartAddress = ( uint32_t ) pvBuffer; + ulBufferEndAddress = ( ( ( uint32_t ) pvBuffer ) + ulBufferLength - 1UL ); + + for( i = 0; i < portTOTAL_NUM_REGIONS; i++ ) + { + /* Is the MPU region enabled? */ + if( ( xTaskMpuSettings->xRegionsSettings[ i ].ulRLAR & portMPU_RLAR_REGION_ENABLE ) == portMPU_RLAR_REGION_ENABLE ) + { + if( portIS_ADDRESS_WITHIN_RANGE( ulBufferStartAddress, + portEXTRACT_FIRST_ADDRESS_FROM_RBAR( xTaskMpuSettings->xRegionsSettings[ i ].ulRBAR ), + portEXTRACT_LAST_ADDRESS_FROM_RLAR( xTaskMpuSettings->xRegionsSettings[ i ].ulRLAR ) ) && + portIS_ADDRESS_WITHIN_RANGE( ulBufferEndAddress, + portEXTRACT_FIRST_ADDRESS_FROM_RBAR( xTaskMpuSettings->xRegionsSettings[ i ].ulRBAR ), + portEXTRACT_LAST_ADDRESS_FROM_RLAR( xTaskMpuSettings->xRegionsSettings[ i ].ulRLAR ) ) && + portIS_AUTHORIZED( ulAccessRequested, + prvGetRegionAccessPermissions( xTaskMpuSettings->xRegionsSettings[ i ].ulRBAR ) ) ) + { + xAccessGranted = pdTRUE; + break; + } + } + } + } + } + + return xAccessGranted; + } +#endif /* configENABLE_MPU */ +/*-----------------------------------------------------------*/ + BaseType_t xPortIsInsideInterrupt( void ) { uint32_t ulCurrentInterrupt; diff --git a/portable/GCC/ARM_CM85/non_secure/portasm.c b/portable/GCC/ARM_CM85/non_secure/portasm.c index 9f9b2e68d39..f7ec7d9c072 100644 --- a/portable/GCC/ARM_CM85/non_secure/portasm.c +++ b/portable/GCC/ARM_CM85/non_secure/portasm.c @@ -40,95 +40,120 @@ * header files. */ #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE +#if ( configENABLE_MPU == 1 ) + void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ { __asm volatile ( - " .syntax unified \n" - " \n" - " ldr r2, pxCurrentTCBConst2 \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - " ldr r3, [r2] \n"/* Read pxCurrentTCB. */ - " ldr r0, [r3] \n"/* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ - " \n" - #if ( configENABLE_MPU == 1 ) - " dmb \n"/* Complete outstanding transfers before disabling MPU. */ - " ldr r2, xMPUCTRLConst2 \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ - " ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */ - " bic r4, #1 \n"/* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */ - " str r4, [r2] \n"/* Disable MPU. */ - " \n" - " adds r3, #4 \n"/* r3 = r3 + 4. r3 now points to MAIR0 in TCB. */ - " ldr r4, [r3] \n"/* r4 = *r3 i.e. r4 = MAIR0. */ - " ldr r2, xMAIR0Const2 \n"/* r2 = 0xe000edc0 [Location of MAIR0]. */ - " str r4, [r2] \n"/* Program MAIR0. */ - " ldr r2, xRNRConst2 \n"/* r2 = 0xe000ed98 [Location of RNR]. */ - " movs r4, #4 \n"/* r4 = 4. */ - " str r4, [r2] \n"/* Program RNR = 4. */ - " adds r3, #4 \n"/* r3 = r3 + 4. r3 now points to first RBAR in TCB. */ - " ldr r2, xRBARConst2 \n"/* r2 = 0xe000ed9c [Location of RBAR]. */ - " ldmia r3!, {r4-r11} \n"/* Read 4 set of RBAR/RLAR registers from TCB. */ - " stmia r2!, {r4-r11} \n"/* Write 4 set of RBAR/RLAR registers using alias registers. */ - " \n" + " .syntax unified \n" + " \n" + " program_mpu_first_task: \n" + " ldr r3, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r0, [r3] \n" /* r0 = pxCurrentTCB. */ + " \n" + " dmb \n" /* Complete outstanding transfers before disabling MPU. */ + " ldr r1, xMPUCTRLConst2 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ + " bic r2, #1 \n" /* r2 = r2 & ~1 i.e. Clear the bit 0 in r2. */ + " str r2, [r1] \n" /* Disable MPU. */ + " \n" + " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */ + " ldr r1, [r0] \n" /* r1 = *r0 i.e. r1 = MAIR0. */ + " ldr r2, xMAIR0Const2 \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */ + " str r1, [r2] \n" /* Program MAIR0. */ + " \n" + " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */ + " ldr r1, xRNRConst2 \n" /* r1 = 0xe000ed98 [Location of RNR]. */ + " ldr r2, xRBARConst2 \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ + " \n" + " movs r3, #4 \n" /* r3 = 4. */ + " str r3, [r1] \n" /* Program RNR = 4. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + " \n" #if ( configTOTAL_MPU_REGIONS == 16 ) - " ldr r2, xRNRConst2 \n"/* r2 = 0xe000ed98 [Location of RNR]. */ - " movs r4, #8 \n"/* r4 = 8. */ - " str r4, [r2] \n"/* Program RNR = 8. */ - " ldr r2, xRBARConst2 \n"/* r2 = 0xe000ed9c [Location of RBAR]. */ - " ldmia r3!, {r4-r11} \n"/* Read 4 set of RBAR/RLAR registers from TCB. */ - " stmia r2!, {r4-r11} \n"/* Write 4 set of RBAR/RLAR registers using alias registers. */ - " ldr r2, xRNRConst2 \n"/* r2 = 0xe000ed98 [Location of RNR]. */ - " movs r4, #12 \n"/* r4 = 12. */ - " str r4, [r2] \n"/* Program RNR = 12. */ - " ldr r2, xRBARConst2 \n"/* r2 = 0xe000ed9c [Location of RBAR]. */ - " ldmia r3!, {r4-r11} \n"/* Read 4 set of RBAR/RLAR registers from TCB. */ - " stmia r2!, {r4-r11} \n"/* Write 4 set of RBAR/RLAR registers using alias registers. */ + " movs r3, #8 \n" /* r3 = 8. */ + " str r3, [r1] \n" /* Program RNR = 8. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + " movs r3, #12 \n" /* r3 = 12. */ + " str r3, [r1] \n" /* Program RNR = 12. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ #endif /* configTOTAL_MPU_REGIONS == 16 */ - " \n" - " ldr r2, xMPUCTRLConst2 \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ - " ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */ - " orr r4, #1 \n"/* r4 = r4 | 1 i.e. Set the bit 0 in r4. */ - " str r4, [r2] \n"/* Enable MPU. */ - " dsb \n"/* Force memory writes before continuing. */ - #endif /* configENABLE_MPU */ + " \n" + " ldr r1, xMPUCTRLConst2 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ + " orr r2, #1 \n" /* r2 = r1 | 1 i.e. Set the bit 0 in r2. */ + " str r2, [r1] \n" /* Enable MPU. */ + " dsb \n" /* Force memory writes before continuing. */ + " \n" + " restore_context_first_task: \n" + " ldr r3, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r1, [r3] \n" /* r1 = pxCurrentTCB.*/ + " ldr r2, [r1] \n" /* r2 = Location of saved context in TCB. */ + " \n" + " restore_special_regs_first_task: \n" + " ldmdb r2!, {r0, r3-r5, lr} \n" /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */ + " msr psp, r3 \n" + " msr psplim, r4 \n" + " msr control, r5 \n" + " ldr r4, xSecureContextConst2 \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ + " str r0, [r4] \n" /* Restore xSecureContext. */ + " \n" + " restore_general_regs_first_task: \n" + " ldmdb r2!, {r4-r11} \n" /* r4-r11 contain hardware saved context. */ + " stmia r3!, {r4-r11} \n" /* Copy the hardware saved context on the task stack. */ + " ldmdb r2!, {r4-r11} \n" /* r4-r11 restored. */ + " \n" + " restore_context_done_first_task: \n" + " str r2, [r1] \n" /* Save the location where the context should be saved next as the first member of TCB. */ + " mov r0, #0 \n" + " msr basepri, r0 \n" /* Ensure that interrupts are enabled when the first task starts. */ + " bx lr \n" + " \n" + " .align 4 \n" + " pxCurrentTCBConst2: .word pxCurrentTCB \n" + " xSecureContextConst2: .word xSecureContext \n" + " xMPUCTRLConst2: .word 0xe000ed94 \n" + " xMAIR0Const2: .word 0xe000edc0 \n" + " xRNRConst2: .word 0xe000ed98 \n" + " xRBARConst2: .word 0xe000ed9c \n" + ); +} + +#else /* configENABLE_MPU */ + +void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ +{ + __asm volatile + ( + " .syntax unified \n" " \n" - #if ( configENABLE_MPU == 1 ) - " ldm r0!, {r1-r4} \n"/* Read from stack - r1 = xSecureContext, r2 = PSPLIM, r3 = CONTROL and r4 = EXC_RETURN. */ - " ldr r5, xSecureContextConst2 \n" - " str r1, [r5] \n"/* Set xSecureContext to this task's value for the same. */ - " msr psplim, r2 \n"/* Set this task's PSPLIM value. */ - " msr control, r3 \n"/* Set this task's CONTROL value. */ - " adds r0, #32 \n"/* Discard everything up to r0. */ - " msr psp, r0 \n"/* This is now the new top of stack to use in the task. */ - " isb \n" - " mov r0, #0 \n" - " msr basepri, r0 \n"/* Ensure that interrupts are enabled when the first task starts. */ - " bx r4 \n"/* Finally, branch to EXC_RETURN. */ - #else /* configENABLE_MPU */ - " ldm r0!, {r1-r3} \n"/* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */ - " ldr r4, xSecureContextConst2 \n" - " str r1, [r4] \n"/* Set xSecureContext to this task's value for the same. */ - " msr psplim, r2 \n"/* Set this task's PSPLIM value. */ - " movs r1, #2 \n"/* r1 = 2. */ - " msr CONTROL, r1 \n"/* Switch to use PSP in the thread mode. */ - " adds r0, #32 \n"/* Discard everything up to r0. */ - " msr psp, r0 \n"/* This is now the new top of stack to use in the task. */ - " isb \n" - " mov r0, #0 \n" - " msr basepri, r0 \n"/* Ensure that interrupts are enabled when the first task starts. */ - " bx r3 \n"/* Finally, branch to EXC_RETURN. */ - #endif /* configENABLE_MPU */ + " ldr r2, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r3, [r2] \n" /* Read pxCurrentTCB. */ + " ldr r0, [r3] \n" /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ " \n" + " ldm r0!, {r1-r3} \n" /* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */ + " ldr r4, xSecureContextConst2 \n" + " str r1, [r4] \n" /* Set xSecureContext to this task's value for the same. */ + " msr psplim, r2 \n" /* Set this task's PSPLIM value. */ + " movs r1, #2 \n" /* r1 = 2. */ + " msr CONTROL, r1 \n" /* Switch to use PSP in the thread mode. */ + " adds r0, #32 \n" /* Discard everything up to r0. */ + " msr psp, r0 \n" /* This is now the new top of stack to use in the task. */ + " isb \n" + " mov r0, #0 \n" + " msr basepri, r0 \n" /* Ensure that interrupts are enabled when the first task starts. */ + " bx r3 \n" /* Finally, branch to EXC_RETURN. */ " .align 4 \n" "pxCurrentTCBConst2: .word pxCurrentTCB \n" "xSecureContextConst2: .word xSecureContext \n" - #if ( configENABLE_MPU == 1 ) - "xMPUCTRLConst2: .word 0xe000ed94 \n" - "xMAIR0Const2: .word 0xe000edc0 \n" - "xRNRConst2: .word 0xe000ed98 \n" - "xRBARConst2: .word 0xe000ed9c \n" - #endif /* configENABLE_MPU */ ); } + +#endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */ @@ -236,6 +261,160 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att } /*-----------------------------------------------------------*/ +#if ( configENABLE_MPU == 1 ) + +void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern SecureContext_SaveContext \n" + " .extern SecureContext_LoadContext \n" + " \n" + " ldr r3, xSecureContextConst \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ + " ldr r0, [r3] \n" /* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */ + " ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r1, [r3] \n" /* Read pxCurrentTCB - Value of pxCurrentTCB must be in r1 as it is used as a parameter later. */ + " ldr r2, [r1] \n" /* r2 = Location in TCB where the context should be saved. */ + " \n" + " cbz r0, save_ns_context \n" /* No secure context to save. */ + " save_s_context: \n" + " push {r0-r2, lr} \n" + " bl SecureContext_SaveContext \n" /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ + " pop {r0-r2, lr} \n" + " \n" + " save_ns_context: \n" + " mov r3, lr \n" /* r3 = LR (EXC_RETURN). */ + " lsls r3, r3, #25 \n" /* r3 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ + " bmi save_special_regs \n" /* r3 < 0 ==> Bit[6] in EXC_RETURN is 1 ==> secure stack was used to store the stack frame. */ + " \n" + " save_general_regs: \n" + " mrs r3, psp \n" + " \n" + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + " add r3, r3, #0x20 \n" /* Move r3 to location where s0 is saved. */ + " tst lr, #0x10 \n" + " ittt eq \n" + " vstmiaeq r2!, {s16-s31} \n" /* Store s16-s31. */ + " vldmiaeq r3, {s0-s16} \n" /* Copy hardware saved FP context into s0-s16. */ + " vstmiaeq r2!, {s0-s16} \n" /* Store hardware saved FP context. */ + " sub r3, r3, #0x20 \n" /* Set r3 back to the location of hardware saved context. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ + " \n" + " stmia r2!, {r4-r11} \n" /* Store r4-r11. */ + " ldmia r3, {r4-r11} \n" /* Copy the hardware saved context into r4-r11. */ + " stmia r2!, {r4-r11} \n" /* Store the hardware saved context. */ + " \n" + " save_special_regs: \n" + " mrs r3, psp \n" /* r3 = PSP. */ + " mrs r4, psplim \n" /* r4 = PSPLIM. */ + " mrs r5, control \n" /* r5 = CONTROL. */ + " stmia r2!, {r0, r3-r5, lr} \n" /* Store xSecureContext, original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */ + " str r2, [r1] \n" /* Save the location from where the context should be restored as the first member of TCB. */ + " \n" + " select_next_task: \n" + " mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */ + " msr basepri, r0 \n" /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + " dsb \n" + " isb \n" + " bl vTaskSwitchContext \n" + " mov r0, #0 \n" /* r0 = 0. */ + " msr basepri, r0 \n" /* Enable interrupts. */ + " \n" + " program_mpu: \n" + " ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r0, [r3] \n" /* r0 = pxCurrentTCB.*/ + " \n" + " dmb \n" /* Complete outstanding transfers before disabling MPU. */ + " ldr r1, xMPUCTRLConst \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ + " bic r2, #1 \n" /* r2 = r2 & ~1 i.e. Clear the bit 0 in r2. */ + " str r2, [r1] \n" /* Disable MPU. */ + " \n" + " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */ + " ldr r1, [r0] \n" /* r1 = *r0 i.e. r1 = MAIR0. */ + " ldr r2, xMAIR0Const \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */ + " str r1, [r2] \n" /* Program MAIR0. */ + " \n" + " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */ + " ldr r1, xRNRConst \n" /* r1 = 0xe000ed98 [Location of RNR]. */ + " ldr r2, xRBARConst \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ + " \n" + " movs r3, #4 \n" /* r3 = 4. */ + " str r3, [r1] \n" /* Program RNR = 4. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + " \n" + #if ( configTOTAL_MPU_REGIONS == 16 ) + " movs r3, #8 \n" /* r3 = 8. */ + " str r3, [r1] \n" /* Program RNR = 8. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + " movs r3, #12 \n" /* r3 = 12. */ + " str r3, [r1] \n" /* Program RNR = 12. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + #endif /* configTOTAL_MPU_REGIONS == 16 */ + " \n" + " ldr r1, xMPUCTRLConst \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ + " orr r2, #1 \n" /* r2 = r2 | 1 i.e. Set the bit 0 in r2. */ + " str r2, [r1] \n" /* Enable MPU. */ + " dsb \n" /* Force memory writes before continuing. */ + " \n" + " restore_context: \n" + " ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r1, [r3] \n" /* r1 = pxCurrentTCB.*/ + " ldr r2, [r1] \n" /* r2 = Location of saved context in TCB. */ + " \n" + " restore_special_regs: \n" + " ldmdb r2!, {r0, r3-r5, lr} \n" /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */ + " msr psp, r3 \n" + " msr psplim, r4 \n" + " msr control, r5 \n" + " ldr r4, xSecureContextConst \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ + " str r0, [r4] \n" /* Restore xSecureContext. */ + " cbz r0, restore_ns_context \n" /* No secure context to restore. */ + " \n" + " restore_s_context: \n" + " push {r1-r3, lr} \n" + " bl SecureContext_LoadContext \n" /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ + " pop {r1-r3, lr} \n" + " \n" + " restore_ns_context: \n" + " mov r0, lr \n" /* r0 = LR (EXC_RETURN). */ + " lsls r0, r0, #25 \n" /* r0 = r0 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ + " bmi restore_context_done \n" /* r0 < 0 ==> Bit[6] in EXC_RETURN is 1 ==> secure stack was used to store the stack frame. */ + " \n" + " restore_general_regs: \n" + " ldmdb r2!, {r4-r11} \n" /* r4-r11 contain hardware saved context. */ + " stmia r3!, {r4-r11} \n" /* Copy the hardware saved context on the task stack. */ + " ldmdb r2!, {r4-r11} \n" /* r4-r11 restored. */ + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + " tst lr, #0x10 \n" + " ittt eq \n" + " vldmdbeq r2!, {s0-s16} \n" /* s0-s16 contain hardware saved FP context. */ + " vstmiaeq r3!, {s0-s16} \n" /* Copy hardware saved FP context on the task stack. */ + " vldmdbeq r2!, {s16-s31} \n" /* Restore s16-s31. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ + " \n" + " restore_context_done: \n" + " str r2, [r1] \n" /* Save the location where the context should be saved next as the first member of TCB. */ + " bx lr \n" + " \n" + " .align 4 \n" + " pxCurrentTCBConst: .word pxCurrentTCB \n" + " xSecureContextConst: .word xSecureContext \n" + " xMPUCTRLConst: .word 0xe000ed94 \n" + " xMAIR0Const: .word 0xe000edc0 \n" + " xRNRConst: .word 0xe000ed98 \n" + " xRBARConst: .word 0xe000ed9c \n" + ::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) + ); +} + +#else /* configENABLE_MPU */ + void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ { __asm volatile @@ -260,20 +439,11 @@ void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ " \n" " ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r3] \n"/* Read pxCurrentTCB.*/ - #if ( configENABLE_MPU == 1 ) - " subs r2, r2, #16 \n"/* Make space for xSecureContext, PSPLIM, CONTROL and LR on the stack. */ - " str r2, [r1] \n"/* Save the new top of stack in TCB. */ - " mrs r1, psplim \n"/* r1 = PSPLIM. */ - " mrs r3, control \n"/* r3 = CONTROL. */ - " mov r4, lr \n"/* r4 = LR/EXC_RETURN. */ - " stmia r2!, {r0, r1, r3, r4} \n"/* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */ - #else /* configENABLE_MPU */ - " subs r2, r2, #12 \n"/* Make space for xSecureContext, PSPLIM and LR on the stack. */ - " str r2, [r1] \n"/* Save the new top of stack in TCB. */ - " mrs r1, psplim \n"/* r1 = PSPLIM. */ - " mov r3, lr \n"/* r3 = LR/EXC_RETURN. */ - " stmia r2!, {r0, r1, r3} \n"/* Store xSecureContext, PSPLIM and LR on the stack. */ - #endif /* configENABLE_MPU */ + " subs r2, r2, #12 \n"/* Make space for xSecureContext, PSPLIM and LR on the stack. */ + " str r2, [r1] \n"/* Save the new top of stack in TCB. */ + " mrs r1, psplim \n"/* r1 = PSPLIM. */ + " mov r3, lr \n"/* r3 = LR/EXC_RETURN. */ + " stmia r2!, {r0, r1, r3} \n"/* Store xSecureContext, PSPLIM and LR on the stack. */ " b select_next_task \n" " \n" " save_ns_context: \n" @@ -284,26 +454,14 @@ void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ " it eq \n" " vstmdbeq r2!, {s16-s31} \n"/* Store the additional FP context registers which are not saved automatically. */ #endif /* configENABLE_FPU || configENABLE_MVE */ - #if ( configENABLE_MPU == 1 ) - " subs r2, r2, #48 \n"/* Make space for xSecureContext, PSPLIM, CONTROL, LR and the remaining registers on the stack. */ - " str r2, [r1] \n"/* Save the new top of stack in TCB. */ - " adds r2, r2, #16 \n"/* r2 = r2 + 16. */ - " stm r2, {r4-r11} \n"/* Store the registers that are not saved automatically. */ - " mrs r1, psplim \n"/* r1 = PSPLIM. */ - " mrs r3, control \n"/* r3 = CONTROL. */ - " mov r4, lr \n"/* r4 = LR/EXC_RETURN. */ - " subs r2, r2, #16 \n"/* r2 = r2 - 16. */ - " stmia r2!, {r0, r1, r3, r4} \n"/* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */ - #else /* configENABLE_MPU */ - " subs r2, r2, #44 \n"/* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */ - " str r2, [r1] \n"/* Save the new top of stack in TCB. */ - " adds r2, r2, #12 \n"/* r2 = r2 + 12. */ - " stm r2, {r4-r11} \n"/* Store the registers that are not saved automatically. */ - " mrs r1, psplim \n"/* r1 = PSPLIM. */ - " mov r3, lr \n"/* r3 = LR/EXC_RETURN. */ - " subs r2, r2, #12 \n"/* r2 = r2 - 12. */ - " stmia r2!, {r0, r1, r3} \n"/* Store xSecureContext, PSPLIM and LR on the stack. */ - #endif /* configENABLE_MPU */ + " subs r2, r2, #44 \n"/* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */ + " str r2, [r1] \n"/* Save the new top of stack in TCB. */ + " adds r2, r2, #12 \n"/* r2 = r2 + 12. */ + " stm r2, {r4-r11} \n"/* Store the registers that are not saved automatically. */ + " mrs r1, psplim \n"/* r1 = PSPLIM. */ + " mov r3, lr \n"/* r3 = LR/EXC_RETURN. */ + " subs r2, r2, #12 \n"/* r2 = r2 - 12. */ + " stmia r2!, {r0, r1, r3} \n"/* Store xSecureContext, PSPLIM and LR on the stack. */ " \n" " select_next_task: \n" " mov r0, %0 \n"/* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */ @@ -318,83 +476,22 @@ void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ " ldr r1, [r3] \n"/* Read pxCurrentTCB. */ " ldr r2, [r1] \n"/* The first item in pxCurrentTCB is the task top of stack. r2 now points to the top of stack. */ " \n" - #if ( configENABLE_MPU == 1 ) - " dmb \n"/* Complete outstanding transfers before disabling MPU. */ - " ldr r3, xMPUCTRLConst \n"/* r3 = 0xe000ed94 [Location of MPU_CTRL]. */ - " ldr r4, [r3] \n"/* Read the value of MPU_CTRL. */ - " bic r4, #1 \n"/* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */ - " str r4, [r3] \n"/* Disable MPU. */ - " \n" - " adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */ - " ldr r4, [r1] \n"/* r4 = *r1 i.e. r4 = MAIR0. */ - " ldr r3, xMAIR0Const \n"/* r3 = 0xe000edc0 [Location of MAIR0]. */ - " str r4, [r3] \n"/* Program MAIR0. */ - " ldr r3, xRNRConst \n"/* r3 = 0xe000ed98 [Location of RNR]. */ - " movs r4, #4 \n"/* r4 = 4. */ - " str r4, [r3] \n"/* Program RNR = 4. */ - " adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to first RBAR in TCB. */ - " ldr r3, xRBARConst \n"/* r3 = 0xe000ed9c [Location of RBAR]. */ - " ldmia r1!, {r4-r11} \n"/* Read 4 sets of RBAR/RLAR registers from TCB. */ - " stmia r3!, {r4-r11} \n"/* Write 4 set of RBAR/RLAR registers using alias registers. */ - " \n" - #if ( configTOTAL_MPU_REGIONS == 16 ) - " ldr r3, xRNRConst \n"/* r3 = 0xe000ed98 [Location of RNR]. */ - " movs r4, #8 \n"/* r4 = 8. */ - " str r4, [r3] \n"/* Program RNR = 8. */ - " ldr r3, xRBARConst \n"/* r3 = 0xe000ed9c [Location of RBAR]. */ - " ldmia r1!, {r4-r11} \n"/* Read 4 sets of RBAR/RLAR registers from TCB. */ - " stmia r3!, {r4-r11} \n"/* Write 4 set of RBAR/RLAR registers using alias registers. */ - " ldr r3, xRNRConst \n"/* r3 = 0xe000ed98 [Location of RNR]. */ - " movs r4, #12 \n"/* r4 = 12. */ - " str r4, [r3] \n"/* Program RNR = 12. */ - " ldr r3, xRBARConst \n"/* r3 = 0xe000ed9c [Location of RBAR]. */ - " ldmia r1!, {r4-r11} \n"/* Read 4 sets of RBAR/RLAR registers from TCB. */ - " stmia r3!, {r4-r11} \n"/* Write 4 set of RBAR/RLAR registers using alias registers. */ - #endif /* configTOTAL_MPU_REGIONS == 16 */ - " \n" - " ldr r3, xMPUCTRLConst \n"/* r3 = 0xe000ed94 [Location of MPU_CTRL]. */ - " ldr r4, [r3] \n"/* Read the value of MPU_CTRL. */ - " orr r4, #1 \n"/* r4 = r4 | 1 i.e. Set the bit 0 in r4. */ - " str r4, [r3] \n"/* Enable MPU. */ - " dsb \n"/* Force memory writes before continuing. */ - #endif /* configENABLE_MPU */ - " \n" - #if ( configENABLE_MPU == 1 ) - " ldmia r2!, {r0, r1, r3, r4} \n"/* Read from stack - r0 = xSecureContext, r1 = PSPLIM, r3 = CONTROL and r4 = LR. */ - " msr psplim, r1 \n"/* Restore the PSPLIM register value for the task. */ - " msr control, r3 \n"/* Restore the CONTROL register value for the task. */ - " mov lr, r4 \n"/* LR = r4. */ - " ldr r3, xSecureContextConst \n"/* Read the location of xSecureContext i.e. &( xSecureContext ). */ - " str r0, [r3] \n"/* Restore the task's xSecureContext. */ - " cbz r0, restore_ns_context \n"/* If there is no secure context for the task, restore the non-secure context. */ - " ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - " ldr r1, [r3] \n"/* Read pxCurrentTCB. */ - " push {r2, r4} \n" - " bl SecureContext_LoadContext \n"/* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ - " pop {r2, r4} \n" - " mov lr, r4 \n"/* LR = r4. */ - " lsls r1, r4, #25 \n"/* r1 = r4 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ - " bpl restore_ns_context \n"/* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ - " msr psp, r2 \n"/* Remember the new top of stack for the task. */ - " bx lr \n" - #else /* configENABLE_MPU */ - " ldmia r2!, {r0, r1, r4} \n"/* Read from stack - r0 = xSecureContext, r1 = PSPLIM and r4 = LR. */ - " msr psplim, r1 \n"/* Restore the PSPLIM register value for the task. */ - " mov lr, r4 \n"/* LR = r4. */ - " ldr r3, xSecureContextConst \n"/* Read the location of xSecureContext i.e. &( xSecureContext ). */ - " str r0, [r3] \n"/* Restore the task's xSecureContext. */ - " cbz r0, restore_ns_context \n"/* If there is no secure context for the task, restore the non-secure context. */ - " ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - " ldr r1, [r3] \n"/* Read pxCurrentTCB. */ - " push {r2, r4} \n" - " bl SecureContext_LoadContext \n"/* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ - " pop {r2, r4} \n" - " mov lr, r4 \n"/* LR = r4. */ - " lsls r1, r4, #25 \n"/* r1 = r4 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ - " bpl restore_ns_context \n"/* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ - " msr psp, r2 \n"/* Remember the new top of stack for the task. */ - " bx lr \n" - #endif /* configENABLE_MPU */ + " ldmia r2!, {r0, r1, r4} \n"/* Read from stack - r0 = xSecureContext, r1 = PSPLIM and r4 = LR. */ + " msr psplim, r1 \n"/* Restore the PSPLIM register value for the task. */ + " mov lr, r4 \n"/* LR = r4. */ + " ldr r3, xSecureContextConst \n"/* Read the location of xSecureContext i.e. &( xSecureContext ). */ + " str r0, [r3] \n"/* Restore the task's xSecureContext. */ + " cbz r0, restore_ns_context \n"/* If there is no secure context for the task, restore the non-secure context. */ + " ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r1, [r3] \n"/* Read pxCurrentTCB. */ + " push {r2, r4} \n" + " bl SecureContext_LoadContext \n"/* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ + " pop {r2, r4} \n" + " mov lr, r4 \n"/* LR = r4. */ + " lsls r1, r4, #25 \n"/* r1 = r4 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ + " bpl restore_ns_context \n"/* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ + " msr psp, r2 \n"/* Remember the new top of stack for the task. */ + " bx lr \n" " \n" " restore_ns_context: \n" " ldmia r2!, {r4-r11} \n"/* Restore the registers that are not automatically restored. */ @@ -409,17 +506,60 @@ void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ " .align 4 \n" "pxCurrentTCBConst: .word pxCurrentTCB \n" "xSecureContextConst: .word xSecureContext \n" - #if ( configENABLE_MPU == 1 ) - "xMPUCTRLConst: .word 0xe000ed94 \n" - "xMAIR0Const: .word 0xe000edc0 \n" - "xRNRConst: .word 0xe000ed98 \n" - "xRBARConst: .word 0xe000ed9c \n" - #endif /* configENABLE_MPU */ ::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) ); } + +#endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + +void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ +{ + __asm volatile + ( + ".syntax unified \n" + ".extern vPortSVCHandler_C \n" + ".extern vSystemCallEnter \n" + ".extern vSystemCallEnter_1 \n" + ".extern vSystemCallExit \n" + " \n" + "tst lr, #4 \n" + "ite eq \n" + "mrseq r0, msp \n" + "mrsne r0, psp \n" + " \n" + "ldr r1, [r0, #24] \n" + "ldrb r2, [r1, #-2] \n" + "cmp r2, %0 \n" + "beq syscall_enter \n" + "cmp r2, %1 \n" + "beq syscall_enter_1 \n" + "cmp r2, %2 \n" + "beq syscall_exit \n" + "b vPortSVCHandler_C \n" + " \n" + "syscall_enter: \n" + " mov r1, lr \n" + " b vSystemCallEnter \n" + " \n" + "syscall_enter_1: \n" + " mov r1, lr \n" + " b vSystemCallEnter_1 \n" + " \n" + "syscall_exit: \n" + " mov r1, lr \n" + " b vSystemCallExit \n" + " \n" + : /* No outputs. */ + :"i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_ENTER_1 ), "i" ( portSVC_SYSTEM_CALL_EXIT ) + : "r0", "r1", "r2", "memory" + ); +} + +#else /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ { __asm volatile @@ -437,6 +577,8 @@ void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ "svchandler_address_const: .word vPortSVCHandler_C \n" ); } + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ /*-----------------------------------------------------------*/ void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) /* __attribute__ (( naked )) */ diff --git a/portable/GCC/ARM_CM85/non_secure/portmacro.h b/portable/GCC/ARM_CM85/non_secure/portmacro.h index c45dd21c29e..99f913d3491 100644 --- a/portable/GCC/ARM_CM85/non_secure/portmacro.h +++ b/portable/GCC/ARM_CM85/non_secure/portmacro.h @@ -56,7 +56,6 @@ #define portARCH_NAME "Cortex-M85" #define portHAS_BASEPRI 1 #define portDONT_DISCARD __attribute__( ( used ) ) -#define portNORETURN __attribute__( ( noreturn ) ) /*-----------------------------------------------------------*/ /* ARMv8-M common port configurations. */ diff --git a/portable/GCC/ARM_CM85/non_secure/portmacrocommon.h b/portable/GCC/ARM_CM85/non_secure/portmacrocommon.h index c2ca5fa7730..65ac109c802 100644 --- a/portable/GCC/ARM_CM85/non_secure/portmacrocommon.h +++ b/portable/GCC/ARM_CM85/non_secure/portmacrocommon.h @@ -186,23 +186,120 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #define portMPU_REGION_EXECUTE_NEVER ( 1UL ) /*-----------------------------------------------------------*/ -/** - * @brief Settings to define an MPU region. - */ -typedef struct MPURegionSettings -{ - uint32_t ulRBAR; /**< RBAR for the region. */ - uint32_t ulRLAR; /**< RLAR for the region. */ -} MPURegionSettings_t; +#if ( configENABLE_MPU == 1 ) -/** - * @brief MPU settings as stored in the TCB. - */ -typedef struct MPU_SETTINGS -{ - uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ - MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */ -} xMPU_SETTINGS; + /** + * @brief Settings to define an MPU region. + */ + typedef struct MPURegionSettings + { + uint32_t ulRBAR; /**< RBAR for the region. */ + uint32_t ulRLAR; /**< RLAR for the region. */ + } MPURegionSettings_t; + + #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + + #ifndef configSYSTEM_CALL_STACK_SIZE + #error configSYSTEM_CALL_STACK_SIZE must be defined to the desired size of the system call stack in words for using MPU wrappers v2. + #endif + + /** + * @brief System call stack. + */ + typedef struct SYSTEM_CALL_STACK_INFO + { + uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ]; + uint32_t * pulSystemCallStack; + uint32_t * pulSystemCallStackLimit; + uint32_t * pulTaskStack; + uint32_t ulLinkRegisterAtSystemCallEntry; + uint32_t ulStackLimitRegisterAtSystemCallEntry; + } xSYSTEM_CALL_STACK_INFO; + + #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + + /** + * @brief MPU settings as stored in the TCB. + */ + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + + #if( configENABLE_TRUSTZONE == 1 ) + + /* + * +-----------+---------------+----------+-----------------+------------------------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | + * | | | | PC, xPSR | CONTROL, EXC_RETURN | | + * +-----------+---------------+----------+-----------------+------------------------------+-----+ + * + * <-----------><--------------><---------><----------------><-----------------------------><----> + * 16 16 8 8 5 1 + */ + #define MAX_CONTEXT_SIZE 54 + + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ + + /* + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | + * | | | | PC, xPSR | EXC_RETURN | | + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * + * <-----------><--------------><---------><----------------><---------------------><----> + * 16 16 8 8 4 1 + */ + #define MAX_CONTEXT_SIZE 53 + + #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + + #else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ + + #if( configENABLE_TRUSTZONE == 1 ) + + /* + * +----------+-----------------+------------------------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | + * | | PC, xPSR | CONTROL, EXC_RETURN | | + * +----------+-----------------+------------------------------+-----+ + * + * <---------><----------------><------------------------------><----> + * 8 8 5 1 + */ + #define MAX_CONTEXT_SIZE 22 + + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ + + /* + * +----------+-----------------+----------------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | + * | | PC, xPSR | EXC_RETURN | | + * +----------+-----------------+----------------------+-----+ + * + * <---------><----------------><----------------------><----> + * 8 8 4 1 + */ + #define MAX_CONTEXT_SIZE 21 + + #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + + #endif /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ + + /* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ + #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) + #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) + + typedef struct MPU_SETTINGS + { + uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ + MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */ + uint32_t ulContext[ MAX_CONTEXT_SIZE ]; + uint32_t ulTaskFlags; + + #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo; + #endif + } xMPU_SETTINGS; + +#endif /* configENABLE_MPU == 1 */ /*-----------------------------------------------------------*/ /** @@ -223,6 +320,9 @@ typedef struct MPU_SETTINGS #define portSVC_FREE_SECURE_CONTEXT 1 #define portSVC_START_SCHEDULER 2 #define portSVC_RAISE_PRIVILEGE 3 +#define portSVC_SYSTEM_CALL_ENTER 4 /* System calls with upto 4 parameters. */ +#define portSVC_SYSTEM_CALL_ENTER_1 5 /* System calls with 5 parameters. */ +#define portSVC_SYSTEM_CALL_EXIT 6 /*-----------------------------------------------------------*/ /** @@ -315,6 +415,20 @@ typedef struct MPU_SETTINGS #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ +#if ( configENABLE_MPU == 1 ) + + extern BaseType_t xPortIsTaskPrivileged( void ); + + /** + * @brief Checks whether or not the calling task is privileged. + * + * @return pdTRUE if the calling task is privileged, pdFALSE otherwise. + */ + #define portIS_TASK_PRIVILEGED() xPortIsTaskPrivileged() + +#endif /* configENABLE_MPU == 1 */ +/*-----------------------------------------------------------*/ + /** * @brief Barriers. */ diff --git a/portable/GCC/ARM_CM85_NTZ/non_secure/mpu_wrappers_v2_asm.c b/portable/GCC/ARM_CM85_NTZ/non_secure/mpu_wrappers_v2_asm.c new file mode 100644 index 00000000000..6e2043427fe --- /dev/null +++ b/portable/GCC/ARM_CM85_NTZ/non_secure/mpu_wrappers_v2_asm.c @@ -0,0 +1,2349 @@ +/* + * FreeRTOS Kernel + * Copyright (C) 2021 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 + * + */ + +/* 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. */ +#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +/* Scheduler includes. */ +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" +#include "timers.h" +#include "event_groups.h" +#include "stream_buffer.h" + +#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + +#if ( INCLUDE_xTaskDelayUntil == 1 ) + +BaseType_t MPU_xTaskDelayUntil( TickType_t * const pxPreviousWakeTime, + const TickType_t xTimeIncrement ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskDelayUntil( TickType_t * const pxPreviousWakeTime, + const TickType_t xTimeIncrement ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskDelayUntilImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskDelayUntil_Unpriv \n" + " MPU_xTaskDelayUntil_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskDelayUntilImpl \n" + " MPU_xTaskDelayUntil_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskDelayUntilImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_xTaskDelayUntil == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_xTaskAbortDelay == 1 ) + +BaseType_t MPU_xTaskAbortDelay( TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskAbortDelay( TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskAbortDelayImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskAbortDelay_Unpriv \n" + " MPU_xTaskAbortDelay_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskAbortDelayImpl \n" + " MPU_xTaskAbortDelay_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskAbortDelayImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_xTaskAbortDelay == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskDelay == 1 ) + +void MPU_vTaskDelay( const TickType_t xTicksToDelay ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskDelay( const TickType_t xTicksToDelay ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskDelayImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vTaskDelay_Unpriv \n" + " MPU_vTaskDelay_Priv: \n" + " pop {r0} \n" + " b MPU_vTaskDelayImpl \n" + " MPU_vTaskDelay_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vTaskDelayImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_vTaskDelay == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_uxTaskPriorityGet == 1 ) + +UBaseType_t MPU_uxTaskPriorityGet( const TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxTaskPriorityGet( const TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxTaskPriorityGetImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_uxTaskPriorityGet_Unpriv \n" + " MPU_uxTaskPriorityGet_Priv: \n" + " pop {r0} \n" + " b MPU_uxTaskPriorityGetImpl \n" + " MPU_uxTaskPriorityGet_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_uxTaskPriorityGetImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_uxTaskPriorityGet == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_eTaskGetState == 1 ) + +eTaskState MPU_eTaskGetState( TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +eTaskState MPU_eTaskGetState( TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_eTaskGetStateImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_eTaskGetState_Unpriv \n" + " MPU_eTaskGetState_Priv: \n" + " pop {r0} \n" + " b MPU_eTaskGetStateImpl \n" + " MPU_eTaskGetState_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_eTaskGetStateImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_eTaskGetState == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + +void MPU_vTaskGetInfo( TaskHandle_t xTask, + TaskStatus_t * pxTaskStatus, + BaseType_t xGetFreeStackSpace, + eTaskState eState ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskGetInfo( TaskHandle_t xTask, + TaskStatus_t * pxTaskStatus, + BaseType_t xGetFreeStackSpace, + eTaskState eState ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskGetInfoImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vTaskGetInfo_Unpriv \n" + " MPU_vTaskGetInfo_Priv: \n" + " pop {r0} \n" + " b MPU_vTaskGetInfoImpl \n" + " MPU_vTaskGetInfo_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vTaskGetInfoImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TRACE_FACILITY == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) + +TaskHandle_t MPU_xTaskGetIdleTaskHandle( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TaskHandle_t MPU_xTaskGetIdleTaskHandle( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGetIdleTaskHandleImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskGetIdleTaskHandle_Unpriv \n" + " MPU_xTaskGetIdleTaskHandle_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskGetIdleTaskHandleImpl \n" + " MPU_xTaskGetIdleTaskHandle_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskGetIdleTaskHandleImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskSuspend == 1 ) + +void MPU_vTaskSuspend( TaskHandle_t xTaskToSuspend ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskSuspend( TaskHandle_t xTaskToSuspend ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskSuspendImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vTaskSuspend_Unpriv \n" + " MPU_vTaskSuspend_Priv: \n" + " pop {r0} \n" + " b MPU_vTaskSuspendImpl \n" + " MPU_vTaskSuspend_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vTaskSuspendImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_vTaskSuspend == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskSuspend == 1 ) + +void MPU_vTaskResume( TaskHandle_t xTaskToResume ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskResume( TaskHandle_t xTaskToResume ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskResumeImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vTaskResume_Unpriv \n" + " MPU_vTaskResume_Priv: \n" + " pop {r0} \n" + " b MPU_vTaskResumeImpl \n" + " MPU_vTaskResume_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vTaskResumeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_vTaskSuspend == 1 ) */ +/*-----------------------------------------------------------*/ + +TickType_t MPU_xTaskGetTickCount( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TickType_t MPU_xTaskGetTickCount( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGetTickCountImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskGetTickCount_Unpriv \n" + " MPU_xTaskGetTickCount_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskGetTickCountImpl \n" + " MPU_xTaskGetTickCount_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskGetTickCountImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +UBaseType_t MPU_uxTaskGetNumberOfTasks( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxTaskGetNumberOfTasks( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxTaskGetNumberOfTasksImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_uxTaskGetNumberOfTasks_Unpriv \n" + " MPU_uxTaskGetNumberOfTasks_Priv: \n" + " pop {r0} \n" + " b MPU_uxTaskGetNumberOfTasksImpl \n" + " MPU_uxTaskGetNumberOfTasks_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_uxTaskGetNumberOfTasksImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +char * MPU_pcTaskGetName( TaskHandle_t xTaskToQuery ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +char * MPU_pcTaskGetName( TaskHandle_t xTaskToQuery ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_pcTaskGetNameImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_pcTaskGetName_Unpriv \n" + " MPU_pcTaskGetName_Priv: \n" + " pop {r0} \n" + " b MPU_pcTaskGetNameImpl \n" + " MPU_pcTaskGetName_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_pcTaskGetNameImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +#if ( configGENERATE_RUN_TIME_STATS == 1 ) + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetRunTimeCounter( const TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetRunTimeCounter( const TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_ulTaskGetRunTimeCounterImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_ulTaskGetRunTimeCounter_Unpriv \n" + " MPU_ulTaskGetRunTimeCounter_Priv: \n" + " pop {r0} \n" + " b MPU_ulTaskGetRunTimeCounterImpl \n" + " MPU_ulTaskGetRunTimeCounter_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_ulTaskGetRunTimeCounterImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( ( configGENERATE_RUN_TIME_STATS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configGENERATE_RUN_TIME_STATS == 1 ) + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetRunTimePercent( const TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetRunTimePercent( const TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_ulTaskGetRunTimePercentImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_ulTaskGetRunTimePercent_Unpriv \n" + " MPU_ulTaskGetRunTimePercent_Priv: \n" + " pop {r0} \n" + " b MPU_ulTaskGetRunTimePercentImpl \n" + " MPU_ulTaskGetRunTimePercent_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_ulTaskGetRunTimePercentImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( ( configGENERATE_RUN_TIME_STATS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimePercent( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimePercent( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_ulTaskGetIdleRunTimePercentImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_ulTaskGetIdleRunTimePercent_Unpriv \n" + " MPU_ulTaskGetIdleRunTimePercent_Priv: \n" + " pop {r0} \n" + " b MPU_ulTaskGetIdleRunTimePercentImpl \n" + " MPU_ulTaskGetIdleRunTimePercent_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_ulTaskGetIdleRunTimePercentImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimeCounter( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimeCounter( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_ulTaskGetIdleRunTimeCounterImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_ulTaskGetIdleRunTimeCounter_Unpriv \n" + " MPU_ulTaskGetIdleRunTimeCounter_Priv: \n" + " pop {r0} \n" + " b MPU_ulTaskGetIdleRunTimeCounterImpl \n" + " MPU_ulTaskGetIdleRunTimeCounter_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_ulTaskGetIdleRunTimeCounterImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_APPLICATION_TASK_TAG == 1 ) + +void MPU_vTaskSetApplicationTaskTag( TaskHandle_t xTask, + TaskHookFunction_t pxHookFunction ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskSetApplicationTaskTag( TaskHandle_t xTask, + TaskHookFunction_t pxHookFunction ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskSetApplicationTaskTagImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vTaskSetApplicationTaskTag_Unpriv \n" + " MPU_vTaskSetApplicationTaskTag_Priv: \n" + " pop {r0} \n" + " b MPU_vTaskSetApplicationTaskTagImpl \n" + " MPU_vTaskSetApplicationTaskTag_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vTaskSetApplicationTaskTagImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_APPLICATION_TASK_TAG == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_APPLICATION_TASK_TAG == 1 ) + +TaskHookFunction_t MPU_xTaskGetApplicationTaskTag( TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TaskHookFunction_t MPU_xTaskGetApplicationTaskTag( TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGetApplicationTaskTagImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskGetApplicationTaskTag_Unpriv \n" + " MPU_xTaskGetApplicationTaskTag_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskGetApplicationTaskTagImpl \n" + " MPU_xTaskGetApplicationTaskTag_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskGetApplicationTaskTagImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_APPLICATION_TASK_TAG == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) + +void MPU_vTaskSetThreadLocalStoragePointer( TaskHandle_t xTaskToSet, + BaseType_t xIndex, + void * pvValue ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskSetThreadLocalStoragePointer( TaskHandle_t xTaskToSet, + BaseType_t xIndex, + void * pvValue ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskSetThreadLocalStoragePointerImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vTaskSetThreadLocalStoragePointer_Unpriv \n" + " MPU_vTaskSetThreadLocalStoragePointer_Priv: \n" + " pop {r0} \n" + " b MPU_vTaskSetThreadLocalStoragePointerImpl \n" + " MPU_vTaskSetThreadLocalStoragePointer_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vTaskSetThreadLocalStoragePointerImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) + +void * MPU_pvTaskGetThreadLocalStoragePointer( TaskHandle_t xTaskToQuery, + BaseType_t xIndex ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void * MPU_pvTaskGetThreadLocalStoragePointer( TaskHandle_t xTaskToQuery, + BaseType_t xIndex ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_pvTaskGetThreadLocalStoragePointerImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_pvTaskGetThreadLocalStoragePointer_Unpriv \n" + " MPU_pvTaskGetThreadLocalStoragePointer_Priv: \n" + " pop {r0} \n" + " b MPU_pvTaskGetThreadLocalStoragePointerImpl \n" + " MPU_pvTaskGetThreadLocalStoragePointer_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_pvTaskGetThreadLocalStoragePointerImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + +UBaseType_t MPU_uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray, + const UBaseType_t uxArraySize, + configRUN_TIME_COUNTER_TYPE * const pulTotalRunTime ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray, + const UBaseType_t uxArraySize, + configRUN_TIME_COUNTER_TYPE * const pulTotalRunTime ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxTaskGetSystemStateImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_uxTaskGetSystemState_Unpriv \n" + " MPU_uxTaskGetSystemState_Priv: \n" + " pop {r0} \n" + " b MPU_uxTaskGetSystemStateImpl \n" + " MPU_uxTaskGetSystemState_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_uxTaskGetSystemStateImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TRACE_FACILITY == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) + +UBaseType_t MPU_uxTaskGetStackHighWaterMark( TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxTaskGetStackHighWaterMark( TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxTaskGetStackHighWaterMarkImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_uxTaskGetStackHighWaterMark_Unpriv \n" + " MPU_uxTaskGetStackHighWaterMark_Priv: \n" + " pop {r0} \n" + " b MPU_uxTaskGetStackHighWaterMarkImpl \n" + " MPU_uxTaskGetStackHighWaterMark_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_uxTaskGetStackHighWaterMarkImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) + +configSTACK_DEPTH_TYPE MPU_uxTaskGetStackHighWaterMark2( TaskHandle_t xTask ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +configSTACK_DEPTH_TYPE MPU_uxTaskGetStackHighWaterMark2( TaskHandle_t xTask ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxTaskGetStackHighWaterMark2Impl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_uxTaskGetStackHighWaterMark2_Unpriv \n" + " MPU_uxTaskGetStackHighWaterMark2_Priv: \n" + " pop {r0} \n" + " b MPU_uxTaskGetStackHighWaterMark2Impl \n" + " MPU_uxTaskGetStackHighWaterMark2_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_uxTaskGetStackHighWaterMark2Impl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) ) + +TaskHandle_t MPU_xTaskGetCurrentTaskHandle( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TaskHandle_t MPU_xTaskGetCurrentTaskHandle( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGetCurrentTaskHandleImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskGetCurrentTaskHandle_Unpriv \n" + " MPU_xTaskGetCurrentTaskHandle_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskGetCurrentTaskHandleImpl \n" + " MPU_xTaskGetCurrentTaskHandle_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskGetCurrentTaskHandleImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_xTaskGetSchedulerState == 1 ) + +BaseType_t MPU_xTaskGetSchedulerState( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskGetSchedulerState( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGetSchedulerStateImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskGetSchedulerState_Unpriv \n" + " MPU_xTaskGetSchedulerState_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskGetSchedulerStateImpl \n" + " MPU_xTaskGetSchedulerState_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskGetSchedulerStateImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( INCLUDE_xTaskGetSchedulerState == 1 ) */ +/*-----------------------------------------------------------*/ + +void MPU_vTaskSetTimeOutState( TimeOut_t * const pxTimeOut ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskSetTimeOutState( TimeOut_t * const pxTimeOut ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTaskSetTimeOutStateImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vTaskSetTimeOutState_Unpriv \n" + " MPU_vTaskSetTimeOutState_Priv: \n" + " pop {r0} \n" + " b MPU_vTaskSetTimeOutStateImpl \n" + " MPU_vTaskSetTimeOutState_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vTaskSetTimeOutStateImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut, + TickType_t * const pxTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut, + TickType_t * const pxTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskCheckForTimeOutImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskCheckForTimeOut_Unpriv \n" + " MPU_xTaskCheckForTimeOut_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskCheckForTimeOutImpl \n" + " MPU_xTaskCheckForTimeOut_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskCheckForTimeOutImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +#if ( configUSE_TASK_NOTIFICATIONS == 1 ) + +BaseType_t MPU_xTaskGenericNotify( TaskHandle_t xTaskToNotify, + UBaseType_t uxIndexToNotify, + uint32_t ulValue, + eNotifyAction eAction, + uint32_t * pulPreviousNotificationValue ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskGenericNotify( TaskHandle_t xTaskToNotify, + UBaseType_t uxIndexToNotify, + uint32_t ulValue, + eNotifyAction eAction, + uint32_t * pulPreviousNotificationValue ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGenericNotifyImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskGenericNotify_Unpriv \n" + " MPU_xTaskGenericNotify_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskGenericNotifyImpl \n" + " MPU_xTaskGenericNotify_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskGenericNotifyImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER_1 ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TASK_NOTIFICATIONS == 1 ) + +BaseType_t MPU_xTaskGenericNotifyWait( UBaseType_t uxIndexToWaitOn, + uint32_t ulBitsToClearOnEntry, + uint32_t ulBitsToClearOnExit, + uint32_t * pulNotificationValue, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskGenericNotifyWait( UBaseType_t uxIndexToWaitOn, + uint32_t ulBitsToClearOnEntry, + uint32_t ulBitsToClearOnExit, + uint32_t * pulNotificationValue, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGenericNotifyWaitImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskGenericNotifyWait_Unpriv \n" + " MPU_xTaskGenericNotifyWait_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskGenericNotifyWaitImpl \n" + " MPU_xTaskGenericNotifyWait_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskGenericNotifyWaitImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER_1 ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TASK_NOTIFICATIONS == 1 ) + +uint32_t MPU_ulTaskGenericNotifyTake( UBaseType_t uxIndexToWaitOn, + BaseType_t xClearCountOnExit, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +uint32_t MPU_ulTaskGenericNotifyTake( UBaseType_t uxIndexToWaitOn, + BaseType_t xClearCountOnExit, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_ulTaskGenericNotifyTakeImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_ulTaskGenericNotifyTake_Unpriv \n" + " MPU_ulTaskGenericNotifyTake_Priv: \n" + " pop {r0} \n" + " b MPU_ulTaskGenericNotifyTakeImpl \n" + " MPU_ulTaskGenericNotifyTake_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_ulTaskGenericNotifyTakeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TASK_NOTIFICATIONS == 1 ) + +BaseType_t MPU_xTaskGenericNotifyStateClear( TaskHandle_t xTask, + UBaseType_t uxIndexToClear ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskGenericNotifyStateClear( TaskHandle_t xTask, + UBaseType_t uxIndexToClear ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTaskGenericNotifyStateClearImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTaskGenericNotifyStateClear_Unpriv \n" + " MPU_xTaskGenericNotifyStateClear_Priv: \n" + " pop {r0} \n" + " b MPU_xTaskGenericNotifyStateClearImpl \n" + " MPU_xTaskGenericNotifyStateClear_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTaskGenericNotifyStateClearImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TASK_NOTIFICATIONS == 1 ) + +uint32_t MPU_ulTaskGenericNotifyValueClear( TaskHandle_t xTask, + UBaseType_t uxIndexToClear, + uint32_t ulBitsToClear ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +uint32_t MPU_ulTaskGenericNotifyValueClear( TaskHandle_t xTask, + UBaseType_t uxIndexToClear, + uint32_t ulBitsToClear ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_ulTaskGenericNotifyValueClearImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_ulTaskGenericNotifyValueClear_Unpriv \n" + " MPU_ulTaskGenericNotifyValueClear_Priv: \n" + " pop {r0} \n" + " b MPU_ulTaskGenericNotifyValueClearImpl \n" + " MPU_ulTaskGenericNotifyValueClear_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_ulTaskGenericNotifyValueClearImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xQueueGenericSend( QueueHandle_t xQueue, + const void * const pvItemToQueue, + TickType_t xTicksToWait, + const BaseType_t xCopyPosition ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueueGenericSend( QueueHandle_t xQueue, + const void * const pvItemToQueue, + TickType_t xTicksToWait, + const BaseType_t xCopyPosition ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueGenericSendImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xQueueGenericSend_Unpriv \n" + " MPU_xQueueGenericSend_Priv: \n" + " pop {r0} \n" + " b MPU_xQueueGenericSendImpl \n" + " MPU_xQueueGenericSend_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xQueueGenericSendImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +UBaseType_t MPU_uxQueueMessagesWaiting( const QueueHandle_t xQueue ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxQueueMessagesWaiting( const QueueHandle_t xQueue ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxQueueMessagesWaitingImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_uxQueueMessagesWaiting_Unpriv \n" + " MPU_uxQueueMessagesWaiting_Priv: \n" + " pop {r0} \n" + " b MPU_uxQueueMessagesWaitingImpl \n" + " MPU_uxQueueMessagesWaiting_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_uxQueueMessagesWaitingImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +UBaseType_t MPU_uxQueueSpacesAvailable( const QueueHandle_t xQueue ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxQueueSpacesAvailable( const QueueHandle_t xQueue ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxQueueSpacesAvailableImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_uxQueueSpacesAvailable_Unpriv \n" + " MPU_uxQueueSpacesAvailable_Priv: \n" + " pop {r0} \n" + " b MPU_uxQueueSpacesAvailableImpl \n" + " MPU_uxQueueSpacesAvailable_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_uxQueueSpacesAvailableImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xQueueReceive( QueueHandle_t xQueue, + void * const pvBuffer, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueueReceive( QueueHandle_t xQueue, + void * const pvBuffer, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueReceiveImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xQueueReceive_Unpriv \n" + " MPU_xQueueReceive_Priv: \n" + " pop {r0} \n" + " b MPU_xQueueReceiveImpl \n" + " MPU_xQueueReceive_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xQueueReceiveImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xQueuePeek( QueueHandle_t xQueue, + void * const pvBuffer, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueuePeek( QueueHandle_t xQueue, + void * const pvBuffer, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueuePeekImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xQueuePeek_Unpriv \n" + " MPU_xQueuePeek_Priv: \n" + " pop {r0} \n" + " b MPU_xQueuePeekImpl \n" + " MPU_xQueuePeek_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xQueuePeekImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xQueueSemaphoreTake( QueueHandle_t xQueue, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueueSemaphoreTake( QueueHandle_t xQueue, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueSemaphoreTakeImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xQueueSemaphoreTake_Unpriv \n" + " MPU_xQueueSemaphoreTake_Priv: \n" + " pop {r0} \n" + " b MPU_xQueueSemaphoreTakeImpl \n" + " MPU_xQueueSemaphoreTake_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xQueueSemaphoreTakeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +#if ( ( configUSE_MUTEXES == 1 ) && ( INCLUDE_xSemaphoreGetMutexHolder == 1 ) ) + +TaskHandle_t MPU_xQueueGetMutexHolder( QueueHandle_t xSemaphore ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TaskHandle_t MPU_xQueueGetMutexHolder( QueueHandle_t xSemaphore ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueGetMutexHolderImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xQueueGetMutexHolder_Unpriv \n" + " MPU_xQueueGetMutexHolder_Priv: \n" + " pop {r0} \n" + " b MPU_xQueueGetMutexHolderImpl \n" + " MPU_xQueueGetMutexHolder_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xQueueGetMutexHolderImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( ( configUSE_MUTEXES == 1 ) && ( INCLUDE_xSemaphoreGetMutexHolder == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_RECURSIVE_MUTEXES == 1 ) + +BaseType_t MPU_xQueueTakeMutexRecursive( QueueHandle_t xMutex, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueueTakeMutexRecursive( QueueHandle_t xMutex, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueTakeMutexRecursiveImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xQueueTakeMutexRecursive_Unpriv \n" + " MPU_xQueueTakeMutexRecursive_Priv: \n" + " pop {r0} \n" + " b MPU_xQueueTakeMutexRecursiveImpl \n" + " MPU_xQueueTakeMutexRecursive_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xQueueTakeMutexRecursiveImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_RECURSIVE_MUTEXES == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_RECURSIVE_MUTEXES == 1 ) + +BaseType_t MPU_xQueueGiveMutexRecursive( QueueHandle_t pxMutex ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueueGiveMutexRecursive( QueueHandle_t pxMutex ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueGiveMutexRecursiveImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xQueueGiveMutexRecursive_Unpriv \n" + " MPU_xQueueGiveMutexRecursive_Priv: \n" + " pop {r0} \n" + " b MPU_xQueueGiveMutexRecursiveImpl \n" + " MPU_xQueueGiveMutexRecursive_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xQueueGiveMutexRecursiveImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_RECURSIVE_MUTEXES == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_QUEUE_SETS == 1 ) + +QueueSetMemberHandle_t MPU_xQueueSelectFromSet( QueueSetHandle_t xQueueSet, + const TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +QueueSetMemberHandle_t MPU_xQueueSelectFromSet( QueueSetHandle_t xQueueSet, + const TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueSelectFromSetImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xQueueSelectFromSet_Unpriv \n" + " MPU_xQueueSelectFromSet_Priv: \n" + " pop {r0} \n" + " b MPU_xQueueSelectFromSetImpl \n" + " MPU_xQueueSelectFromSet_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xQueueSelectFromSetImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_QUEUE_SETS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_QUEUE_SETS == 1 ) + +BaseType_t MPU_xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore, + QueueSetHandle_t xQueueSet ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore, + QueueSetHandle_t xQueueSet ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xQueueAddToSetImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xQueueAddToSet_Unpriv \n" + " MPU_xQueueAddToSet_Priv: \n" + " pop {r0} \n" + " b MPU_xQueueAddToSetImpl \n" + " MPU_xQueueAddToSet_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xQueueAddToSetImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_QUEUE_SETS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configQUEUE_REGISTRY_SIZE > 0 ) + +void MPU_vQueueAddToRegistry( QueueHandle_t xQueue, + const char * pcName ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vQueueAddToRegistry( QueueHandle_t xQueue, + const char * pcName ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vQueueAddToRegistryImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vQueueAddToRegistry_Unpriv \n" + " MPU_vQueueAddToRegistry_Priv: \n" + " pop {r0} \n" + " b MPU_vQueueAddToRegistryImpl \n" + " MPU_vQueueAddToRegistry_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vQueueAddToRegistryImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configQUEUE_REGISTRY_SIZE > 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configQUEUE_REGISTRY_SIZE > 0 ) + +void MPU_vQueueUnregisterQueue( QueueHandle_t xQueue ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vQueueUnregisterQueue( QueueHandle_t xQueue ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vQueueUnregisterQueueImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vQueueUnregisterQueue_Unpriv \n" + " MPU_vQueueUnregisterQueue_Priv: \n" + " pop {r0} \n" + " b MPU_vQueueUnregisterQueueImpl \n" + " MPU_vQueueUnregisterQueue_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vQueueUnregisterQueueImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configQUEUE_REGISTRY_SIZE > 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configQUEUE_REGISTRY_SIZE > 0 ) + +const char * MPU_pcQueueGetName( QueueHandle_t xQueue ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +const char * MPU_pcQueueGetName( QueueHandle_t xQueue ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_pcQueueGetNameImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_pcQueueGetName_Unpriv \n" + " MPU_pcQueueGetName_Priv: \n" + " pop {r0} \n" + " b MPU_pcQueueGetNameImpl \n" + " MPU_pcQueueGetName_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_pcQueueGetNameImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configQUEUE_REGISTRY_SIZE > 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +void * MPU_pvTimerGetTimerID( const TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void * MPU_pvTimerGetTimerID( const TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_pvTimerGetTimerIDImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_pvTimerGetTimerID_Unpriv \n" + " MPU_pvTimerGetTimerID_Priv: \n" + " pop {r0} \n" + " b MPU_pvTimerGetTimerIDImpl \n" + " MPU_pvTimerGetTimerID_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_pvTimerGetTimerIDImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +void MPU_vTimerSetTimerID( TimerHandle_t xTimer, + void * pvNewID ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTimerSetTimerID( TimerHandle_t xTimer, + void * pvNewID ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTimerSetTimerIDImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vTimerSetTimerID_Unpriv \n" + " MPU_vTimerSetTimerID_Priv: \n" + " pop {r0} \n" + " b MPU_vTimerSetTimerIDImpl \n" + " MPU_vTimerSetTimerID_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vTimerSetTimerIDImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +BaseType_t MPU_xTimerIsTimerActive( TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTimerIsTimerActive( TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTimerIsTimerActiveImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTimerIsTimerActive_Unpriv \n" + " MPU_xTimerIsTimerActive_Priv: \n" + " pop {r0} \n" + " b MPU_xTimerIsTimerActiveImpl \n" + " MPU_xTimerIsTimerActive_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTimerIsTimerActiveImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +TaskHandle_t MPU_xTimerGetTimerDaemonTaskHandle( void ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TaskHandle_t MPU_xTimerGetTimerDaemonTaskHandle( void ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTimerGetTimerDaemonTaskHandleImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTimerGetTimerDaemonTaskHandle_Unpriv \n" + " MPU_xTimerGetTimerDaemonTaskHandle_Priv: \n" + " pop {r0} \n" + " b MPU_xTimerGetTimerDaemonTaskHandleImpl \n" + " MPU_xTimerGetTimerDaemonTaskHandle_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTimerGetTimerDaemonTaskHandleImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +BaseType_t MPU_xTimerGenericCommand( TimerHandle_t xTimer, + const BaseType_t xCommandID, + const TickType_t xOptionalValue, + BaseType_t * const pxHigherPriorityTaskWoken, + const TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTimerGenericCommand( TimerHandle_t xTimer, + const BaseType_t xCommandID, + const TickType_t xOptionalValue, + BaseType_t * const pxHigherPriorityTaskWoken, + const TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTimerGenericCommandImpl \n" + " \n" + " push {r0} \n" + " mrs r0, ipsr \n" + " cmp r0, #0 \n" + " bne MPU_xTimerGenericCommand_Priv \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " beq MPU_xTimerGenericCommand_Priv \n" + " MPU_xTimerGenericCommand_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTimerGenericCommandImpl \n" + " svc %1 \n" + " bx lr \n" + " MPU_xTimerGenericCommand_Priv: \n" + " pop {r0} \n" + " b MPU_xTimerGenericCommandImpl \n" + " \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER_1 ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +const char * MPU_pcTimerGetName( TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +const char * MPU_pcTimerGetName( TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_pcTimerGetNameImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_pcTimerGetName_Unpriv \n" + " MPU_pcTimerGetName_Priv: \n" + " pop {r0} \n" + " b MPU_pcTimerGetNameImpl \n" + " MPU_pcTimerGetName_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_pcTimerGetNameImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, + const BaseType_t uxAutoReload ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, + const BaseType_t uxAutoReload ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vTimerSetReloadModeImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vTimerSetReloadMode_Unpriv \n" + " MPU_vTimerSetReloadMode_Priv: \n" + " pop {r0} \n" + " b MPU_vTimerSetReloadModeImpl \n" + " MPU_vTimerSetReloadMode_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vTimerSetReloadModeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +BaseType_t MPU_xTimerGetReloadMode( TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTimerGetReloadMode( TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTimerGetReloadModeImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTimerGetReloadMode_Unpriv \n" + " MPU_xTimerGetReloadMode_Priv: \n" + " pop {r0} \n" + " b MPU_xTimerGetReloadModeImpl \n" + " MPU_xTimerGetReloadMode_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTimerGetReloadModeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +UBaseType_t MPU_uxTimerGetReloadMode( TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxTimerGetReloadMode( TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxTimerGetReloadModeImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_uxTimerGetReloadMode_Unpriv \n" + " MPU_uxTimerGetReloadMode_Priv: \n" + " pop {r0} \n" + " b MPU_uxTimerGetReloadModeImpl \n" + " MPU_uxTimerGetReloadMode_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_uxTimerGetReloadModeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +TickType_t MPU_xTimerGetPeriod( TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TickType_t MPU_xTimerGetPeriod( TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTimerGetPeriodImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTimerGetPeriod_Unpriv \n" + " MPU_xTimerGetPeriod_Priv: \n" + " pop {r0} \n" + " b MPU_xTimerGetPeriodImpl \n" + " MPU_xTimerGetPeriod_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTimerGetPeriodImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +TickType_t MPU_xTimerGetExpiryTime( TimerHandle_t xTimer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +TickType_t MPU_xTimerGetExpiryTime( TimerHandle_t xTimer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xTimerGetExpiryTimeImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xTimerGetExpiryTime_Unpriv \n" + " MPU_xTimerGetExpiryTime_Priv: \n" + " pop {r0} \n" + " b MPU_xTimerGetExpiryTimeImpl \n" + " MPU_xTimerGetExpiryTime_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xTimerGetExpiryTimeImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +EventBits_t MPU_xEventGroupWaitBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToWaitFor, + const BaseType_t xClearOnExit, + const BaseType_t xWaitForAllBits, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +EventBits_t MPU_xEventGroupWaitBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToWaitFor, + const BaseType_t xClearOnExit, + const BaseType_t xWaitForAllBits, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupWaitBitsImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xEventGroupWaitBits_Unpriv \n" + " MPU_xEventGroupWaitBits_Priv: \n" + " pop {r0} \n" + " b MPU_xEventGroupWaitBitsImpl \n" + " MPU_xEventGroupWaitBits_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xEventGroupWaitBitsImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER_1 ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToClear ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToClear ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupClearBitsImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xEventGroupClearBits_Unpriv \n" + " MPU_xEventGroupClearBits_Priv: \n" + " pop {r0} \n" + " b MPU_xEventGroupClearBitsImpl \n" + " MPU_xEventGroupClearBits_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xEventGroupClearBitsImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupSetBitsImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xEventGroupSetBits_Unpriv \n" + " MPU_xEventGroupSetBits_Priv: \n" + " pop {r0} \n" + " b MPU_xEventGroupSetBitsImpl \n" + " MPU_xEventGroupSetBits_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xEventGroupSetBitsImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet, + const EventBits_t uxBitsToWaitFor, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet, + const EventBits_t uxBitsToWaitFor, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xEventGroupSyncImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xEventGroupSync_Unpriv \n" + " MPU_xEventGroupSync_Priv: \n" + " pop {r0} \n" + " b MPU_xEventGroupSyncImpl \n" + " MPU_xEventGroupSync_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xEventGroupSyncImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + +UBaseType_t MPU_uxEventGroupGetNumber( void * xEventGroup ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxEventGroupGetNumber( void * xEventGroup ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_uxEventGroupGetNumberImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_uxEventGroupGetNumber_Unpriv \n" + " MPU_uxEventGroupGetNumber_Priv: \n" + " pop {r0} \n" + " b MPU_uxEventGroupGetNumberImpl \n" + " MPU_uxEventGroupGetNumber_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_uxEventGroupGetNumberImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /*( configUSE_TRACE_FACILITY == 1 )*/ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + +void MPU_vEventGroupSetNumber( void * xEventGroup, + UBaseType_t uxEventGroupNumber ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +void MPU_vEventGroupSetNumber( void * xEventGroup, + UBaseType_t uxEventGroupNumber ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_vEventGroupSetNumberImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_vEventGroupSetNumber_Unpriv \n" + " MPU_vEventGroupSetNumber_Priv: \n" + " pop {r0} \n" + " b MPU_vEventGroupSetNumberImpl \n" + " MPU_vEventGroupSetNumber_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_vEventGroupSetNumberImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} + +#endif /*( configUSE_TRACE_FACILITY == 1 )*/ +/*-----------------------------------------------------------*/ + +size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, + const void * pvTxData, + size_t xDataLengthBytes, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, + const void * pvTxData, + size_t xDataLengthBytes, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferSendImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferSend_Unpriv \n" + " MPU_xStreamBufferSend_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferSendImpl \n" + " MPU_xStreamBufferSend_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xStreamBufferSendImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, + void * pvRxData, + size_t xBufferLengthBytes, + TickType_t xTicksToWait ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, + void * pvRxData, + size_t xBufferLengthBytes, + TickType_t xTicksToWait ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferReceiveImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferReceive_Unpriv \n" + " MPU_xStreamBufferReceive_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferReceiveImpl \n" + " MPU_xStreamBufferReceive_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xStreamBufferReceiveImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferIsFullImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferIsFull_Unpriv \n" + " MPU_xStreamBufferIsFull_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferIsFullImpl \n" + " MPU_xStreamBufferIsFull_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xStreamBufferIsFullImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferIsEmptyImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferIsEmpty_Unpriv \n" + " MPU_xStreamBufferIsEmpty_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferIsEmptyImpl \n" + " MPU_xStreamBufferIsEmpty_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xStreamBufferIsEmptyImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferSpacesAvailableImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferSpacesAvailable_Unpriv \n" + " MPU_xStreamBufferSpacesAvailable_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferSpacesAvailableImpl \n" + " MPU_xStreamBufferSpacesAvailable_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xStreamBufferSpacesAvailableImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferBytesAvailableImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferBytesAvailable_Unpriv \n" + " MPU_xStreamBufferBytesAvailable_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferBytesAvailableImpl \n" + " MPU_xStreamBufferBytesAvailable_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xStreamBufferBytesAvailableImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, + size_t xTriggerLevel ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, + size_t xTriggerLevel ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferSetTriggerLevelImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferSetTriggerLevel_Unpriv \n" + " MPU_xStreamBufferSetTriggerLevel_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferSetTriggerLevelImpl \n" + " MPU_xStreamBufferSetTriggerLevel_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xStreamBufferSetTriggerLevelImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) __attribute__ (( naked )) FREERTOS_SYSTEM_CALL; + +size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ +{ + __asm volatile + ( + " .syntax unified \n" + " .extern MPU_xStreamBufferNextMessageLengthBytesImpl \n" + " \n" + " push {r0} \n" + " mrs r0, control \n" + " tst r0, #1 \n" + " bne MPU_xStreamBufferNextMessageLengthBytes_Unpriv \n" + " MPU_xStreamBufferNextMessageLengthBytes_Priv: \n" + " pop {r0} \n" + " b MPU_xStreamBufferNextMessageLengthBytesImpl \n" + " MPU_xStreamBufferNextMessageLengthBytes_Unpriv: \n" + " pop {r0} \n" + " svc %0 \n" + " bl MPU_xStreamBufferNextMessageLengthBytesImpl \n" + " svc %1 \n" + " bx lr \n" + " \n" + : : "i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ diff --git a/portable/GCC/ARM_CM85_NTZ/non_secure/port.c b/portable/GCC/ARM_CM85_NTZ/non_secure/port.c index 7bbe1b7bc53..cab1b3668bf 100644 --- a/portable/GCC/ARM_CM85_NTZ/non_secure/port.c +++ b/portable/GCC/ARM_CM85_NTZ/non_secure/port.c @@ -107,6 +107,13 @@ #define portPRIGROUP_SHIFT ( 8UL ) /*-----------------------------------------------------------*/ +/** + * @brief Constants used during system call enter and exit. + */ +#define portPSR_STACK_PADDING_MASK ( 1UL << 9UL ) +#define portEXC_RETURN_STACK_FRAME_TYPE_MASK ( 1UL << 4UL ) +/*-----------------------------------------------------------*/ + /** * @brief Constants required to manipulate the FPU. */ @@ -123,6 +130,14 @@ #define portFPCCR_LSPEN_MASK ( 1UL << portFPCCR_LSPEN_POS ) /*-----------------------------------------------------------*/ +/** + * @brief Offsets in the stack to the parameters when inside the SVC handler. + */ +#define portOFFSET_TO_LR ( 5 ) +#define portOFFSET_TO_PC ( 6 ) +#define portOFFSET_TO_PSR ( 7 ) +/*-----------------------------------------------------------*/ + /** * @brief Constants required to manipulate the MPU. */ @@ -148,6 +163,8 @@ #define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ #define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ +#define portMPU_RBAR_ACCESS_PERMISSIONS_MASK ( 3UL << 1UL ) + #define portMPU_MAIR_ATTR0_POS ( 0UL ) #define portMPU_MAIR_ATTR0_MASK ( 0x000000ff ) @@ -191,6 +208,30 @@ /* Expected value of the portMPU_TYPE register. */ #define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) + +/* Extract first address of the MPU region as encoded in the + * RBAR (Region Base Address Register) value. */ +#define portEXTRACT_FIRST_ADDRESS_FROM_RBAR( rbar ) \ + ( ( rbar ) & portMPU_RBAR_ADDRESS_MASK ) + +/* Extract last address of the MPU region as encoded in the + * RLAR (Region Limit Address Register) value. */ +#define portEXTRACT_LAST_ADDRESS_FROM_RLAR( rlar ) \ + ( ( ( rlar ) & portMPU_RLAR_ADDRESS_MASK ) | ~portMPU_RLAR_ADDRESS_MASK ) + +/* Does addr lies within [start, end] address range? */ +#define portIS_ADDRESS_WITHIN_RANGE( addr, start, end ) \ + ( ( ( addr ) >= ( start ) ) && ( ( addr ) <= ( end ) ) ) + +/* Is the access request satisfied by the available permissions? */ +#define portIS_AUTHORIZED( accessRequest, permissions ) \ + ( ( ( permissions ) & ( accessRequest ) ) == accessRequest ) + +/* 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 ) ) ) /*-----------------------------------------------------------*/ /** @@ -311,6 +352,19 @@ static void prvTaskExitError( void ); #if ( configENABLE_MPU == 1 ) +/** + * @brief Extract MPU region's access permissions from the Region Base Address + * Register (RBAR) value. + * + * @param ulRBARValue RBAR value for the MPU region. + * + * @return uint32_t Access permissions. + */ + static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) PRIVILEGED_FUNCTION; +#endif /* configENABLE_MPU */ + +#if ( configENABLE_MPU == 1 ) + /** * @brief Setup the Memory Protection Unit (MPU). */ @@ -365,6 +419,60 @@ void SysTick_Handler( void ) PRIVILEGED_FUNCTION; * @brief C part of SVC handler. */ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIVILEGED_FUNCTION; + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + + /** + * @brief Sets up the system call stack so that upon returning from + * SVC, the system call stack is used. + * + * It is used for the system calls with up to 4 parameters. + * + * @param pulTaskStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + */ + void vSystemCallEnter( uint32_t * pulTaskStack, uint32_t ulLR ) PRIVILEGED_FUNCTION; + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + + /** + * @brief Sets up the system call stack so that upon returning from + * SVC, the system call stack is used. + * + * It is used for the system calls with 5 parameters. + * + * @param pulTaskStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + */ + void vSystemCallEnter_1( uint32_t * pulTaskStack, uint32_t ulLR ) PRIVILEGED_FUNCTION; + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + + /** + * @brief Sets up the task stack so that upon returning from + * SVC, the task stack is used again. + * + * @param pulSystemCallStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + */ + void vSystemCallExit( uint32_t * pulSystemCallStack, uint32_t ulLR ) PRIVILEGED_FUNCTION; + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + +#if ( configENABLE_MPU == 1 ) + + /** + * @brief Checks whether or not the calling task is privileged. + * + * @return pdTRUE if the calling task is privileged, pdFALSE otherwise. + */ + BaseType_t xPortIsTaskPrivileged( void ) PRIVILEGED_FUNCTION; + +#endif /* configENABLE_MPU == 1 */ /*-----------------------------------------------------------*/ /** @@ -681,6 +789,26 @@ static void prvTaskExitError( void ) } /*-----------------------------------------------------------*/ +#if ( configENABLE_MPU == 1 ) + static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) /* PRIVILEGED_FUNCTION */ + { + uint32_t ulAccessPermissions = 0; + + if( ( ulRBARValue & portMPU_RBAR_ACCESS_PERMISSIONS_MASK ) == portMPU_REGION_READ_ONLY ) + { + ulAccessPermissions = tskMPU_READ_PERMISSION; + } + + if( ( ulRBARValue & portMPU_RBAR_ACCESS_PERMISSIONS_MASK ) == portMPU_REGION_READ_WRITE ) + { + ulAccessPermissions = ( tskMPU_READ_PERMISSION | tskMPU_WRITE_PERMISSION ); + } + + return ulAccessPermissions; + } +#endif /* configENABLE_MPU */ +/*-----------------------------------------------------------*/ + #if ( configENABLE_MPU == 1 ) static void prvSetupMPU( void ) /* PRIVILEGED_FUNCTION */ { @@ -853,7 +981,7 @@ void SysTick_Handler( void ) /* PRIVILEGED_FUNCTION */ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTION portDONT_DISCARD */ { - #if ( configENABLE_MPU == 1 ) + #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) ) #if defined( __ARMCC_VERSION ) /* Declaration when these variable are defined in code instead of being @@ -865,7 +993,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO extern uint32_t __syscalls_flash_start__[]; extern uint32_t __syscalls_flash_end__[]; #endif /* defined( __ARMCC_VERSION ) */ - #endif /* configENABLE_MPU */ + #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */ uint32_t ulPC; @@ -880,7 +1008,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO /* Register are stored on the stack in the following order - R0, R1, R2, R3, * R12, LR, PC, xPSR. */ - ulPC = pulCallerStackAddress[ 6 ]; + ulPC = pulCallerStackAddress[ portOFFSET_TO_PC ]; ucSVCNumber = ( ( uint8_t * ) ulPC )[ -2 ]; switch( ucSVCNumber ) @@ -951,18 +1079,18 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO vRestoreContextOfFirstTask(); break; - #if ( configENABLE_MPU == 1 ) - case portSVC_RAISE_PRIVILEGE: + #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) ) + case portSVC_RAISE_PRIVILEGE: - /* Only raise the privilege, if the svc was raised from any of - * the system calls. */ - if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) && - ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ) - { - vRaisePrivilege(); - } - break; - #endif /* configENABLE_MPU */ + /* Only raise the privilege, if the svc was raised from any of + * the system calls. */ + if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ) + { + vRaisePrivilege(); + } + break; + #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */ default: /* Incorrect SVC call. */ @@ -971,51 +1099,455 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } /*-----------------------------------------------------------*/ -/* *INDENT-OFF* */ -#if ( configENABLE_MPU == 1 ) - StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, - StackType_t * pxEndOfStack, - TaskFunction_t pxCode, - void * pvParameters, - BaseType_t xRunPrivileged ) /* PRIVILEGED_FUNCTION */ -#else - StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, - StackType_t * pxEndOfStack, - TaskFunction_t pxCode, - void * pvParameters ) /* PRIVILEGED_FUNCTION */ -#endif /* configENABLE_MPU */ -/* *INDENT-ON* */ +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + +void vSystemCallEnter( uint32_t * pulTaskStack, uint32_t ulLR ) /* PRIVILEGED_FUNCTION */ { - /* Simulate the stack frame as it would be created by a context switch - * interrupt. */ - #if ( portPRELOAD_REGISTERS == 0 ) + extern TaskHandle_t pxCurrentTCB; + xMPU_SETTINGS * pxMpuSettings; + uint32_t * pulSystemCallStack; + uint32_t ulStackFrameSize, ulSystemCallLocation, i; + #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being + * exported from linker scripts. */ + extern uint32_t * __syscalls_flash_start__; + extern uint32_t * __syscalls_flash_end__; + #else + /* Declaration when these variable are exported from linker scripts. */ + extern uint32_t __syscalls_flash_start__[]; + extern uint32_t __syscalls_flash_end__[]; + #endif /* #if defined( __ARMCC_VERSION ) */ + + ulSystemCallLocation = pulTaskStack[ portOFFSET_TO_PC ]; + + /* If the request did not come from the system call section, do nothing. */ + if( ( ulSystemCallLocation >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulSystemCallLocation <= ( uint32_t ) __syscalls_flash_end__ ) ) { - pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ - *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ - pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pxCode; /* PC */ - pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR */ - pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ - *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ - pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */ - *pxTopOfStack = portINITIAL_EXC_RETURN; + pxMpuSettings = xTaskGetMPUSettings( pxCurrentTCB ); + pulSystemCallStack = pxMpuSettings->xSystemCallStackInfo.pulSystemCallStack; - #if ( configENABLE_MPU == 1 ) + /* This is not NULL only for the duration of the system call. */ + configASSERT( pxMpuSettings->xSystemCallStackInfo.pulTaskStack == NULL ); + + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) { - pxTopOfStack--; + if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) + { + /* Extended frame i.e. FPU in use. */ + ulStackFrameSize = 26; + __asm volatile ( + " vpush {s0} \n" /* Trigger lazy stacking. */ + " vpop {s0} \n" /* Nullify the affect of the above instruction. */ + ::: "memory" + ); + } + else + { + /* Standard frame i.e. FPU not in use. */ + ulStackFrameSize = 8; + } + } + #else + { + ulStackFrameSize = 8; + } + #endif /* configENABLE_FPU || configENABLE_MVE */ + + /* Make space on the system call stack for the stack frame. */ + pulSystemCallStack = pulSystemCallStack - ulStackFrameSize; + + /* Copy the stack frame. */ + for( i = 0; i < ulStackFrameSize; i++ ) + { + pulSystemCallStack[ i ] = pulTaskStack[ i ]; + } + + /* Store the value of the LR and PSPLIM registers before the SVC was raised. We need to + * restore it when we exit from the system call. */ + pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; + __asm volatile ( "mrs %0, psplim" : "=r" ( pxMpuSettings->xSystemCallStackInfo.ulStackLimitRegisterAtSystemCallEntry ) ); + + /* Use the pulSystemCallStack in thread mode. */ + __asm volatile ( "msr psp, %0" : : "r" ( pulSystemCallStack ) ); + __asm volatile ( "msr psplim, %0" : : "r" ( pxMpuSettings->xSystemCallStackInfo.pulSystemCallStackLimit ) ); + + /* Remember the location where we should copy the stack frame when we exit from + * the system call. */ + pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulStackFrameSize; + + /* Record if the hardware used padding to force the stack pointer + * to be double word aligned. */ + if( ( pulTaskStack[ portOFFSET_TO_PSR ] & portPSR_STACK_PADDING_MASK ) == portPSR_STACK_PADDING_MASK ) + { + pxMpuSettings->ulTaskFlags |= portSTACK_FRAME_HAS_PADDING_FLAG; + } + else + { + pxMpuSettings->ulTaskFlags &= ( ~portSTACK_FRAME_HAS_PADDING_FLAG ); + } + + /* We ensure in pxPortInitialiseStack that the system call stack is + * double word aligned and therefore, there is no need of padding. + * Clear the bit[9] of stacked xPSR. */ + pulSystemCallStack[ portOFFSET_TO_PSR ] &= ( ~portPSR_STACK_PADDING_MASK ); + + /* Raise the privilege for the duration of the system call. */ + __asm volatile ( + " mrs r0, control \n" /* Obtain current control value. */ + " movs r1, #1 \n" /* r1 = 1. */ + " bics r0, r1 \n" /* Clear nPRIV bit. */ + " msr control, r0 \n" /* Write back new control value. */ + ::: "r0", "r1", "memory" + ); + } +} - if( xRunPrivileged == pdTRUE ) +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + +void vSystemCallEnter_1( uint32_t * pulTaskStack, uint32_t ulLR ) /* PRIVILEGED_FUNCTION */ +{ + extern TaskHandle_t pxCurrentTCB; + xMPU_SETTINGS * pxMpuSettings; + uint32_t * pulSystemCallStack; + uint32_t ulStackFrameSize, ulSystemCallLocation, i; + #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being + * exported from linker scripts. */ + extern uint32_t * __syscalls_flash_start__; + extern uint32_t * __syscalls_flash_end__; + #else + /* Declaration when these variable are exported from linker scripts. */ + extern uint32_t __syscalls_flash_start__[]; + extern uint32_t __syscalls_flash_end__[]; + #endif /* #if defined( __ARMCC_VERSION ) */ + + ulSystemCallLocation = pulTaskStack[ portOFFSET_TO_PC ]; + + /* If the request did not come from the system call section, do nothing. */ + if( ( ulSystemCallLocation >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulSystemCallLocation <= ( uint32_t ) __syscalls_flash_end__ ) ) + { + pxMpuSettings = xTaskGetMPUSettings( pxCurrentTCB ); + pulSystemCallStack = pxMpuSettings->xSystemCallStackInfo.pulSystemCallStack; + + /* This is not NULL only for the duration of the system call. */ + configASSERT( pxMpuSettings->xSystemCallStackInfo.pulTaskStack == NULL ); + + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + { + if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) { - *pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */ + /* Extended frame i.e. FPU in use. */ + ulStackFrameSize = 26; + __asm volatile ( + " vpush {s0} \n" /* Trigger lazy stacking. */ + " vpop {s0} \n" /* Nullify the affect of the above instruction. */ + ::: "memory" + ); } else { - *pxTopOfStack = portINITIAL_CONTROL_UNPRIVILEGED; /* Slot used to hold this task's CONTROL value. */ + /* Standard frame i.e. FPU not in use. */ + ulStackFrameSize = 8; } } - #endif /* configENABLE_MPU */ + #else + { + ulStackFrameSize = 8; + } + #endif /* configENABLE_FPU || configENABLE_MVE */ + + /* Make space on the system call stack for the stack frame and + * the parameter passed on the stack. We only need to copy one + * parameter but we still reserve 2 spaces to keep the stack + * double word aligned. */ + pulSystemCallStack = pulSystemCallStack - ulStackFrameSize - 2UL; + + /* Copy the stack frame. */ + for( i = 0; i < ulStackFrameSize; i++ ) + { + pulSystemCallStack[ i ] = pulTaskStack[ i ]; + } + + /* Copy the parameter which is passed the stack. */ + if( ( pulTaskStack[ portOFFSET_TO_PSR ] & portPSR_STACK_PADDING_MASK ) == portPSR_STACK_PADDING_MASK ) + { + pulSystemCallStack[ ulStackFrameSize ] = pulTaskStack[ ulStackFrameSize + 1 ]; + /* Record if the hardware used padding to force the stack pointer + * to be double word aligned. */ + pxMpuSettings->ulTaskFlags |= portSTACK_FRAME_HAS_PADDING_FLAG; + } + else + { + pulSystemCallStack[ ulStackFrameSize ] = pulTaskStack[ ulStackFrameSize ]; + /* Record if the hardware used padding to force the stack pointer + * to be double word aligned. */ + pxMpuSettings->ulTaskFlags &= ( ~portSTACK_FRAME_HAS_PADDING_FLAG ); + } + + /* Store the value of the LR and PSPLIM registers before the SVC was raised. + * We need to restore it when we exit from the system call. */ + pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; + __asm volatile ( "mrs %0, psplim" : "=r" ( pxMpuSettings->xSystemCallStackInfo.ulStackLimitRegisterAtSystemCallEntry ) ); + + /* Use the pulSystemCallStack in thread mode. */ + __asm volatile ( "msr psp, %0" : : "r" ( pulSystemCallStack ) ); + __asm volatile ( "msr psplim, %0" : : "r" ( pxMpuSettings->xSystemCallStackInfo.pulSystemCallStackLimit ) ); + + /* Remember the location where we should copy the stack frame when we exit from + * the system call. */ + pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulStackFrameSize; + + /* We ensure in pxPortInitialiseStack that the system call stack is + * double word aligned and therefore, there is no need of padding. + * Clear the bit[9] of stacked xPSR. */ + pulSystemCallStack[ portOFFSET_TO_PSR ] &= ( ~portPSR_STACK_PADDING_MASK ); + + /* Raise the privilege for the duration of the system call. */ + __asm volatile ( + " mrs r0, control \n" /* Obtain current control value. */ + " movs r1, #1 \n" /* r1 = 1. */ + " bics r0, r1 \n" /* Clear nPRIV bit. */ + " msr control, r0 \n" /* Write back new control value. */ + ::: "r0", "r1", "memory" + ); + } +} + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) +void vSystemCallExit( uint32_t * pulSystemCallStack, uint32_t ulLR ) /* PRIVILEGED_FUNCTION */ +{ + extern TaskHandle_t pxCurrentTCB; + xMPU_SETTINGS * pxMpuSettings; + uint32_t * pulTaskStack; + uint32_t ulStackFrameSize, ulSystemCallLocation, i; + #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being + * exported from linker scripts. */ + extern uint32_t * __syscalls_flash_start__; + extern uint32_t * __syscalls_flash_end__; + #else + /* Declaration when these variable are exported from linker scripts. */ + extern uint32_t __syscalls_flash_start__[]; + extern uint32_t __syscalls_flash_end__[]; + #endif /* #if defined( __ARMCC_VERSION ) */ + + ulSystemCallLocation = pulSystemCallStack[ portOFFSET_TO_PC ]; + + /* If the request did not come from the system call section, do nothing. */ + if( ( ulSystemCallLocation >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulSystemCallLocation <= ( uint32_t ) __syscalls_flash_end__ ) ) + { + pxMpuSettings = xTaskGetMPUSettings( pxCurrentTCB ); + pulTaskStack = pxMpuSettings->xSystemCallStackInfo.pulTaskStack; + + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + { + if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) + { + /* Extended frame i.e. FPU in use. */ + ulStackFrameSize = 26; + __asm volatile ( + " vpush {s0} \n" /* Trigger lazy stacking. */ + " vpop {s0} \n" /* Nullify the affect of the above instruction. */ + ::: "memory" + ); + } + else + { + /* Standard frame i.e. FPU not in use. */ + ulStackFrameSize = 8; + } + } + #else + { + ulStackFrameSize = 8; + } + #endif /* configENABLE_FPU || configENABLE_MVE */ + + /* Make space on the task stack for the stack frame. */ + pulTaskStack = pulTaskStack - ulStackFrameSize; + + /* Copy the stack frame. */ + for( i = 0; i < ulStackFrameSize; i++ ) + { + pulTaskStack[ i ] = pulSystemCallStack[ i ]; + } + + /* Use the pulTaskStack in thread mode. */ + __asm volatile ( "msr psp, %0" : : "r" ( pulTaskStack ) ); + + /* Restore the LR and PSPLIM to what they were at the time of + * system call entry. */ + pulTaskStack[ portOFFSET_TO_LR ] = pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry; + __asm volatile ( "msr psplim, %0" : : "r" ( pxMpuSettings->xSystemCallStackInfo.ulStackLimitRegisterAtSystemCallEntry ) ); + + /* If the hardware used padding to force the stack pointer + * to be double word aligned, set the stacked xPSR bit[9], + * otherwise clear it. */ + if( ( pxMpuSettings->ulTaskFlags & portSTACK_FRAME_HAS_PADDING_FLAG ) == portSTACK_FRAME_HAS_PADDING_FLAG ) + { + pulTaskStack[ portOFFSET_TO_PSR ] |= portPSR_STACK_PADDING_MASK; + } + else + { + pulTaskStack[ portOFFSET_TO_PSR ] &= ( ~portPSR_STACK_PADDING_MASK ); + } + + /* This is not NULL only for the duration of the system call. */ + pxMpuSettings->xSystemCallStackInfo.pulTaskStack = NULL; + + /* Drop the privilege before returning to the thread mode. */ + __asm volatile ( + " mrs r0, control \n" /* Obtain current control value. */ + " movs r1, #1 \n" /* r1 = 1. */ + " orrs r0, r1 \n" /* Set nPRIV bit. */ + " msr control, r0 \n" /* Write back new control value. */ + ::: "r0", "r1", "memory" + ); + } +} + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configENABLE_MPU == 1 ) + +BaseType_t xPortIsTaskPrivileged( void ) /* PRIVILEGED_FUNCTION */ +{ + BaseType_t xTaskIsPrivileged = pdFALSE; + const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */ + + if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) + { + xTaskIsPrivileged = pdTRUE; + } + + return xTaskIsPrivileged; +} + +#endif /* configENABLE_MPU == 1 */ +/*-----------------------------------------------------------*/ + +#if( configENABLE_MPU == 1 ) + +StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, + StackType_t * pxEndOfStack, + TaskFunction_t pxCode, + void * pvParameters, + BaseType_t xRunPrivileged, + xMPU_SETTINGS * xMPUSettings ) /* PRIVILEGED_FUNCTION */ +{ + uint32_t ulIndex = 0; + + xMPUSettings->ulContext[ ulIndex ] = 0x04040404; /* r4. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x05050505; /* r5. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x06060606; /* r6. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x07070707; /* r7. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x08080808; /* r8. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x09090909; /* r9. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x10101010; /* r10. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x11111111; /* r11. */ + ulIndex++; + + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pvParameters; /* r0. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x01010101; /* r1. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x02020202; /* r2. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x03030303; /* r3. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x12121212; /* r12. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portTASK_RETURN_ADDRESS; /* LR. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxCode; /* PC. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = portINITIAL_XPSR; /* xPSR. */ + ulIndex++; + + #if ( configENABLE_TRUSTZONE == 1 ) + { + xMPUSettings->ulContext[ ulIndex ] = portNO_SECURE_CONTEXT; /* xSecureContext. */ + ulIndex++; + } + #endif /* configENABLE_TRUSTZONE */ + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) ( pxTopOfStack - 8 ); /* PSP with the hardware saved stack. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */ + ulIndex++; + if( xRunPrivileged == pdTRUE ) + { + xMPUSettings->ulTaskFlags |= portTASK_IS_PRIVILEGED_FLAG; + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_PRIVILEGED; /* CONTROL. */ + ulIndex++; + } + else + { + xMPUSettings->ulTaskFlags &= ( ~portTASK_IS_PRIVILEGED_FLAG ); + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_UNPRIVILEGED; /* CONTROL. */ + ulIndex++; + } + xMPUSettings->ulContext[ ulIndex ] = portINITIAL_EXC_RETURN; /* LR (EXC_RETURN). */ + ulIndex++; + + #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + { + /* Ensure that the system call stack is double word aligned. */ + xMPUSettings->xSystemCallStackInfo.pulSystemCallStack = &( xMPUSettings->xSystemCallStackInfo.ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE - 1 ] ); + xMPUSettings->xSystemCallStackInfo.pulSystemCallStack = ( uint32_t * ) ( ( uint32_t ) ( xMPUSettings->xSystemCallStackInfo.pulSystemCallStack ) & + ( uint32_t ) ( ~( portBYTE_ALIGNMENT_MASK ) ) ); + + xMPUSettings->xSystemCallStackInfo.pulSystemCallStackLimit = &( xMPUSettings->xSystemCallStackInfo.ulSystemCallStackBuffer[ 0 ] ); + xMPUSettings->xSystemCallStackInfo.pulSystemCallStackLimit = ( uint32_t * ) ( ( ( uint32_t ) ( xMPUSettings->xSystemCallStackInfo.pulSystemCallStackLimit ) + + ( uint32_t ) ( portBYTE_ALIGNMENT - 1 ) ) & + ( uint32_t ) ( ~( portBYTE_ALIGNMENT_MASK ) ) ); + + /* This is not NULL only for the duration of a system call. */ + xMPUSettings->xSystemCallStackInfo.pulTaskStack = NULL; + } + #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + + return &( xMPUSettings->ulContext[ ulIndex ] ); +} + +#else /* configENABLE_MPU */ + +StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, + StackType_t * pxEndOfStack, + TaskFunction_t pxCode, + void * pvParameters ) /* PRIVILEGED_FUNCTION */ +{ + /* Simulate the stack frame as it would be created by a context switch + * interrupt. */ + #if ( portPRELOAD_REGISTERS == 0 ) + { + pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ + *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR. */ + pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ + pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */ + *pxTopOfStack = portINITIAL_EXC_RETURN; pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ @@ -1029,55 +1561,39 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO #else /* portPRELOAD_REGISTERS */ { pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ - *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ + *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pxCode; /* PC */ + *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR */ + *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x12121212UL; /* R12 */ + *pxTopOfStack = ( StackType_t ) 0x12121212UL; /* R12. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x03030303UL; /* R3 */ + *pxTopOfStack = ( StackType_t ) 0x03030303UL; /* R3. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x02020202UL; /* R2 */ + *pxTopOfStack = ( StackType_t ) 0x02020202UL; /* R2. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x01010101UL; /* R1 */ + *pxTopOfStack = ( StackType_t ) 0x01010101UL; /* R1. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x11111111UL; /* R11 */ + *pxTopOfStack = ( StackType_t ) 0x11111111UL; /* R11. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x10101010UL; /* R10 */ + *pxTopOfStack = ( StackType_t ) 0x10101010UL; /* R10. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x09090909UL; /* R09 */ + *pxTopOfStack = ( StackType_t ) 0x09090909UL; /* R09. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x08080808UL; /* R08 */ + *pxTopOfStack = ( StackType_t ) 0x08080808UL; /* R08. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x07070707UL; /* R07 */ + *pxTopOfStack = ( StackType_t ) 0x07070707UL; /* R07. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x06060606UL; /* R06 */ + *pxTopOfStack = ( StackType_t ) 0x06060606UL; /* R06. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x05050505UL; /* R05 */ + *pxTopOfStack = ( StackType_t ) 0x05050505UL; /* R05. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x04040404UL; /* R04 */ + *pxTopOfStack = ( StackType_t ) 0x04040404UL; /* R04. */ pxTopOfStack--; - *pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN */ - - #if ( configENABLE_MPU == 1 ) - { - pxTopOfStack--; - - if( xRunPrivileged == pdTRUE ) - { - *pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */ - } - else - { - *pxTopOfStack = portINITIAL_CONTROL_UNPRIVILEGED; /* Slot used to hold this task's CONTROL value. */ - } - } - #endif /* configENABLE_MPU */ - + *pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN. */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ @@ -1092,6 +1608,8 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO return pxTopOfStack; } + +#endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ @@ -1128,6 +1646,10 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ configASSERT( ucMaxSysCallPriority ); + /* Check that the bits not implemented in hardware are zero in + * configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & ( ~ucMaxPriorityValue ) ) == 0U ); + /* Calculate the maximum acceptable priority group value for the number * of bits read back. */ @@ -1164,35 +1686,6 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulImplementedPrioBits; } - /* The interrupt priority bits are not modelled in QEMU and the assert that - * checks the number of implemented bits and __NVIC_PRIO_BITS will always fail. - * Therefore, this assert is not adding any value for QEMU targets. The config - * option `configDISABLE_INTERRUPT_PRIO_BITS_CHECK` should be defined in the - * `FreeRTOSConfig.h` for QEMU targets. */ - #ifndef configDISABLE_INTERRUPT_PRIO_BITS_CHECK - { - #ifdef __NVIC_PRIO_BITS - { - /* - * Check that the number of implemented priority bits queried from - * hardware is equal to the CMSIS __NVIC_PRIO_BITS configuration macro. - */ - configASSERT( ulImplementedPrioBits == __NVIC_PRIO_BITS ); - } - #endif /* __NVIC_PRIO_BITS */ - - #ifdef configPRIO_BITS - { - /* - * Check that the number of implemented priority bits queried from - * hardware is equal to the FreeRTOS configPRIO_BITS configuration macro. - */ - configASSERT( ulImplementedPrioBits == configPRIO_BITS ); - } - #endif /* configPRIO_BITS */ - } - #endif /* #ifndef configDISABLE_INTERRUPT_PRIO_BITS_CHECK */ - /* Shift the priority group value back to its position within the AIRCR * register. */ ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT; @@ -1372,6 +1865,54 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ +#if ( configENABLE_MPU == 1 ) + BaseType_t xPortIsAuthorizedToAccessBuffer( const void * pvBuffer, + uint32_t ulBufferLength, + uint32_t ulAccessRequested ) /* PRIVILEGED_FUNCTION */ + + { + uint32_t i, ulBufferStartAddress, ulBufferEndAddress; + BaseType_t xAccessGranted = pdFALSE; + const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */ + + if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) + { + xAccessGranted = pdTRUE; + } + else + { + if( portADD_UINT32_WILL_OVERFLOW( ( ( uint32_t ) pvBuffer ), ( ulBufferLength - 1UL ) ) == pdFALSE ) + { + ulBufferStartAddress = ( uint32_t ) pvBuffer; + ulBufferEndAddress = ( ( ( uint32_t ) pvBuffer ) + ulBufferLength - 1UL ); + + for( i = 0; i < portTOTAL_NUM_REGIONS; i++ ) + { + /* Is the MPU region enabled? */ + if( ( xTaskMpuSettings->xRegionsSettings[ i ].ulRLAR & portMPU_RLAR_REGION_ENABLE ) == portMPU_RLAR_REGION_ENABLE ) + { + if( portIS_ADDRESS_WITHIN_RANGE( ulBufferStartAddress, + portEXTRACT_FIRST_ADDRESS_FROM_RBAR( xTaskMpuSettings->xRegionsSettings[ i ].ulRBAR ), + portEXTRACT_LAST_ADDRESS_FROM_RLAR( xTaskMpuSettings->xRegionsSettings[ i ].ulRLAR ) ) && + portIS_ADDRESS_WITHIN_RANGE( ulBufferEndAddress, + portEXTRACT_FIRST_ADDRESS_FROM_RBAR( xTaskMpuSettings->xRegionsSettings[ i ].ulRBAR ), + portEXTRACT_LAST_ADDRESS_FROM_RLAR( xTaskMpuSettings->xRegionsSettings[ i ].ulRLAR ) ) && + portIS_AUTHORIZED( ulAccessRequested, + prvGetRegionAccessPermissions( xTaskMpuSettings->xRegionsSettings[ i ].ulRBAR ) ) ) + { + xAccessGranted = pdTRUE; + break; + } + } + } + } + } + + return xAccessGranted; + } +#endif /* configENABLE_MPU */ +/*-----------------------------------------------------------*/ + BaseType_t xPortIsInsideInterrupt( void ) { uint32_t ulCurrentInterrupt; diff --git a/portable/GCC/ARM_CM85_NTZ/non_secure/portasm.c b/portable/GCC/ARM_CM85_NTZ/non_secure/portasm.c index a78529d04d9..504b6bf3be3 100644 --- a/portable/GCC/ARM_CM85_NTZ/non_secure/portasm.c +++ b/portable/GCC/ARM_CM85_NTZ/non_secure/portasm.c @@ -40,6 +40,88 @@ * header files. */ #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE +#if ( configENABLE_MPU == 1 ) + +void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ +{ + __asm volatile + ( + " .syntax unified \n" + " \n" + " program_mpu_first_task: \n" + " ldr r2, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r0, [r2] \n" /* r0 = pxCurrentTCB. */ + " \n" + " dmb \n" /* Complete outstanding transfers before disabling MPU. */ + " ldr r1, xMPUCTRLConst2 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ + " bic r2, #1 \n" /* r2 = r2 & ~1 i.e. Clear the bit 0 in r2. */ + " str r2, [r1] \n" /* Disable MPU. */ + " \n" + " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */ + " ldr r1, [r0] \n" /* r1 = *r0 i.e. r1 = MAIR0. */ + " ldr r2, xMAIR0Const2 \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */ + " str r1, [r2] \n" /* Program MAIR0. */ + " \n" + " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */ + " ldr r1, xRNRConst2 \n" /* r1 = 0xe000ed98 [Location of RNR]. */ + " ldr r2, xRBARConst2 \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ + " \n" + " movs r3, #4 \n" /* r3 = 4. */ + " str r3, [r1] \n" /* Program RNR = 4. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + " \n" + #if ( configTOTAL_MPU_REGIONS == 16 ) + " movs r3, #8 \n" /* r3 = 8. */ + " str r3, [r1] \n" /* Program RNR = 8. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + " movs r3, #12 \n" /* r3 = 12. */ + " str r3, [r1] \n" /* Program RNR = 12. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + #endif /* configTOTAL_MPU_REGIONS == 16 */ + " \n" + " ldr r1, xMPUCTRLConst2 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ + " orr r2, #1 \n" /* r2 = r2 | 1 i.e. Set the bit 0 in r2. */ + " str r2, [r1] \n" /* Enable MPU. */ + " dsb \n" /* Force memory writes before continuing. */ + " \n" + " restore_context_first_task: \n" + " ldr r2, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r0, [r2] \n" /* r0 = pxCurrentTCB.*/ + " ldr r1, [r0] \n" /* r1 = Location of saved context in TCB. */ + " \n" + " restore_special_regs_first_task: \n" + " ldmdb r1!, {r2-r4, lr} \n" /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */ + " msr psp, r2 \n" + " msr psplim, r3 \n" + " msr control, r4 \n" + " \n" + " restore_general_regs_first_task: \n" + " ldmdb r1!, {r4-r11} \n" /* r4-r11 contain hardware saved context. */ + " stmia r2!, {r4-r11} \n" /* Copy the hardware saved context on the task stack. */ + " ldmdb r1!, {r4-r11} \n" /* r4-r11 restored. */ + " \n" + " restore_context_done_first_task: \n" + " str r1, [r0] \n" /* Save the location where the context should be saved next as the first member of TCB. */ + " mov r0, #0 \n" + " msr basepri, r0 \n" /* Ensure that interrupts are enabled when the first task starts. */ + " bx lr \n" + " \n" + " .align 4 \n" + " pxCurrentTCBConst2: .word pxCurrentTCB \n" + " xMPUCTRLConst2: .word 0xe000ed94 \n" + " xMAIR0Const2: .word 0xe000edc0 \n" + " xRNRConst2: .word 0xe000ed98 \n" + " xRBARConst2: .word 0xe000ed9c \n" + ); +} + +#else /* configENABLE_MPU */ + void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ { __asm volatile @@ -50,80 +132,23 @@ void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_ " ldr r1, [r2] \n"/* Read pxCurrentTCB. */ " ldr r0, [r1] \n"/* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ " \n" - #if ( configENABLE_MPU == 1 ) - " dmb \n"/* Complete outstanding transfers before disabling MPU. */ - " ldr r2, xMPUCTRLConst2 \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ - " ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */ - " bic r4, #1 \n"/* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */ - " str r4, [r2] \n"/* Disable MPU. */ - " \n" - " adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */ - " ldr r3, [r1] \n"/* r3 = *r1 i.e. r3 = MAIR0. */ - " ldr r2, xMAIR0Const2 \n"/* r2 = 0xe000edc0 [Location of MAIR0]. */ - " str r3, [r2] \n"/* Program MAIR0. */ - " ldr r2, xRNRConst2 \n"/* r2 = 0xe000ed98 [Location of RNR]. */ - " movs r3, #4 \n"/* r3 = 4. */ - " str r3, [r2] \n"/* Program RNR = 4. */ - " adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to first RBAR in TCB. */ - " ldr r2, xRBARConst2 \n"/* r2 = 0xe000ed9c [Location of RBAR]. */ - " ldmia r1!, {r4-r11} \n"/* Read 4 set of RBAR/RLAR registers from TCB. */ - " stmia r2!, {r4-r11} \n"/* Write 4 set of RBAR/RLAR registers using alias registers. */ - " \n" - #if ( configTOTAL_MPU_REGIONS == 16 ) - " ldr r2, xRNRConst2 \n"/* r2 = 0xe000ed98 [Location of RNR]. */ - " movs r3, #8 \n"/* r3 = 8. */ - " str r3, [r2] \n"/* Program RNR = 8. */ - " ldr r2, xRBARConst2 \n"/* r2 = 0xe000ed9c [Location of RBAR]. */ - " ldmia r1!, {r4-r11} \n"/* Read 4 set of RBAR/RLAR registers from TCB. */ - " stmia r2!, {r4-r11} \n"/* Write 4 set of RBAR/RLAR registers using alias registers. */ - " ldr r2, xRNRConst2 \n"/* r2 = 0xe000ed98 [Location of RNR]. */ - " movs r3, #12 \n"/* r3 = 12. */ - " str r3, [r2] \n"/* Program RNR = 12. */ - " ldr r2, xRBARConst2 \n"/* r2 = 0xe000ed9c [Location of RBAR]. */ - " ldmia r1!, {r4-r11} \n"/* Read 4 set of RBAR/RLAR registers from TCB. */ - " stmia r2!, {r4-r11} \n"/* Write 4 set of RBAR/RLAR registers using alias registers. */ - #endif /* configTOTAL_MPU_REGIONS == 16 */ - " \n" - " ldr r2, xMPUCTRLConst2 \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ - " ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */ - " orr r4, #1 \n"/* r4 = r4 | 1 i.e. Set the bit 0 in r4. */ - " str r4, [r2] \n"/* Enable MPU. */ - " dsb \n"/* Force memory writes before continuing. */ - #endif /* configENABLE_MPU */ - " \n" - #if ( configENABLE_MPU == 1 ) - " ldm r0!, {r1-r3} \n"/* Read from stack - r1 = PSPLIM, r2 = CONTROL and r3 = EXC_RETURN. */ - " msr psplim, r1 \n"/* Set this task's PSPLIM value. */ - " msr control, r2 \n"/* Set this task's CONTROL value. */ - " adds r0, #32 \n"/* Discard everything up to r0. */ - " msr psp, r0 \n"/* This is now the new top of stack to use in the task. */ - " isb \n" - " mov r0, #0 \n" - " msr basepri, r0 \n"/* Ensure that interrupts are enabled when the first task starts. */ - " bx r3 \n"/* Finally, branch to EXC_RETURN. */ - #else /* configENABLE_MPU */ - " ldm r0!, {r1-r2} \n"/* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */ - " msr psplim, r1 \n"/* Set this task's PSPLIM value. */ - " movs r1, #2 \n"/* r1 = 2. */ - " msr CONTROL, r1 \n"/* Switch to use PSP in the thread mode. */ - " adds r0, #32 \n"/* Discard everything up to r0. */ - " msr psp, r0 \n"/* This is now the new top of stack to use in the task. */ - " isb \n" - " mov r0, #0 \n" - " msr basepri, r0 \n"/* Ensure that interrupts are enabled when the first task starts. */ - " bx r2 \n"/* Finally, branch to EXC_RETURN. */ - #endif /* configENABLE_MPU */ + " ldm r0!, {r1-r2} \n"/* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */ + " msr psplim, r1 \n"/* Set this task's PSPLIM value. */ + " movs r1, #2 \n"/* r1 = 2. */ + " msr CONTROL, r1 \n"/* Switch to use PSP in the thread mode. */ + " adds r0, #32 \n"/* Discard everything up to r0. */ + " msr psp, r0 \n"/* This is now the new top of stack to use in the task. */ + " isb \n" + " mov r0, #0 \n" + " msr basepri, r0 \n"/* Ensure that interrupts are enabled when the first task starts. */ + " bx r2 \n"/* Finally, branch to EXC_RETURN. */ " \n" " .align 4 \n" "pxCurrentTCBConst2: .word pxCurrentTCB \n" - #if ( configENABLE_MPU == 1 ) - "xMPUCTRLConst2: .word 0xe000ed94 \n" - "xMAIR0Const2: .word 0xe000edc0 \n" - "xRNRConst2: .word 0xe000ed98 \n" - "xRBARConst2: .word 0xe000ed9c \n" - #endif /* configENABLE_MPU */ ); } + +#endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */ @@ -231,6 +256,129 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att } /*-----------------------------------------------------------*/ +#if ( configENABLE_MPU == 1 ) + +void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ +{ + __asm volatile + ( + " .syntax unified \n" + " \n" + " ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r0, [r2] \n" /* r0 = pxCurrentTCB. */ + " ldr r1, [r0] \n" /* r1 = Location in TCB where the context should be saved. */ + " mrs r2, psp \n" /* r2 = PSP. */ + " \n" + " save_general_regs: \n" + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + " add r2, r2, #0x20 \n" /* Move r2 to location where s0 is saved. */ + " tst lr, #0x10 \n" + " ittt eq \n" + " vstmiaeq r1!, {s16-s31} \n" /* Store s16-s31. */ + " vldmiaeq r2, {s0-s16} \n" /* Copy hardware saved FP context into s0-s16. */ + " vstmiaeq r1!, {s0-s16} \n" /* Store hardware saved FP context. */ + " sub r2, r2, #0x20 \n" /* Set r2 back to the location of hardware saved context. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ + " \n" + " stmia r1!, {r4-r11} \n" /* Store r4-r11. */ + " ldmia r2, {r4-r11} \n" /* Copy the hardware saved context into r4-r11. */ + " stmia r1!, {r4-r11} \n" /* Store the hardware saved context. */ + " \n" + " save_special_regs: \n" + " mrs r3, psplim \n" /* r3 = PSPLIM. */ + " mrs r4, control \n" /* r4 = CONTROL. */ + " stmia r1!, {r2-r4, lr} \n" /* Store original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */ + " str r1, [r0] \n" /* Save the location from where the context should be restored as the first member of TCB. */ + " \n" + " select_next_task: \n" + " mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */ + " msr basepri, r0 \n" /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + " dsb \n" + " isb \n" + " bl vTaskSwitchContext \n" + " mov r0, #0 \n" /* r0 = 0. */ + " msr basepri, r0 \n" /* Enable interrupts. */ + " \n" + " program_mpu: \n" + " ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r0, [r2] \n" /* r0 = pxCurrentTCB. */ + " \n" + " dmb \n" /* Complete outstanding transfers before disabling MPU. */ + " ldr r1, xMPUCTRLConst \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ + " bic r2, #1 \n" /* r2 = r2 & ~1 i.e. Clear the bit 0 in r2. */ + " str r2, [r1] \n" /* Disable MPU. */ + " \n" + " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */ + " ldr r1, [r0] \n" /* r1 = *r0 i.e. r1 = MAIR0. */ + " ldr r2, xMAIR0Const \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */ + " str r1, [r2] \n" /* Program MAIR0. */ + " \n" + " adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */ + " ldr r1, xRNRConst \n" /* r1 = 0xe000ed98 [Location of RNR]. */ + " ldr r2, xRBARConst \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ + " \n" + " movs r3, #4 \n" /* r3 = 4. */ + " str r3, [r1] \n" /* Program RNR = 4. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + " \n" + #if ( configTOTAL_MPU_REGIONS == 16 ) + " movs r3, #8 \n" /* r3 = 8. */ + " str r3, [r1] \n" /* Program RNR = 8. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + " movs r3, #12 \n" /* r3 = 12. */ + " str r3, [r1] \n" /* Program RNR = 12. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + #endif /* configTOTAL_MPU_REGIONS == 16 */ + " \n" + " ldr r1, xMPUCTRLConst \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ + " orr r2, #1 \n" /* r2 = r2 | 1 i.e. Set the bit 0 in r2. */ + " str r2, [r1] \n" /* Enable MPU. */ + " dsb \n" /* Force memory writes before continuing. */ + " \n" + " restore_context: \n" + " ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r0, [r2] \n" /* r0 = pxCurrentTCB.*/ + " ldr r1, [r0] \n" /* r1 = Location of saved context in TCB. */ + " \n" + " restore_special_regs: \n" + " ldmdb r1!, {r2-r4, lr} \n" /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */ + " msr psp, r2 \n" + " msr psplim, r3 \n" + " msr control, r4 \n" + " \n" + " restore_general_regs: \n" + " ldmdb r1!, {r4-r11} \n" /* r4-r11 contain hardware saved context. */ + " stmia r2!, {r4-r11} \n" /* Copy the hardware saved context on the task stack. */ + " ldmdb r1!, {r4-r11} \n" /* r4-r11 restored. */ + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + " tst lr, #0x10 \n" + " ittt eq \n" + " vldmdbeq r1!, {s0-s16} \n" /* s0-s16 contain hardware saved FP context. */ + " vstmiaeq r2!, {s0-s16} \n" /* Copy hardware saved FP context on the task stack. */ + " vldmdbeq r1!, {s16-s31} \n" /* Restore s16-s31. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ + " \n" + " restore_context_done: \n" + " str r1, [r0] \n" /* Save the location where the context should be saved next as the first member of TCB. */ + " bx lr \n" + " \n" + " .align 4 \n" + " pxCurrentTCBConst: .word pxCurrentTCB \n" + " xMPUCTRLConst: .word 0xe000ed94 \n" + " xMAIR0Const: .word 0xe000edc0 \n" + " xRNRConst: .word 0xe000ed98 \n" + " xRBARConst: .word 0xe000ed9c \n" + ::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) + ); +} + +#else /* configENABLE_MPU */ + void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ { __asm volatile @@ -238,21 +386,16 @@ void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ " .syntax unified \n" " \n" " mrs r0, psp \n"/* Read PSP in r0. */ + " \n" #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) " tst lr, #0x10 \n"/* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ " it eq \n" " vstmdbeq r0!, {s16-s31} \n"/* Store the additional FP context registers which are not saved automatically. */ #endif /* configENABLE_FPU || configENABLE_MVE */ - #if ( configENABLE_MPU == 1 ) - " mrs r1, psplim \n"/* r1 = PSPLIM. */ - " mrs r2, control \n"/* r2 = CONTROL. */ - " mov r3, lr \n"/* r3 = LR/EXC_RETURN. */ - " stmdb r0!, {r1-r11} \n"/* Store on the stack - PSPLIM, CONTROL, LR and registers that are not automatically saved. */ - #else /* configENABLE_MPU */ - " mrs r2, psplim \n"/* r2 = PSPLIM. */ - " mov r3, lr \n"/* r3 = LR/EXC_RETURN. */ - " stmdb r0!, {r2-r11} \n"/* Store on the stack - PSPLIM, LR and registers that are not automatically saved. */ - #endif /* configENABLE_MPU */ + " \n" + " mrs r2, psplim \n"/* r2 = PSPLIM. */ + " mov r3, lr \n"/* r3 = LR/EXC_RETURN. */ + " stmdb r0!, {r2-r11} \n"/* Store on the stack - PSPLIM, LR and registers that are not automatically saved. */ " \n" " ldr r2, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r2] \n"/* Read pxCurrentTCB. */ @@ -270,52 +413,7 @@ void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ " ldr r1, [r2] \n"/* Read pxCurrentTCB. */ " ldr r0, [r1] \n"/* The first item in pxCurrentTCB is the task top of stack. r0 now points to the top of stack. */ " \n" - #if ( configENABLE_MPU == 1 ) - " dmb \n"/* Complete outstanding transfers before disabling MPU. */ - " ldr r2, xMPUCTRLConst \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ - " ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */ - " bic r4, #1 \n"/* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */ - " str r4, [r2] \n"/* Disable MPU. */ - " \n" - " adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */ - " ldr r3, [r1] \n"/* r3 = *r1 i.e. r3 = MAIR0. */ - " ldr r2, xMAIR0Const \n"/* r2 = 0xe000edc0 [Location of MAIR0]. */ - " str r3, [r2] \n"/* Program MAIR0. */ - " ldr r2, xRNRConst \n"/* r2 = 0xe000ed98 [Location of RNR]. */ - " movs r3, #4 \n"/* r3 = 4. */ - " str r3, [r2] \n"/* Program RNR = 4. */ - " adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to first RBAR in TCB. */ - " ldr r2, xRBARConst \n"/* r2 = 0xe000ed9c [Location of RBAR]. */ - " ldmia r1!, {r4-r11} \n"/* Read 4 sets of RBAR/RLAR registers from TCB. */ - " stmia r2!, {r4-r11} \n"/* Write 4 set of RBAR/RLAR registers using alias registers. */ - " \n" - #if ( configTOTAL_MPU_REGIONS == 16 ) - " ldr r2, xRNRConst \n"/* r2 = 0xe000ed98 [Location of RNR]. */ - " movs r3, #8 \n"/* r3 = 8. */ - " str r3, [r2] \n"/* Program RNR = 8. */ - " ldr r2, xRBARConst \n"/* r2 = 0xe000ed9c [Location of RBAR]. */ - " ldmia r1!, {r4-r11} \n"/* Read 4 sets of RBAR/RLAR registers from TCB. */ - " stmia r2!, {r4-r11} \n"/* Write 4 set of RBAR/RLAR registers using alias registers. */ - " ldr r2, xRNRConst \n"/* r2 = 0xe000ed98 [Location of RNR]. */ - " movs r3, #12 \n"/* r3 = 12. */ - " str r3, [r2] \n"/* Program RNR = 12. */ - " ldr r2, xRBARConst \n"/* r2 = 0xe000ed9c [Location of RBAR]. */ - " ldmia r1!, {r4-r11} \n"/* Read 4 sets of RBAR/RLAR registers from TCB. */ - " stmia r2!, {r4-r11} \n"/* Write 4 set of RBAR/RLAR registers using alias registers. */ - #endif /* configTOTAL_MPU_REGIONS == 16 */ - " \n" - " ldr r2, xMPUCTRLConst \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ - " ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */ - " orr r4, #1 \n"/* r4 = r4 | 1 i.e. Set the bit 0 in r4. */ - " str r4, [r2] \n"/* Enable MPU. */ - " dsb \n"/* Force memory writes before continuing. */ - #endif /* configENABLE_MPU */ - " \n" - #if ( configENABLE_MPU == 1 ) - " ldmia r0!, {r1-r11} \n"/* Read from stack - r1 = PSPLIM, r2 = CONTROL, r3 = LR and r4-r11 restored. */ - #else /* configENABLE_MPU */ - " ldmia r0!, {r2-r11} \n"/* Read from stack - r2 = PSPLIM, r3 = LR and r4-r11 restored. */ - #endif /* configENABLE_MPU */ + " ldmia r0!, {r2-r11} \n"/* Read from stack - r2 = PSPLIM, r3 = LR and r4-r11 restored. */ " \n" #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) " tst r3, #0x10 \n"/* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ @@ -323,28 +421,66 @@ void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ " vldmiaeq r0!, {s16-s31} \n"/* Restore the additional FP context registers which are not restored automatically. */ #endif /* configENABLE_FPU || configENABLE_MVE */ " \n" - #if ( configENABLE_MPU == 1 ) - " msr psplim, r1 \n"/* Restore the PSPLIM register value for the task. */ - " msr control, r2 \n"/* Restore the CONTROL register value for the task. */ - #else /* configENABLE_MPU */ - " msr psplim, r2 \n"/* Restore the PSPLIM register value for the task. */ - #endif /* configENABLE_MPU */ + " msr psplim, r2 \n"/* Restore the PSPLIM register value for the task. */ " msr psp, r0 \n"/* Remember the new top of stack for the task. */ " bx r3 \n" " \n" " .align 4 \n" "pxCurrentTCBConst: .word pxCurrentTCB \n" - #if ( configENABLE_MPU == 1 ) - "xMPUCTRLConst: .word 0xe000ed94 \n" - "xMAIR0Const: .word 0xe000edc0 \n" - "xRNRConst: .word 0xe000ed98 \n" - "xRBARConst: .word 0xe000ed9c \n" - #endif /* configENABLE_MPU */ ::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) ); } + +#endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + +void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ +{ + __asm volatile + ( + ".syntax unified \n" + ".extern vPortSVCHandler_C \n" + ".extern vSystemCallEnter \n" + ".extern vSystemCallEnter_1 \n" + ".extern vSystemCallExit \n" + " \n" + "tst lr, #4 \n" + "ite eq \n" + "mrseq r0, msp \n" + "mrsne r0, psp \n" + " \n" + "ldr r1, [r0, #24] \n" + "ldrb r2, [r1, #-2] \n" + "cmp r2, %0 \n" + "beq syscall_enter \n" + "cmp r2, %1 \n" + "beq syscall_enter_1 \n" + "cmp r2, %2 \n" + "beq syscall_exit \n" + "b vPortSVCHandler_C \n" + " \n" + "syscall_enter: \n" + " mov r1, lr \n" + " b vSystemCallEnter \n" + " \n" + "syscall_enter_1: \n" + " mov r1, lr \n" + " b vSystemCallEnter_1 \n" + " \n" + "syscall_exit: \n" + " mov r1, lr \n" + " b vSystemCallExit \n" + " \n" + : /* No outputs. */ + :"i" ( portSVC_SYSTEM_CALL_ENTER ), "i" ( portSVC_SYSTEM_CALL_ENTER_1 ), "i" ( portSVC_SYSTEM_CALL_EXIT ) + : "r0", "r1", "r2", "memory" + ); +} + +#else /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ { __asm volatile @@ -362,4 +498,6 @@ void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ "svchandler_address_const: .word vPortSVCHandler_C \n" ); } + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ /*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM85_NTZ/non_secure/portmacro.h b/portable/GCC/ARM_CM85_NTZ/non_secure/portmacro.h index c45dd21c29e..99f913d3491 100644 --- a/portable/GCC/ARM_CM85_NTZ/non_secure/portmacro.h +++ b/portable/GCC/ARM_CM85_NTZ/non_secure/portmacro.h @@ -56,7 +56,6 @@ #define portARCH_NAME "Cortex-M85" #define portHAS_BASEPRI 1 #define portDONT_DISCARD __attribute__( ( used ) ) -#define portNORETURN __attribute__( ( noreturn ) ) /*-----------------------------------------------------------*/ /* ARMv8-M common port configurations. */ diff --git a/portable/GCC/ARM_CM85_NTZ/non_secure/portmacrocommon.h b/portable/GCC/ARM_CM85_NTZ/non_secure/portmacrocommon.h index c2ca5fa7730..65ac109c802 100644 --- a/portable/GCC/ARM_CM85_NTZ/non_secure/portmacrocommon.h +++ b/portable/GCC/ARM_CM85_NTZ/non_secure/portmacrocommon.h @@ -186,23 +186,120 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #define portMPU_REGION_EXECUTE_NEVER ( 1UL ) /*-----------------------------------------------------------*/ -/** - * @brief Settings to define an MPU region. - */ -typedef struct MPURegionSettings -{ - uint32_t ulRBAR; /**< RBAR for the region. */ - uint32_t ulRLAR; /**< RLAR for the region. */ -} MPURegionSettings_t; +#if ( configENABLE_MPU == 1 ) -/** - * @brief MPU settings as stored in the TCB. - */ -typedef struct MPU_SETTINGS -{ - uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ - MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */ -} xMPU_SETTINGS; + /** + * @brief Settings to define an MPU region. + */ + typedef struct MPURegionSettings + { + uint32_t ulRBAR; /**< RBAR for the region. */ + uint32_t ulRLAR; /**< RLAR for the region. */ + } MPURegionSettings_t; + + #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + + #ifndef configSYSTEM_CALL_STACK_SIZE + #error configSYSTEM_CALL_STACK_SIZE must be defined to the desired size of the system call stack in words for using MPU wrappers v2. + #endif + + /** + * @brief System call stack. + */ + typedef struct SYSTEM_CALL_STACK_INFO + { + uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ]; + uint32_t * pulSystemCallStack; + uint32_t * pulSystemCallStackLimit; + uint32_t * pulTaskStack; + uint32_t ulLinkRegisterAtSystemCallEntry; + uint32_t ulStackLimitRegisterAtSystemCallEntry; + } xSYSTEM_CALL_STACK_INFO; + + #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + + /** + * @brief MPU settings as stored in the TCB. + */ + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + + #if( configENABLE_TRUSTZONE == 1 ) + + /* + * +-----------+---------------+----------+-----------------+------------------------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | + * | | | | PC, xPSR | CONTROL, EXC_RETURN | | + * +-----------+---------------+----------+-----------------+------------------------------+-----+ + * + * <-----------><--------------><---------><----------------><-----------------------------><----> + * 16 16 8 8 5 1 + */ + #define MAX_CONTEXT_SIZE 54 + + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ + + /* + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | + * | | | | PC, xPSR | EXC_RETURN | | + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * + * <-----------><--------------><---------><----------------><---------------------><----> + * 16 16 8 8 4 1 + */ + #define MAX_CONTEXT_SIZE 53 + + #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + + #else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ + + #if( configENABLE_TRUSTZONE == 1 ) + + /* + * +----------+-----------------+------------------------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | + * | | PC, xPSR | CONTROL, EXC_RETURN | | + * +----------+-----------------+------------------------------+-----+ + * + * <---------><----------------><------------------------------><----> + * 8 8 5 1 + */ + #define MAX_CONTEXT_SIZE 22 + + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ + + /* + * +----------+-----------------+----------------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | + * | | PC, xPSR | EXC_RETURN | | + * +----------+-----------------+----------------------+-----+ + * + * <---------><----------------><----------------------><----> + * 8 8 4 1 + */ + #define MAX_CONTEXT_SIZE 21 + + #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + + #endif /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ + + /* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ + #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) + #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) + + typedef struct MPU_SETTINGS + { + uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ + MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */ + uint32_t ulContext[ MAX_CONTEXT_SIZE ]; + uint32_t ulTaskFlags; + + #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo; + #endif + } xMPU_SETTINGS; + +#endif /* configENABLE_MPU == 1 */ /*-----------------------------------------------------------*/ /** @@ -223,6 +320,9 @@ typedef struct MPU_SETTINGS #define portSVC_FREE_SECURE_CONTEXT 1 #define portSVC_START_SCHEDULER 2 #define portSVC_RAISE_PRIVILEGE 3 +#define portSVC_SYSTEM_CALL_ENTER 4 /* System calls with upto 4 parameters. */ +#define portSVC_SYSTEM_CALL_ENTER_1 5 /* System calls with 5 parameters. */ +#define portSVC_SYSTEM_CALL_EXIT 6 /*-----------------------------------------------------------*/ /** @@ -315,6 +415,20 @@ typedef struct MPU_SETTINGS #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ +#if ( configENABLE_MPU == 1 ) + + extern BaseType_t xPortIsTaskPrivileged( void ); + + /** + * @brief Checks whether or not the calling task is privileged. + * + * @return pdTRUE if the calling task is privileged, pdFALSE otherwise. + */ + #define portIS_TASK_PRIVILEGED() xPortIsTaskPrivileged() + +#endif /* configENABLE_MPU == 1 */ +/*-----------------------------------------------------------*/ + /** * @brief Barriers. */ diff --git a/portable/GCC/AVR32_UC3/portmacro.h b/portable/GCC/AVR32_UC3/portmacro.h index 5bc7c8b0877..ebf5010919d 100644 --- a/portable/GCC/AVR32_UC3/portmacro.h +++ b/portable/GCC/AVR32_UC3/portmacro.h @@ -116,7 +116,7 @@ typedef unsigned long UBaseType_t; #define portMAX_DELAY ( TickType_t ) 0xffff #elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; - #define portMAX_DELAY ( TickType_t ) ( 0xFFFFFFFF ) + #define portMAX_DELAY ( TickType_t ) ( 0xFFFFFFFFUL ) #else #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif diff --git a/portable/GCC/CORTUS_APS3/portmacro.h b/portable/GCC/CORTUS_APS3/portmacro.h index 37e739bb55f..9d2d0e0cdb5 100644 --- a/portable/GCC/CORTUS_APS3/portmacro.h +++ b/portable/GCC/CORTUS_APS3/portmacro.h @@ -65,7 +65,7 @@ typedef unsigned long UBaseType_t; #define portMAX_DELAY ( TickType_t ) 0xffff #elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; - #define portMAX_DELAY ( TickType_t ) ( 0xFFFFFFFF ) + #define portMAX_DELAY ( TickType_t ) ( 0xFFFFFFFFUL ) #else #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif diff --git a/portable/GCC/ColdFire_V2/portmacro.h b/portable/GCC/ColdFire_V2/portmacro.h index 14d318b7b94..06ddbd88764 100644 --- a/portable/GCC/ColdFire_V2/portmacro.h +++ b/portable/GCC/ColdFire_V2/portmacro.h @@ -63,7 +63,7 @@ typedef unsigned long UBaseType_t; #define portMAX_DELAY ( TickType_t ) 0xffff #elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; - #define portMAX_DELAY ( TickType_t ) ( 0xFFFFFFFF ) + #define portMAX_DELAY ( TickType_t ) ( 0xFFFFFFFFUL ) #else #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif diff --git a/portable/GCC/H8S2329/portmacro.h b/portable/GCC/H8S2329/portmacro.h index 829ff9f9b64..a5612cadfb8 100644 --- a/portable/GCC/H8S2329/portmacro.h +++ b/portable/GCC/H8S2329/portmacro.h @@ -64,7 +64,7 @@ typedef unsigned char UBaseType_t; #define portMAX_DELAY ( TickType_t ) 0xffff #elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; - #define portMAX_DELAY ( TickType_t ) ( 0xFFFFFFFF ) + #define portMAX_DELAY ( TickType_t ) ( 0xFFFFFFFFUL ) #else #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif diff --git a/portable/GCC/HCS12/portmacro.h b/portable/GCC/HCS12/portmacro.h index a864419899f..a11b96c37d0 100644 --- a/portable/GCC/HCS12/portmacro.h +++ b/portable/GCC/HCS12/portmacro.h @@ -65,7 +65,7 @@ typedef unsigned char UBaseType_t; #define portMAX_DELAY ( TickType_t ) 0xffff #elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; - #define portMAX_DELAY ( TickType_t ) ( 0xFFFFFFFF ) + #define portMAX_DELAY ( TickType_t ) ( 0xFFFFFFFFUL ) #else #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif diff --git a/portable/GCC/MSP430F449/portmacro.h b/portable/GCC/MSP430F449/portmacro.h index 5a6e1db9c94..2f70a24d1b2 100644 --- a/portable/GCC/MSP430F449/portmacro.h +++ b/portable/GCC/MSP430F449/portmacro.h @@ -63,7 +63,7 @@ typedef unsigned short UBaseType_t; #define portMAX_DELAY ( TickType_t ) 0xffff #elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; - #define portMAX_DELAY ( TickType_t ) ( 0xFFFFFFFF ) + #define portMAX_DELAY ( TickType_t ) ( 0xFFFFFFFFUL ) #else #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif diff --git a/portable/GCC/PPC405_Xilinx/portmacro.h b/portable/GCC/PPC405_Xilinx/portmacro.h index e6f1c06c845..06cca5df9ed 100644 --- a/portable/GCC/PPC405_Xilinx/portmacro.h +++ b/portable/GCC/PPC405_Xilinx/portmacro.h @@ -65,7 +65,7 @@ typedef unsigned long UBaseType_t; #define portMAX_DELAY ( TickType_t ) 0xffff #elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; - #define portMAX_DELAY ( TickType_t ) ( 0xFFFFFFFF ) + #define portMAX_DELAY ( TickType_t ) ( 0xFFFFFFFFUL ) #else #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif diff --git a/portable/GCC/PPC440_Xilinx/portmacro.h b/portable/GCC/PPC440_Xilinx/portmacro.h index e6f1c06c845..06cca5df9ed 100644 --- a/portable/GCC/PPC440_Xilinx/portmacro.h +++ b/portable/GCC/PPC440_Xilinx/portmacro.h @@ -65,7 +65,7 @@ typedef unsigned long UBaseType_t; #define portMAX_DELAY ( TickType_t ) 0xffff #elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; - #define portMAX_DELAY ( TickType_t ) ( 0xFFFFFFFF ) + #define portMAX_DELAY ( TickType_t ) ( 0xFFFFFFFFUL ) #else #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif diff --git a/portable/GCC/RL78/portmacro.h b/portable/GCC/RL78/portmacro.h index 8108f1c1221..34940200838 100644 --- a/portable/GCC/RL78/portmacro.h +++ b/portable/GCC/RL78/portmacro.h @@ -59,7 +59,7 @@ typedef unsigned short UBaseType_t; #define portMAX_DELAY ( TickType_t ) 0xffff #elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; - #define portMAX_DELAY ( TickType_t ) ( 0xFFFFFFFF ) + #define portMAX_DELAY ( TickType_t ) ( 0xFFFFFFFFUL ) #else #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif diff --git a/portable/GCC/STR75x/portmacro.h b/portable/GCC/STR75x/portmacro.h index 8d5e832c59e..876783dcb67 100644 --- a/portable/GCC/STR75x/portmacro.h +++ b/portable/GCC/STR75x/portmacro.h @@ -64,7 +64,7 @@ typedef unsigned long UBaseType_t; #define portMAX_DELAY ( TickType_t ) 0xffff #elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; - #define portMAX_DELAY ( TickType_t ) ( 0xFFFFFFFF ) + #define portMAX_DELAY ( TickType_t ) ( 0xFFFFFFFFUL ) #else #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif diff --git a/portable/IAR/78K0R/portmacro.h b/portable/IAR/78K0R/portmacro.h index 4ccc083c080..03bb5dee7ef 100644 --- a/portable/IAR/78K0R/portmacro.h +++ b/portable/IAR/78K0R/portmacro.h @@ -64,7 +64,7 @@ typedef unsigned short UBaseType_t; #define portMAX_DELAY ( TickType_t ) 0xffff #elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; - #define portMAX_DELAY ( TickType_t ) ( 0xFFFFFFFF ) + #define portMAX_DELAY ( TickType_t ) ( 0xFFFFFFFFUL ) #else #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif diff --git a/portable/IAR/ARM_CM23/non_secure/mpu_wrappers_v2_asm.S b/portable/IAR/ARM_CM23/non_secure/mpu_wrappers_v2_asm.S new file mode 100644 index 00000000000..867642b5e97 --- /dev/null +++ b/portable/IAR/ARM_CM23/non_secure/mpu_wrappers_v2_asm.S @@ -0,0 +1,1623 @@ +/* + * FreeRTOS Kernel + * Copyright (C) 2021 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 + * + */ + + + SECTION freertos_system_calls:CODE:NOROOT(2) + THUMB +/*-----------------------------------------------------------*/ + +#include "FreeRTOSConfig.h" + +#ifndef configUSE_MPU_WRAPPERS_V1 + #define configUSE_MPU_WRAPPERS_V1 0 +#endif + +/* These must be in sync with portmacro.h. */ +#define portSVC_SYSTEM_CALL_ENTER 4 /* System calls with upto 4 parameters. */ +#define portSVC_SYSTEM_CALL_ENTER_1 5 /* System calls with 5 parameters. */ +#define portSVC_SYSTEM_CALL_EXIT 6 +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + + PUBLIC MPU_xTaskDelayUntil +MPU_xTaskDelayUntil: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xTaskDelayUntil_Unpriv + MPU_xTaskDelayUntil_Priv: + pop {r0, r1} + b MPU_xTaskDelayUntilImpl + MPU_xTaskDelayUntil_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskDelayUntilImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskAbortDelay +MPU_xTaskAbortDelay: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xTaskAbortDelay_Unpriv + MPU_xTaskAbortDelay_Priv: + pop {r0, r1} + b MPU_xTaskAbortDelayImpl + MPU_xTaskAbortDelay_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskAbortDelayImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTaskDelay +MPU_vTaskDelay: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_vTaskDelay_Unpriv + MPU_vTaskDelay_Priv: + pop {r0, r1} + b MPU_vTaskDelayImpl + MPU_vTaskDelay_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskDelayImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxTaskPriorityGet +MPU_uxTaskPriorityGet: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_uxTaskPriorityGet_Unpriv + MPU_uxTaskPriorityGet_Priv: + pop {r0, r1} + b MPU_uxTaskPriorityGetImpl + MPU_uxTaskPriorityGet_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxTaskPriorityGetImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_eTaskGetState +MPU_eTaskGetState: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_eTaskGetState_Unpriv + MPU_eTaskGetState_Priv: + pop {r0, r1} + b MPU_eTaskGetStateImpl + MPU_eTaskGetState_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_eTaskGetStateImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTaskGetInfo +MPU_vTaskGetInfo: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_vTaskGetInfo_Unpriv + MPU_vTaskGetInfo_Priv: + pop {r0, r1} + b MPU_vTaskGetInfoImpl + MPU_vTaskGetInfo_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskGetInfoImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGetIdleTaskHandle +MPU_xTaskGetIdleTaskHandle: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xTaskGetIdleTaskHandle_Unpriv + MPU_xTaskGetIdleTaskHandle_Priv: + pop {r0, r1} + b MPU_xTaskGetIdleTaskHandleImpl + MPU_xTaskGetIdleTaskHandle_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskGetIdleTaskHandleImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTaskSuspend +MPU_vTaskSuspend: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_vTaskSuspend_Unpriv + MPU_vTaskSuspend_Priv: + pop {r0, r1} + b MPU_vTaskSuspendImpl + MPU_vTaskSuspend_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskSuspendImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTaskResume +MPU_vTaskResume: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_vTaskResume_Unpriv + MPU_vTaskResume_Priv: + pop {r0, r1} + b MPU_vTaskResumeImpl + MPU_vTaskResume_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskResumeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGetTickCount +MPU_xTaskGetTickCount: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xTaskGetTickCount_Unpriv + MPU_xTaskGetTickCount_Priv: + pop {r0, r1} + b MPU_xTaskGetTickCountImpl + MPU_xTaskGetTickCount_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskGetTickCountImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxTaskGetNumberOfTasks +MPU_uxTaskGetNumberOfTasks: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_uxTaskGetNumberOfTasks_Unpriv + MPU_uxTaskGetNumberOfTasks_Priv: + pop {r0, r1} + b MPU_uxTaskGetNumberOfTasksImpl + MPU_uxTaskGetNumberOfTasks_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxTaskGetNumberOfTasksImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_pcTaskGetName +MPU_pcTaskGetName: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_pcTaskGetName_Unpriv + MPU_pcTaskGetName_Priv: + pop {r0, r1} + b MPU_pcTaskGetNameImpl + MPU_pcTaskGetName_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_pcTaskGetNameImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_ulTaskGetRunTimeCounter +MPU_ulTaskGetRunTimeCounter: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_ulTaskGetRunTimeCounter_Unpriv + MPU_ulTaskGetRunTimeCounter_Priv: + pop {r0, r1} + b MPU_ulTaskGetRunTimeCounterImpl + MPU_ulTaskGetRunTimeCounter_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_ulTaskGetRunTimeCounterImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_ulTaskGetRunTimePercent +MPU_ulTaskGetRunTimePercent: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_ulTaskGetRunTimePercent_Unpriv + MPU_ulTaskGetRunTimePercent_Priv: + pop {r0, r1} + b MPU_ulTaskGetRunTimePercentImpl + MPU_ulTaskGetRunTimePercent_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_ulTaskGetRunTimePercentImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_ulTaskGetIdleRunTimePercent +MPU_ulTaskGetIdleRunTimePercent: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_ulTaskGetIdleRunTimePercent_Unpriv + MPU_ulTaskGetIdleRunTimePercent_Priv: + pop {r0, r1} + b MPU_ulTaskGetIdleRunTimePercentImpl + MPU_ulTaskGetIdleRunTimePercent_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_ulTaskGetIdleRunTimePercentImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_ulTaskGetIdleRunTimeCounter +MPU_ulTaskGetIdleRunTimeCounter: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_ulTaskGetIdleRunTimeCounter_Unpriv + MPU_ulTaskGetIdleRunTimeCounter_Priv: + pop {r0, r1} + b MPU_ulTaskGetIdleRunTimeCounterImpl + MPU_ulTaskGetIdleRunTimeCounter_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_ulTaskGetIdleRunTimeCounterImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTaskSetApplicationTaskTag +MPU_vTaskSetApplicationTaskTag: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_vTaskSetApplicationTaskTag_Unpriv + MPU_vTaskSetApplicationTaskTag_Priv: + pop {r0, r1} + b MPU_vTaskSetApplicationTaskTagImpl + MPU_vTaskSetApplicationTaskTag_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskSetApplicationTaskTagImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGetApplicationTaskTag +MPU_xTaskGetApplicationTaskTag: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xTaskGetApplicationTaskTag_Unpriv + MPU_xTaskGetApplicationTaskTag_Priv: + pop {r0, r1} + b MPU_xTaskGetApplicationTaskTagImpl + MPU_xTaskGetApplicationTaskTag_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskGetApplicationTaskTagImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTaskSetThreadLocalStoragePointer +MPU_vTaskSetThreadLocalStoragePointer: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_vTaskSetThreadLocalStoragePointer_Unpriv + MPU_vTaskSetThreadLocalStoragePointer_Priv: + pop {r0, r1} + b MPU_vTaskSetThreadLocalStoragePointerImpl + MPU_vTaskSetThreadLocalStoragePointer_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskSetThreadLocalStoragePointerImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_pvTaskGetThreadLocalStoragePointer +MPU_pvTaskGetThreadLocalStoragePointer: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_pvTaskGetThreadLocalStoragePointer_Unpriv + MPU_pvTaskGetThreadLocalStoragePointer_Priv: + pop {r0, r1} + b MPU_pvTaskGetThreadLocalStoragePointerImpl + MPU_pvTaskGetThreadLocalStoragePointer_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_pvTaskGetThreadLocalStoragePointerImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxTaskGetSystemState +MPU_uxTaskGetSystemState: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_uxTaskGetSystemState_Unpriv + MPU_uxTaskGetSystemState_Priv: + pop {r0, r1} + b MPU_uxTaskGetSystemStateImpl + MPU_uxTaskGetSystemState_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxTaskGetSystemStateImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxTaskGetStackHighWaterMark +MPU_uxTaskGetStackHighWaterMark: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_uxTaskGetStackHighWaterMark_Unpriv + MPU_uxTaskGetStackHighWaterMark_Priv: + pop {r0, r1} + b MPU_uxTaskGetStackHighWaterMarkImpl + MPU_uxTaskGetStackHighWaterMark_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxTaskGetStackHighWaterMarkImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxTaskGetStackHighWaterMark2 +MPU_uxTaskGetStackHighWaterMark2: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_uxTaskGetStackHighWaterMark2_Unpriv + MPU_uxTaskGetStackHighWaterMark2_Priv: + pop {r0, r1} + b MPU_uxTaskGetStackHighWaterMark2Impl + MPU_uxTaskGetStackHighWaterMark2_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxTaskGetStackHighWaterMark2Impl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGetCurrentTaskHandle +MPU_xTaskGetCurrentTaskHandle: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xTaskGetCurrentTaskHandle_Unpriv + MPU_xTaskGetCurrentTaskHandle_Priv: + pop {r0, r1} + b MPU_xTaskGetCurrentTaskHandleImpl + MPU_xTaskGetCurrentTaskHandle_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskGetCurrentTaskHandleImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGetSchedulerState +MPU_xTaskGetSchedulerState: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xTaskGetSchedulerState_Unpriv + MPU_xTaskGetSchedulerState_Priv: + pop {r0, r1} + b MPU_xTaskGetSchedulerStateImpl + MPU_xTaskGetSchedulerState_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskGetSchedulerStateImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTaskSetTimeOutState +MPU_vTaskSetTimeOutState: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_vTaskSetTimeOutState_Unpriv + MPU_vTaskSetTimeOutState_Priv: + pop {r0, r1} + b MPU_vTaskSetTimeOutStateImpl + MPU_vTaskSetTimeOutState_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskSetTimeOutStateImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskCheckForTimeOut +MPU_xTaskCheckForTimeOut: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xTaskCheckForTimeOut_Unpriv + MPU_xTaskCheckForTimeOut_Priv: + pop {r0, r1} + b MPU_xTaskCheckForTimeOutImpl + MPU_xTaskCheckForTimeOut_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskCheckForTimeOutImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGenericNotify +MPU_xTaskGenericNotify: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xTaskGenericNotify_Unpriv + MPU_xTaskGenericNotify_Priv: + pop {r0, r1} + b MPU_xTaskGenericNotifyImpl + MPU_xTaskGenericNotify_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER_1 + bl MPU_xTaskGenericNotifyImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGenericNotifyWait +MPU_xTaskGenericNotifyWait: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xTaskGenericNotifyWait_Unpriv + MPU_xTaskGenericNotifyWait_Priv: + pop {r0, r1} + b MPU_xTaskGenericNotifyWaitImpl + MPU_xTaskGenericNotifyWait_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER_1 + bl MPU_xTaskGenericNotifyWaitImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_ulTaskGenericNotifyTake +MPU_ulTaskGenericNotifyTake: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_ulTaskGenericNotifyTake_Unpriv + MPU_ulTaskGenericNotifyTake_Priv: + pop {r0, r1} + b MPU_ulTaskGenericNotifyTakeImpl + MPU_ulTaskGenericNotifyTake_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_ulTaskGenericNotifyTakeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGenericNotifyStateClear +MPU_xTaskGenericNotifyStateClear: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xTaskGenericNotifyStateClear_Unpriv + MPU_xTaskGenericNotifyStateClear_Priv: + pop {r0, r1} + b MPU_xTaskGenericNotifyStateClearImpl + MPU_xTaskGenericNotifyStateClear_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskGenericNotifyStateClearImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_ulTaskGenericNotifyValueClear +MPU_ulTaskGenericNotifyValueClear: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_ulTaskGenericNotifyValueClear_Unpriv + MPU_ulTaskGenericNotifyValueClear_Priv: + pop {r0, r1} + b MPU_ulTaskGenericNotifyValueClearImpl + MPU_ulTaskGenericNotifyValueClear_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_ulTaskGenericNotifyValueClearImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueGenericSend +MPU_xQueueGenericSend: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xQueueGenericSend_Unpriv + MPU_xQueueGenericSend_Priv: + pop {r0, r1} + b MPU_xQueueGenericSendImpl + MPU_xQueueGenericSend_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueGenericSendImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxQueueMessagesWaiting +MPU_uxQueueMessagesWaiting: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_uxQueueMessagesWaiting_Unpriv + MPU_uxQueueMessagesWaiting_Priv: + pop {r0, r1} + b MPU_uxQueueMessagesWaitingImpl + MPU_uxQueueMessagesWaiting_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxQueueMessagesWaitingImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxQueueSpacesAvailable +MPU_uxQueueSpacesAvailable: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_uxQueueSpacesAvailable_Unpriv + MPU_uxQueueSpacesAvailable_Priv: + pop {r0, r1} + b MPU_uxQueueSpacesAvailableImpl + MPU_uxQueueSpacesAvailable_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxQueueSpacesAvailableImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueReceive +MPU_xQueueReceive: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xQueueReceive_Unpriv + MPU_xQueueReceive_Priv: + pop {r0, r1} + b MPU_xQueueReceiveImpl + MPU_xQueueReceive_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueReceiveImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueuePeek +MPU_xQueuePeek: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xQueuePeek_Unpriv + MPU_xQueuePeek_Priv: + pop {r0, r1} + b MPU_xQueuePeekImpl + MPU_xQueuePeek_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueuePeekImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueSemaphoreTake +MPU_xQueueSemaphoreTake: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xQueueSemaphoreTake_Unpriv + MPU_xQueueSemaphoreTake_Priv: + pop {r0, r1} + b MPU_xQueueSemaphoreTakeImpl + MPU_xQueueSemaphoreTake_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueSemaphoreTakeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueGetMutexHolder +MPU_xQueueGetMutexHolder: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xQueueGetMutexHolder_Unpriv + MPU_xQueueGetMutexHolder_Priv: + pop {r0, r1} + b MPU_xQueueGetMutexHolderImpl + MPU_xQueueGetMutexHolder_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueGetMutexHolderImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueTakeMutexRecursive +MPU_xQueueTakeMutexRecursive: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xQueueTakeMutexRecursive_Unpriv + MPU_xQueueTakeMutexRecursive_Priv: + pop {r0, r1} + b MPU_xQueueTakeMutexRecursiveImpl + MPU_xQueueTakeMutexRecursive_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueTakeMutexRecursiveImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueGiveMutexRecursive +MPU_xQueueGiveMutexRecursive: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xQueueGiveMutexRecursive_Unpriv + MPU_xQueueGiveMutexRecursive_Priv: + pop {r0, r1} + b MPU_xQueueGiveMutexRecursiveImpl + MPU_xQueueGiveMutexRecursive_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueGiveMutexRecursiveImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueSelectFromSet +MPU_xQueueSelectFromSet: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xQueueSelectFromSet_Unpriv + MPU_xQueueSelectFromSet_Priv: + pop {r0, r1} + b MPU_xQueueSelectFromSetImpl + MPU_xQueueSelectFromSet_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueSelectFromSetImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueAddToSet +MPU_xQueueAddToSet: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xQueueAddToSet_Unpriv + MPU_xQueueAddToSet_Priv: + pop {r0, r1} + b MPU_xQueueAddToSetImpl + MPU_xQueueAddToSet_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueAddToSetImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vQueueAddToRegistry +MPU_vQueueAddToRegistry: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_vQueueAddToRegistry_Unpriv + MPU_vQueueAddToRegistry_Priv: + pop {r0, r1} + b MPU_vQueueAddToRegistryImpl + MPU_vQueueAddToRegistry_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vQueueAddToRegistryImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vQueueUnregisterQueue +MPU_vQueueUnregisterQueue: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_vQueueUnregisterQueue_Unpriv + MPU_vQueueUnregisterQueue_Priv: + pop {r0, r1} + b MPU_vQueueUnregisterQueueImpl + MPU_vQueueUnregisterQueue_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vQueueUnregisterQueueImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_pcQueueGetName +MPU_pcQueueGetName: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_pcQueueGetName_Unpriv + MPU_pcQueueGetName_Priv: + pop {r0, r1} + b MPU_pcQueueGetNameImpl + MPU_pcQueueGetName_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_pcQueueGetNameImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_pvTimerGetTimerID +MPU_pvTimerGetTimerID: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_pvTimerGetTimerID_Unpriv + MPU_pvTimerGetTimerID_Priv: + pop {r0, r1} + b MPU_pvTimerGetTimerIDImpl + MPU_pvTimerGetTimerID_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_pvTimerGetTimerIDImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTimerSetTimerID +MPU_vTimerSetTimerID: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_vTimerSetTimerID_Unpriv + MPU_vTimerSetTimerID_Priv: + pop {r0, r1} + b MPU_vTimerSetTimerIDImpl + MPU_vTimerSetTimerID_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTimerSetTimerIDImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTimerIsTimerActive +MPU_xTimerIsTimerActive: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xTimerIsTimerActive_Unpriv + MPU_xTimerIsTimerActive_Priv: + pop {r0, r1} + b MPU_xTimerIsTimerActiveImpl + MPU_xTimerIsTimerActive_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTimerIsTimerActiveImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTimerGetTimerDaemonTaskHandle +MPU_xTimerGetTimerDaemonTaskHandle: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xTimerGetTimerDaemonTaskHandle_Unpriv + MPU_xTimerGetTimerDaemonTaskHandle_Priv: + pop {r0, r1} + b MPU_xTimerGetTimerDaemonTaskHandleImpl + MPU_xTimerGetTimerDaemonTaskHandle_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTimerGetTimerDaemonTaskHandleImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTimerGenericCommand +MPU_xTimerGenericCommand: + push {r0, r1} + /* This function can be called from ISR also and therefore, we need a check + * to take privileged path, if called from ISR. */ + mrs r0, ipsr + cmp r0, #0 + bne MPU_xTimerGenericCommand_Priv + mrs r0, control + movs r1, #1 + tst r0, r1 + beq MPU_xTimerGenericCommand_Priv + MPU_xTimerGenericCommand_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER_1 + bl MPU_xTimerGenericCommandImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr + MPU_xTimerGenericCommand_Priv: + pop {r0, r1} + b MPU_xTimerGenericCommandImpl + +/*-----------------------------------------------------------*/ + + PUBLIC MPU_pcTimerGetName +MPU_pcTimerGetName: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_pcTimerGetName_Unpriv + MPU_pcTimerGetName_Priv: + pop {r0, r1} + b MPU_pcTimerGetNameImpl + MPU_pcTimerGetName_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_pcTimerGetNameImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTimerSetReloadMode +MPU_vTimerSetReloadMode: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_vTimerSetReloadMode_Unpriv + MPU_vTimerSetReloadMode_Priv: + pop {r0, r1} + b MPU_vTimerSetReloadModeImpl + MPU_vTimerSetReloadMode_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTimerSetReloadModeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTimerGetReloadMode +MPU_xTimerGetReloadMode: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xTimerGetReloadMode_Unpriv + MPU_xTimerGetReloadMode_Priv: + pop {r0, r1} + b MPU_xTimerGetReloadModeImpl + MPU_xTimerGetReloadMode_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTimerGetReloadModeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxTimerGetReloadMode +MPU_uxTimerGetReloadMode: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_uxTimerGetReloadMode_Unpriv + MPU_uxTimerGetReloadMode_Priv: + pop {r0, r1} + b MPU_uxTimerGetReloadModeImpl + MPU_uxTimerGetReloadMode_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxTimerGetReloadModeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTimerGetPeriod +MPU_xTimerGetPeriod: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xTimerGetPeriod_Unpriv + MPU_xTimerGetPeriod_Priv: + pop {r0, r1} + b MPU_xTimerGetPeriodImpl + MPU_xTimerGetPeriod_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTimerGetPeriodImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTimerGetExpiryTime +MPU_xTimerGetExpiryTime: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xTimerGetExpiryTime_Unpriv + MPU_xTimerGetExpiryTime_Priv: + pop {r0, r1} + b MPU_xTimerGetExpiryTimeImpl + MPU_xTimerGetExpiryTime_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTimerGetExpiryTimeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xEventGroupWaitBits +MPU_xEventGroupWaitBits: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xEventGroupWaitBits_Unpriv + MPU_xEventGroupWaitBits_Priv: + pop {r0, r1} + b MPU_xEventGroupWaitBitsImpl + MPU_xEventGroupWaitBits_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER_1 + bl MPU_xEventGroupWaitBitsImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xEventGroupClearBits +MPU_xEventGroupClearBits: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xEventGroupClearBits_Unpriv + MPU_xEventGroupClearBits_Priv: + pop {r0, r1} + b MPU_xEventGroupClearBitsImpl + MPU_xEventGroupClearBits_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xEventGroupClearBitsImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xEventGroupSetBits +MPU_xEventGroupSetBits: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xEventGroupSetBits_Unpriv + MPU_xEventGroupSetBits_Priv: + pop {r0, r1} + b MPU_xEventGroupSetBitsImpl + MPU_xEventGroupSetBits_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xEventGroupSetBitsImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xEventGroupSync +MPU_xEventGroupSync: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xEventGroupSync_Unpriv + MPU_xEventGroupSync_Priv: + pop {r0, r1} + b MPU_xEventGroupSyncImpl + MPU_xEventGroupSync_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xEventGroupSyncImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxEventGroupGetNumber +MPU_uxEventGroupGetNumber: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_uxEventGroupGetNumber_Unpriv + MPU_uxEventGroupGetNumber_Priv: + pop {r0, r1} + b MPU_uxEventGroupGetNumberImpl + MPU_uxEventGroupGetNumber_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxEventGroupGetNumberImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vEventGroupSetNumber +MPU_vEventGroupSetNumber: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_vEventGroupSetNumber_Unpriv + MPU_vEventGroupSetNumber_Priv: + pop {r0, r1} + b MPU_vEventGroupSetNumberImpl + MPU_vEventGroupSetNumber_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vEventGroupSetNumberImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferSend +MPU_xStreamBufferSend: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xStreamBufferSend_Unpriv + MPU_xStreamBufferSend_Priv: + pop {r0, r1} + b MPU_xStreamBufferSendImpl + MPU_xStreamBufferSend_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferSendImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferReceive +MPU_xStreamBufferReceive: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xStreamBufferReceive_Unpriv + MPU_xStreamBufferReceive_Priv: + pop {r0, r1} + b MPU_xStreamBufferReceiveImpl + MPU_xStreamBufferReceive_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferReceiveImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferIsFull +MPU_xStreamBufferIsFull: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xStreamBufferIsFull_Unpriv + MPU_xStreamBufferIsFull_Priv: + pop {r0, r1} + b MPU_xStreamBufferIsFullImpl + MPU_xStreamBufferIsFull_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferIsFullImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferIsEmpty +MPU_xStreamBufferIsEmpty: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xStreamBufferIsEmpty_Unpriv + MPU_xStreamBufferIsEmpty_Priv: + pop {r0, r1} + b MPU_xStreamBufferIsEmptyImpl + MPU_xStreamBufferIsEmpty_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferIsEmptyImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferSpacesAvailable +MPU_xStreamBufferSpacesAvailable: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xStreamBufferSpacesAvailable_Unpriv + MPU_xStreamBufferSpacesAvailable_Priv: + pop {r0, r1} + b MPU_xStreamBufferSpacesAvailableImpl + MPU_xStreamBufferSpacesAvailable_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferSpacesAvailableImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferBytesAvailable +MPU_xStreamBufferBytesAvailable: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xStreamBufferBytesAvailable_Unpriv + MPU_xStreamBufferBytesAvailable_Priv: + pop {r0, r1} + b MPU_xStreamBufferBytesAvailableImpl + MPU_xStreamBufferBytesAvailable_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferBytesAvailableImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferSetTriggerLevel +MPU_xStreamBufferSetTriggerLevel: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xStreamBufferSetTriggerLevel_Unpriv + MPU_xStreamBufferSetTriggerLevel_Priv: + pop {r0, r1} + b MPU_xStreamBufferSetTriggerLevelImpl + MPU_xStreamBufferSetTriggerLevel_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferSetTriggerLevelImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferNextMessageLengthBytes +MPU_xStreamBufferNextMessageLengthBytes: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xStreamBufferNextMessageLengthBytes_Unpriv + MPU_xStreamBufferNextMessageLengthBytes_Priv: + pop {r0, r1} + b MPU_xStreamBufferNextMessageLengthBytesImpl + MPU_xStreamBufferNextMessageLengthBytes_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferNextMessageLengthBytesImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + +/* Default weak implementations in case one is not available from + * mpu_wrappers because of config options. */ + + PUBWEAK MPU_xTaskDelayUntilImpl +MPU_xTaskDelayUntilImpl: + b MPU_xTaskDelayUntilImpl + + PUBWEAK MPU_xTaskAbortDelayImpl +MPU_xTaskAbortDelayImpl: + b MPU_xTaskAbortDelayImpl + + PUBWEAK MPU_vTaskDelayImpl +MPU_vTaskDelayImpl: + b MPU_vTaskDelayImpl + + PUBWEAK MPU_uxTaskPriorityGetImpl +MPU_uxTaskPriorityGetImpl: + b MPU_uxTaskPriorityGetImpl + + PUBWEAK MPU_eTaskGetStateImpl +MPU_eTaskGetStateImpl: + b MPU_eTaskGetStateImpl + + PUBWEAK MPU_vTaskGetInfoImpl +MPU_vTaskGetInfoImpl: + b MPU_vTaskGetInfoImpl + + PUBWEAK MPU_xTaskGetIdleTaskHandleImpl +MPU_xTaskGetIdleTaskHandleImpl: + b MPU_xTaskGetIdleTaskHandleImpl + + PUBWEAK MPU_vTaskSuspendImpl +MPU_vTaskSuspendImpl: + b MPU_vTaskSuspendImpl + + PUBWEAK MPU_vTaskResumeImpl +MPU_vTaskResumeImpl: + b MPU_vTaskResumeImpl + + PUBWEAK MPU_xTaskGetTickCountImpl +MPU_xTaskGetTickCountImpl: + b MPU_xTaskGetTickCountImpl + + PUBWEAK MPU_uxTaskGetNumberOfTasksImpl +MPU_uxTaskGetNumberOfTasksImpl: + b MPU_uxTaskGetNumberOfTasksImpl + + PUBWEAK MPU_pcTaskGetNameImpl +MPU_pcTaskGetNameImpl: + b MPU_pcTaskGetNameImpl + + PUBWEAK MPU_ulTaskGetRunTimeCounterImpl +MPU_ulTaskGetRunTimeCounterImpl: + b MPU_ulTaskGetRunTimeCounterImpl + + PUBWEAK MPU_ulTaskGetRunTimePercentImpl +MPU_ulTaskGetRunTimePercentImpl: + b MPU_ulTaskGetRunTimePercentImpl + + PUBWEAK MPU_ulTaskGetIdleRunTimePercentImpl +MPU_ulTaskGetIdleRunTimePercentImpl: + b MPU_ulTaskGetIdleRunTimePercentImpl + + PUBWEAK MPU_ulTaskGetIdleRunTimeCounterImpl +MPU_ulTaskGetIdleRunTimeCounterImpl: + b MPU_ulTaskGetIdleRunTimeCounterImpl + + PUBWEAK MPU_vTaskSetApplicationTaskTagImpl +MPU_vTaskSetApplicationTaskTagImpl: + b MPU_vTaskSetApplicationTaskTagImpl + + PUBWEAK MPU_xTaskGetApplicationTaskTagImpl +MPU_xTaskGetApplicationTaskTagImpl: + b MPU_xTaskGetApplicationTaskTagImpl + + PUBWEAK MPU_vTaskSetThreadLocalStoragePointerImpl +MPU_vTaskSetThreadLocalStoragePointerImpl: + b MPU_vTaskSetThreadLocalStoragePointerImpl + + PUBWEAK MPU_pvTaskGetThreadLocalStoragePointerImpl +MPU_pvTaskGetThreadLocalStoragePointerImpl: + b MPU_pvTaskGetThreadLocalStoragePointerImpl + + PUBWEAK MPU_uxTaskGetSystemStateImpl +MPU_uxTaskGetSystemStateImpl: + b MPU_uxTaskGetSystemStateImpl + + PUBWEAK MPU_uxTaskGetStackHighWaterMarkImpl +MPU_uxTaskGetStackHighWaterMarkImpl: + b MPU_uxTaskGetStackHighWaterMarkImpl + + PUBWEAK MPU_uxTaskGetStackHighWaterMark2Impl +MPU_uxTaskGetStackHighWaterMark2Impl: + b MPU_uxTaskGetStackHighWaterMark2Impl + + PUBWEAK MPU_xTaskGetCurrentTaskHandleImpl +MPU_xTaskGetCurrentTaskHandleImpl: + b MPU_xTaskGetCurrentTaskHandleImpl + + PUBWEAK MPU_xTaskGetSchedulerStateImpl +MPU_xTaskGetSchedulerStateImpl: + b MPU_xTaskGetSchedulerStateImpl + + PUBWEAK MPU_vTaskSetTimeOutStateImpl +MPU_vTaskSetTimeOutStateImpl: + b MPU_vTaskSetTimeOutStateImpl + + PUBWEAK MPU_xTaskCheckForTimeOutImpl +MPU_xTaskCheckForTimeOutImpl: + b MPU_xTaskCheckForTimeOutImpl + + PUBWEAK MPU_xTaskGenericNotifyImpl +MPU_xTaskGenericNotifyImpl: + b MPU_xTaskGenericNotifyImpl + + PUBWEAK MPU_xTaskGenericNotifyWaitImpl +MPU_xTaskGenericNotifyWaitImpl: + b MPU_xTaskGenericNotifyWaitImpl + + PUBWEAK MPU_ulTaskGenericNotifyTakeImpl +MPU_ulTaskGenericNotifyTakeImpl: + b MPU_ulTaskGenericNotifyTakeImpl + + PUBWEAK MPU_xTaskGenericNotifyStateClearImpl +MPU_xTaskGenericNotifyStateClearImpl: + b MPU_xTaskGenericNotifyStateClearImpl + + PUBWEAK MPU_ulTaskGenericNotifyValueClearImpl +MPU_ulTaskGenericNotifyValueClearImpl: + b MPU_ulTaskGenericNotifyValueClearImpl + + PUBWEAK MPU_xQueueGenericSendImpl +MPU_xQueueGenericSendImpl: + b MPU_xQueueGenericSendImpl + + PUBWEAK MPU_uxQueueMessagesWaitingImpl +MPU_uxQueueMessagesWaitingImpl: + b MPU_uxQueueMessagesWaitingImpl + + PUBWEAK MPU_uxQueueSpacesAvailableImpl +MPU_uxQueueSpacesAvailableImpl: + b MPU_uxQueueSpacesAvailableImpl + + PUBWEAK MPU_xQueueReceiveImpl +MPU_xQueueReceiveImpl: + b MPU_xQueueReceiveImpl + + PUBWEAK MPU_xQueuePeekImpl +MPU_xQueuePeekImpl: + b MPU_xQueuePeekImpl + + PUBWEAK MPU_xQueueSemaphoreTakeImpl +MPU_xQueueSemaphoreTakeImpl: + b MPU_xQueueSemaphoreTakeImpl + + PUBWEAK MPU_xQueueGetMutexHolderImpl +MPU_xQueueGetMutexHolderImpl: + b MPU_xQueueGetMutexHolderImpl + + PUBWEAK MPU_xQueueTakeMutexRecursiveImpl +MPU_xQueueTakeMutexRecursiveImpl: + b MPU_xQueueTakeMutexRecursiveImpl + + PUBWEAK MPU_xQueueGiveMutexRecursiveImpl +MPU_xQueueGiveMutexRecursiveImpl: + b MPU_xQueueGiveMutexRecursiveImpl + + PUBWEAK MPU_xQueueSelectFromSetImpl +MPU_xQueueSelectFromSetImpl: + b MPU_xQueueSelectFromSetImpl + + PUBWEAK MPU_xQueueAddToSetImpl +MPU_xQueueAddToSetImpl: + b MPU_xQueueAddToSetImpl + + PUBWEAK MPU_vQueueAddToRegistryImpl +MPU_vQueueAddToRegistryImpl: + b MPU_vQueueAddToRegistryImpl + + PUBWEAK MPU_vQueueUnregisterQueueImpl +MPU_vQueueUnregisterQueueImpl: + b MPU_vQueueUnregisterQueueImpl + + PUBWEAK MPU_pcQueueGetNameImpl +MPU_pcQueueGetNameImpl: + b MPU_pcQueueGetNameImpl + + PUBWEAK MPU_pvTimerGetTimerIDImpl +MPU_pvTimerGetTimerIDImpl: + b MPU_pvTimerGetTimerIDImpl + + PUBWEAK MPU_vTimerSetTimerIDImpl +MPU_vTimerSetTimerIDImpl: + b MPU_vTimerSetTimerIDImpl + + PUBWEAK MPU_xTimerIsTimerActiveImpl +MPU_xTimerIsTimerActiveImpl: + b MPU_xTimerIsTimerActiveImpl + + PUBWEAK MPU_xTimerGetTimerDaemonTaskHandleImpl +MPU_xTimerGetTimerDaemonTaskHandleImpl: + b MPU_xTimerGetTimerDaemonTaskHandleImpl + + PUBWEAK MPU_xTimerGenericCommandImpl +MPU_xTimerGenericCommandImpl: + b MPU_xTimerGenericCommandImpl + + PUBWEAK MPU_pcTimerGetNameImpl +MPU_pcTimerGetNameImpl: + b MPU_pcTimerGetNameImpl + + PUBWEAK MPU_vTimerSetReloadModeImpl +MPU_vTimerSetReloadModeImpl: + b MPU_vTimerSetReloadModeImpl + + PUBWEAK MPU_xTimerGetReloadModeImpl +MPU_xTimerGetReloadModeImpl: + b MPU_xTimerGetReloadModeImpl + + PUBWEAK MPU_uxTimerGetReloadModeImpl +MPU_uxTimerGetReloadModeImpl: + b MPU_uxTimerGetReloadModeImpl + + PUBWEAK MPU_xTimerGetPeriodImpl +MPU_xTimerGetPeriodImpl: + b MPU_xTimerGetPeriodImpl + + PUBWEAK MPU_xTimerGetExpiryTimeImpl +MPU_xTimerGetExpiryTimeImpl: + b MPU_xTimerGetExpiryTimeImpl + + PUBWEAK MPU_xEventGroupWaitBitsImpl +MPU_xEventGroupWaitBitsImpl: + b MPU_xEventGroupWaitBitsImpl + + PUBWEAK MPU_xEventGroupClearBitsImpl +MPU_xEventGroupClearBitsImpl: + b MPU_xEventGroupClearBitsImpl + + PUBWEAK MPU_xEventGroupSetBitsImpl +MPU_xEventGroupSetBitsImpl: + b MPU_xEventGroupSetBitsImpl + + PUBWEAK MPU_xEventGroupSyncImpl +MPU_xEventGroupSyncImpl: + b MPU_xEventGroupSyncImpl + + PUBWEAK MPU_uxEventGroupGetNumberImpl +MPU_uxEventGroupGetNumberImpl: + b MPU_uxEventGroupGetNumberImpl + + PUBWEAK MPU_vEventGroupSetNumberImpl +MPU_vEventGroupSetNumberImpl: + b MPU_vEventGroupSetNumberImpl + + PUBWEAK MPU_xStreamBufferSendImpl +MPU_xStreamBufferSendImpl: + b MPU_xStreamBufferSendImpl + + PUBWEAK MPU_xStreamBufferReceiveImpl +MPU_xStreamBufferReceiveImpl: + b MPU_xStreamBufferReceiveImpl + + PUBWEAK MPU_xStreamBufferIsFullImpl +MPU_xStreamBufferIsFullImpl: + b MPU_xStreamBufferIsFullImpl + + PUBWEAK MPU_xStreamBufferIsEmptyImpl +MPU_xStreamBufferIsEmptyImpl: + b MPU_xStreamBufferIsEmptyImpl + + PUBWEAK MPU_xStreamBufferSpacesAvailableImpl +MPU_xStreamBufferSpacesAvailableImpl: + b MPU_xStreamBufferSpacesAvailableImpl + + PUBWEAK MPU_xStreamBufferBytesAvailableImpl +MPU_xStreamBufferBytesAvailableImpl: + b MPU_xStreamBufferBytesAvailableImpl + + PUBWEAK MPU_xStreamBufferSetTriggerLevelImpl +MPU_xStreamBufferSetTriggerLevelImpl: + b MPU_xStreamBufferSetTriggerLevelImpl + + PUBWEAK MPU_xStreamBufferNextMessageLengthBytesImpl +MPU_xStreamBufferNextMessageLengthBytesImpl: + b MPU_xStreamBufferNextMessageLengthBytesImpl + +/*-----------------------------------------------------------*/ + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + + END diff --git a/portable/IAR/ARM_CM23/non_secure/port.c b/portable/IAR/ARM_CM23/non_secure/port.c index 7bbe1b7bc53..cab1b3668bf 100644 --- a/portable/IAR/ARM_CM23/non_secure/port.c +++ b/portable/IAR/ARM_CM23/non_secure/port.c @@ -107,6 +107,13 @@ #define portPRIGROUP_SHIFT ( 8UL ) /*-----------------------------------------------------------*/ +/** + * @brief Constants used during system call enter and exit. + */ +#define portPSR_STACK_PADDING_MASK ( 1UL << 9UL ) +#define portEXC_RETURN_STACK_FRAME_TYPE_MASK ( 1UL << 4UL ) +/*-----------------------------------------------------------*/ + /** * @brief Constants required to manipulate the FPU. */ @@ -123,6 +130,14 @@ #define portFPCCR_LSPEN_MASK ( 1UL << portFPCCR_LSPEN_POS ) /*-----------------------------------------------------------*/ +/** + * @brief Offsets in the stack to the parameters when inside the SVC handler. + */ +#define portOFFSET_TO_LR ( 5 ) +#define portOFFSET_TO_PC ( 6 ) +#define portOFFSET_TO_PSR ( 7 ) +/*-----------------------------------------------------------*/ + /** * @brief Constants required to manipulate the MPU. */ @@ -148,6 +163,8 @@ #define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ #define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ +#define portMPU_RBAR_ACCESS_PERMISSIONS_MASK ( 3UL << 1UL ) + #define portMPU_MAIR_ATTR0_POS ( 0UL ) #define portMPU_MAIR_ATTR0_MASK ( 0x000000ff ) @@ -191,6 +208,30 @@ /* Expected value of the portMPU_TYPE register. */ #define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) + +/* Extract first address of the MPU region as encoded in the + * RBAR (Region Base Address Register) value. */ +#define portEXTRACT_FIRST_ADDRESS_FROM_RBAR( rbar ) \ + ( ( rbar ) & portMPU_RBAR_ADDRESS_MASK ) + +/* Extract last address of the MPU region as encoded in the + * RLAR (Region Limit Address Register) value. */ +#define portEXTRACT_LAST_ADDRESS_FROM_RLAR( rlar ) \ + ( ( ( rlar ) & portMPU_RLAR_ADDRESS_MASK ) | ~portMPU_RLAR_ADDRESS_MASK ) + +/* Does addr lies within [start, end] address range? */ +#define portIS_ADDRESS_WITHIN_RANGE( addr, start, end ) \ + ( ( ( addr ) >= ( start ) ) && ( ( addr ) <= ( end ) ) ) + +/* Is the access request satisfied by the available permissions? */ +#define portIS_AUTHORIZED( accessRequest, permissions ) \ + ( ( ( permissions ) & ( accessRequest ) ) == accessRequest ) + +/* 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 ) ) ) /*-----------------------------------------------------------*/ /** @@ -311,6 +352,19 @@ static void prvTaskExitError( void ); #if ( configENABLE_MPU == 1 ) +/** + * @brief Extract MPU region's access permissions from the Region Base Address + * Register (RBAR) value. + * + * @param ulRBARValue RBAR value for the MPU region. + * + * @return uint32_t Access permissions. + */ + static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) PRIVILEGED_FUNCTION; +#endif /* configENABLE_MPU */ + +#if ( configENABLE_MPU == 1 ) + /** * @brief Setup the Memory Protection Unit (MPU). */ @@ -365,6 +419,60 @@ void SysTick_Handler( void ) PRIVILEGED_FUNCTION; * @brief C part of SVC handler. */ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIVILEGED_FUNCTION; + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + + /** + * @brief Sets up the system call stack so that upon returning from + * SVC, the system call stack is used. + * + * It is used for the system calls with up to 4 parameters. + * + * @param pulTaskStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + */ + void vSystemCallEnter( uint32_t * pulTaskStack, uint32_t ulLR ) PRIVILEGED_FUNCTION; + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + + /** + * @brief Sets up the system call stack so that upon returning from + * SVC, the system call stack is used. + * + * It is used for the system calls with 5 parameters. + * + * @param pulTaskStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + */ + void vSystemCallEnter_1( uint32_t * pulTaskStack, uint32_t ulLR ) PRIVILEGED_FUNCTION; + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + + /** + * @brief Sets up the task stack so that upon returning from + * SVC, the task stack is used again. + * + * @param pulSystemCallStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + */ + void vSystemCallExit( uint32_t * pulSystemCallStack, uint32_t ulLR ) PRIVILEGED_FUNCTION; + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + +#if ( configENABLE_MPU == 1 ) + + /** + * @brief Checks whether or not the calling task is privileged. + * + * @return pdTRUE if the calling task is privileged, pdFALSE otherwise. + */ + BaseType_t xPortIsTaskPrivileged( void ) PRIVILEGED_FUNCTION; + +#endif /* configENABLE_MPU == 1 */ /*-----------------------------------------------------------*/ /** @@ -681,6 +789,26 @@ static void prvTaskExitError( void ) } /*-----------------------------------------------------------*/ +#if ( configENABLE_MPU == 1 ) + static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) /* PRIVILEGED_FUNCTION */ + { + uint32_t ulAccessPermissions = 0; + + if( ( ulRBARValue & portMPU_RBAR_ACCESS_PERMISSIONS_MASK ) == portMPU_REGION_READ_ONLY ) + { + ulAccessPermissions = tskMPU_READ_PERMISSION; + } + + if( ( ulRBARValue & portMPU_RBAR_ACCESS_PERMISSIONS_MASK ) == portMPU_REGION_READ_WRITE ) + { + ulAccessPermissions = ( tskMPU_READ_PERMISSION | tskMPU_WRITE_PERMISSION ); + } + + return ulAccessPermissions; + } +#endif /* configENABLE_MPU */ +/*-----------------------------------------------------------*/ + #if ( configENABLE_MPU == 1 ) static void prvSetupMPU( void ) /* PRIVILEGED_FUNCTION */ { @@ -853,7 +981,7 @@ void SysTick_Handler( void ) /* PRIVILEGED_FUNCTION */ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTION portDONT_DISCARD */ { - #if ( configENABLE_MPU == 1 ) + #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) ) #if defined( __ARMCC_VERSION ) /* Declaration when these variable are defined in code instead of being @@ -865,7 +993,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO extern uint32_t __syscalls_flash_start__[]; extern uint32_t __syscalls_flash_end__[]; #endif /* defined( __ARMCC_VERSION ) */ - #endif /* configENABLE_MPU */ + #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */ uint32_t ulPC; @@ -880,7 +1008,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO /* Register are stored on the stack in the following order - R0, R1, R2, R3, * R12, LR, PC, xPSR. */ - ulPC = pulCallerStackAddress[ 6 ]; + ulPC = pulCallerStackAddress[ portOFFSET_TO_PC ]; ucSVCNumber = ( ( uint8_t * ) ulPC )[ -2 ]; switch( ucSVCNumber ) @@ -951,18 +1079,18 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO vRestoreContextOfFirstTask(); break; - #if ( configENABLE_MPU == 1 ) - case portSVC_RAISE_PRIVILEGE: + #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) ) + case portSVC_RAISE_PRIVILEGE: - /* Only raise the privilege, if the svc was raised from any of - * the system calls. */ - if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) && - ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ) - { - vRaisePrivilege(); - } - break; - #endif /* configENABLE_MPU */ + /* Only raise the privilege, if the svc was raised from any of + * the system calls. */ + if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ) + { + vRaisePrivilege(); + } + break; + #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */ default: /* Incorrect SVC call. */ @@ -971,51 +1099,455 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } /*-----------------------------------------------------------*/ -/* *INDENT-OFF* */ -#if ( configENABLE_MPU == 1 ) - StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, - StackType_t * pxEndOfStack, - TaskFunction_t pxCode, - void * pvParameters, - BaseType_t xRunPrivileged ) /* PRIVILEGED_FUNCTION */ -#else - StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, - StackType_t * pxEndOfStack, - TaskFunction_t pxCode, - void * pvParameters ) /* PRIVILEGED_FUNCTION */ -#endif /* configENABLE_MPU */ -/* *INDENT-ON* */ +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + +void vSystemCallEnter( uint32_t * pulTaskStack, uint32_t ulLR ) /* PRIVILEGED_FUNCTION */ { - /* Simulate the stack frame as it would be created by a context switch - * interrupt. */ - #if ( portPRELOAD_REGISTERS == 0 ) + extern TaskHandle_t pxCurrentTCB; + xMPU_SETTINGS * pxMpuSettings; + uint32_t * pulSystemCallStack; + uint32_t ulStackFrameSize, ulSystemCallLocation, i; + #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being + * exported from linker scripts. */ + extern uint32_t * __syscalls_flash_start__; + extern uint32_t * __syscalls_flash_end__; + #else + /* Declaration when these variable are exported from linker scripts. */ + extern uint32_t __syscalls_flash_start__[]; + extern uint32_t __syscalls_flash_end__[]; + #endif /* #if defined( __ARMCC_VERSION ) */ + + ulSystemCallLocation = pulTaskStack[ portOFFSET_TO_PC ]; + + /* If the request did not come from the system call section, do nothing. */ + if( ( ulSystemCallLocation >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulSystemCallLocation <= ( uint32_t ) __syscalls_flash_end__ ) ) { - pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ - *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ - pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pxCode; /* PC */ - pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR */ - pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ - *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ - pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */ - *pxTopOfStack = portINITIAL_EXC_RETURN; + pxMpuSettings = xTaskGetMPUSettings( pxCurrentTCB ); + pulSystemCallStack = pxMpuSettings->xSystemCallStackInfo.pulSystemCallStack; - #if ( configENABLE_MPU == 1 ) + /* This is not NULL only for the duration of the system call. */ + configASSERT( pxMpuSettings->xSystemCallStackInfo.pulTaskStack == NULL ); + + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) { - pxTopOfStack--; + if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) + { + /* Extended frame i.e. FPU in use. */ + ulStackFrameSize = 26; + __asm volatile ( + " vpush {s0} \n" /* Trigger lazy stacking. */ + " vpop {s0} \n" /* Nullify the affect of the above instruction. */ + ::: "memory" + ); + } + else + { + /* Standard frame i.e. FPU not in use. */ + ulStackFrameSize = 8; + } + } + #else + { + ulStackFrameSize = 8; + } + #endif /* configENABLE_FPU || configENABLE_MVE */ + + /* Make space on the system call stack for the stack frame. */ + pulSystemCallStack = pulSystemCallStack - ulStackFrameSize; + + /* Copy the stack frame. */ + for( i = 0; i < ulStackFrameSize; i++ ) + { + pulSystemCallStack[ i ] = pulTaskStack[ i ]; + } + + /* Store the value of the LR and PSPLIM registers before the SVC was raised. We need to + * restore it when we exit from the system call. */ + pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; + __asm volatile ( "mrs %0, psplim" : "=r" ( pxMpuSettings->xSystemCallStackInfo.ulStackLimitRegisterAtSystemCallEntry ) ); + + /* Use the pulSystemCallStack in thread mode. */ + __asm volatile ( "msr psp, %0" : : "r" ( pulSystemCallStack ) ); + __asm volatile ( "msr psplim, %0" : : "r" ( pxMpuSettings->xSystemCallStackInfo.pulSystemCallStackLimit ) ); + + /* Remember the location where we should copy the stack frame when we exit from + * the system call. */ + pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulStackFrameSize; + + /* Record if the hardware used padding to force the stack pointer + * to be double word aligned. */ + if( ( pulTaskStack[ portOFFSET_TO_PSR ] & portPSR_STACK_PADDING_MASK ) == portPSR_STACK_PADDING_MASK ) + { + pxMpuSettings->ulTaskFlags |= portSTACK_FRAME_HAS_PADDING_FLAG; + } + else + { + pxMpuSettings->ulTaskFlags &= ( ~portSTACK_FRAME_HAS_PADDING_FLAG ); + } + + /* We ensure in pxPortInitialiseStack that the system call stack is + * double word aligned and therefore, there is no need of padding. + * Clear the bit[9] of stacked xPSR. */ + pulSystemCallStack[ portOFFSET_TO_PSR ] &= ( ~portPSR_STACK_PADDING_MASK ); + + /* Raise the privilege for the duration of the system call. */ + __asm volatile ( + " mrs r0, control \n" /* Obtain current control value. */ + " movs r1, #1 \n" /* r1 = 1. */ + " bics r0, r1 \n" /* Clear nPRIV bit. */ + " msr control, r0 \n" /* Write back new control value. */ + ::: "r0", "r1", "memory" + ); + } +} - if( xRunPrivileged == pdTRUE ) +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + +void vSystemCallEnter_1( uint32_t * pulTaskStack, uint32_t ulLR ) /* PRIVILEGED_FUNCTION */ +{ + extern TaskHandle_t pxCurrentTCB; + xMPU_SETTINGS * pxMpuSettings; + uint32_t * pulSystemCallStack; + uint32_t ulStackFrameSize, ulSystemCallLocation, i; + #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being + * exported from linker scripts. */ + extern uint32_t * __syscalls_flash_start__; + extern uint32_t * __syscalls_flash_end__; + #else + /* Declaration when these variable are exported from linker scripts. */ + extern uint32_t __syscalls_flash_start__[]; + extern uint32_t __syscalls_flash_end__[]; + #endif /* #if defined( __ARMCC_VERSION ) */ + + ulSystemCallLocation = pulTaskStack[ portOFFSET_TO_PC ]; + + /* If the request did not come from the system call section, do nothing. */ + if( ( ulSystemCallLocation >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulSystemCallLocation <= ( uint32_t ) __syscalls_flash_end__ ) ) + { + pxMpuSettings = xTaskGetMPUSettings( pxCurrentTCB ); + pulSystemCallStack = pxMpuSettings->xSystemCallStackInfo.pulSystemCallStack; + + /* This is not NULL only for the duration of the system call. */ + configASSERT( pxMpuSettings->xSystemCallStackInfo.pulTaskStack == NULL ); + + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + { + if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) { - *pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */ + /* Extended frame i.e. FPU in use. */ + ulStackFrameSize = 26; + __asm volatile ( + " vpush {s0} \n" /* Trigger lazy stacking. */ + " vpop {s0} \n" /* Nullify the affect of the above instruction. */ + ::: "memory" + ); } else { - *pxTopOfStack = portINITIAL_CONTROL_UNPRIVILEGED; /* Slot used to hold this task's CONTROL value. */ + /* Standard frame i.e. FPU not in use. */ + ulStackFrameSize = 8; } } - #endif /* configENABLE_MPU */ + #else + { + ulStackFrameSize = 8; + } + #endif /* configENABLE_FPU || configENABLE_MVE */ + + /* Make space on the system call stack for the stack frame and + * the parameter passed on the stack. We only need to copy one + * parameter but we still reserve 2 spaces to keep the stack + * double word aligned. */ + pulSystemCallStack = pulSystemCallStack - ulStackFrameSize - 2UL; + + /* Copy the stack frame. */ + for( i = 0; i < ulStackFrameSize; i++ ) + { + pulSystemCallStack[ i ] = pulTaskStack[ i ]; + } + + /* Copy the parameter which is passed the stack. */ + if( ( pulTaskStack[ portOFFSET_TO_PSR ] & portPSR_STACK_PADDING_MASK ) == portPSR_STACK_PADDING_MASK ) + { + pulSystemCallStack[ ulStackFrameSize ] = pulTaskStack[ ulStackFrameSize + 1 ]; + /* Record if the hardware used padding to force the stack pointer + * to be double word aligned. */ + pxMpuSettings->ulTaskFlags |= portSTACK_FRAME_HAS_PADDING_FLAG; + } + else + { + pulSystemCallStack[ ulStackFrameSize ] = pulTaskStack[ ulStackFrameSize ]; + /* Record if the hardware used padding to force the stack pointer + * to be double word aligned. */ + pxMpuSettings->ulTaskFlags &= ( ~portSTACK_FRAME_HAS_PADDING_FLAG ); + } + + /* Store the value of the LR and PSPLIM registers before the SVC was raised. + * We need to restore it when we exit from the system call. */ + pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; + __asm volatile ( "mrs %0, psplim" : "=r" ( pxMpuSettings->xSystemCallStackInfo.ulStackLimitRegisterAtSystemCallEntry ) ); + + /* Use the pulSystemCallStack in thread mode. */ + __asm volatile ( "msr psp, %0" : : "r" ( pulSystemCallStack ) ); + __asm volatile ( "msr psplim, %0" : : "r" ( pxMpuSettings->xSystemCallStackInfo.pulSystemCallStackLimit ) ); + + /* Remember the location where we should copy the stack frame when we exit from + * the system call. */ + pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulStackFrameSize; + + /* We ensure in pxPortInitialiseStack that the system call stack is + * double word aligned and therefore, there is no need of padding. + * Clear the bit[9] of stacked xPSR. */ + pulSystemCallStack[ portOFFSET_TO_PSR ] &= ( ~portPSR_STACK_PADDING_MASK ); + + /* Raise the privilege for the duration of the system call. */ + __asm volatile ( + " mrs r0, control \n" /* Obtain current control value. */ + " movs r1, #1 \n" /* r1 = 1. */ + " bics r0, r1 \n" /* Clear nPRIV bit. */ + " msr control, r0 \n" /* Write back new control value. */ + ::: "r0", "r1", "memory" + ); + } +} + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) +void vSystemCallExit( uint32_t * pulSystemCallStack, uint32_t ulLR ) /* PRIVILEGED_FUNCTION */ +{ + extern TaskHandle_t pxCurrentTCB; + xMPU_SETTINGS * pxMpuSettings; + uint32_t * pulTaskStack; + uint32_t ulStackFrameSize, ulSystemCallLocation, i; + #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being + * exported from linker scripts. */ + extern uint32_t * __syscalls_flash_start__; + extern uint32_t * __syscalls_flash_end__; + #else + /* Declaration when these variable are exported from linker scripts. */ + extern uint32_t __syscalls_flash_start__[]; + extern uint32_t __syscalls_flash_end__[]; + #endif /* #if defined( __ARMCC_VERSION ) */ + + ulSystemCallLocation = pulSystemCallStack[ portOFFSET_TO_PC ]; + + /* If the request did not come from the system call section, do nothing. */ + if( ( ulSystemCallLocation >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulSystemCallLocation <= ( uint32_t ) __syscalls_flash_end__ ) ) + { + pxMpuSettings = xTaskGetMPUSettings( pxCurrentTCB ); + pulTaskStack = pxMpuSettings->xSystemCallStackInfo.pulTaskStack; + + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + { + if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) + { + /* Extended frame i.e. FPU in use. */ + ulStackFrameSize = 26; + __asm volatile ( + " vpush {s0} \n" /* Trigger lazy stacking. */ + " vpop {s0} \n" /* Nullify the affect of the above instruction. */ + ::: "memory" + ); + } + else + { + /* Standard frame i.e. FPU not in use. */ + ulStackFrameSize = 8; + } + } + #else + { + ulStackFrameSize = 8; + } + #endif /* configENABLE_FPU || configENABLE_MVE */ + + /* Make space on the task stack for the stack frame. */ + pulTaskStack = pulTaskStack - ulStackFrameSize; + + /* Copy the stack frame. */ + for( i = 0; i < ulStackFrameSize; i++ ) + { + pulTaskStack[ i ] = pulSystemCallStack[ i ]; + } + + /* Use the pulTaskStack in thread mode. */ + __asm volatile ( "msr psp, %0" : : "r" ( pulTaskStack ) ); + + /* Restore the LR and PSPLIM to what they were at the time of + * system call entry. */ + pulTaskStack[ portOFFSET_TO_LR ] = pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry; + __asm volatile ( "msr psplim, %0" : : "r" ( pxMpuSettings->xSystemCallStackInfo.ulStackLimitRegisterAtSystemCallEntry ) ); + + /* If the hardware used padding to force the stack pointer + * to be double word aligned, set the stacked xPSR bit[9], + * otherwise clear it. */ + if( ( pxMpuSettings->ulTaskFlags & portSTACK_FRAME_HAS_PADDING_FLAG ) == portSTACK_FRAME_HAS_PADDING_FLAG ) + { + pulTaskStack[ portOFFSET_TO_PSR ] |= portPSR_STACK_PADDING_MASK; + } + else + { + pulTaskStack[ portOFFSET_TO_PSR ] &= ( ~portPSR_STACK_PADDING_MASK ); + } + + /* This is not NULL only for the duration of the system call. */ + pxMpuSettings->xSystemCallStackInfo.pulTaskStack = NULL; + + /* Drop the privilege before returning to the thread mode. */ + __asm volatile ( + " mrs r0, control \n" /* Obtain current control value. */ + " movs r1, #1 \n" /* r1 = 1. */ + " orrs r0, r1 \n" /* Set nPRIV bit. */ + " msr control, r0 \n" /* Write back new control value. */ + ::: "r0", "r1", "memory" + ); + } +} + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configENABLE_MPU == 1 ) + +BaseType_t xPortIsTaskPrivileged( void ) /* PRIVILEGED_FUNCTION */ +{ + BaseType_t xTaskIsPrivileged = pdFALSE; + const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */ + + if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) + { + xTaskIsPrivileged = pdTRUE; + } + + return xTaskIsPrivileged; +} + +#endif /* configENABLE_MPU == 1 */ +/*-----------------------------------------------------------*/ + +#if( configENABLE_MPU == 1 ) + +StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, + StackType_t * pxEndOfStack, + TaskFunction_t pxCode, + void * pvParameters, + BaseType_t xRunPrivileged, + xMPU_SETTINGS * xMPUSettings ) /* PRIVILEGED_FUNCTION */ +{ + uint32_t ulIndex = 0; + + xMPUSettings->ulContext[ ulIndex ] = 0x04040404; /* r4. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x05050505; /* r5. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x06060606; /* r6. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x07070707; /* r7. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x08080808; /* r8. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x09090909; /* r9. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x10101010; /* r10. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x11111111; /* r11. */ + ulIndex++; + + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pvParameters; /* r0. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x01010101; /* r1. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x02020202; /* r2. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x03030303; /* r3. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x12121212; /* r12. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portTASK_RETURN_ADDRESS; /* LR. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxCode; /* PC. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = portINITIAL_XPSR; /* xPSR. */ + ulIndex++; + + #if ( configENABLE_TRUSTZONE == 1 ) + { + xMPUSettings->ulContext[ ulIndex ] = portNO_SECURE_CONTEXT; /* xSecureContext. */ + ulIndex++; + } + #endif /* configENABLE_TRUSTZONE */ + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) ( pxTopOfStack - 8 ); /* PSP with the hardware saved stack. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */ + ulIndex++; + if( xRunPrivileged == pdTRUE ) + { + xMPUSettings->ulTaskFlags |= portTASK_IS_PRIVILEGED_FLAG; + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_PRIVILEGED; /* CONTROL. */ + ulIndex++; + } + else + { + xMPUSettings->ulTaskFlags &= ( ~portTASK_IS_PRIVILEGED_FLAG ); + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_UNPRIVILEGED; /* CONTROL. */ + ulIndex++; + } + xMPUSettings->ulContext[ ulIndex ] = portINITIAL_EXC_RETURN; /* LR (EXC_RETURN). */ + ulIndex++; + + #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + { + /* Ensure that the system call stack is double word aligned. */ + xMPUSettings->xSystemCallStackInfo.pulSystemCallStack = &( xMPUSettings->xSystemCallStackInfo.ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE - 1 ] ); + xMPUSettings->xSystemCallStackInfo.pulSystemCallStack = ( uint32_t * ) ( ( uint32_t ) ( xMPUSettings->xSystemCallStackInfo.pulSystemCallStack ) & + ( uint32_t ) ( ~( portBYTE_ALIGNMENT_MASK ) ) ); + + xMPUSettings->xSystemCallStackInfo.pulSystemCallStackLimit = &( xMPUSettings->xSystemCallStackInfo.ulSystemCallStackBuffer[ 0 ] ); + xMPUSettings->xSystemCallStackInfo.pulSystemCallStackLimit = ( uint32_t * ) ( ( ( uint32_t ) ( xMPUSettings->xSystemCallStackInfo.pulSystemCallStackLimit ) + + ( uint32_t ) ( portBYTE_ALIGNMENT - 1 ) ) & + ( uint32_t ) ( ~( portBYTE_ALIGNMENT_MASK ) ) ); + + /* This is not NULL only for the duration of a system call. */ + xMPUSettings->xSystemCallStackInfo.pulTaskStack = NULL; + } + #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + + return &( xMPUSettings->ulContext[ ulIndex ] ); +} + +#else /* configENABLE_MPU */ + +StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, + StackType_t * pxEndOfStack, + TaskFunction_t pxCode, + void * pvParameters ) /* PRIVILEGED_FUNCTION */ +{ + /* Simulate the stack frame as it would be created by a context switch + * interrupt. */ + #if ( portPRELOAD_REGISTERS == 0 ) + { + pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ + *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR. */ + pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ + pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */ + *pxTopOfStack = portINITIAL_EXC_RETURN; pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ @@ -1029,55 +1561,39 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO #else /* portPRELOAD_REGISTERS */ { pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ - *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ + *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pxCode; /* PC */ + *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR */ + *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x12121212UL; /* R12 */ + *pxTopOfStack = ( StackType_t ) 0x12121212UL; /* R12. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x03030303UL; /* R3 */ + *pxTopOfStack = ( StackType_t ) 0x03030303UL; /* R3. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x02020202UL; /* R2 */ + *pxTopOfStack = ( StackType_t ) 0x02020202UL; /* R2. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x01010101UL; /* R1 */ + *pxTopOfStack = ( StackType_t ) 0x01010101UL; /* R1. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x11111111UL; /* R11 */ + *pxTopOfStack = ( StackType_t ) 0x11111111UL; /* R11. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x10101010UL; /* R10 */ + *pxTopOfStack = ( StackType_t ) 0x10101010UL; /* R10. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x09090909UL; /* R09 */ + *pxTopOfStack = ( StackType_t ) 0x09090909UL; /* R09. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x08080808UL; /* R08 */ + *pxTopOfStack = ( StackType_t ) 0x08080808UL; /* R08. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x07070707UL; /* R07 */ + *pxTopOfStack = ( StackType_t ) 0x07070707UL; /* R07. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x06060606UL; /* R06 */ + *pxTopOfStack = ( StackType_t ) 0x06060606UL; /* R06. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x05050505UL; /* R05 */ + *pxTopOfStack = ( StackType_t ) 0x05050505UL; /* R05. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x04040404UL; /* R04 */ + *pxTopOfStack = ( StackType_t ) 0x04040404UL; /* R04. */ pxTopOfStack--; - *pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN */ - - #if ( configENABLE_MPU == 1 ) - { - pxTopOfStack--; - - if( xRunPrivileged == pdTRUE ) - { - *pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */ - } - else - { - *pxTopOfStack = portINITIAL_CONTROL_UNPRIVILEGED; /* Slot used to hold this task's CONTROL value. */ - } - } - #endif /* configENABLE_MPU */ - + *pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN. */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ @@ -1092,6 +1608,8 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO return pxTopOfStack; } + +#endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ @@ -1128,6 +1646,10 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ configASSERT( ucMaxSysCallPriority ); + /* Check that the bits not implemented in hardware are zero in + * configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & ( ~ucMaxPriorityValue ) ) == 0U ); + /* Calculate the maximum acceptable priority group value for the number * of bits read back. */ @@ -1164,35 +1686,6 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulImplementedPrioBits; } - /* The interrupt priority bits are not modelled in QEMU and the assert that - * checks the number of implemented bits and __NVIC_PRIO_BITS will always fail. - * Therefore, this assert is not adding any value for QEMU targets. The config - * option `configDISABLE_INTERRUPT_PRIO_BITS_CHECK` should be defined in the - * `FreeRTOSConfig.h` for QEMU targets. */ - #ifndef configDISABLE_INTERRUPT_PRIO_BITS_CHECK - { - #ifdef __NVIC_PRIO_BITS - { - /* - * Check that the number of implemented priority bits queried from - * hardware is equal to the CMSIS __NVIC_PRIO_BITS configuration macro. - */ - configASSERT( ulImplementedPrioBits == __NVIC_PRIO_BITS ); - } - #endif /* __NVIC_PRIO_BITS */ - - #ifdef configPRIO_BITS - { - /* - * Check that the number of implemented priority bits queried from - * hardware is equal to the FreeRTOS configPRIO_BITS configuration macro. - */ - configASSERT( ulImplementedPrioBits == configPRIO_BITS ); - } - #endif /* configPRIO_BITS */ - } - #endif /* #ifndef configDISABLE_INTERRUPT_PRIO_BITS_CHECK */ - /* Shift the priority group value back to its position within the AIRCR * register. */ ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT; @@ -1372,6 +1865,54 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ +#if ( configENABLE_MPU == 1 ) + BaseType_t xPortIsAuthorizedToAccessBuffer( const void * pvBuffer, + uint32_t ulBufferLength, + uint32_t ulAccessRequested ) /* PRIVILEGED_FUNCTION */ + + { + uint32_t i, ulBufferStartAddress, ulBufferEndAddress; + BaseType_t xAccessGranted = pdFALSE; + const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */ + + if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) + { + xAccessGranted = pdTRUE; + } + else + { + if( portADD_UINT32_WILL_OVERFLOW( ( ( uint32_t ) pvBuffer ), ( ulBufferLength - 1UL ) ) == pdFALSE ) + { + ulBufferStartAddress = ( uint32_t ) pvBuffer; + ulBufferEndAddress = ( ( ( uint32_t ) pvBuffer ) + ulBufferLength - 1UL ); + + for( i = 0; i < portTOTAL_NUM_REGIONS; i++ ) + { + /* Is the MPU region enabled? */ + if( ( xTaskMpuSettings->xRegionsSettings[ i ].ulRLAR & portMPU_RLAR_REGION_ENABLE ) == portMPU_RLAR_REGION_ENABLE ) + { + if( portIS_ADDRESS_WITHIN_RANGE( ulBufferStartAddress, + portEXTRACT_FIRST_ADDRESS_FROM_RBAR( xTaskMpuSettings->xRegionsSettings[ i ].ulRBAR ), + portEXTRACT_LAST_ADDRESS_FROM_RLAR( xTaskMpuSettings->xRegionsSettings[ i ].ulRLAR ) ) && + portIS_ADDRESS_WITHIN_RANGE( ulBufferEndAddress, + portEXTRACT_FIRST_ADDRESS_FROM_RBAR( xTaskMpuSettings->xRegionsSettings[ i ].ulRBAR ), + portEXTRACT_LAST_ADDRESS_FROM_RLAR( xTaskMpuSettings->xRegionsSettings[ i ].ulRLAR ) ) && + portIS_AUTHORIZED( ulAccessRequested, + prvGetRegionAccessPermissions( xTaskMpuSettings->xRegionsSettings[ i ].ulRBAR ) ) ) + { + xAccessGranted = pdTRUE; + break; + } + } + } + } + } + + return xAccessGranted; + } +#endif /* configENABLE_MPU */ +/*-----------------------------------------------------------*/ + BaseType_t xPortIsInsideInterrupt( void ) { uint32_t ulCurrentInterrupt; diff --git a/portable/IAR/ARM_CM23/non_secure/portasm.s b/portable/IAR/ARM_CM23/non_secure/portasm.s index fffed8df619..648ae005010 100644 --- a/portable/IAR/ARM_CM23/non_secure/portasm.s +++ b/portable/IAR/ARM_CM23/non_secure/portasm.s @@ -33,12 +33,21 @@ the code is included in C files but excluded by the preprocessor in assembly files (__ICCARM__ is defined by the IAR C compiler but not by the IAR assembler. */ #include "FreeRTOSConfig.h" +#ifndef configUSE_MPU_WRAPPERS_V1 + #define configUSE_MPU_WRAPPERS_V1 0 +#endif + EXTERN pxCurrentTCB EXTERN xSecureContext EXTERN vTaskSwitchContext EXTERN vPortSVCHandler_C EXTERN SecureContext_SaveContext EXTERN SecureContext_LoadContext +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + EXTERN vSystemCallEnter + EXTERN vSystemCallEnter_1 + EXTERN vSystemCallExit +#endif PUBLIC xIsPrivileged PUBLIC vResetPrivilege @@ -98,65 +107,99 @@ vPortAllocateSecureContext: THUMB /*-----------------------------------------------------------*/ +#if ( configENABLE_MPU == 1 ) + +vRestoreContextOfFirstTask: + program_mpu_first_task: + ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + ldr r0, [r3] /* r0 = pxCurrentTCB.*/ + + dmb /* Complete outstanding transfers before disabling MPU. */ + ldr r1, =0xe000ed94 /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + ldr r2, [r1] /* Read the value of MPU_CTRL. */ + movs r3, #1 /* r3 = 1. */ + bics r2, r3 /* r2 = r2 & ~r3 i.e. Clear the bit 0 in r2. */ + str r2, [r1] /* Disable MPU. */ + + adds r0, #4 /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */ + ldr r1, [r0] /* r1 = *r0 i.e. r1 = MAIR0. */ + ldr r2, =0xe000edc0 /* r2 = 0xe000edc0 [Location of MAIR0]. */ + str r1, [r2] /* Program MAIR0. */ + + adds r0, #4 /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */ + ldr r1, =0xe000ed98 /* r1 = 0xe000ed98 [Location of RNR]. */ + + movs r3, #4 /* r3 = 4. */ + str r3, [r1] /* Program RNR = 4. */ + ldmia r0!, {r4-r5} /* Read first set of RBAR/RLAR registers from TCB. */ + ldr r2, =0xe000ed9c /* r2 = 0xe000ed9c [Location of RBAR]. */ + stmia r2!, {r4-r5} /* Write first set of RBAR/RLAR registers. */ + movs r3, #5 /* r3 = 5. */ + str r3, [r1] /* Program RNR = 5. */ + ldmia r0!, {r4-r5} /* Read second set of RBAR/RLAR registers from TCB. */ + ldr r2, =0xe000ed9c /* r2 = 0xe000ed9c [Location of RBAR]. */ + stmia r2!, {r4-r5} /* Write second set of RBAR/RLAR registers. */ + movs r3, #6 /* r3 = 6. */ + str r3, [r1] /* Program RNR = 6. */ + ldmia r0!, {r4-r5} /* Read third set of RBAR/RLAR registers from TCB. */ + ldr r2, =0xe000ed9c /* r2 = 0xe000ed9c [Location of RBAR]. */ + stmia r2!, {r4-r5} /* Write third set of RBAR/RLAR registers. */ + movs r3, #7 /* r3 = 6. */ + str r3, [r1] /* Program RNR = 7. */ + ldmia r0!, {r4-r5} /* Read fourth set of RBAR/RLAR registers from TCB. */ + ldr r2, =0xe000ed9c /* r2 = 0xe000ed9c [Location of RBAR]. */ + stmia r2!, {r4-r5} /* Write fourth set of RBAR/RLAR registers. */ + + ldr r1, =0xe000ed94 /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + ldr r2, [r1] /* Read the value of MPU_CTRL. */ + movs r3, #1 /* r3 = 1. */ + orrs r2, r3 /* r2 = r2 | r3 i.e. Set the bit 0 in r2. */ + str r2, [r1] /* Enable MPU. */ + dsb /* Force memory writes before continuing. */ + + restore_context_first_task: + ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + ldr r1, [r3] /* r1 = pxCurrentTCB.*/ + ldr r2, [r1] /* r2 = Location of saved context in TCB. */ + + restore_special_regs_first_task: + subs r2, #20 + ldmia r2!, {r0, r3-r6} /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, r6 = LR. */ + subs r2, #20 + msr psp, r3 + msr psplim, r4 + msr control, r5 + mov lr, r6 + ldr r4, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */ + str r0, [r4] /* Restore xSecureContext. */ + + restore_general_regs_first_task: + subs r2, #32 + ldmia r2!, {r4-r7} /* r4-r7 contain half of the hardware saved context. */ + stmia r3!, {r4-r7} /* Copy half of the the hardware saved context on the task stack. */ + ldmia r2!, {r4-r7} /* r4-r7 contain rest half of the hardware saved context. */ + stmia r3!, {r4-r7} /* Copy rest half of the the hardware saved context on the task stack. */ + subs r2, #48 + ldmia r2!, {r4-r7} /* Restore r8-r11. */ + mov r8, r4 /* r8 = r4. */ + mov r9, r5 /* r9 = r5. */ + mov r10, r6 /* r10 = r6. */ + mov r11, r7 /* r11 = r7. */ + subs r2, #32 + ldmia r2!, {r4-r7} /* Restore r4-r7. */ + subs r2, #16 + + restore_context_done_first_task: + str r2, [r1] /* Save the location where the context should be saved next as the first member of TCB. */ + bx lr + +#else /* configENABLE_MPU */ + vRestoreContextOfFirstTask: ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r3, [r2] /* Read pxCurrentTCB. */ ldr r0, [r3] /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ -#if ( configENABLE_MPU == 1 ) - dmb /* Complete outstanding transfers before disabling MPU. */ - ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ - ldr r4, [r2] /* Read the value of MPU_CTRL. */ - movs r5, #1 /* r5 = 1. */ - bics r4, r5 /* r4 = r4 & ~r5 i.e. Clear the bit 0 in r4. */ - str r4, [r2] /* Disable MPU. */ - - adds r3, #4 /* r3 = r3 + 4. r3 now points to MAIR0 in TCB. */ - ldr r4, [r3] /* r4 = *r3 i.e. r4 = MAIR0. */ - ldr r2, =0xe000edc0 /* r2 = 0xe000edc0 [Location of MAIR0]. */ - str r4, [r2] /* Program MAIR0. */ - ldr r2, =0xe000ed98 /* r2 = 0xe000ed98 [Location of RNR]. */ - adds r3, #4 /* r3 = r3 + 4. r3 now points to first RBAR in TCB. */ - movs r5, #4 /* r5 = 4. */ - str r5, [r2] /* Program RNR = 4. */ - ldmia r3!, {r6,r7} /* Read first set of RBAR/RLAR from TCB. */ - ldr r4, =0xe000ed9c /* r4 = 0xe000ed9c [Location of RBAR]. */ - stmia r4!, {r6,r7} /* Write first set of RBAR/RLAR registers. */ - movs r5, #5 /* r5 = 5. */ - str r5, [r2] /* Program RNR = 5. */ - ldmia r3!, {r6,r7} /* Read second set of RBAR/RLAR from TCB. */ - ldr r4, =0xe000ed9c /* r4 = 0xe000ed9c [Location of RBAR]. */ - stmia r4!, {r6,r7} /* Write second set of RBAR/RLAR registers. */ - movs r5, #6 /* r5 = 6. */ - str r5, [r2] /* Program RNR = 6. */ - ldmia r3!, {r6,r7} /* Read third set of RBAR/RLAR from TCB. */ - ldr r4, =0xe000ed9c /* r4 = 0xe000ed9c [Location of RBAR]. */ - stmia r4!, {r6,r7} /* Write third set of RBAR/RLAR registers. */ - movs r5, #7 /* r5 = 7. */ - str r5, [r2] /* Program RNR = 7. */ - ldmia r3!, {r6,r7} /* Read fourth set of RBAR/RLAR from TCB. */ - ldr r4, =0xe000ed9c /* r4 = 0xe000ed9c [Location of RBAR]. */ - stmia r4!, {r6,r7} /* Write fourth set of RBAR/RLAR registers. */ - - ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ - ldr r4, [r2] /* Read the value of MPU_CTRL. */ - movs r5, #1 /* r5 = 1. */ - orrs r4, r5 /* r4 = r4 | r5 i.e. Set the bit 0 in r4. */ - str r4, [r2] /* Enable MPU. */ - dsb /* Force memory writes before continuing. */ -#endif /* configENABLE_MPU */ - -#if ( configENABLE_MPU == 1 ) - ldm r0!, {r1-r4} /* Read from stack - r1 = xSecureContext, r2 = PSPLIM, r3 = CONTROL and r4 = EXC_RETURN. */ - ldr r5, =xSecureContext - str r1, [r5] /* Set xSecureContext to this task's value for the same. */ - msr psplim, r2 /* Set this task's PSPLIM value. */ - msr control, r3 /* Set this task's CONTROL value. */ - adds r0, #32 /* Discard everything up to r0. */ - msr psp, r0 /* This is now the new top of stack to use in the task. */ - isb - bx r4 /* Finally, branch to EXC_RETURN. */ -#else /* configENABLE_MPU */ ldm r0!, {r1-r3} /* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */ ldr r4, =xSecureContext str r1, [r4] /* Set xSecureContext to this task's value for the same. */ @@ -167,6 +210,7 @@ vRestoreContextOfFirstTask: msr psp, r0 /* This is now the new top of stack to use in the task. */ isb bx r3 /* Finally, branch to EXC_RETURN. */ + #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ @@ -199,6 +243,149 @@ vClearInterruptMask: msr PRIMASK, r0 bx lr /*-----------------------------------------------------------*/ +#if ( configENABLE_MPU == 1 ) + +PendSV_Handler: + ldr r3, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */ + ldr r0, [r3] /* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */ + ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + ldr r1, [r3] /* Read pxCurrentTCB - Value of pxCurrentTCB must be in r1 as it is used as a parameter later.*/ + ldr r2, [r1] /* r2 = Location in TCB where the context should be saved. */ + + cbz r0, save_ns_context /* No secure context to save. */ + save_s_context: + push {r0-r2, lr} + bl SecureContext_SaveContext /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ + pop {r0-r3} /* LR is now in r3. */ + mov lr, r3 /* Restore LR. */ + + save_ns_context: + mov r3, lr /* r3 = LR (EXC_RETURN). */ + lsls r3, r3, #25 /* r3 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ + bmi save_special_regs /* r3 < 0 ==> Bit[6] in EXC_RETURN is 1 ==> secure stack was used to store the stack frame. */ + + save_general_regs: + mrs r3, psp + stmia r2!, {r4-r7} /* Store r4-r7. */ + mov r4, r8 /* r4 = r8. */ + mov r5, r9 /* r5 = r9. */ + mov r6, r10 /* r6 = r10. */ + mov r7, r11 /* r7 = r11. */ + stmia r2!, {r4-r7} /* Store r8-r11. */ + ldmia r3!, {r4-r7} /* Copy half of the hardware saved context into r4-r7. */ + stmia r2!, {r4-r7} /* Store the hardware saved context. */ + ldmia r3!, {r4-r7} /* Copy rest half of the hardware saved context into r4-r7. */ + stmia r2!, {r4-r7} /* Store the hardware saved context. */ + + save_special_regs: + mrs r3, psp /* r3 = PSP. */ + mrs r4, psplim /* r4 = PSPLIM. */ + mrs r5, control /* r5 = CONTROL. */ + mov r6, lr /* r6 = LR. */ + stmia r2!, {r0, r3-r6} /* Store xSecureContext, original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */ + str r2, [r1] /* Save the location from where the context should be restored as the first member of TCB. */ + + select_next_task: + cpsid i + bl vTaskSwitchContext + cpsie i + + program_mpu: + ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + ldr r0, [r3] /* r0 = pxCurrentTCB.*/ + + dmb /* Complete outstanding transfers before disabling MPU. */ + ldr r1, =0xe000ed94 /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + ldr r2, [r1] /* Read the value of MPU_CTRL. */ + movs r3, #1 /* r3 = 1. */ + bics r2, r3 /* r2 = r2 & ~r3 i.e. Clear the bit 0 in r2. */ + str r2, [r1] /* Disable MPU. */ + + adds r0, #4 /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */ + ldr r1, [r0] /* r1 = *r0 i.e. r1 = MAIR0. */ + ldr r2, =0xe000edc0 /* r2 = 0xe000edc0 [Location of MAIR0]. */ + str r1, [r2] /* Program MAIR0. */ + + adds r0, #4 /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */ + ldr r1, =0xe000ed98 /* r1 = 0xe000ed98 [Location of RNR]. */ + + movs r3, #4 /* r3 = 4. */ + str r3, [r1] /* Program RNR = 4. */ + ldmia r0!, {r4-r5} /* Read first set of RBAR/RLAR registers from TCB. */ + ldr r2, =0xe000ed9c /* r2 = 0xe000ed9c [Location of RBAR]. */ + stmia r2!, {r4-r5} /* Write first set of RBAR/RLAR registers. */ + movs r3, #5 /* r3 = 5. */ + str r3, [r1] /* Program RNR = 5. */ + ldmia r0!, {r4-r5} /* Read second set of RBAR/RLAR registers from TCB. */ + ldr r2, =0xe000ed9c /* r2 = 0xe000ed9c [Location of RBAR]. */ + stmia r2!, {r4-r5} /* Write second set of RBAR/RLAR registers. */ + movs r3, #6 /* r3 = 6. */ + str r3, [r1] /* Program RNR = 6. */ + ldmia r0!, {r4-r5} /* Read third set of RBAR/RLAR registers from TCB. */ + ldr r2, =0xe000ed9c /* r2 = 0xe000ed9c [Location of RBAR]. */ + stmia r2!, {r4-r5} /* Write third set of RBAR/RLAR registers. */ + movs r3, #7 /* r3 = 6. */ + str r3, [r1] /* Program RNR = 7. */ + ldmia r0!, {r4-r5} /* Read fourth set of RBAR/RLAR registers from TCB. */ + ldr r2, =0xe000ed9c /* r2 = 0xe000ed9c [Location of RBAR]. */ + stmia r2!, {r4-r5} /* Write fourth set of RBAR/RLAR registers. */ + + ldr r1, =0xe000ed94 /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + ldr r2, [r1] /* Read the value of MPU_CTRL. */ + movs r3, #1 /* r3 = 1. */ + orrs r2, r3 /* r2 = r2 | r3 i.e. Set the bit 0 in r2. */ + str r2, [r1] /* Enable MPU. */ + dsb /* Force memory writes before continuing. */ + + restore_context: + ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + ldr r1, [r3] /* r1 = pxCurrentTCB.*/ + ldr r2, [r1] /* r2 = Location of saved context in TCB. */ + + restore_special_regs: + subs r2, #20 + ldmia r2!, {r0, r3-r6} /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, r6 = LR. */ + subs r2, #20 + msr psp, r3 + msr psplim, r4 + msr control, r5 + mov lr, r6 + ldr r4, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */ + str r0, [r4] /* Restore xSecureContext. */ + cbz r0, restore_ns_context /* No secure context to restore. */ + + restore_s_context: + push {r1-r3, lr} + bl SecureContext_LoadContext /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ + pop {r1-r4} /* LR is now in r4. */ + mov lr, r4 + + restore_ns_context: + mov r0, lr /* r0 = LR (EXC_RETURN). */ + lsls r0, r0, #25 /* r0 = r0 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ + bmi restore_context_done /* r0 < 0 ==> Bit[6] in EXC_RETURN is 1 ==> secure stack was used to store the stack frame. */ + + restore_general_regs: + subs r2, #32 + ldmia r2!, {r4-r7} /* r4-r7 contain half of the hardware saved context. */ + stmia r3!, {r4-r7} /* Copy half of the the hardware saved context on the task stack. */ + ldmia r2!, {r4-r7} /* r4-r7 contain rest half of the hardware saved context. */ + stmia r3!, {r4-r7} /* Copy rest half of the the hardware saved context on the task stack. */ + subs r2, #48 + ldmia r2!, {r4-r7} /* Restore r8-r11. */ + mov r8, r4 /* r8 = r4. */ + mov r9, r5 /* r9 = r5. */ + mov r10, r6 /* r10 = r6. */ + mov r11, r7 /* r11 = r7. */ + subs r2, #32 + ldmia r2!, {r4-r7} /* Restore r4-r7. */ + subs r2, #16 + + restore_context_done: + str r2, [r1] /* Save the location where the context should be saved next as the first member of TCB. */ + bx lr + +#else /* configENABLE_MPU */ PendSV_Handler: ldr r3, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */ @@ -216,41 +403,18 @@ PendSV_Handler: bpl save_ns_context /* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r3] /* Read pxCurrentTCB. */ -#if ( configENABLE_MPU == 1 ) - subs r2, r2, #16 /* Make space for xSecureContext, PSPLIM, CONTROL and LR on the stack. */ - str r2, [r1] /* Save the new top of stack in TCB. */ - mrs r1, psplim /* r1 = PSPLIM. */ - mrs r3, control /* r3 = CONTROL. */ - mov r4, lr /* r4 = LR/EXC_RETURN. */ - stmia r2!, {r0, r1, r3, r4} /* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */ -#else /* configENABLE_MPU */ + subs r2, r2, #12 /* Make space for xSecureContext, PSPLIM and LR on the stack. */ str r2, [r1] /* Save the new top of stack in TCB. */ mrs r1, psplim /* r1 = PSPLIM. */ mov r3, lr /* r3 = LR/EXC_RETURN. */ stmia r2!, {r0, r1, r3} /* Store xSecureContext, PSPLIM and LR on the stack. */ -#endif /* configENABLE_MPU */ + b select_next_task save_ns_context: ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r3] /* Read pxCurrentTCB. */ - #if ( configENABLE_MPU == 1 ) - subs r2, r2, #48 /* Make space for xSecureContext, PSPLIM, CONTROL, LR and the remaining registers on the stack. */ - str r2, [r1] /* Save the new top of stack in TCB. */ - adds r2, r2, #16 /* r2 = r2 + 16. */ - stmia r2!, {r4-r7} /* Store the low registers that are not saved automatically. */ - mov r4, r8 /* r4 = r8. */ - mov r5, r9 /* r5 = r9. */ - mov r6, r10 /* r6 = r10. */ - mov r7, r11 /* r7 = r11. */ - stmia r2!, {r4-r7} /* Store the high registers that are not saved automatically. */ - mrs r1, psplim /* r1 = PSPLIM. */ - mrs r3, control /* r3 = CONTROL. */ - mov r4, lr /* r4 = LR/EXC_RETURN. */ - subs r2, r2, #48 /* r2 = r2 - 48. */ - stmia r2!, {r0, r1, r3, r4} /* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */ - #else /* configENABLE_MPU */ subs r2, r2, #44 /* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */ str r2, [r1] /* Save the new top of stack in TCB. */ mrs r1, psplim /* r1 = PSPLIM. */ @@ -261,7 +425,6 @@ PendSV_Handler: mov r6, r10 /* r6 = r10. */ mov r7, r11 /* r7 = r11. */ stmia r2!, {r4-r7} /* Store the high registers that are not saved automatically. */ - #endif /* configENABLE_MPU */ select_next_task: cpsid i @@ -272,68 +435,6 @@ PendSV_Handler: ldr r1, [r3] /* Read pxCurrentTCB. */ ldr r2, [r1] /* The first item in pxCurrentTCB is the task top of stack. r2 now points to the top of stack. */ - #if ( configENABLE_MPU == 1 ) - dmb /* Complete outstanding transfers before disabling MPU. */ - ldr r3, =0xe000ed94 /* r3 = 0xe000ed94 [Location of MPU_CTRL]. */ - ldr r4, [r3] /* Read the value of MPU_CTRL. */ - movs r5, #1 /* r5 = 1. */ - bics r4, r5 /* r4 = r4 & ~r5 i.e. Clear the bit 0 in r4. */ - str r4, [r3] /* Disable MPU. */ - - adds r1, #4 /* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */ - ldr r4, [r1] /* r4 = *r1 i.e. r4 = MAIR0. */ - ldr r3, =0xe000edc0 /* r3 = 0xe000edc0 [Location of MAIR0]. */ - str r4, [r3] /* Program MAIR0. */ - ldr r4, =0xe000ed98 /* r4 = 0xe000ed98 [Location of RNR]. */ - adds r1, #4 /* r1 = r1 + 4. r1 now points to first RBAR in TCB. */ - movs r5, #4 /* r5 = 4. */ - str r5, [r4] /* Program RNR = 4. */ - ldmia r1!, {r6,r7} /* Read first set of RBAR/RLAR from TCB. */ - ldr r3, =0xe000ed9c /* r3 = 0xe000ed9c [Location of RBAR]. */ - stmia r3!, {r6,r7} /* Write first set of RBAR/RLAR registers. */ - movs r5, #5 /* r5 = 5. */ - str r5, [r4] /* Program RNR = 5. */ - ldmia r1!, {r6,r7} /* Read second set of RBAR/RLAR from TCB. */ - ldr r3, =0xe000ed9c /* r3 = 0xe000ed9c [Location of RBAR]. */ - stmia r3!, {r6,r7} /* Write second set of RBAR/RLAR registers. */ - movs r5, #6 /* r5 = 6. */ - str r5, [r4] /* Program RNR = 6. */ - ldmia r1!, {r6,r7} /* Read third set of RBAR/RLAR from TCB. */ - ldr r3, =0xe000ed9c /* r3 = 0xe000ed9c [Location of RBAR]. */ - stmia r3!, {r6,r7} /* Write third set of RBAR/RLAR registers. */ - movs r5, #7 /* r5 = 7. */ - str r5, [r4] /* Program RNR = 7. */ - ldmia r1!, {r6,r7} /* Read fourth set of RBAR/RLAR from TCB. */ - ldr r3, =0xe000ed9c /* r3 = 0xe000ed9c [Location of RBAR]. */ - stmia r3!, {r6,r7} /* Write fourth set of RBAR/RLAR registers. */ - - ldr r3, =0xe000ed94 /* r3 = 0xe000ed94 [Location of MPU_CTRL]. */ - ldr r4, [r3] /* Read the value of MPU_CTRL. */ - movs r5, #1 /* r5 = 1. */ - orrs r4, r5 /* r4 = r4 | r5 i.e. Set the bit 0 in r4. */ - str r4, [r3] /* Enable MPU. */ - dsb /* Force memory writes before continuing. */ - #endif /* configENABLE_MPU */ - - #if ( configENABLE_MPU == 1 ) - ldmia r2!, {r0, r1, r3, r4} /* Read from stack - r0 = xSecureContext, r1 = PSPLIM, r3 = CONTROL and r4 = LR. */ - msr psplim, r1 /* Restore the PSPLIM register value for the task. */ - msr control, r3 /* Restore the CONTROL register value for the task. */ - mov lr, r4 /* LR = r4. */ - ldr r3, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */ - str r0, [r3] /* Restore the task's xSecureContext. */ - cbz r0, restore_ns_context /* If there is no secure context for the task, restore the non-secure context. */ - ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - ldr r1, [r3] /* Read pxCurrentTCB. */ - push {r2, r4} - bl SecureContext_LoadContext /* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ - pop {r2, r4} - mov lr, r4 /* LR = r4. */ - lsls r1, r4, #25 /* r1 = r4 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ - bpl restore_ns_context /* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ - msr psp, r2 /* Remember the new top of stack for the task. */ - bx lr - #else /* configENABLE_MPU */ ldmia r2!, {r0, r1, r4} /* Read from stack - r0 = xSecureContext, r1 = PSPLIM and r4 = LR. */ msr psplim, r1 /* Restore the PSPLIM register value for the task. */ mov lr, r4 /* LR = r4. */ @@ -350,7 +451,6 @@ PendSV_Handler: bpl restore_ns_context /* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ msr psp, r2 /* Remember the new top of stack for the task. */ bx lr - #endif /* configENABLE_MPU */ restore_ns_context: adds r2, r2, #16 /* Move to the high registers. */ @@ -363,8 +463,45 @@ PendSV_Handler: subs r2, r2, #32 /* Go back to the low registers. */ ldmia r2!, {r4-r7} /* Restore the low registers that are not automatically restored. */ bx lr + +#endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + +SVC_Handler: + movs r0, #4 + mov r1, lr + tst r0, r1 + beq stack_on_msp + stack_on_psp: + mrs r0, psp + b route_svc + stack_on_msp: + mrs r0, msp + b route_svc + + route_svc: + ldr r2, [r0, #24] + subs r2, #2 + ldrb r3, [r2, #0] + cmp r3, #4 /* portSVC_SYSTEM_CALL_ENTER. */ + beq system_call_enter + cmp r3, #5 /* portSVC_SYSTEM_CALL_ENTER_1. */ + beq system_call_enter_1 + cmp r3, #6 /* portSVC_SYSTEM_CALL_EXIT. */ + beq system_call_exit + b vPortSVCHandler_C + + system_call_enter: + b vSystemCallEnter + system_call_enter_1: + b vSystemCallEnter_1 + system_call_exit: + b vSystemCallExit + +#else /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + SVC_Handler: movs r0, #4 mov r1, lr @@ -375,6 +512,8 @@ SVC_Handler: stacking_used_msp: mrs r0, msp b vPortSVCHandler_C + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ /*-----------------------------------------------------------*/ vPortFreeSecureContext: diff --git a/portable/IAR/ARM_CM23/non_secure/portmacrocommon.h b/portable/IAR/ARM_CM23/non_secure/portmacrocommon.h index c2ca5fa7730..65ac109c802 100644 --- a/portable/IAR/ARM_CM23/non_secure/portmacrocommon.h +++ b/portable/IAR/ARM_CM23/non_secure/portmacrocommon.h @@ -186,23 +186,120 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #define portMPU_REGION_EXECUTE_NEVER ( 1UL ) /*-----------------------------------------------------------*/ -/** - * @brief Settings to define an MPU region. - */ -typedef struct MPURegionSettings -{ - uint32_t ulRBAR; /**< RBAR for the region. */ - uint32_t ulRLAR; /**< RLAR for the region. */ -} MPURegionSettings_t; +#if ( configENABLE_MPU == 1 ) -/** - * @brief MPU settings as stored in the TCB. - */ -typedef struct MPU_SETTINGS -{ - uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ - MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */ -} xMPU_SETTINGS; + /** + * @brief Settings to define an MPU region. + */ + typedef struct MPURegionSettings + { + uint32_t ulRBAR; /**< RBAR for the region. */ + uint32_t ulRLAR; /**< RLAR for the region. */ + } MPURegionSettings_t; + + #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + + #ifndef configSYSTEM_CALL_STACK_SIZE + #error configSYSTEM_CALL_STACK_SIZE must be defined to the desired size of the system call stack in words for using MPU wrappers v2. + #endif + + /** + * @brief System call stack. + */ + typedef struct SYSTEM_CALL_STACK_INFO + { + uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ]; + uint32_t * pulSystemCallStack; + uint32_t * pulSystemCallStackLimit; + uint32_t * pulTaskStack; + uint32_t ulLinkRegisterAtSystemCallEntry; + uint32_t ulStackLimitRegisterAtSystemCallEntry; + } xSYSTEM_CALL_STACK_INFO; + + #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + + /** + * @brief MPU settings as stored in the TCB. + */ + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + + #if( configENABLE_TRUSTZONE == 1 ) + + /* + * +-----------+---------------+----------+-----------------+------------------------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | + * | | | | PC, xPSR | CONTROL, EXC_RETURN | | + * +-----------+---------------+----------+-----------------+------------------------------+-----+ + * + * <-----------><--------------><---------><----------------><-----------------------------><----> + * 16 16 8 8 5 1 + */ + #define MAX_CONTEXT_SIZE 54 + + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ + + /* + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | + * | | | | PC, xPSR | EXC_RETURN | | + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * + * <-----------><--------------><---------><----------------><---------------------><----> + * 16 16 8 8 4 1 + */ + #define MAX_CONTEXT_SIZE 53 + + #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + + #else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ + + #if( configENABLE_TRUSTZONE == 1 ) + + /* + * +----------+-----------------+------------------------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | + * | | PC, xPSR | CONTROL, EXC_RETURN | | + * +----------+-----------------+------------------------------+-----+ + * + * <---------><----------------><------------------------------><----> + * 8 8 5 1 + */ + #define MAX_CONTEXT_SIZE 22 + + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ + + /* + * +----------+-----------------+----------------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | + * | | PC, xPSR | EXC_RETURN | | + * +----------+-----------------+----------------------+-----+ + * + * <---------><----------------><----------------------><----> + * 8 8 4 1 + */ + #define MAX_CONTEXT_SIZE 21 + + #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + + #endif /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ + + /* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ + #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) + #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) + + typedef struct MPU_SETTINGS + { + uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ + MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */ + uint32_t ulContext[ MAX_CONTEXT_SIZE ]; + uint32_t ulTaskFlags; + + #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo; + #endif + } xMPU_SETTINGS; + +#endif /* configENABLE_MPU == 1 */ /*-----------------------------------------------------------*/ /** @@ -223,6 +320,9 @@ typedef struct MPU_SETTINGS #define portSVC_FREE_SECURE_CONTEXT 1 #define portSVC_START_SCHEDULER 2 #define portSVC_RAISE_PRIVILEGE 3 +#define portSVC_SYSTEM_CALL_ENTER 4 /* System calls with upto 4 parameters. */ +#define portSVC_SYSTEM_CALL_ENTER_1 5 /* System calls with 5 parameters. */ +#define portSVC_SYSTEM_CALL_EXIT 6 /*-----------------------------------------------------------*/ /** @@ -315,6 +415,20 @@ typedef struct MPU_SETTINGS #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ +#if ( configENABLE_MPU == 1 ) + + extern BaseType_t xPortIsTaskPrivileged( void ); + + /** + * @brief Checks whether or not the calling task is privileged. + * + * @return pdTRUE if the calling task is privileged, pdFALSE otherwise. + */ + #define portIS_TASK_PRIVILEGED() xPortIsTaskPrivileged() + +#endif /* configENABLE_MPU == 1 */ +/*-----------------------------------------------------------*/ + /** * @brief Barriers. */ diff --git a/portable/IAR/ARM_CM23_NTZ/non_secure/mpu_wrappers_v2_asm.S b/portable/IAR/ARM_CM23_NTZ/non_secure/mpu_wrappers_v2_asm.S new file mode 100644 index 00000000000..867642b5e97 --- /dev/null +++ b/portable/IAR/ARM_CM23_NTZ/non_secure/mpu_wrappers_v2_asm.S @@ -0,0 +1,1623 @@ +/* + * FreeRTOS Kernel + * Copyright (C) 2021 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 + * + */ + + + SECTION freertos_system_calls:CODE:NOROOT(2) + THUMB +/*-----------------------------------------------------------*/ + +#include "FreeRTOSConfig.h" + +#ifndef configUSE_MPU_WRAPPERS_V1 + #define configUSE_MPU_WRAPPERS_V1 0 +#endif + +/* These must be in sync with portmacro.h. */ +#define portSVC_SYSTEM_CALL_ENTER 4 /* System calls with upto 4 parameters. */ +#define portSVC_SYSTEM_CALL_ENTER_1 5 /* System calls with 5 parameters. */ +#define portSVC_SYSTEM_CALL_EXIT 6 +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + + PUBLIC MPU_xTaskDelayUntil +MPU_xTaskDelayUntil: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xTaskDelayUntil_Unpriv + MPU_xTaskDelayUntil_Priv: + pop {r0, r1} + b MPU_xTaskDelayUntilImpl + MPU_xTaskDelayUntil_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskDelayUntilImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskAbortDelay +MPU_xTaskAbortDelay: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xTaskAbortDelay_Unpriv + MPU_xTaskAbortDelay_Priv: + pop {r0, r1} + b MPU_xTaskAbortDelayImpl + MPU_xTaskAbortDelay_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskAbortDelayImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTaskDelay +MPU_vTaskDelay: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_vTaskDelay_Unpriv + MPU_vTaskDelay_Priv: + pop {r0, r1} + b MPU_vTaskDelayImpl + MPU_vTaskDelay_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskDelayImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxTaskPriorityGet +MPU_uxTaskPriorityGet: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_uxTaskPriorityGet_Unpriv + MPU_uxTaskPriorityGet_Priv: + pop {r0, r1} + b MPU_uxTaskPriorityGetImpl + MPU_uxTaskPriorityGet_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxTaskPriorityGetImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_eTaskGetState +MPU_eTaskGetState: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_eTaskGetState_Unpriv + MPU_eTaskGetState_Priv: + pop {r0, r1} + b MPU_eTaskGetStateImpl + MPU_eTaskGetState_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_eTaskGetStateImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTaskGetInfo +MPU_vTaskGetInfo: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_vTaskGetInfo_Unpriv + MPU_vTaskGetInfo_Priv: + pop {r0, r1} + b MPU_vTaskGetInfoImpl + MPU_vTaskGetInfo_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskGetInfoImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGetIdleTaskHandle +MPU_xTaskGetIdleTaskHandle: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xTaskGetIdleTaskHandle_Unpriv + MPU_xTaskGetIdleTaskHandle_Priv: + pop {r0, r1} + b MPU_xTaskGetIdleTaskHandleImpl + MPU_xTaskGetIdleTaskHandle_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskGetIdleTaskHandleImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTaskSuspend +MPU_vTaskSuspend: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_vTaskSuspend_Unpriv + MPU_vTaskSuspend_Priv: + pop {r0, r1} + b MPU_vTaskSuspendImpl + MPU_vTaskSuspend_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskSuspendImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTaskResume +MPU_vTaskResume: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_vTaskResume_Unpriv + MPU_vTaskResume_Priv: + pop {r0, r1} + b MPU_vTaskResumeImpl + MPU_vTaskResume_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskResumeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGetTickCount +MPU_xTaskGetTickCount: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xTaskGetTickCount_Unpriv + MPU_xTaskGetTickCount_Priv: + pop {r0, r1} + b MPU_xTaskGetTickCountImpl + MPU_xTaskGetTickCount_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskGetTickCountImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxTaskGetNumberOfTasks +MPU_uxTaskGetNumberOfTasks: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_uxTaskGetNumberOfTasks_Unpriv + MPU_uxTaskGetNumberOfTasks_Priv: + pop {r0, r1} + b MPU_uxTaskGetNumberOfTasksImpl + MPU_uxTaskGetNumberOfTasks_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxTaskGetNumberOfTasksImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_pcTaskGetName +MPU_pcTaskGetName: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_pcTaskGetName_Unpriv + MPU_pcTaskGetName_Priv: + pop {r0, r1} + b MPU_pcTaskGetNameImpl + MPU_pcTaskGetName_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_pcTaskGetNameImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_ulTaskGetRunTimeCounter +MPU_ulTaskGetRunTimeCounter: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_ulTaskGetRunTimeCounter_Unpriv + MPU_ulTaskGetRunTimeCounter_Priv: + pop {r0, r1} + b MPU_ulTaskGetRunTimeCounterImpl + MPU_ulTaskGetRunTimeCounter_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_ulTaskGetRunTimeCounterImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_ulTaskGetRunTimePercent +MPU_ulTaskGetRunTimePercent: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_ulTaskGetRunTimePercent_Unpriv + MPU_ulTaskGetRunTimePercent_Priv: + pop {r0, r1} + b MPU_ulTaskGetRunTimePercentImpl + MPU_ulTaskGetRunTimePercent_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_ulTaskGetRunTimePercentImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_ulTaskGetIdleRunTimePercent +MPU_ulTaskGetIdleRunTimePercent: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_ulTaskGetIdleRunTimePercent_Unpriv + MPU_ulTaskGetIdleRunTimePercent_Priv: + pop {r0, r1} + b MPU_ulTaskGetIdleRunTimePercentImpl + MPU_ulTaskGetIdleRunTimePercent_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_ulTaskGetIdleRunTimePercentImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_ulTaskGetIdleRunTimeCounter +MPU_ulTaskGetIdleRunTimeCounter: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_ulTaskGetIdleRunTimeCounter_Unpriv + MPU_ulTaskGetIdleRunTimeCounter_Priv: + pop {r0, r1} + b MPU_ulTaskGetIdleRunTimeCounterImpl + MPU_ulTaskGetIdleRunTimeCounter_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_ulTaskGetIdleRunTimeCounterImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTaskSetApplicationTaskTag +MPU_vTaskSetApplicationTaskTag: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_vTaskSetApplicationTaskTag_Unpriv + MPU_vTaskSetApplicationTaskTag_Priv: + pop {r0, r1} + b MPU_vTaskSetApplicationTaskTagImpl + MPU_vTaskSetApplicationTaskTag_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskSetApplicationTaskTagImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGetApplicationTaskTag +MPU_xTaskGetApplicationTaskTag: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xTaskGetApplicationTaskTag_Unpriv + MPU_xTaskGetApplicationTaskTag_Priv: + pop {r0, r1} + b MPU_xTaskGetApplicationTaskTagImpl + MPU_xTaskGetApplicationTaskTag_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskGetApplicationTaskTagImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTaskSetThreadLocalStoragePointer +MPU_vTaskSetThreadLocalStoragePointer: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_vTaskSetThreadLocalStoragePointer_Unpriv + MPU_vTaskSetThreadLocalStoragePointer_Priv: + pop {r0, r1} + b MPU_vTaskSetThreadLocalStoragePointerImpl + MPU_vTaskSetThreadLocalStoragePointer_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskSetThreadLocalStoragePointerImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_pvTaskGetThreadLocalStoragePointer +MPU_pvTaskGetThreadLocalStoragePointer: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_pvTaskGetThreadLocalStoragePointer_Unpriv + MPU_pvTaskGetThreadLocalStoragePointer_Priv: + pop {r0, r1} + b MPU_pvTaskGetThreadLocalStoragePointerImpl + MPU_pvTaskGetThreadLocalStoragePointer_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_pvTaskGetThreadLocalStoragePointerImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxTaskGetSystemState +MPU_uxTaskGetSystemState: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_uxTaskGetSystemState_Unpriv + MPU_uxTaskGetSystemState_Priv: + pop {r0, r1} + b MPU_uxTaskGetSystemStateImpl + MPU_uxTaskGetSystemState_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxTaskGetSystemStateImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxTaskGetStackHighWaterMark +MPU_uxTaskGetStackHighWaterMark: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_uxTaskGetStackHighWaterMark_Unpriv + MPU_uxTaskGetStackHighWaterMark_Priv: + pop {r0, r1} + b MPU_uxTaskGetStackHighWaterMarkImpl + MPU_uxTaskGetStackHighWaterMark_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxTaskGetStackHighWaterMarkImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxTaskGetStackHighWaterMark2 +MPU_uxTaskGetStackHighWaterMark2: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_uxTaskGetStackHighWaterMark2_Unpriv + MPU_uxTaskGetStackHighWaterMark2_Priv: + pop {r0, r1} + b MPU_uxTaskGetStackHighWaterMark2Impl + MPU_uxTaskGetStackHighWaterMark2_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxTaskGetStackHighWaterMark2Impl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGetCurrentTaskHandle +MPU_xTaskGetCurrentTaskHandle: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xTaskGetCurrentTaskHandle_Unpriv + MPU_xTaskGetCurrentTaskHandle_Priv: + pop {r0, r1} + b MPU_xTaskGetCurrentTaskHandleImpl + MPU_xTaskGetCurrentTaskHandle_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskGetCurrentTaskHandleImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGetSchedulerState +MPU_xTaskGetSchedulerState: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xTaskGetSchedulerState_Unpriv + MPU_xTaskGetSchedulerState_Priv: + pop {r0, r1} + b MPU_xTaskGetSchedulerStateImpl + MPU_xTaskGetSchedulerState_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskGetSchedulerStateImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTaskSetTimeOutState +MPU_vTaskSetTimeOutState: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_vTaskSetTimeOutState_Unpriv + MPU_vTaskSetTimeOutState_Priv: + pop {r0, r1} + b MPU_vTaskSetTimeOutStateImpl + MPU_vTaskSetTimeOutState_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskSetTimeOutStateImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskCheckForTimeOut +MPU_xTaskCheckForTimeOut: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xTaskCheckForTimeOut_Unpriv + MPU_xTaskCheckForTimeOut_Priv: + pop {r0, r1} + b MPU_xTaskCheckForTimeOutImpl + MPU_xTaskCheckForTimeOut_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskCheckForTimeOutImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGenericNotify +MPU_xTaskGenericNotify: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xTaskGenericNotify_Unpriv + MPU_xTaskGenericNotify_Priv: + pop {r0, r1} + b MPU_xTaskGenericNotifyImpl + MPU_xTaskGenericNotify_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER_1 + bl MPU_xTaskGenericNotifyImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGenericNotifyWait +MPU_xTaskGenericNotifyWait: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xTaskGenericNotifyWait_Unpriv + MPU_xTaskGenericNotifyWait_Priv: + pop {r0, r1} + b MPU_xTaskGenericNotifyWaitImpl + MPU_xTaskGenericNotifyWait_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER_1 + bl MPU_xTaskGenericNotifyWaitImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_ulTaskGenericNotifyTake +MPU_ulTaskGenericNotifyTake: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_ulTaskGenericNotifyTake_Unpriv + MPU_ulTaskGenericNotifyTake_Priv: + pop {r0, r1} + b MPU_ulTaskGenericNotifyTakeImpl + MPU_ulTaskGenericNotifyTake_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_ulTaskGenericNotifyTakeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGenericNotifyStateClear +MPU_xTaskGenericNotifyStateClear: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xTaskGenericNotifyStateClear_Unpriv + MPU_xTaskGenericNotifyStateClear_Priv: + pop {r0, r1} + b MPU_xTaskGenericNotifyStateClearImpl + MPU_xTaskGenericNotifyStateClear_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskGenericNotifyStateClearImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_ulTaskGenericNotifyValueClear +MPU_ulTaskGenericNotifyValueClear: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_ulTaskGenericNotifyValueClear_Unpriv + MPU_ulTaskGenericNotifyValueClear_Priv: + pop {r0, r1} + b MPU_ulTaskGenericNotifyValueClearImpl + MPU_ulTaskGenericNotifyValueClear_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_ulTaskGenericNotifyValueClearImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueGenericSend +MPU_xQueueGenericSend: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xQueueGenericSend_Unpriv + MPU_xQueueGenericSend_Priv: + pop {r0, r1} + b MPU_xQueueGenericSendImpl + MPU_xQueueGenericSend_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueGenericSendImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxQueueMessagesWaiting +MPU_uxQueueMessagesWaiting: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_uxQueueMessagesWaiting_Unpriv + MPU_uxQueueMessagesWaiting_Priv: + pop {r0, r1} + b MPU_uxQueueMessagesWaitingImpl + MPU_uxQueueMessagesWaiting_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxQueueMessagesWaitingImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxQueueSpacesAvailable +MPU_uxQueueSpacesAvailable: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_uxQueueSpacesAvailable_Unpriv + MPU_uxQueueSpacesAvailable_Priv: + pop {r0, r1} + b MPU_uxQueueSpacesAvailableImpl + MPU_uxQueueSpacesAvailable_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxQueueSpacesAvailableImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueReceive +MPU_xQueueReceive: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xQueueReceive_Unpriv + MPU_xQueueReceive_Priv: + pop {r0, r1} + b MPU_xQueueReceiveImpl + MPU_xQueueReceive_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueReceiveImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueuePeek +MPU_xQueuePeek: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xQueuePeek_Unpriv + MPU_xQueuePeek_Priv: + pop {r0, r1} + b MPU_xQueuePeekImpl + MPU_xQueuePeek_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueuePeekImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueSemaphoreTake +MPU_xQueueSemaphoreTake: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xQueueSemaphoreTake_Unpriv + MPU_xQueueSemaphoreTake_Priv: + pop {r0, r1} + b MPU_xQueueSemaphoreTakeImpl + MPU_xQueueSemaphoreTake_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueSemaphoreTakeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueGetMutexHolder +MPU_xQueueGetMutexHolder: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xQueueGetMutexHolder_Unpriv + MPU_xQueueGetMutexHolder_Priv: + pop {r0, r1} + b MPU_xQueueGetMutexHolderImpl + MPU_xQueueGetMutexHolder_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueGetMutexHolderImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueTakeMutexRecursive +MPU_xQueueTakeMutexRecursive: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xQueueTakeMutexRecursive_Unpriv + MPU_xQueueTakeMutexRecursive_Priv: + pop {r0, r1} + b MPU_xQueueTakeMutexRecursiveImpl + MPU_xQueueTakeMutexRecursive_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueTakeMutexRecursiveImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueGiveMutexRecursive +MPU_xQueueGiveMutexRecursive: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xQueueGiveMutexRecursive_Unpriv + MPU_xQueueGiveMutexRecursive_Priv: + pop {r0, r1} + b MPU_xQueueGiveMutexRecursiveImpl + MPU_xQueueGiveMutexRecursive_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueGiveMutexRecursiveImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueSelectFromSet +MPU_xQueueSelectFromSet: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xQueueSelectFromSet_Unpriv + MPU_xQueueSelectFromSet_Priv: + pop {r0, r1} + b MPU_xQueueSelectFromSetImpl + MPU_xQueueSelectFromSet_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueSelectFromSetImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueAddToSet +MPU_xQueueAddToSet: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xQueueAddToSet_Unpriv + MPU_xQueueAddToSet_Priv: + pop {r0, r1} + b MPU_xQueueAddToSetImpl + MPU_xQueueAddToSet_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueAddToSetImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vQueueAddToRegistry +MPU_vQueueAddToRegistry: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_vQueueAddToRegistry_Unpriv + MPU_vQueueAddToRegistry_Priv: + pop {r0, r1} + b MPU_vQueueAddToRegistryImpl + MPU_vQueueAddToRegistry_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vQueueAddToRegistryImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vQueueUnregisterQueue +MPU_vQueueUnregisterQueue: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_vQueueUnregisterQueue_Unpriv + MPU_vQueueUnregisterQueue_Priv: + pop {r0, r1} + b MPU_vQueueUnregisterQueueImpl + MPU_vQueueUnregisterQueue_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vQueueUnregisterQueueImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_pcQueueGetName +MPU_pcQueueGetName: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_pcQueueGetName_Unpriv + MPU_pcQueueGetName_Priv: + pop {r0, r1} + b MPU_pcQueueGetNameImpl + MPU_pcQueueGetName_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_pcQueueGetNameImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_pvTimerGetTimerID +MPU_pvTimerGetTimerID: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_pvTimerGetTimerID_Unpriv + MPU_pvTimerGetTimerID_Priv: + pop {r0, r1} + b MPU_pvTimerGetTimerIDImpl + MPU_pvTimerGetTimerID_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_pvTimerGetTimerIDImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTimerSetTimerID +MPU_vTimerSetTimerID: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_vTimerSetTimerID_Unpriv + MPU_vTimerSetTimerID_Priv: + pop {r0, r1} + b MPU_vTimerSetTimerIDImpl + MPU_vTimerSetTimerID_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTimerSetTimerIDImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTimerIsTimerActive +MPU_xTimerIsTimerActive: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xTimerIsTimerActive_Unpriv + MPU_xTimerIsTimerActive_Priv: + pop {r0, r1} + b MPU_xTimerIsTimerActiveImpl + MPU_xTimerIsTimerActive_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTimerIsTimerActiveImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTimerGetTimerDaemonTaskHandle +MPU_xTimerGetTimerDaemonTaskHandle: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xTimerGetTimerDaemonTaskHandle_Unpriv + MPU_xTimerGetTimerDaemonTaskHandle_Priv: + pop {r0, r1} + b MPU_xTimerGetTimerDaemonTaskHandleImpl + MPU_xTimerGetTimerDaemonTaskHandle_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTimerGetTimerDaemonTaskHandleImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTimerGenericCommand +MPU_xTimerGenericCommand: + push {r0, r1} + /* This function can be called from ISR also and therefore, we need a check + * to take privileged path, if called from ISR. */ + mrs r0, ipsr + cmp r0, #0 + bne MPU_xTimerGenericCommand_Priv + mrs r0, control + movs r1, #1 + tst r0, r1 + beq MPU_xTimerGenericCommand_Priv + MPU_xTimerGenericCommand_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER_1 + bl MPU_xTimerGenericCommandImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr + MPU_xTimerGenericCommand_Priv: + pop {r0, r1} + b MPU_xTimerGenericCommandImpl + +/*-----------------------------------------------------------*/ + + PUBLIC MPU_pcTimerGetName +MPU_pcTimerGetName: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_pcTimerGetName_Unpriv + MPU_pcTimerGetName_Priv: + pop {r0, r1} + b MPU_pcTimerGetNameImpl + MPU_pcTimerGetName_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_pcTimerGetNameImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTimerSetReloadMode +MPU_vTimerSetReloadMode: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_vTimerSetReloadMode_Unpriv + MPU_vTimerSetReloadMode_Priv: + pop {r0, r1} + b MPU_vTimerSetReloadModeImpl + MPU_vTimerSetReloadMode_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTimerSetReloadModeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTimerGetReloadMode +MPU_xTimerGetReloadMode: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xTimerGetReloadMode_Unpriv + MPU_xTimerGetReloadMode_Priv: + pop {r0, r1} + b MPU_xTimerGetReloadModeImpl + MPU_xTimerGetReloadMode_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTimerGetReloadModeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxTimerGetReloadMode +MPU_uxTimerGetReloadMode: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_uxTimerGetReloadMode_Unpriv + MPU_uxTimerGetReloadMode_Priv: + pop {r0, r1} + b MPU_uxTimerGetReloadModeImpl + MPU_uxTimerGetReloadMode_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxTimerGetReloadModeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTimerGetPeriod +MPU_xTimerGetPeriod: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xTimerGetPeriod_Unpriv + MPU_xTimerGetPeriod_Priv: + pop {r0, r1} + b MPU_xTimerGetPeriodImpl + MPU_xTimerGetPeriod_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTimerGetPeriodImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTimerGetExpiryTime +MPU_xTimerGetExpiryTime: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xTimerGetExpiryTime_Unpriv + MPU_xTimerGetExpiryTime_Priv: + pop {r0, r1} + b MPU_xTimerGetExpiryTimeImpl + MPU_xTimerGetExpiryTime_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTimerGetExpiryTimeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xEventGroupWaitBits +MPU_xEventGroupWaitBits: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xEventGroupWaitBits_Unpriv + MPU_xEventGroupWaitBits_Priv: + pop {r0, r1} + b MPU_xEventGroupWaitBitsImpl + MPU_xEventGroupWaitBits_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER_1 + bl MPU_xEventGroupWaitBitsImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xEventGroupClearBits +MPU_xEventGroupClearBits: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xEventGroupClearBits_Unpriv + MPU_xEventGroupClearBits_Priv: + pop {r0, r1} + b MPU_xEventGroupClearBitsImpl + MPU_xEventGroupClearBits_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xEventGroupClearBitsImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xEventGroupSetBits +MPU_xEventGroupSetBits: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xEventGroupSetBits_Unpriv + MPU_xEventGroupSetBits_Priv: + pop {r0, r1} + b MPU_xEventGroupSetBitsImpl + MPU_xEventGroupSetBits_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xEventGroupSetBitsImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xEventGroupSync +MPU_xEventGroupSync: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xEventGroupSync_Unpriv + MPU_xEventGroupSync_Priv: + pop {r0, r1} + b MPU_xEventGroupSyncImpl + MPU_xEventGroupSync_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xEventGroupSyncImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxEventGroupGetNumber +MPU_uxEventGroupGetNumber: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_uxEventGroupGetNumber_Unpriv + MPU_uxEventGroupGetNumber_Priv: + pop {r0, r1} + b MPU_uxEventGroupGetNumberImpl + MPU_uxEventGroupGetNumber_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxEventGroupGetNumberImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vEventGroupSetNumber +MPU_vEventGroupSetNumber: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_vEventGroupSetNumber_Unpriv + MPU_vEventGroupSetNumber_Priv: + pop {r0, r1} + b MPU_vEventGroupSetNumberImpl + MPU_vEventGroupSetNumber_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vEventGroupSetNumberImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferSend +MPU_xStreamBufferSend: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xStreamBufferSend_Unpriv + MPU_xStreamBufferSend_Priv: + pop {r0, r1} + b MPU_xStreamBufferSendImpl + MPU_xStreamBufferSend_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferSendImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferReceive +MPU_xStreamBufferReceive: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xStreamBufferReceive_Unpriv + MPU_xStreamBufferReceive_Priv: + pop {r0, r1} + b MPU_xStreamBufferReceiveImpl + MPU_xStreamBufferReceive_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferReceiveImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferIsFull +MPU_xStreamBufferIsFull: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xStreamBufferIsFull_Unpriv + MPU_xStreamBufferIsFull_Priv: + pop {r0, r1} + b MPU_xStreamBufferIsFullImpl + MPU_xStreamBufferIsFull_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferIsFullImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferIsEmpty +MPU_xStreamBufferIsEmpty: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xStreamBufferIsEmpty_Unpriv + MPU_xStreamBufferIsEmpty_Priv: + pop {r0, r1} + b MPU_xStreamBufferIsEmptyImpl + MPU_xStreamBufferIsEmpty_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferIsEmptyImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferSpacesAvailable +MPU_xStreamBufferSpacesAvailable: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xStreamBufferSpacesAvailable_Unpriv + MPU_xStreamBufferSpacesAvailable_Priv: + pop {r0, r1} + b MPU_xStreamBufferSpacesAvailableImpl + MPU_xStreamBufferSpacesAvailable_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferSpacesAvailableImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferBytesAvailable +MPU_xStreamBufferBytesAvailable: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xStreamBufferBytesAvailable_Unpriv + MPU_xStreamBufferBytesAvailable_Priv: + pop {r0, r1} + b MPU_xStreamBufferBytesAvailableImpl + MPU_xStreamBufferBytesAvailable_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferBytesAvailableImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferSetTriggerLevel +MPU_xStreamBufferSetTriggerLevel: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xStreamBufferSetTriggerLevel_Unpriv + MPU_xStreamBufferSetTriggerLevel_Priv: + pop {r0, r1} + b MPU_xStreamBufferSetTriggerLevelImpl + MPU_xStreamBufferSetTriggerLevel_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferSetTriggerLevelImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferNextMessageLengthBytes +MPU_xStreamBufferNextMessageLengthBytes: + push {r0, r1} + mrs r0, control + movs r1, #1 + tst r0, r1 + bne MPU_xStreamBufferNextMessageLengthBytes_Unpriv + MPU_xStreamBufferNextMessageLengthBytes_Priv: + pop {r0, r1} + b MPU_xStreamBufferNextMessageLengthBytesImpl + MPU_xStreamBufferNextMessageLengthBytes_Unpriv: + pop {r0, r1} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferNextMessageLengthBytesImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + +/* Default weak implementations in case one is not available from + * mpu_wrappers because of config options. */ + + PUBWEAK MPU_xTaskDelayUntilImpl +MPU_xTaskDelayUntilImpl: + b MPU_xTaskDelayUntilImpl + + PUBWEAK MPU_xTaskAbortDelayImpl +MPU_xTaskAbortDelayImpl: + b MPU_xTaskAbortDelayImpl + + PUBWEAK MPU_vTaskDelayImpl +MPU_vTaskDelayImpl: + b MPU_vTaskDelayImpl + + PUBWEAK MPU_uxTaskPriorityGetImpl +MPU_uxTaskPriorityGetImpl: + b MPU_uxTaskPriorityGetImpl + + PUBWEAK MPU_eTaskGetStateImpl +MPU_eTaskGetStateImpl: + b MPU_eTaskGetStateImpl + + PUBWEAK MPU_vTaskGetInfoImpl +MPU_vTaskGetInfoImpl: + b MPU_vTaskGetInfoImpl + + PUBWEAK MPU_xTaskGetIdleTaskHandleImpl +MPU_xTaskGetIdleTaskHandleImpl: + b MPU_xTaskGetIdleTaskHandleImpl + + PUBWEAK MPU_vTaskSuspendImpl +MPU_vTaskSuspendImpl: + b MPU_vTaskSuspendImpl + + PUBWEAK MPU_vTaskResumeImpl +MPU_vTaskResumeImpl: + b MPU_vTaskResumeImpl + + PUBWEAK MPU_xTaskGetTickCountImpl +MPU_xTaskGetTickCountImpl: + b MPU_xTaskGetTickCountImpl + + PUBWEAK MPU_uxTaskGetNumberOfTasksImpl +MPU_uxTaskGetNumberOfTasksImpl: + b MPU_uxTaskGetNumberOfTasksImpl + + PUBWEAK MPU_pcTaskGetNameImpl +MPU_pcTaskGetNameImpl: + b MPU_pcTaskGetNameImpl + + PUBWEAK MPU_ulTaskGetRunTimeCounterImpl +MPU_ulTaskGetRunTimeCounterImpl: + b MPU_ulTaskGetRunTimeCounterImpl + + PUBWEAK MPU_ulTaskGetRunTimePercentImpl +MPU_ulTaskGetRunTimePercentImpl: + b MPU_ulTaskGetRunTimePercentImpl + + PUBWEAK MPU_ulTaskGetIdleRunTimePercentImpl +MPU_ulTaskGetIdleRunTimePercentImpl: + b MPU_ulTaskGetIdleRunTimePercentImpl + + PUBWEAK MPU_ulTaskGetIdleRunTimeCounterImpl +MPU_ulTaskGetIdleRunTimeCounterImpl: + b MPU_ulTaskGetIdleRunTimeCounterImpl + + PUBWEAK MPU_vTaskSetApplicationTaskTagImpl +MPU_vTaskSetApplicationTaskTagImpl: + b MPU_vTaskSetApplicationTaskTagImpl + + PUBWEAK MPU_xTaskGetApplicationTaskTagImpl +MPU_xTaskGetApplicationTaskTagImpl: + b MPU_xTaskGetApplicationTaskTagImpl + + PUBWEAK MPU_vTaskSetThreadLocalStoragePointerImpl +MPU_vTaskSetThreadLocalStoragePointerImpl: + b MPU_vTaskSetThreadLocalStoragePointerImpl + + PUBWEAK MPU_pvTaskGetThreadLocalStoragePointerImpl +MPU_pvTaskGetThreadLocalStoragePointerImpl: + b MPU_pvTaskGetThreadLocalStoragePointerImpl + + PUBWEAK MPU_uxTaskGetSystemStateImpl +MPU_uxTaskGetSystemStateImpl: + b MPU_uxTaskGetSystemStateImpl + + PUBWEAK MPU_uxTaskGetStackHighWaterMarkImpl +MPU_uxTaskGetStackHighWaterMarkImpl: + b MPU_uxTaskGetStackHighWaterMarkImpl + + PUBWEAK MPU_uxTaskGetStackHighWaterMark2Impl +MPU_uxTaskGetStackHighWaterMark2Impl: + b MPU_uxTaskGetStackHighWaterMark2Impl + + PUBWEAK MPU_xTaskGetCurrentTaskHandleImpl +MPU_xTaskGetCurrentTaskHandleImpl: + b MPU_xTaskGetCurrentTaskHandleImpl + + PUBWEAK MPU_xTaskGetSchedulerStateImpl +MPU_xTaskGetSchedulerStateImpl: + b MPU_xTaskGetSchedulerStateImpl + + PUBWEAK MPU_vTaskSetTimeOutStateImpl +MPU_vTaskSetTimeOutStateImpl: + b MPU_vTaskSetTimeOutStateImpl + + PUBWEAK MPU_xTaskCheckForTimeOutImpl +MPU_xTaskCheckForTimeOutImpl: + b MPU_xTaskCheckForTimeOutImpl + + PUBWEAK MPU_xTaskGenericNotifyImpl +MPU_xTaskGenericNotifyImpl: + b MPU_xTaskGenericNotifyImpl + + PUBWEAK MPU_xTaskGenericNotifyWaitImpl +MPU_xTaskGenericNotifyWaitImpl: + b MPU_xTaskGenericNotifyWaitImpl + + PUBWEAK MPU_ulTaskGenericNotifyTakeImpl +MPU_ulTaskGenericNotifyTakeImpl: + b MPU_ulTaskGenericNotifyTakeImpl + + PUBWEAK MPU_xTaskGenericNotifyStateClearImpl +MPU_xTaskGenericNotifyStateClearImpl: + b MPU_xTaskGenericNotifyStateClearImpl + + PUBWEAK MPU_ulTaskGenericNotifyValueClearImpl +MPU_ulTaskGenericNotifyValueClearImpl: + b MPU_ulTaskGenericNotifyValueClearImpl + + PUBWEAK MPU_xQueueGenericSendImpl +MPU_xQueueGenericSendImpl: + b MPU_xQueueGenericSendImpl + + PUBWEAK MPU_uxQueueMessagesWaitingImpl +MPU_uxQueueMessagesWaitingImpl: + b MPU_uxQueueMessagesWaitingImpl + + PUBWEAK MPU_uxQueueSpacesAvailableImpl +MPU_uxQueueSpacesAvailableImpl: + b MPU_uxQueueSpacesAvailableImpl + + PUBWEAK MPU_xQueueReceiveImpl +MPU_xQueueReceiveImpl: + b MPU_xQueueReceiveImpl + + PUBWEAK MPU_xQueuePeekImpl +MPU_xQueuePeekImpl: + b MPU_xQueuePeekImpl + + PUBWEAK MPU_xQueueSemaphoreTakeImpl +MPU_xQueueSemaphoreTakeImpl: + b MPU_xQueueSemaphoreTakeImpl + + PUBWEAK MPU_xQueueGetMutexHolderImpl +MPU_xQueueGetMutexHolderImpl: + b MPU_xQueueGetMutexHolderImpl + + PUBWEAK MPU_xQueueTakeMutexRecursiveImpl +MPU_xQueueTakeMutexRecursiveImpl: + b MPU_xQueueTakeMutexRecursiveImpl + + PUBWEAK MPU_xQueueGiveMutexRecursiveImpl +MPU_xQueueGiveMutexRecursiveImpl: + b MPU_xQueueGiveMutexRecursiveImpl + + PUBWEAK MPU_xQueueSelectFromSetImpl +MPU_xQueueSelectFromSetImpl: + b MPU_xQueueSelectFromSetImpl + + PUBWEAK MPU_xQueueAddToSetImpl +MPU_xQueueAddToSetImpl: + b MPU_xQueueAddToSetImpl + + PUBWEAK MPU_vQueueAddToRegistryImpl +MPU_vQueueAddToRegistryImpl: + b MPU_vQueueAddToRegistryImpl + + PUBWEAK MPU_vQueueUnregisterQueueImpl +MPU_vQueueUnregisterQueueImpl: + b MPU_vQueueUnregisterQueueImpl + + PUBWEAK MPU_pcQueueGetNameImpl +MPU_pcQueueGetNameImpl: + b MPU_pcQueueGetNameImpl + + PUBWEAK MPU_pvTimerGetTimerIDImpl +MPU_pvTimerGetTimerIDImpl: + b MPU_pvTimerGetTimerIDImpl + + PUBWEAK MPU_vTimerSetTimerIDImpl +MPU_vTimerSetTimerIDImpl: + b MPU_vTimerSetTimerIDImpl + + PUBWEAK MPU_xTimerIsTimerActiveImpl +MPU_xTimerIsTimerActiveImpl: + b MPU_xTimerIsTimerActiveImpl + + PUBWEAK MPU_xTimerGetTimerDaemonTaskHandleImpl +MPU_xTimerGetTimerDaemonTaskHandleImpl: + b MPU_xTimerGetTimerDaemonTaskHandleImpl + + PUBWEAK MPU_xTimerGenericCommandImpl +MPU_xTimerGenericCommandImpl: + b MPU_xTimerGenericCommandImpl + + PUBWEAK MPU_pcTimerGetNameImpl +MPU_pcTimerGetNameImpl: + b MPU_pcTimerGetNameImpl + + PUBWEAK MPU_vTimerSetReloadModeImpl +MPU_vTimerSetReloadModeImpl: + b MPU_vTimerSetReloadModeImpl + + PUBWEAK MPU_xTimerGetReloadModeImpl +MPU_xTimerGetReloadModeImpl: + b MPU_xTimerGetReloadModeImpl + + PUBWEAK MPU_uxTimerGetReloadModeImpl +MPU_uxTimerGetReloadModeImpl: + b MPU_uxTimerGetReloadModeImpl + + PUBWEAK MPU_xTimerGetPeriodImpl +MPU_xTimerGetPeriodImpl: + b MPU_xTimerGetPeriodImpl + + PUBWEAK MPU_xTimerGetExpiryTimeImpl +MPU_xTimerGetExpiryTimeImpl: + b MPU_xTimerGetExpiryTimeImpl + + PUBWEAK MPU_xEventGroupWaitBitsImpl +MPU_xEventGroupWaitBitsImpl: + b MPU_xEventGroupWaitBitsImpl + + PUBWEAK MPU_xEventGroupClearBitsImpl +MPU_xEventGroupClearBitsImpl: + b MPU_xEventGroupClearBitsImpl + + PUBWEAK MPU_xEventGroupSetBitsImpl +MPU_xEventGroupSetBitsImpl: + b MPU_xEventGroupSetBitsImpl + + PUBWEAK MPU_xEventGroupSyncImpl +MPU_xEventGroupSyncImpl: + b MPU_xEventGroupSyncImpl + + PUBWEAK MPU_uxEventGroupGetNumberImpl +MPU_uxEventGroupGetNumberImpl: + b MPU_uxEventGroupGetNumberImpl + + PUBWEAK MPU_vEventGroupSetNumberImpl +MPU_vEventGroupSetNumberImpl: + b MPU_vEventGroupSetNumberImpl + + PUBWEAK MPU_xStreamBufferSendImpl +MPU_xStreamBufferSendImpl: + b MPU_xStreamBufferSendImpl + + PUBWEAK MPU_xStreamBufferReceiveImpl +MPU_xStreamBufferReceiveImpl: + b MPU_xStreamBufferReceiveImpl + + PUBWEAK MPU_xStreamBufferIsFullImpl +MPU_xStreamBufferIsFullImpl: + b MPU_xStreamBufferIsFullImpl + + PUBWEAK MPU_xStreamBufferIsEmptyImpl +MPU_xStreamBufferIsEmptyImpl: + b MPU_xStreamBufferIsEmptyImpl + + PUBWEAK MPU_xStreamBufferSpacesAvailableImpl +MPU_xStreamBufferSpacesAvailableImpl: + b MPU_xStreamBufferSpacesAvailableImpl + + PUBWEAK MPU_xStreamBufferBytesAvailableImpl +MPU_xStreamBufferBytesAvailableImpl: + b MPU_xStreamBufferBytesAvailableImpl + + PUBWEAK MPU_xStreamBufferSetTriggerLevelImpl +MPU_xStreamBufferSetTriggerLevelImpl: + b MPU_xStreamBufferSetTriggerLevelImpl + + PUBWEAK MPU_xStreamBufferNextMessageLengthBytesImpl +MPU_xStreamBufferNextMessageLengthBytesImpl: + b MPU_xStreamBufferNextMessageLengthBytesImpl + +/*-----------------------------------------------------------*/ + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + + END diff --git a/portable/IAR/ARM_CM23_NTZ/non_secure/port.c b/portable/IAR/ARM_CM23_NTZ/non_secure/port.c index 7bbe1b7bc53..cab1b3668bf 100644 --- a/portable/IAR/ARM_CM23_NTZ/non_secure/port.c +++ b/portable/IAR/ARM_CM23_NTZ/non_secure/port.c @@ -107,6 +107,13 @@ #define portPRIGROUP_SHIFT ( 8UL ) /*-----------------------------------------------------------*/ +/** + * @brief Constants used during system call enter and exit. + */ +#define portPSR_STACK_PADDING_MASK ( 1UL << 9UL ) +#define portEXC_RETURN_STACK_FRAME_TYPE_MASK ( 1UL << 4UL ) +/*-----------------------------------------------------------*/ + /** * @brief Constants required to manipulate the FPU. */ @@ -123,6 +130,14 @@ #define portFPCCR_LSPEN_MASK ( 1UL << portFPCCR_LSPEN_POS ) /*-----------------------------------------------------------*/ +/** + * @brief Offsets in the stack to the parameters when inside the SVC handler. + */ +#define portOFFSET_TO_LR ( 5 ) +#define portOFFSET_TO_PC ( 6 ) +#define portOFFSET_TO_PSR ( 7 ) +/*-----------------------------------------------------------*/ + /** * @brief Constants required to manipulate the MPU. */ @@ -148,6 +163,8 @@ #define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ #define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ +#define portMPU_RBAR_ACCESS_PERMISSIONS_MASK ( 3UL << 1UL ) + #define portMPU_MAIR_ATTR0_POS ( 0UL ) #define portMPU_MAIR_ATTR0_MASK ( 0x000000ff ) @@ -191,6 +208,30 @@ /* Expected value of the portMPU_TYPE register. */ #define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) + +/* Extract first address of the MPU region as encoded in the + * RBAR (Region Base Address Register) value. */ +#define portEXTRACT_FIRST_ADDRESS_FROM_RBAR( rbar ) \ + ( ( rbar ) & portMPU_RBAR_ADDRESS_MASK ) + +/* Extract last address of the MPU region as encoded in the + * RLAR (Region Limit Address Register) value. */ +#define portEXTRACT_LAST_ADDRESS_FROM_RLAR( rlar ) \ + ( ( ( rlar ) & portMPU_RLAR_ADDRESS_MASK ) | ~portMPU_RLAR_ADDRESS_MASK ) + +/* Does addr lies within [start, end] address range? */ +#define portIS_ADDRESS_WITHIN_RANGE( addr, start, end ) \ + ( ( ( addr ) >= ( start ) ) && ( ( addr ) <= ( end ) ) ) + +/* Is the access request satisfied by the available permissions? */ +#define portIS_AUTHORIZED( accessRequest, permissions ) \ + ( ( ( permissions ) & ( accessRequest ) ) == accessRequest ) + +/* 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 ) ) ) /*-----------------------------------------------------------*/ /** @@ -311,6 +352,19 @@ static void prvTaskExitError( void ); #if ( configENABLE_MPU == 1 ) +/** + * @brief Extract MPU region's access permissions from the Region Base Address + * Register (RBAR) value. + * + * @param ulRBARValue RBAR value for the MPU region. + * + * @return uint32_t Access permissions. + */ + static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) PRIVILEGED_FUNCTION; +#endif /* configENABLE_MPU */ + +#if ( configENABLE_MPU == 1 ) + /** * @brief Setup the Memory Protection Unit (MPU). */ @@ -365,6 +419,60 @@ void SysTick_Handler( void ) PRIVILEGED_FUNCTION; * @brief C part of SVC handler. */ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIVILEGED_FUNCTION; + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + + /** + * @brief Sets up the system call stack so that upon returning from + * SVC, the system call stack is used. + * + * It is used for the system calls with up to 4 parameters. + * + * @param pulTaskStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + */ + void vSystemCallEnter( uint32_t * pulTaskStack, uint32_t ulLR ) PRIVILEGED_FUNCTION; + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + + /** + * @brief Sets up the system call stack so that upon returning from + * SVC, the system call stack is used. + * + * It is used for the system calls with 5 parameters. + * + * @param pulTaskStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + */ + void vSystemCallEnter_1( uint32_t * pulTaskStack, uint32_t ulLR ) PRIVILEGED_FUNCTION; + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + + /** + * @brief Sets up the task stack so that upon returning from + * SVC, the task stack is used again. + * + * @param pulSystemCallStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + */ + void vSystemCallExit( uint32_t * pulSystemCallStack, uint32_t ulLR ) PRIVILEGED_FUNCTION; + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + +#if ( configENABLE_MPU == 1 ) + + /** + * @brief Checks whether or not the calling task is privileged. + * + * @return pdTRUE if the calling task is privileged, pdFALSE otherwise. + */ + BaseType_t xPortIsTaskPrivileged( void ) PRIVILEGED_FUNCTION; + +#endif /* configENABLE_MPU == 1 */ /*-----------------------------------------------------------*/ /** @@ -681,6 +789,26 @@ static void prvTaskExitError( void ) } /*-----------------------------------------------------------*/ +#if ( configENABLE_MPU == 1 ) + static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) /* PRIVILEGED_FUNCTION */ + { + uint32_t ulAccessPermissions = 0; + + if( ( ulRBARValue & portMPU_RBAR_ACCESS_PERMISSIONS_MASK ) == portMPU_REGION_READ_ONLY ) + { + ulAccessPermissions = tskMPU_READ_PERMISSION; + } + + if( ( ulRBARValue & portMPU_RBAR_ACCESS_PERMISSIONS_MASK ) == portMPU_REGION_READ_WRITE ) + { + ulAccessPermissions = ( tskMPU_READ_PERMISSION | tskMPU_WRITE_PERMISSION ); + } + + return ulAccessPermissions; + } +#endif /* configENABLE_MPU */ +/*-----------------------------------------------------------*/ + #if ( configENABLE_MPU == 1 ) static void prvSetupMPU( void ) /* PRIVILEGED_FUNCTION */ { @@ -853,7 +981,7 @@ void SysTick_Handler( void ) /* PRIVILEGED_FUNCTION */ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTION portDONT_DISCARD */ { - #if ( configENABLE_MPU == 1 ) + #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) ) #if defined( __ARMCC_VERSION ) /* Declaration when these variable are defined in code instead of being @@ -865,7 +993,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO extern uint32_t __syscalls_flash_start__[]; extern uint32_t __syscalls_flash_end__[]; #endif /* defined( __ARMCC_VERSION ) */ - #endif /* configENABLE_MPU */ + #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */ uint32_t ulPC; @@ -880,7 +1008,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO /* Register are stored on the stack in the following order - R0, R1, R2, R3, * R12, LR, PC, xPSR. */ - ulPC = pulCallerStackAddress[ 6 ]; + ulPC = pulCallerStackAddress[ portOFFSET_TO_PC ]; ucSVCNumber = ( ( uint8_t * ) ulPC )[ -2 ]; switch( ucSVCNumber ) @@ -951,18 +1079,18 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO vRestoreContextOfFirstTask(); break; - #if ( configENABLE_MPU == 1 ) - case portSVC_RAISE_PRIVILEGE: + #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) ) + case portSVC_RAISE_PRIVILEGE: - /* Only raise the privilege, if the svc was raised from any of - * the system calls. */ - if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) && - ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ) - { - vRaisePrivilege(); - } - break; - #endif /* configENABLE_MPU */ + /* Only raise the privilege, if the svc was raised from any of + * the system calls. */ + if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ) + { + vRaisePrivilege(); + } + break; + #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */ default: /* Incorrect SVC call. */ @@ -971,51 +1099,455 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } /*-----------------------------------------------------------*/ -/* *INDENT-OFF* */ -#if ( configENABLE_MPU == 1 ) - StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, - StackType_t * pxEndOfStack, - TaskFunction_t pxCode, - void * pvParameters, - BaseType_t xRunPrivileged ) /* PRIVILEGED_FUNCTION */ -#else - StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, - StackType_t * pxEndOfStack, - TaskFunction_t pxCode, - void * pvParameters ) /* PRIVILEGED_FUNCTION */ -#endif /* configENABLE_MPU */ -/* *INDENT-ON* */ +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + +void vSystemCallEnter( uint32_t * pulTaskStack, uint32_t ulLR ) /* PRIVILEGED_FUNCTION */ { - /* Simulate the stack frame as it would be created by a context switch - * interrupt. */ - #if ( portPRELOAD_REGISTERS == 0 ) + extern TaskHandle_t pxCurrentTCB; + xMPU_SETTINGS * pxMpuSettings; + uint32_t * pulSystemCallStack; + uint32_t ulStackFrameSize, ulSystemCallLocation, i; + #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being + * exported from linker scripts. */ + extern uint32_t * __syscalls_flash_start__; + extern uint32_t * __syscalls_flash_end__; + #else + /* Declaration when these variable are exported from linker scripts. */ + extern uint32_t __syscalls_flash_start__[]; + extern uint32_t __syscalls_flash_end__[]; + #endif /* #if defined( __ARMCC_VERSION ) */ + + ulSystemCallLocation = pulTaskStack[ portOFFSET_TO_PC ]; + + /* If the request did not come from the system call section, do nothing. */ + if( ( ulSystemCallLocation >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulSystemCallLocation <= ( uint32_t ) __syscalls_flash_end__ ) ) { - pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ - *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ - pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pxCode; /* PC */ - pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR */ - pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ - *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ - pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */ - *pxTopOfStack = portINITIAL_EXC_RETURN; + pxMpuSettings = xTaskGetMPUSettings( pxCurrentTCB ); + pulSystemCallStack = pxMpuSettings->xSystemCallStackInfo.pulSystemCallStack; - #if ( configENABLE_MPU == 1 ) + /* This is not NULL only for the duration of the system call. */ + configASSERT( pxMpuSettings->xSystemCallStackInfo.pulTaskStack == NULL ); + + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) { - pxTopOfStack--; + if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) + { + /* Extended frame i.e. FPU in use. */ + ulStackFrameSize = 26; + __asm volatile ( + " vpush {s0} \n" /* Trigger lazy stacking. */ + " vpop {s0} \n" /* Nullify the affect of the above instruction. */ + ::: "memory" + ); + } + else + { + /* Standard frame i.e. FPU not in use. */ + ulStackFrameSize = 8; + } + } + #else + { + ulStackFrameSize = 8; + } + #endif /* configENABLE_FPU || configENABLE_MVE */ + + /* Make space on the system call stack for the stack frame. */ + pulSystemCallStack = pulSystemCallStack - ulStackFrameSize; + + /* Copy the stack frame. */ + for( i = 0; i < ulStackFrameSize; i++ ) + { + pulSystemCallStack[ i ] = pulTaskStack[ i ]; + } + + /* Store the value of the LR and PSPLIM registers before the SVC was raised. We need to + * restore it when we exit from the system call. */ + pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; + __asm volatile ( "mrs %0, psplim" : "=r" ( pxMpuSettings->xSystemCallStackInfo.ulStackLimitRegisterAtSystemCallEntry ) ); + + /* Use the pulSystemCallStack in thread mode. */ + __asm volatile ( "msr psp, %0" : : "r" ( pulSystemCallStack ) ); + __asm volatile ( "msr psplim, %0" : : "r" ( pxMpuSettings->xSystemCallStackInfo.pulSystemCallStackLimit ) ); + + /* Remember the location where we should copy the stack frame when we exit from + * the system call. */ + pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulStackFrameSize; + + /* Record if the hardware used padding to force the stack pointer + * to be double word aligned. */ + if( ( pulTaskStack[ portOFFSET_TO_PSR ] & portPSR_STACK_PADDING_MASK ) == portPSR_STACK_PADDING_MASK ) + { + pxMpuSettings->ulTaskFlags |= portSTACK_FRAME_HAS_PADDING_FLAG; + } + else + { + pxMpuSettings->ulTaskFlags &= ( ~portSTACK_FRAME_HAS_PADDING_FLAG ); + } + + /* We ensure in pxPortInitialiseStack that the system call stack is + * double word aligned and therefore, there is no need of padding. + * Clear the bit[9] of stacked xPSR. */ + pulSystemCallStack[ portOFFSET_TO_PSR ] &= ( ~portPSR_STACK_PADDING_MASK ); + + /* Raise the privilege for the duration of the system call. */ + __asm volatile ( + " mrs r0, control \n" /* Obtain current control value. */ + " movs r1, #1 \n" /* r1 = 1. */ + " bics r0, r1 \n" /* Clear nPRIV bit. */ + " msr control, r0 \n" /* Write back new control value. */ + ::: "r0", "r1", "memory" + ); + } +} - if( xRunPrivileged == pdTRUE ) +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + +void vSystemCallEnter_1( uint32_t * pulTaskStack, uint32_t ulLR ) /* PRIVILEGED_FUNCTION */ +{ + extern TaskHandle_t pxCurrentTCB; + xMPU_SETTINGS * pxMpuSettings; + uint32_t * pulSystemCallStack; + uint32_t ulStackFrameSize, ulSystemCallLocation, i; + #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being + * exported from linker scripts. */ + extern uint32_t * __syscalls_flash_start__; + extern uint32_t * __syscalls_flash_end__; + #else + /* Declaration when these variable are exported from linker scripts. */ + extern uint32_t __syscalls_flash_start__[]; + extern uint32_t __syscalls_flash_end__[]; + #endif /* #if defined( __ARMCC_VERSION ) */ + + ulSystemCallLocation = pulTaskStack[ portOFFSET_TO_PC ]; + + /* If the request did not come from the system call section, do nothing. */ + if( ( ulSystemCallLocation >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulSystemCallLocation <= ( uint32_t ) __syscalls_flash_end__ ) ) + { + pxMpuSettings = xTaskGetMPUSettings( pxCurrentTCB ); + pulSystemCallStack = pxMpuSettings->xSystemCallStackInfo.pulSystemCallStack; + + /* This is not NULL only for the duration of the system call. */ + configASSERT( pxMpuSettings->xSystemCallStackInfo.pulTaskStack == NULL ); + + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + { + if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) { - *pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */ + /* Extended frame i.e. FPU in use. */ + ulStackFrameSize = 26; + __asm volatile ( + " vpush {s0} \n" /* Trigger lazy stacking. */ + " vpop {s0} \n" /* Nullify the affect of the above instruction. */ + ::: "memory" + ); } else { - *pxTopOfStack = portINITIAL_CONTROL_UNPRIVILEGED; /* Slot used to hold this task's CONTROL value. */ + /* Standard frame i.e. FPU not in use. */ + ulStackFrameSize = 8; } } - #endif /* configENABLE_MPU */ + #else + { + ulStackFrameSize = 8; + } + #endif /* configENABLE_FPU || configENABLE_MVE */ + + /* Make space on the system call stack for the stack frame and + * the parameter passed on the stack. We only need to copy one + * parameter but we still reserve 2 spaces to keep the stack + * double word aligned. */ + pulSystemCallStack = pulSystemCallStack - ulStackFrameSize - 2UL; + + /* Copy the stack frame. */ + for( i = 0; i < ulStackFrameSize; i++ ) + { + pulSystemCallStack[ i ] = pulTaskStack[ i ]; + } + + /* Copy the parameter which is passed the stack. */ + if( ( pulTaskStack[ portOFFSET_TO_PSR ] & portPSR_STACK_PADDING_MASK ) == portPSR_STACK_PADDING_MASK ) + { + pulSystemCallStack[ ulStackFrameSize ] = pulTaskStack[ ulStackFrameSize + 1 ]; + /* Record if the hardware used padding to force the stack pointer + * to be double word aligned. */ + pxMpuSettings->ulTaskFlags |= portSTACK_FRAME_HAS_PADDING_FLAG; + } + else + { + pulSystemCallStack[ ulStackFrameSize ] = pulTaskStack[ ulStackFrameSize ]; + /* Record if the hardware used padding to force the stack pointer + * to be double word aligned. */ + pxMpuSettings->ulTaskFlags &= ( ~portSTACK_FRAME_HAS_PADDING_FLAG ); + } + + /* Store the value of the LR and PSPLIM registers before the SVC was raised. + * We need to restore it when we exit from the system call. */ + pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; + __asm volatile ( "mrs %0, psplim" : "=r" ( pxMpuSettings->xSystemCallStackInfo.ulStackLimitRegisterAtSystemCallEntry ) ); + + /* Use the pulSystemCallStack in thread mode. */ + __asm volatile ( "msr psp, %0" : : "r" ( pulSystemCallStack ) ); + __asm volatile ( "msr psplim, %0" : : "r" ( pxMpuSettings->xSystemCallStackInfo.pulSystemCallStackLimit ) ); + + /* Remember the location where we should copy the stack frame when we exit from + * the system call. */ + pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulStackFrameSize; + + /* We ensure in pxPortInitialiseStack that the system call stack is + * double word aligned and therefore, there is no need of padding. + * Clear the bit[9] of stacked xPSR. */ + pulSystemCallStack[ portOFFSET_TO_PSR ] &= ( ~portPSR_STACK_PADDING_MASK ); + + /* Raise the privilege for the duration of the system call. */ + __asm volatile ( + " mrs r0, control \n" /* Obtain current control value. */ + " movs r1, #1 \n" /* r1 = 1. */ + " bics r0, r1 \n" /* Clear nPRIV bit. */ + " msr control, r0 \n" /* Write back new control value. */ + ::: "r0", "r1", "memory" + ); + } +} + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) +void vSystemCallExit( uint32_t * pulSystemCallStack, uint32_t ulLR ) /* PRIVILEGED_FUNCTION */ +{ + extern TaskHandle_t pxCurrentTCB; + xMPU_SETTINGS * pxMpuSettings; + uint32_t * pulTaskStack; + uint32_t ulStackFrameSize, ulSystemCallLocation, i; + #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being + * exported from linker scripts. */ + extern uint32_t * __syscalls_flash_start__; + extern uint32_t * __syscalls_flash_end__; + #else + /* Declaration when these variable are exported from linker scripts. */ + extern uint32_t __syscalls_flash_start__[]; + extern uint32_t __syscalls_flash_end__[]; + #endif /* #if defined( __ARMCC_VERSION ) */ + + ulSystemCallLocation = pulSystemCallStack[ portOFFSET_TO_PC ]; + + /* If the request did not come from the system call section, do nothing. */ + if( ( ulSystemCallLocation >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulSystemCallLocation <= ( uint32_t ) __syscalls_flash_end__ ) ) + { + pxMpuSettings = xTaskGetMPUSettings( pxCurrentTCB ); + pulTaskStack = pxMpuSettings->xSystemCallStackInfo.pulTaskStack; + + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + { + if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) + { + /* Extended frame i.e. FPU in use. */ + ulStackFrameSize = 26; + __asm volatile ( + " vpush {s0} \n" /* Trigger lazy stacking. */ + " vpop {s0} \n" /* Nullify the affect of the above instruction. */ + ::: "memory" + ); + } + else + { + /* Standard frame i.e. FPU not in use. */ + ulStackFrameSize = 8; + } + } + #else + { + ulStackFrameSize = 8; + } + #endif /* configENABLE_FPU || configENABLE_MVE */ + + /* Make space on the task stack for the stack frame. */ + pulTaskStack = pulTaskStack - ulStackFrameSize; + + /* Copy the stack frame. */ + for( i = 0; i < ulStackFrameSize; i++ ) + { + pulTaskStack[ i ] = pulSystemCallStack[ i ]; + } + + /* Use the pulTaskStack in thread mode. */ + __asm volatile ( "msr psp, %0" : : "r" ( pulTaskStack ) ); + + /* Restore the LR and PSPLIM to what they were at the time of + * system call entry. */ + pulTaskStack[ portOFFSET_TO_LR ] = pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry; + __asm volatile ( "msr psplim, %0" : : "r" ( pxMpuSettings->xSystemCallStackInfo.ulStackLimitRegisterAtSystemCallEntry ) ); + + /* If the hardware used padding to force the stack pointer + * to be double word aligned, set the stacked xPSR bit[9], + * otherwise clear it. */ + if( ( pxMpuSettings->ulTaskFlags & portSTACK_FRAME_HAS_PADDING_FLAG ) == portSTACK_FRAME_HAS_PADDING_FLAG ) + { + pulTaskStack[ portOFFSET_TO_PSR ] |= portPSR_STACK_PADDING_MASK; + } + else + { + pulTaskStack[ portOFFSET_TO_PSR ] &= ( ~portPSR_STACK_PADDING_MASK ); + } + + /* This is not NULL only for the duration of the system call. */ + pxMpuSettings->xSystemCallStackInfo.pulTaskStack = NULL; + + /* Drop the privilege before returning to the thread mode. */ + __asm volatile ( + " mrs r0, control \n" /* Obtain current control value. */ + " movs r1, #1 \n" /* r1 = 1. */ + " orrs r0, r1 \n" /* Set nPRIV bit. */ + " msr control, r0 \n" /* Write back new control value. */ + ::: "r0", "r1", "memory" + ); + } +} + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configENABLE_MPU == 1 ) + +BaseType_t xPortIsTaskPrivileged( void ) /* PRIVILEGED_FUNCTION */ +{ + BaseType_t xTaskIsPrivileged = pdFALSE; + const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */ + + if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) + { + xTaskIsPrivileged = pdTRUE; + } + + return xTaskIsPrivileged; +} + +#endif /* configENABLE_MPU == 1 */ +/*-----------------------------------------------------------*/ + +#if( configENABLE_MPU == 1 ) + +StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, + StackType_t * pxEndOfStack, + TaskFunction_t pxCode, + void * pvParameters, + BaseType_t xRunPrivileged, + xMPU_SETTINGS * xMPUSettings ) /* PRIVILEGED_FUNCTION */ +{ + uint32_t ulIndex = 0; + + xMPUSettings->ulContext[ ulIndex ] = 0x04040404; /* r4. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x05050505; /* r5. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x06060606; /* r6. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x07070707; /* r7. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x08080808; /* r8. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x09090909; /* r9. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x10101010; /* r10. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x11111111; /* r11. */ + ulIndex++; + + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pvParameters; /* r0. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x01010101; /* r1. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x02020202; /* r2. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x03030303; /* r3. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x12121212; /* r12. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portTASK_RETURN_ADDRESS; /* LR. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxCode; /* PC. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = portINITIAL_XPSR; /* xPSR. */ + ulIndex++; + + #if ( configENABLE_TRUSTZONE == 1 ) + { + xMPUSettings->ulContext[ ulIndex ] = portNO_SECURE_CONTEXT; /* xSecureContext. */ + ulIndex++; + } + #endif /* configENABLE_TRUSTZONE */ + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) ( pxTopOfStack - 8 ); /* PSP with the hardware saved stack. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */ + ulIndex++; + if( xRunPrivileged == pdTRUE ) + { + xMPUSettings->ulTaskFlags |= portTASK_IS_PRIVILEGED_FLAG; + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_PRIVILEGED; /* CONTROL. */ + ulIndex++; + } + else + { + xMPUSettings->ulTaskFlags &= ( ~portTASK_IS_PRIVILEGED_FLAG ); + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_UNPRIVILEGED; /* CONTROL. */ + ulIndex++; + } + xMPUSettings->ulContext[ ulIndex ] = portINITIAL_EXC_RETURN; /* LR (EXC_RETURN). */ + ulIndex++; + + #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + { + /* Ensure that the system call stack is double word aligned. */ + xMPUSettings->xSystemCallStackInfo.pulSystemCallStack = &( xMPUSettings->xSystemCallStackInfo.ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE - 1 ] ); + xMPUSettings->xSystemCallStackInfo.pulSystemCallStack = ( uint32_t * ) ( ( uint32_t ) ( xMPUSettings->xSystemCallStackInfo.pulSystemCallStack ) & + ( uint32_t ) ( ~( portBYTE_ALIGNMENT_MASK ) ) ); + + xMPUSettings->xSystemCallStackInfo.pulSystemCallStackLimit = &( xMPUSettings->xSystemCallStackInfo.ulSystemCallStackBuffer[ 0 ] ); + xMPUSettings->xSystemCallStackInfo.pulSystemCallStackLimit = ( uint32_t * ) ( ( ( uint32_t ) ( xMPUSettings->xSystemCallStackInfo.pulSystemCallStackLimit ) + + ( uint32_t ) ( portBYTE_ALIGNMENT - 1 ) ) & + ( uint32_t ) ( ~( portBYTE_ALIGNMENT_MASK ) ) ); + + /* This is not NULL only for the duration of a system call. */ + xMPUSettings->xSystemCallStackInfo.pulTaskStack = NULL; + } + #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + + return &( xMPUSettings->ulContext[ ulIndex ] ); +} + +#else /* configENABLE_MPU */ + +StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, + StackType_t * pxEndOfStack, + TaskFunction_t pxCode, + void * pvParameters ) /* PRIVILEGED_FUNCTION */ +{ + /* Simulate the stack frame as it would be created by a context switch + * interrupt. */ + #if ( portPRELOAD_REGISTERS == 0 ) + { + pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ + *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR. */ + pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ + pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */ + *pxTopOfStack = portINITIAL_EXC_RETURN; pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ @@ -1029,55 +1561,39 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO #else /* portPRELOAD_REGISTERS */ { pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ - *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ + *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pxCode; /* PC */ + *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR */ + *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x12121212UL; /* R12 */ + *pxTopOfStack = ( StackType_t ) 0x12121212UL; /* R12. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x03030303UL; /* R3 */ + *pxTopOfStack = ( StackType_t ) 0x03030303UL; /* R3. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x02020202UL; /* R2 */ + *pxTopOfStack = ( StackType_t ) 0x02020202UL; /* R2. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x01010101UL; /* R1 */ + *pxTopOfStack = ( StackType_t ) 0x01010101UL; /* R1. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x11111111UL; /* R11 */ + *pxTopOfStack = ( StackType_t ) 0x11111111UL; /* R11. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x10101010UL; /* R10 */ + *pxTopOfStack = ( StackType_t ) 0x10101010UL; /* R10. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x09090909UL; /* R09 */ + *pxTopOfStack = ( StackType_t ) 0x09090909UL; /* R09. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x08080808UL; /* R08 */ + *pxTopOfStack = ( StackType_t ) 0x08080808UL; /* R08. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x07070707UL; /* R07 */ + *pxTopOfStack = ( StackType_t ) 0x07070707UL; /* R07. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x06060606UL; /* R06 */ + *pxTopOfStack = ( StackType_t ) 0x06060606UL; /* R06. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x05050505UL; /* R05 */ + *pxTopOfStack = ( StackType_t ) 0x05050505UL; /* R05. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x04040404UL; /* R04 */ + *pxTopOfStack = ( StackType_t ) 0x04040404UL; /* R04. */ pxTopOfStack--; - *pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN */ - - #if ( configENABLE_MPU == 1 ) - { - pxTopOfStack--; - - if( xRunPrivileged == pdTRUE ) - { - *pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */ - } - else - { - *pxTopOfStack = portINITIAL_CONTROL_UNPRIVILEGED; /* Slot used to hold this task's CONTROL value. */ - } - } - #endif /* configENABLE_MPU */ - + *pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN. */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ @@ -1092,6 +1608,8 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO return pxTopOfStack; } + +#endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ @@ -1128,6 +1646,10 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ configASSERT( ucMaxSysCallPriority ); + /* Check that the bits not implemented in hardware are zero in + * configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & ( ~ucMaxPriorityValue ) ) == 0U ); + /* Calculate the maximum acceptable priority group value for the number * of bits read back. */ @@ -1164,35 +1686,6 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulImplementedPrioBits; } - /* The interrupt priority bits are not modelled in QEMU and the assert that - * checks the number of implemented bits and __NVIC_PRIO_BITS will always fail. - * Therefore, this assert is not adding any value for QEMU targets. The config - * option `configDISABLE_INTERRUPT_PRIO_BITS_CHECK` should be defined in the - * `FreeRTOSConfig.h` for QEMU targets. */ - #ifndef configDISABLE_INTERRUPT_PRIO_BITS_CHECK - { - #ifdef __NVIC_PRIO_BITS - { - /* - * Check that the number of implemented priority bits queried from - * hardware is equal to the CMSIS __NVIC_PRIO_BITS configuration macro. - */ - configASSERT( ulImplementedPrioBits == __NVIC_PRIO_BITS ); - } - #endif /* __NVIC_PRIO_BITS */ - - #ifdef configPRIO_BITS - { - /* - * Check that the number of implemented priority bits queried from - * hardware is equal to the FreeRTOS configPRIO_BITS configuration macro. - */ - configASSERT( ulImplementedPrioBits == configPRIO_BITS ); - } - #endif /* configPRIO_BITS */ - } - #endif /* #ifndef configDISABLE_INTERRUPT_PRIO_BITS_CHECK */ - /* Shift the priority group value back to its position within the AIRCR * register. */ ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT; @@ -1372,6 +1865,54 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ +#if ( configENABLE_MPU == 1 ) + BaseType_t xPortIsAuthorizedToAccessBuffer( const void * pvBuffer, + uint32_t ulBufferLength, + uint32_t ulAccessRequested ) /* PRIVILEGED_FUNCTION */ + + { + uint32_t i, ulBufferStartAddress, ulBufferEndAddress; + BaseType_t xAccessGranted = pdFALSE; + const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */ + + if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) + { + xAccessGranted = pdTRUE; + } + else + { + if( portADD_UINT32_WILL_OVERFLOW( ( ( uint32_t ) pvBuffer ), ( ulBufferLength - 1UL ) ) == pdFALSE ) + { + ulBufferStartAddress = ( uint32_t ) pvBuffer; + ulBufferEndAddress = ( ( ( uint32_t ) pvBuffer ) + ulBufferLength - 1UL ); + + for( i = 0; i < portTOTAL_NUM_REGIONS; i++ ) + { + /* Is the MPU region enabled? */ + if( ( xTaskMpuSettings->xRegionsSettings[ i ].ulRLAR & portMPU_RLAR_REGION_ENABLE ) == portMPU_RLAR_REGION_ENABLE ) + { + if( portIS_ADDRESS_WITHIN_RANGE( ulBufferStartAddress, + portEXTRACT_FIRST_ADDRESS_FROM_RBAR( xTaskMpuSettings->xRegionsSettings[ i ].ulRBAR ), + portEXTRACT_LAST_ADDRESS_FROM_RLAR( xTaskMpuSettings->xRegionsSettings[ i ].ulRLAR ) ) && + portIS_ADDRESS_WITHIN_RANGE( ulBufferEndAddress, + portEXTRACT_FIRST_ADDRESS_FROM_RBAR( xTaskMpuSettings->xRegionsSettings[ i ].ulRBAR ), + portEXTRACT_LAST_ADDRESS_FROM_RLAR( xTaskMpuSettings->xRegionsSettings[ i ].ulRLAR ) ) && + portIS_AUTHORIZED( ulAccessRequested, + prvGetRegionAccessPermissions( xTaskMpuSettings->xRegionsSettings[ i ].ulRBAR ) ) ) + { + xAccessGranted = pdTRUE; + break; + } + } + } + } + } + + return xAccessGranted; + } +#endif /* configENABLE_MPU */ +/*-----------------------------------------------------------*/ + BaseType_t xPortIsInsideInterrupt( void ) { uint32_t ulCurrentInterrupt; diff --git a/portable/IAR/ARM_CM23_NTZ/non_secure/portasm.s b/portable/IAR/ARM_CM23_NTZ/non_secure/portasm.s index 62bd3872284..8f77c4dafb1 100644 --- a/portable/IAR/ARM_CM23_NTZ/non_secure/portasm.s +++ b/portable/IAR/ARM_CM23_NTZ/non_secure/portasm.s @@ -32,9 +32,18 @@ the code is included in C files but excluded by the preprocessor in assembly files (__ICCARM__ is defined by the IAR C compiler but not by the IAR assembler. */ #include "FreeRTOSConfig.h" +#ifndef configUSE_MPU_WRAPPERS_V1 + #define configUSE_MPU_WRAPPERS_V1 0 +#endif + EXTERN pxCurrentTCB EXTERN vTaskSwitchContext EXTERN vPortSVCHandler_C +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + EXTERN vSystemCallEnter + EXTERN vSystemCallEnter_1 + EXTERN vSystemCallExit +#endif PUBLIC xIsPrivileged PUBLIC vResetPrivilege @@ -88,63 +97,97 @@ vResetPrivilege: THUMB /*-----------------------------------------------------------*/ +#if ( configENABLE_MPU == 1 ) + +vRestoreContextOfFirstTask: + program_mpu_first_task: + ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + ldr r0, [r3] /* r0 = pxCurrentTCB.*/ + + dmb /* Complete outstanding transfers before disabling MPU. */ + ldr r1, =0xe000ed94 /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + ldr r2, [r1] /* Read the value of MPU_CTRL. */ + movs r3, #1 /* r3 = 1. */ + bics r2, r3 /* r2 = r2 & ~r3 i.e. Clear the bit 0 in r2. */ + str r2, [r1] /* Disable MPU. */ + + adds r0, #4 /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */ + ldr r1, [r0] /* r1 = *r0 i.e. r1 = MAIR0. */ + ldr r2, =0xe000edc0 /* r2 = 0xe000edc0 [Location of MAIR0]. */ + str r1, [r2] /* Program MAIR0. */ + + adds r0, #4 /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */ + ldr r1, =0xe000ed98 /* r1 = 0xe000ed98 [Location of RNR]. */ + + movs r3, #4 /* r3 = 4. */ + str r3, [r1] /* Program RNR = 4. */ + ldmia r0!, {r4-r5} /* Read first set of RBAR/RLAR registers from TCB. */ + ldr r2, =0xe000ed9c /* r2 = 0xe000ed9c [Location of RBAR]. */ + stmia r2!, {r4-r5} /* Write first set of RBAR/RLAR registers. */ + movs r3, #5 /* r3 = 5. */ + str r3, [r1] /* Program RNR = 5. */ + ldmia r0!, {r4-r5} /* Read second set of RBAR/RLAR registers from TCB. */ + ldr r2, =0xe000ed9c /* r2 = 0xe000ed9c [Location of RBAR]. */ + stmia r2!, {r4-r5} /* Write second set of RBAR/RLAR registers. */ + movs r3, #6 /* r3 = 6. */ + str r3, [r1] /* Program RNR = 6. */ + ldmia r0!, {r4-r5} /* Read third set of RBAR/RLAR registers from TCB. */ + ldr r2, =0xe000ed9c /* r2 = 0xe000ed9c [Location of RBAR]. */ + stmia r2!, {r4-r5} /* Write third set of RBAR/RLAR registers. */ + movs r3, #7 /* r3 = 6. */ + str r3, [r1] /* Program RNR = 7. */ + ldmia r0!, {r4-r5} /* Read fourth set of RBAR/RLAR registers from TCB. */ + ldr r2, =0xe000ed9c /* r2 = 0xe000ed9c [Location of RBAR]. */ + stmia r2!, {r4-r5} /* Write fourth set of RBAR/RLAR registers. */ + + ldr r1, =0xe000ed94 /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + ldr r2, [r1] /* Read the value of MPU_CTRL. */ + movs r3, #1 /* r3 = 1. */ + orrs r2, r3 /* r2 = r2 | r3 i.e. Set the bit 0 in r2. */ + str r2, [r1] /* Enable MPU. */ + dsb /* Force memory writes before continuing. */ + + restore_context_first_task: + ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + ldr r0, [r2] /* r0 = pxCurrentTCB.*/ + ldr r1, [r0] /* r1 = Location of saved context in TCB. */ + + restore_special_regs_first_task: + subs r1, #16 + ldmia r1!, {r2-r5} /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, r5 = LR. */ + subs r1, #16 + msr psp, r2 + msr psplim, r3 + msr control, r4 + mov lr, r5 + + restore_general_regs_first_task: + subs r1, #32 + ldmia r1!, {r4-r7} /* r4-r7 contain half of the hardware saved context. */ + stmia r2!, {r4-r7} /* Copy half of the the hardware saved context on the task stack. */ + ldmia r1!, {r4-r7} /* r4-r7 contain rest half of the hardware saved context. */ + stmia r2!, {r4-r7} /* Copy rest half of the the hardware saved context on the task stack. */ + subs r1, #48 + ldmia r1!, {r4-r7} /* Restore r8-r11. */ + mov r8, r4 /* r8 = r4. */ + mov r9, r5 /* r9 = r5. */ + mov r10, r6 /* r10 = r6. */ + mov r11, r7 /* r11 = r7. */ + subs r1, #32 + ldmia r1!, {r4-r7} /* Restore r4-r7. */ + subs r1, #16 + + restore_context_done_first_task: + str r1, [r0] /* Save the location where the context should be saved next as the first member of TCB. */ + bx lr + +#else /* configENABLE_MPU */ + vRestoreContextOfFirstTask: ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r2] /* Read pxCurrentTCB. */ ldr r0, [r1] /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ -#if ( configENABLE_MPU == 1 ) - dmb /* Complete outstanding transfers before disabling MPU. */ - ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ - ldr r3, [r2] /* Read the value of MPU_CTRL. */ - movs r4, #1 /* r4 = 1. */ - bics r3, r4 /* r3 = r3 & ~r4 i.e. Clear the bit 0 in r3. */ - str r3, [r2] /* Disable MPU. */ - - adds r1, #4 /* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */ - ldr r4, [r1] /* r4 = *r1 i.e. r4 = MAIR0. */ - ldr r2, =0xe000edc0 /* r2 = 0xe000edc0 [Location of MAIR0]. */ - str r4, [r2] /* Program MAIR0. */ - ldr r2, =0xe000ed98 /* r2 = 0xe000ed98 [Location of RNR]. */ - adds r1, #4 /* r1 = r1 + 4. r1 now points to first RBAR in TCB. */ - movs r4, #4 /* r4 = 4. */ - str r4, [r2] /* Program RNR = 4. */ - ldmia r1!, {r5,r6} /* Read first set of RBAR/RLAR from TCB. */ - ldr r3, =0xe000ed9c /* r3 = 0xe000ed9c [Location of RBAR]. */ - stmia r3!, {r5,r6} /* Write first set of RBAR/RLAR registers. */ - movs r4, #5 /* r4 = 5. */ - str r4, [r2] /* Program RNR = 5. */ - ldmia r1!, {r5,r6} /* Read second set of RBAR/RLAR from TCB. */ - ldr r3, =0xe000ed9c /* r3 = 0xe000ed9c [Location of RBAR]. */ - stmia r3!, {r5,r6} /* Write second set of RBAR/RLAR registers. */ - movs r4, #6 /* r4 = 6. */ - str r4, [r2] /* Program RNR = 6. */ - ldmia r1!, {r5,r6} /* Read third set of RBAR/RLAR from TCB. */ - ldr r3, =0xe000ed9c /* r3 = 0xe000ed9c [Location of RBAR]. */ - stmia r3!, {r5,r6} /* Write third set of RBAR/RLAR registers. */ - movs r4, #7 /* r4 = 7. */ - str r4, [r2] /* Program RNR = 7. */ - ldmia r1!, {r5,r6} /* Read fourth set of RBAR/RLAR from TCB. */ - ldr r3, =0xe000ed9c /* r3 = 0xe000ed9c [Location of RBAR]. */ - stmia r3!, {r5,r6} /* Write fourth set of RBAR/RLAR registers. */ - - ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ - ldr r3, [r2] /* Read the value of MPU_CTRL. */ - movs r4, #1 /* r4 = 1. */ - orrs r3, r4 /* r3 = r3 | r4 i.e. Set the bit 0 in r3. */ - str r3, [r2] /* Enable MPU. */ - dsb /* Force memory writes before continuing. */ -#endif /* configENABLE_MPU */ - -#if ( configENABLE_MPU == 1 ) - ldm r0!, {r1-r3} /* Read from stack - r1 = PSPLIM, r2 = CONTROL and r3 = EXC_RETURN. */ - msr psplim, r1 /* Set this task's PSPLIM value. */ - msr control, r2 /* Set this task's CONTROL value. */ - adds r0, #32 /* Discard everything up to r0. */ - msr psp, r0 /* This is now the new top of stack to use in the task. */ - isb - bx r3 /* Finally, branch to EXC_RETURN. */ -#else /* configENABLE_MPU */ ldm r0!, {r1-r2} /* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */ msr psplim, r1 /* Set this task's PSPLIM value. */ movs r1, #2 /* r1 = 2. */ @@ -153,6 +196,7 @@ vRestoreContextOfFirstTask: msr psp, r0 /* This is now the new top of stack to use in the task. */ isb bx r2 /* Finally, branch to EXC_RETURN. */ + #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ @@ -187,23 +231,127 @@ vClearInterruptMask: bx lr /*-----------------------------------------------------------*/ +#if ( configENABLE_MPU == 1 ) + +PendSV_Handler: + ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + ldr r0, [r2] /* r0 = pxCurrentTCB. */ + ldr r1, [r0] /* r1 = Location in TCB where the context should be saved. */ + mrs r2, psp /* r2 = PSP. */ + + save_general_regs: + stmia r1!, {r4-r7} /* Store r4-r7. */ + mov r4, r8 /* r4 = r8. */ + mov r5, r9 /* r5 = r9. */ + mov r6, r10 /* r6 = r10. */ + mov r7, r11 /* r7 = r11. */ + stmia r1!, {r4-r7} /* Store r8-r11. */ + ldmia r2!, {r4-r7} /* Copy half of the hardware saved context into r4-r7. */ + stmia r1!, {r4-r7} /* Store the hardware saved context. */ + ldmia r2!, {r4-r7} /* Copy rest half of the hardware saved context into r4-r7. */ + stmia r1!, {r4-r7} /* Store the hardware saved context. */ + + save_special_regs: + mrs r2, psp /* r2 = PSP. */ + mrs r3, psplim /* r3 = PSPLIM. */ + mrs r4, control /* r4 = CONTROL. */ + mov r5, lr /* r5 = LR. */ + stmia r1!, {r2-r5} /* Store original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */ + str r1, [r0] /* Save the location from where the context should be restored as the first member of TCB. */ + + select_next_task: + cpsid i + bl vTaskSwitchContext + cpsie i + + program_mpu: + ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + ldr r0, [r3] /* r0 = pxCurrentTCB.*/ + + dmb /* Complete outstanding transfers before disabling MPU. */ + ldr r1, =0xe000ed94 /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + ldr r2, [r1] /* Read the value of MPU_CTRL. */ + movs r3, #1 /* r3 = 1. */ + bics r2, r3 /* r2 = r2 & ~r3 i.e. Clear the bit 0 in r2. */ + str r2, [r1] /* Disable MPU. */ + + adds r0, #4 /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */ + ldr r1, [r0] /* r1 = *r0 i.e. r1 = MAIR0. */ + ldr r2, =0xe000edc0 /* r2 = 0xe000edc0 [Location of MAIR0]. */ + str r1, [r2] /* Program MAIR0. */ + + adds r0, #4 /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */ + ldr r1, =0xe000ed98 /* r1 = 0xe000ed98 [Location of RNR]. */ + + movs r3, #4 /* r3 = 4. */ + str r3, [r1] /* Program RNR = 4. */ + ldmia r0!, {r4-r5} /* Read first set of RBAR/RLAR registers from TCB. */ + ldr r2, =0xe000ed9c /* r2 = 0xe000ed9c [Location of RBAR]. */ + stmia r2!, {r4-r5} /* Write first set of RBAR/RLAR registers. */ + movs r3, #5 /* r3 = 5. */ + str r3, [r1] /* Program RNR = 5. */ + ldmia r0!, {r4-r5} /* Read second set of RBAR/RLAR registers from TCB. */ + ldr r2, =0xe000ed9c /* r2 = 0xe000ed9c [Location of RBAR]. */ + stmia r2!, {r4-r5} /* Write second set of RBAR/RLAR registers. */ + movs r3, #6 /* r3 = 6. */ + str r3, [r1] /* Program RNR = 6. */ + ldmia r0!, {r4-r5} /* Read third set of RBAR/RLAR registers from TCB. */ + ldr r2, =0xe000ed9c /* r2 = 0xe000ed9c [Location of RBAR]. */ + stmia r2!, {r4-r5} /* Write third set of RBAR/RLAR registers. */ + movs r3, #7 /* r3 = 6. */ + str r3, [r1] /* Program RNR = 7. */ + ldmia r0!, {r4-r5} /* Read fourth set of RBAR/RLAR registers from TCB. */ + ldr r2, =0xe000ed9c /* r2 = 0xe000ed9c [Location of RBAR]. */ + stmia r2!, {r4-r5} /* Write fourth set of RBAR/RLAR registers. */ + + ldr r1, =0xe000ed94 /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + ldr r2, [r1] /* Read the value of MPU_CTRL. */ + movs r3, #1 /* r3 = 1. */ + orrs r2, r3 /* r2 = r2 | r3 i.e. Set the bit 0 in r2. */ + str r2, [r1] /* Enable MPU. */ + dsb /* Force memory writes before continuing. */ + + restore_context: + ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + ldr r0, [r2] /* r0 = pxCurrentTCB.*/ + ldr r1, [r0] /* r1 = Location of saved context in TCB. */ + + restore_special_regs: + subs r1, #16 + ldmia r1!, {r2-r5} /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, r5 = LR. */ + subs r1, #16 + msr psp, r2 + msr psplim, r3 + msr control, r4 + mov lr, r5 + + restore_general_regs: + subs r1, #32 + ldmia r1!, {r4-r7} /* r4-r7 contain half of the hardware saved context. */ + stmia r2!, {r4-r7} /* Copy half of the the hardware saved context on the task stack. */ + ldmia r1!, {r4-r7} /* r4-r7 contain rest half of the hardware saved context. */ + stmia r2!, {r4-r7} /* Copy rest half of the the hardware saved context on the task stack. */ + subs r1, #48 + ldmia r1!, {r4-r7} /* Restore r8-r11. */ + mov r8, r4 /* r8 = r4. */ + mov r9, r5 /* r9 = r5. */ + mov r10, r6 /* r10 = r6. */ + mov r11, r7 /* r11 = r7. */ + subs r1, #32 + ldmia r1!, {r4-r7} /* Restore r4-r7. */ + subs r1, #16 + + restore_context_done: + str r1, [r0] /* Save the location where the context should be saved next as the first member of TCB. */ + bx lr + +#else /* configENABLE_MPU */ + PendSV_Handler: mrs r0, psp /* Read PSP in r0. */ ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r2] /* Read pxCurrentTCB. */ -#if ( configENABLE_MPU == 1 ) - subs r0, r0, #44 /* Make space for PSPLIM, CONTROL, LR and the remaining registers on the stack. */ - str r0, [r1] /* Save the new top of stack in TCB. */ - mrs r1, psplim /* r1 = PSPLIM. */ - mrs r2, control /* r2 = CONTROL. */ - mov r3, lr /* r3 = LR/EXC_RETURN. */ - stmia r0!, {r1-r7} /* Store on the stack - PSPLIM, CONTROL, LR and low registers that are not automatically saved. */ - mov r4, r8 /* r4 = r8. */ - mov r5, r9 /* r5 = r9. */ - mov r6, r10 /* r6 = r10. */ - mov r7, r11 /* r7 = r11. */ - stmia r0!, {r4-r7} /* Store the high registers that are not saved automatically. */ -#else /* configENABLE_MPU */ + subs r0, r0, #40 /* Make space for PSPLIM, LR and the remaining registers on the stack. */ str r0, [r1] /* Save the new top of stack in TCB. */ mrs r2, psplim /* r2 = PSPLIM. */ @@ -214,7 +362,6 @@ PendSV_Handler: mov r6, r10 /* r6 = r10. */ mov r7, r11 /* r7 = r11. */ stmia r0!, {r4-r7} /* Store the high registers that are not saved automatically. */ -#endif /* configENABLE_MPU */ cpsid i bl vTaskSwitchContext @@ -224,63 +371,6 @@ PendSV_Handler: ldr r1, [r2] /* Read pxCurrentTCB. */ ldr r0, [r1] /* The first item in pxCurrentTCB is the task top of stack. r0 now points to the top of stack. */ -#if ( configENABLE_MPU == 1 ) - dmb /* Complete outstanding transfers before disabling MPU. */ - ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ - ldr r3, [r2] /* Read the value of MPU_CTRL. */ - movs r4, #1 /* r4 = 1. */ - bics r3, r4 /* r3 = r3 & ~r4 i.e. Clear the bit 0 in r3. */ - str r3, [r2] /* Disable MPU. */ - - adds r1, #4 /* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */ - ldr r4, [r1] /* r4 = *r1 i.e. r4 = MAIR0. */ - ldr r2, =0xe000edc0 /* r2 = 0xe000edc0 [Location of MAIR0]. */ - str r4, [r2] /* Program MAIR0. */ - ldr r2, =0xe000ed98 /* r2 = 0xe000ed98 [Location of RNR]. */ - adds r1, #4 /* r1 = r1 + 4. r1 now points to first RBAR in TCB. */ - movs r4, #4 /* r4 = 4. */ - str r4, [r2] /* Program RNR = 4. */ - ldmia r1!, {r5,r6} /* Read first set of RBAR/RLAR from TCB. */ - ldr r3, =0xe000ed9c /* r3 = 0xe000ed9c [Location of RBAR]. */ - stmia r3!, {r5,r6} /* Write first set of RBAR/RLAR registers. */ - movs r4, #5 /* r4 = 5. */ - str r4, [r2] /* Program RNR = 5. */ - ldmia r1!, {r5,r6} /* Read second set of RBAR/RLAR from TCB. */ - ldr r3, =0xe000ed9c /* r3 = 0xe000ed9c [Location of RBAR]. */ - stmia r3!, {r5,r6} /* Write second set of RBAR/RLAR registers. */ - movs r4, #6 /* r4 = 6. */ - str r4, [r2] /* Program RNR = 6. */ - ldmia r1!, {r5,r6} /* Read third set of RBAR/RLAR from TCB. */ - ldr r3, =0xe000ed9c /* r3 = 0xe000ed9c [Location of RBAR]. */ - stmia r3!, {r5,r6} /* Write third set of RBAR/RLAR registers. */ - movs r4, #7 /* r4 = 7. */ - str r4, [r2] /* Program RNR = 7. */ - ldmia r1!, {r5,r6} /* Read fourth set of RBAR/RLAR from TCB. */ - ldr r3, =0xe000ed9c /* r3 = 0xe000ed9c [Location of RBAR]. */ - stmia r3!, {r5,r6} /* Write fourth set of RBAR/RLAR registers. */ - - ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ - ldr r3, [r2] /* Read the value of MPU_CTRL. */ - movs r4, #1 /* r4 = 1. */ - orrs r3, r4 /* r3 = r3 | r4 i.e. Set the bit 0 in r3. */ - str r3, [r2] /* Enable MPU. */ - dsb /* Force memory writes before continuing. */ -#endif /* configENABLE_MPU */ - -#if ( configENABLE_MPU == 1 ) - adds r0, r0, #28 /* Move to the high registers. */ - ldmia r0!, {r4-r7} /* Restore the high registers that are not automatically restored. */ - mov r8, r4 /* r8 = r4. */ - mov r9, r5 /* r9 = r5. */ - mov r10, r6 /* r10 = r6. */ - mov r11, r7 /* r11 = r7. */ - msr psp, r0 /* Remember the new top of stack for the task. */ - subs r0, r0, #44 /* Move to the starting of the saved context. */ - ldmia r0!, {r1-r7} /* Read from stack - r1 = PSPLIM, r2 = CONTROL, r3 = LR and r4-r7 restored. */ - msr psplim, r1 /* Restore the PSPLIM register value for the task. */ - msr control, r2 /* Restore the CONTROL register value for the task. */ - bx r3 -#else /* configENABLE_MPU */ adds r0, r0, #24 /* Move to the high registers. */ ldmia r0!, {r4-r7} /* Restore the high registers that are not automatically restored. */ mov r8, r4 /* r8 = r4. */ @@ -292,9 +382,45 @@ PendSV_Handler: ldmia r0!, {r2-r7} /* Read from stack - r2 = PSPLIM, r3 = LR and r4-r7 restored. */ msr psplim, r2 /* Restore the PSPLIM register value for the task. */ bx r3 + #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + +SVC_Handler: + movs r0, #4 + mov r1, lr + tst r0, r1 + beq stack_on_msp + stack_on_psp: + mrs r0, psp + b route_svc + stack_on_msp: + mrs r0, msp + b route_svc + + route_svc: + ldr r2, [r0, #24] + subs r2, #2 + ldrb r3, [r2, #0] + cmp r3, #4 /* portSVC_SYSTEM_CALL_ENTER. */ + beq system_call_enter + cmp r3, #5 /* portSVC_SYSTEM_CALL_ENTER_1. */ + beq system_call_enter_1 + cmp r3, #6 /* portSVC_SYSTEM_CALL_EXIT. */ + beq system_call_exit + b vPortSVCHandler_C + + system_call_enter: + b vSystemCallEnter + system_call_enter_1: + b vSystemCallEnter_1 + system_call_exit: + b vSystemCallExit + +#else /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + SVC_Handler: movs r0, #4 mov r1, lr @@ -305,6 +431,8 @@ SVC_Handler: stacking_used_msp: mrs r0, msp b vPortSVCHandler_C + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ /*-----------------------------------------------------------*/ END diff --git a/portable/IAR/ARM_CM23_NTZ/non_secure/portmacrocommon.h b/portable/IAR/ARM_CM23_NTZ/non_secure/portmacrocommon.h index c2ca5fa7730..65ac109c802 100644 --- a/portable/IAR/ARM_CM23_NTZ/non_secure/portmacrocommon.h +++ b/portable/IAR/ARM_CM23_NTZ/non_secure/portmacrocommon.h @@ -186,23 +186,120 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #define portMPU_REGION_EXECUTE_NEVER ( 1UL ) /*-----------------------------------------------------------*/ -/** - * @brief Settings to define an MPU region. - */ -typedef struct MPURegionSettings -{ - uint32_t ulRBAR; /**< RBAR for the region. */ - uint32_t ulRLAR; /**< RLAR for the region. */ -} MPURegionSettings_t; +#if ( configENABLE_MPU == 1 ) -/** - * @brief MPU settings as stored in the TCB. - */ -typedef struct MPU_SETTINGS -{ - uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ - MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */ -} xMPU_SETTINGS; + /** + * @brief Settings to define an MPU region. + */ + typedef struct MPURegionSettings + { + uint32_t ulRBAR; /**< RBAR for the region. */ + uint32_t ulRLAR; /**< RLAR for the region. */ + } MPURegionSettings_t; + + #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + + #ifndef configSYSTEM_CALL_STACK_SIZE + #error configSYSTEM_CALL_STACK_SIZE must be defined to the desired size of the system call stack in words for using MPU wrappers v2. + #endif + + /** + * @brief System call stack. + */ + typedef struct SYSTEM_CALL_STACK_INFO + { + uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ]; + uint32_t * pulSystemCallStack; + uint32_t * pulSystemCallStackLimit; + uint32_t * pulTaskStack; + uint32_t ulLinkRegisterAtSystemCallEntry; + uint32_t ulStackLimitRegisterAtSystemCallEntry; + } xSYSTEM_CALL_STACK_INFO; + + #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + + /** + * @brief MPU settings as stored in the TCB. + */ + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + + #if( configENABLE_TRUSTZONE == 1 ) + + /* + * +-----------+---------------+----------+-----------------+------------------------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | + * | | | | PC, xPSR | CONTROL, EXC_RETURN | | + * +-----------+---------------+----------+-----------------+------------------------------+-----+ + * + * <-----------><--------------><---------><----------------><-----------------------------><----> + * 16 16 8 8 5 1 + */ + #define MAX_CONTEXT_SIZE 54 + + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ + + /* + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | + * | | | | PC, xPSR | EXC_RETURN | | + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * + * <-----------><--------------><---------><----------------><---------------------><----> + * 16 16 8 8 4 1 + */ + #define MAX_CONTEXT_SIZE 53 + + #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + + #else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ + + #if( configENABLE_TRUSTZONE == 1 ) + + /* + * +----------+-----------------+------------------------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | + * | | PC, xPSR | CONTROL, EXC_RETURN | | + * +----------+-----------------+------------------------------+-----+ + * + * <---------><----------------><------------------------------><----> + * 8 8 5 1 + */ + #define MAX_CONTEXT_SIZE 22 + + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ + + /* + * +----------+-----------------+----------------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | + * | | PC, xPSR | EXC_RETURN | | + * +----------+-----------------+----------------------+-----+ + * + * <---------><----------------><----------------------><----> + * 8 8 4 1 + */ + #define MAX_CONTEXT_SIZE 21 + + #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + + #endif /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ + + /* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ + #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) + #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) + + typedef struct MPU_SETTINGS + { + uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ + MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */ + uint32_t ulContext[ MAX_CONTEXT_SIZE ]; + uint32_t ulTaskFlags; + + #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo; + #endif + } xMPU_SETTINGS; + +#endif /* configENABLE_MPU == 1 */ /*-----------------------------------------------------------*/ /** @@ -223,6 +320,9 @@ typedef struct MPU_SETTINGS #define portSVC_FREE_SECURE_CONTEXT 1 #define portSVC_START_SCHEDULER 2 #define portSVC_RAISE_PRIVILEGE 3 +#define portSVC_SYSTEM_CALL_ENTER 4 /* System calls with upto 4 parameters. */ +#define portSVC_SYSTEM_CALL_ENTER_1 5 /* System calls with 5 parameters. */ +#define portSVC_SYSTEM_CALL_EXIT 6 /*-----------------------------------------------------------*/ /** @@ -315,6 +415,20 @@ typedef struct MPU_SETTINGS #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ +#if ( configENABLE_MPU == 1 ) + + extern BaseType_t xPortIsTaskPrivileged( void ); + + /** + * @brief Checks whether or not the calling task is privileged. + * + * @return pdTRUE if the calling task is privileged, pdFALSE otherwise. + */ + #define portIS_TASK_PRIVILEGED() xPortIsTaskPrivileged() + +#endif /* configENABLE_MPU == 1 */ +/*-----------------------------------------------------------*/ + /** * @brief Barriers. */ diff --git a/portable/IAR/ARM_CM3/port.c b/portable/IAR/ARM_CM3/port.c index d54c3aceb4a..1e3a3ded0df 100755 --- a/portable/IAR/ARM_CM3/port.c +++ b/portable/IAR/ARM_CM3/port.c @@ -241,6 +241,10 @@ BaseType_t xPortStartScheduler( void ) * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ configASSERT( ucMaxSysCallPriority ); + /* Check that the bits not implemented in hardware are zero in + * configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & ( ~ucMaxPriorityValue ) ) == 0U ); + /* Calculate the maximum acceptable priority group value for the number * of bits read back. */ @@ -277,28 +281,6 @@ BaseType_t xPortStartScheduler( void ) ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulImplementedPrioBits; } - #ifdef __NVIC_PRIO_BITS - { - /* - * Check that the number of implemented priority bits queried from - * hardware is at least as many as specified in the CMSIS - * __NVIC_PRIO_BITS configuration macro. - */ - configASSERT( ulImplementedPrioBits >= __NVIC_PRIO_BITS ); - } - #endif - - #ifdef configPRIO_BITS - { - /* - * Check that the number of implemented priority bits queried from - * hardware is at least as many as specified in the FreeRTOS - * configPRIO_BITS configuration macro. - */ - configASSERT( ulImplementedPrioBits >= configPRIO_BITS ); - } - #endif - /* Shift the priority group value back to its position within the AIRCR * register. */ ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT; diff --git a/portable/IAR/ARM_CM33/non_secure/mpu_wrappers_v2_asm.S b/portable/IAR/ARM_CM33/non_secure/mpu_wrappers_v2_asm.S new file mode 100644 index 00000000000..f051a6073dd --- /dev/null +++ b/portable/IAR/ARM_CM33/non_secure/mpu_wrappers_v2_asm.S @@ -0,0 +1,1552 @@ +/* + * FreeRTOS Kernel + * Copyright (C) 2021 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 + * + */ + + + SECTION freertos_system_calls:CODE:NOROOT(2) + THUMB +/*-----------------------------------------------------------*/ + +#include "FreeRTOSConfig.h" + +#ifndef configUSE_MPU_WRAPPERS_V1 + #define configUSE_MPU_WRAPPERS_V1 0 +#endif + +/* These must be in sync with portmacro.h. */ +#define portSVC_SYSTEM_CALL_ENTER 4 /* System calls with upto 4 parameters. */ +#define portSVC_SYSTEM_CALL_ENTER_1 5 /* System calls with 5 parameters. */ +#define portSVC_SYSTEM_CALL_EXIT 6 +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + + PUBLIC MPU_xTaskDelayUntil +MPU_xTaskDelayUntil: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskDelayUntil_Unpriv + MPU_xTaskDelayUntil_Priv: + pop {r0} + b MPU_xTaskDelayUntilImpl + MPU_xTaskDelayUntil_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskDelayUntilImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskAbortDelay +MPU_xTaskAbortDelay: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskAbortDelay_Unpriv + MPU_xTaskAbortDelay_Priv: + pop {r0} + b MPU_xTaskAbortDelayImpl + MPU_xTaskAbortDelay_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskAbortDelayImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTaskDelay +MPU_vTaskDelay: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vTaskDelay_Unpriv + MPU_vTaskDelay_Priv: + pop {r0} + b MPU_vTaskDelayImpl + MPU_vTaskDelay_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskDelayImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxTaskPriorityGet +MPU_uxTaskPriorityGet: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_uxTaskPriorityGet_Unpriv + MPU_uxTaskPriorityGet_Priv: + pop {r0} + b MPU_uxTaskPriorityGetImpl + MPU_uxTaskPriorityGet_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxTaskPriorityGetImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_eTaskGetState +MPU_eTaskGetState: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_eTaskGetState_Unpriv + MPU_eTaskGetState_Priv: + pop {r0} + b MPU_eTaskGetStateImpl + MPU_eTaskGetState_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_eTaskGetStateImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTaskGetInfo +MPU_vTaskGetInfo: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vTaskGetInfo_Unpriv + MPU_vTaskGetInfo_Priv: + pop {r0} + b MPU_vTaskGetInfoImpl + MPU_vTaskGetInfo_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskGetInfoImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGetIdleTaskHandle +MPU_xTaskGetIdleTaskHandle: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskGetIdleTaskHandle_Unpriv + MPU_xTaskGetIdleTaskHandle_Priv: + pop {r0} + b MPU_xTaskGetIdleTaskHandleImpl + MPU_xTaskGetIdleTaskHandle_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskGetIdleTaskHandleImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTaskSuspend +MPU_vTaskSuspend: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vTaskSuspend_Unpriv + MPU_vTaskSuspend_Priv: + pop {r0} + b MPU_vTaskSuspendImpl + MPU_vTaskSuspend_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskSuspendImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTaskResume +MPU_vTaskResume: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vTaskResume_Unpriv + MPU_vTaskResume_Priv: + pop {r0} + b MPU_vTaskResumeImpl + MPU_vTaskResume_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskResumeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGetTickCount +MPU_xTaskGetTickCount: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskGetTickCount_Unpriv + MPU_xTaskGetTickCount_Priv: + pop {r0} + b MPU_xTaskGetTickCountImpl + MPU_xTaskGetTickCount_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskGetTickCountImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxTaskGetNumberOfTasks +MPU_uxTaskGetNumberOfTasks: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_uxTaskGetNumberOfTasks_Unpriv + MPU_uxTaskGetNumberOfTasks_Priv: + pop {r0} + b MPU_uxTaskGetNumberOfTasksImpl + MPU_uxTaskGetNumberOfTasks_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxTaskGetNumberOfTasksImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_pcTaskGetName +MPU_pcTaskGetName: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_pcTaskGetName_Unpriv + MPU_pcTaskGetName_Priv: + pop {r0} + b MPU_pcTaskGetNameImpl + MPU_pcTaskGetName_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_pcTaskGetNameImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_ulTaskGetRunTimeCounter +MPU_ulTaskGetRunTimeCounter: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_ulTaskGetRunTimeCounter_Unpriv + MPU_ulTaskGetRunTimeCounter_Priv: + pop {r0} + b MPU_ulTaskGetRunTimeCounterImpl + MPU_ulTaskGetRunTimeCounter_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_ulTaskGetRunTimeCounterImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_ulTaskGetRunTimePercent +MPU_ulTaskGetRunTimePercent: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_ulTaskGetRunTimePercent_Unpriv + MPU_ulTaskGetRunTimePercent_Priv: + pop {r0} + b MPU_ulTaskGetRunTimePercentImpl + MPU_ulTaskGetRunTimePercent_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_ulTaskGetRunTimePercentImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_ulTaskGetIdleRunTimePercent +MPU_ulTaskGetIdleRunTimePercent: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_ulTaskGetIdleRunTimePercent_Unpriv + MPU_ulTaskGetIdleRunTimePercent_Priv: + pop {r0} + b MPU_ulTaskGetIdleRunTimePercentImpl + MPU_ulTaskGetIdleRunTimePercent_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_ulTaskGetIdleRunTimePercentImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_ulTaskGetIdleRunTimeCounter +MPU_ulTaskGetIdleRunTimeCounter: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_ulTaskGetIdleRunTimeCounter_Unpriv + MPU_ulTaskGetIdleRunTimeCounter_Priv: + pop {r0} + b MPU_ulTaskGetIdleRunTimeCounterImpl + MPU_ulTaskGetIdleRunTimeCounter_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_ulTaskGetIdleRunTimeCounterImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTaskSetApplicationTaskTag +MPU_vTaskSetApplicationTaskTag: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vTaskSetApplicationTaskTag_Unpriv + MPU_vTaskSetApplicationTaskTag_Priv: + pop {r0} + b MPU_vTaskSetApplicationTaskTagImpl + MPU_vTaskSetApplicationTaskTag_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskSetApplicationTaskTagImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGetApplicationTaskTag +MPU_xTaskGetApplicationTaskTag: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskGetApplicationTaskTag_Unpriv + MPU_xTaskGetApplicationTaskTag_Priv: + pop {r0} + b MPU_xTaskGetApplicationTaskTagImpl + MPU_xTaskGetApplicationTaskTag_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskGetApplicationTaskTagImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTaskSetThreadLocalStoragePointer +MPU_vTaskSetThreadLocalStoragePointer: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vTaskSetThreadLocalStoragePointer_Unpriv + MPU_vTaskSetThreadLocalStoragePointer_Priv: + pop {r0} + b MPU_vTaskSetThreadLocalStoragePointerImpl + MPU_vTaskSetThreadLocalStoragePointer_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskSetThreadLocalStoragePointerImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_pvTaskGetThreadLocalStoragePointer +MPU_pvTaskGetThreadLocalStoragePointer: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_pvTaskGetThreadLocalStoragePointer_Unpriv + MPU_pvTaskGetThreadLocalStoragePointer_Priv: + pop {r0} + b MPU_pvTaskGetThreadLocalStoragePointerImpl + MPU_pvTaskGetThreadLocalStoragePointer_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_pvTaskGetThreadLocalStoragePointerImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxTaskGetSystemState +MPU_uxTaskGetSystemState: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_uxTaskGetSystemState_Unpriv + MPU_uxTaskGetSystemState_Priv: + pop {r0} + b MPU_uxTaskGetSystemStateImpl + MPU_uxTaskGetSystemState_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxTaskGetSystemStateImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxTaskGetStackHighWaterMark +MPU_uxTaskGetStackHighWaterMark: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_uxTaskGetStackHighWaterMark_Unpriv + MPU_uxTaskGetStackHighWaterMark_Priv: + pop {r0} + b MPU_uxTaskGetStackHighWaterMarkImpl + MPU_uxTaskGetStackHighWaterMark_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxTaskGetStackHighWaterMarkImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxTaskGetStackHighWaterMark2 +MPU_uxTaskGetStackHighWaterMark2: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_uxTaskGetStackHighWaterMark2_Unpriv + MPU_uxTaskGetStackHighWaterMark2_Priv: + pop {r0} + b MPU_uxTaskGetStackHighWaterMark2Impl + MPU_uxTaskGetStackHighWaterMark2_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxTaskGetStackHighWaterMark2Impl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGetCurrentTaskHandle +MPU_xTaskGetCurrentTaskHandle: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskGetCurrentTaskHandle_Unpriv + MPU_xTaskGetCurrentTaskHandle_Priv: + pop {r0} + b MPU_xTaskGetCurrentTaskHandleImpl + MPU_xTaskGetCurrentTaskHandle_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskGetCurrentTaskHandleImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGetSchedulerState +MPU_xTaskGetSchedulerState: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskGetSchedulerState_Unpriv + MPU_xTaskGetSchedulerState_Priv: + pop {r0} + b MPU_xTaskGetSchedulerStateImpl + MPU_xTaskGetSchedulerState_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskGetSchedulerStateImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTaskSetTimeOutState +MPU_vTaskSetTimeOutState: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vTaskSetTimeOutState_Unpriv + MPU_vTaskSetTimeOutState_Priv: + pop {r0} + b MPU_vTaskSetTimeOutStateImpl + MPU_vTaskSetTimeOutState_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskSetTimeOutStateImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskCheckForTimeOut +MPU_xTaskCheckForTimeOut: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskCheckForTimeOut_Unpriv + MPU_xTaskCheckForTimeOut_Priv: + pop {r0} + b MPU_xTaskCheckForTimeOutImpl + MPU_xTaskCheckForTimeOut_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskCheckForTimeOutImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGenericNotify +MPU_xTaskGenericNotify: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskGenericNotify_Unpriv + MPU_xTaskGenericNotify_Priv: + pop {r0} + b MPU_xTaskGenericNotifyImpl + MPU_xTaskGenericNotify_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER_1 + bl MPU_xTaskGenericNotifyImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGenericNotifyWait +MPU_xTaskGenericNotifyWait: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskGenericNotifyWait_Unpriv + MPU_xTaskGenericNotifyWait_Priv: + pop {r0} + b MPU_xTaskGenericNotifyWaitImpl + MPU_xTaskGenericNotifyWait_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER_1 + bl MPU_xTaskGenericNotifyWaitImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_ulTaskGenericNotifyTake +MPU_ulTaskGenericNotifyTake: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_ulTaskGenericNotifyTake_Unpriv + MPU_ulTaskGenericNotifyTake_Priv: + pop {r0} + b MPU_ulTaskGenericNotifyTakeImpl + MPU_ulTaskGenericNotifyTake_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_ulTaskGenericNotifyTakeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGenericNotifyStateClear +MPU_xTaskGenericNotifyStateClear: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskGenericNotifyStateClear_Unpriv + MPU_xTaskGenericNotifyStateClear_Priv: + pop {r0} + b MPU_xTaskGenericNotifyStateClearImpl + MPU_xTaskGenericNotifyStateClear_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskGenericNotifyStateClearImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_ulTaskGenericNotifyValueClear +MPU_ulTaskGenericNotifyValueClear: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_ulTaskGenericNotifyValueClear_Unpriv + MPU_ulTaskGenericNotifyValueClear_Priv: + pop {r0} + b MPU_ulTaskGenericNotifyValueClearImpl + MPU_ulTaskGenericNotifyValueClear_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_ulTaskGenericNotifyValueClearImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueGenericSend +MPU_xQueueGenericSend: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xQueueGenericSend_Unpriv + MPU_xQueueGenericSend_Priv: + pop {r0} + b MPU_xQueueGenericSendImpl + MPU_xQueueGenericSend_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueGenericSendImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxQueueMessagesWaiting +MPU_uxQueueMessagesWaiting: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_uxQueueMessagesWaiting_Unpriv + MPU_uxQueueMessagesWaiting_Priv: + pop {r0} + b MPU_uxQueueMessagesWaitingImpl + MPU_uxQueueMessagesWaiting_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxQueueMessagesWaitingImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxQueueSpacesAvailable +MPU_uxQueueSpacesAvailable: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_uxQueueSpacesAvailable_Unpriv + MPU_uxQueueSpacesAvailable_Priv: + pop {r0} + b MPU_uxQueueSpacesAvailableImpl + MPU_uxQueueSpacesAvailable_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxQueueSpacesAvailableImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueReceive +MPU_xQueueReceive: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xQueueReceive_Unpriv + MPU_xQueueReceive_Priv: + pop {r0} + b MPU_xQueueReceiveImpl + MPU_xQueueReceive_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueReceiveImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueuePeek +MPU_xQueuePeek: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xQueuePeek_Unpriv + MPU_xQueuePeek_Priv: + pop {r0} + b MPU_xQueuePeekImpl + MPU_xQueuePeek_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueuePeekImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueSemaphoreTake +MPU_xQueueSemaphoreTake: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xQueueSemaphoreTake_Unpriv + MPU_xQueueSemaphoreTake_Priv: + pop {r0} + b MPU_xQueueSemaphoreTakeImpl + MPU_xQueueSemaphoreTake_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueSemaphoreTakeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueGetMutexHolder +MPU_xQueueGetMutexHolder: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xQueueGetMutexHolder_Unpriv + MPU_xQueueGetMutexHolder_Priv: + pop {r0} + b MPU_xQueueGetMutexHolderImpl + MPU_xQueueGetMutexHolder_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueGetMutexHolderImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueTakeMutexRecursive +MPU_xQueueTakeMutexRecursive: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xQueueTakeMutexRecursive_Unpriv + MPU_xQueueTakeMutexRecursive_Priv: + pop {r0} + b MPU_xQueueTakeMutexRecursiveImpl + MPU_xQueueTakeMutexRecursive_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueTakeMutexRecursiveImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueGiveMutexRecursive +MPU_xQueueGiveMutexRecursive: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xQueueGiveMutexRecursive_Unpriv + MPU_xQueueGiveMutexRecursive_Priv: + pop {r0} + b MPU_xQueueGiveMutexRecursiveImpl + MPU_xQueueGiveMutexRecursive_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueGiveMutexRecursiveImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueSelectFromSet +MPU_xQueueSelectFromSet: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xQueueSelectFromSet_Unpriv + MPU_xQueueSelectFromSet_Priv: + pop {r0} + b MPU_xQueueSelectFromSetImpl + MPU_xQueueSelectFromSet_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueSelectFromSetImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueAddToSet +MPU_xQueueAddToSet: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xQueueAddToSet_Unpriv + MPU_xQueueAddToSet_Priv: + pop {r0} + b MPU_xQueueAddToSetImpl + MPU_xQueueAddToSet_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueAddToSetImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vQueueAddToRegistry +MPU_vQueueAddToRegistry: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vQueueAddToRegistry_Unpriv + MPU_vQueueAddToRegistry_Priv: + pop {r0} + b MPU_vQueueAddToRegistryImpl + MPU_vQueueAddToRegistry_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vQueueAddToRegistryImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vQueueUnregisterQueue +MPU_vQueueUnregisterQueue: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vQueueUnregisterQueue_Unpriv + MPU_vQueueUnregisterQueue_Priv: + pop {r0} + b MPU_vQueueUnregisterQueueImpl + MPU_vQueueUnregisterQueue_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vQueueUnregisterQueueImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_pcQueueGetName +MPU_pcQueueGetName: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_pcQueueGetName_Unpriv + MPU_pcQueueGetName_Priv: + pop {r0} + b MPU_pcQueueGetNameImpl + MPU_pcQueueGetName_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_pcQueueGetNameImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_pvTimerGetTimerID +MPU_pvTimerGetTimerID: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_pvTimerGetTimerID_Unpriv + MPU_pvTimerGetTimerID_Priv: + pop {r0} + b MPU_pvTimerGetTimerIDImpl + MPU_pvTimerGetTimerID_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_pvTimerGetTimerIDImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTimerSetTimerID +MPU_vTimerSetTimerID: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vTimerSetTimerID_Unpriv + MPU_vTimerSetTimerID_Priv: + pop {r0} + b MPU_vTimerSetTimerIDImpl + MPU_vTimerSetTimerID_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTimerSetTimerIDImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTimerIsTimerActive +MPU_xTimerIsTimerActive: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTimerIsTimerActive_Unpriv + MPU_xTimerIsTimerActive_Priv: + pop {r0} + b MPU_xTimerIsTimerActiveImpl + MPU_xTimerIsTimerActive_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTimerIsTimerActiveImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTimerGetTimerDaemonTaskHandle +MPU_xTimerGetTimerDaemonTaskHandle: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTimerGetTimerDaemonTaskHandle_Unpriv + MPU_xTimerGetTimerDaemonTaskHandle_Priv: + pop {r0} + b MPU_xTimerGetTimerDaemonTaskHandleImpl + MPU_xTimerGetTimerDaemonTaskHandle_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTimerGetTimerDaemonTaskHandleImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTimerGenericCommand +MPU_xTimerGenericCommand: + push {r0} + /* This function can be called from ISR also and therefore, we need a check + * to take privileged path, if called from ISR. */ + mrs r0, ipsr + cmp r0, #0 + bne MPU_xTimerGenericCommand_Priv + mrs r0, control + tst r0, #1 + beq MPU_xTimerGenericCommand_Priv + MPU_xTimerGenericCommand_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER_1 + bl MPU_xTimerGenericCommandImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr + MPU_xTimerGenericCommand_Priv: + pop {r0} + b MPU_xTimerGenericCommandImpl + +/*-----------------------------------------------------------*/ + + PUBLIC MPU_pcTimerGetName +MPU_pcTimerGetName: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_pcTimerGetName_Unpriv + MPU_pcTimerGetName_Priv: + pop {r0} + b MPU_pcTimerGetNameImpl + MPU_pcTimerGetName_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_pcTimerGetNameImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTimerSetReloadMode +MPU_vTimerSetReloadMode: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vTimerSetReloadMode_Unpriv + MPU_vTimerSetReloadMode_Priv: + pop {r0} + b MPU_vTimerSetReloadModeImpl + MPU_vTimerSetReloadMode_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTimerSetReloadModeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTimerGetReloadMode +MPU_xTimerGetReloadMode: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTimerGetReloadMode_Unpriv + MPU_xTimerGetReloadMode_Priv: + pop {r0} + b MPU_xTimerGetReloadModeImpl + MPU_xTimerGetReloadMode_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTimerGetReloadModeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxTimerGetReloadMode +MPU_uxTimerGetReloadMode: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_uxTimerGetReloadMode_Unpriv + MPU_uxTimerGetReloadMode_Priv: + pop {r0} + b MPU_uxTimerGetReloadModeImpl + MPU_uxTimerGetReloadMode_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxTimerGetReloadModeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTimerGetPeriod +MPU_xTimerGetPeriod: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTimerGetPeriod_Unpriv + MPU_xTimerGetPeriod_Priv: + pop {r0} + b MPU_xTimerGetPeriodImpl + MPU_xTimerGetPeriod_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTimerGetPeriodImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTimerGetExpiryTime +MPU_xTimerGetExpiryTime: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTimerGetExpiryTime_Unpriv + MPU_xTimerGetExpiryTime_Priv: + pop {r0} + b MPU_xTimerGetExpiryTimeImpl + MPU_xTimerGetExpiryTime_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTimerGetExpiryTimeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xEventGroupWaitBits +MPU_xEventGroupWaitBits: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xEventGroupWaitBits_Unpriv + MPU_xEventGroupWaitBits_Priv: + pop {r0} + b MPU_xEventGroupWaitBitsImpl + MPU_xEventGroupWaitBits_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER_1 + bl MPU_xEventGroupWaitBitsImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xEventGroupClearBits +MPU_xEventGroupClearBits: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xEventGroupClearBits_Unpriv + MPU_xEventGroupClearBits_Priv: + pop {r0} + b MPU_xEventGroupClearBitsImpl + MPU_xEventGroupClearBits_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xEventGroupClearBitsImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xEventGroupSetBits +MPU_xEventGroupSetBits: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xEventGroupSetBits_Unpriv + MPU_xEventGroupSetBits_Priv: + pop {r0} + b MPU_xEventGroupSetBitsImpl + MPU_xEventGroupSetBits_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xEventGroupSetBitsImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xEventGroupSync +MPU_xEventGroupSync: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xEventGroupSync_Unpriv + MPU_xEventGroupSync_Priv: + pop {r0} + b MPU_xEventGroupSyncImpl + MPU_xEventGroupSync_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xEventGroupSyncImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxEventGroupGetNumber +MPU_uxEventGroupGetNumber: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_uxEventGroupGetNumber_Unpriv + MPU_uxEventGroupGetNumber_Priv: + pop {r0} + b MPU_uxEventGroupGetNumberImpl + MPU_uxEventGroupGetNumber_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxEventGroupGetNumberImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vEventGroupSetNumber +MPU_vEventGroupSetNumber: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vEventGroupSetNumber_Unpriv + MPU_vEventGroupSetNumber_Priv: + pop {r0} + b MPU_vEventGroupSetNumberImpl + MPU_vEventGroupSetNumber_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vEventGroupSetNumberImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferSend +MPU_xStreamBufferSend: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xStreamBufferSend_Unpriv + MPU_xStreamBufferSend_Priv: + pop {r0} + b MPU_xStreamBufferSendImpl + MPU_xStreamBufferSend_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferSendImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferReceive +MPU_xStreamBufferReceive: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xStreamBufferReceive_Unpriv + MPU_xStreamBufferReceive_Priv: + pop {r0} + b MPU_xStreamBufferReceiveImpl + MPU_xStreamBufferReceive_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferReceiveImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferIsFull +MPU_xStreamBufferIsFull: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xStreamBufferIsFull_Unpriv + MPU_xStreamBufferIsFull_Priv: + pop {r0} + b MPU_xStreamBufferIsFullImpl + MPU_xStreamBufferIsFull_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferIsFullImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferIsEmpty +MPU_xStreamBufferIsEmpty: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xStreamBufferIsEmpty_Unpriv + MPU_xStreamBufferIsEmpty_Priv: + pop {r0} + b MPU_xStreamBufferIsEmptyImpl + MPU_xStreamBufferIsEmpty_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferIsEmptyImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferSpacesAvailable +MPU_xStreamBufferSpacesAvailable: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xStreamBufferSpacesAvailable_Unpriv + MPU_xStreamBufferSpacesAvailable_Priv: + pop {r0} + b MPU_xStreamBufferSpacesAvailableImpl + MPU_xStreamBufferSpacesAvailable_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferSpacesAvailableImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferBytesAvailable +MPU_xStreamBufferBytesAvailable: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xStreamBufferBytesAvailable_Unpriv + MPU_xStreamBufferBytesAvailable_Priv: + pop {r0} + b MPU_xStreamBufferBytesAvailableImpl + MPU_xStreamBufferBytesAvailable_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferBytesAvailableImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferSetTriggerLevel +MPU_xStreamBufferSetTriggerLevel: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xStreamBufferSetTriggerLevel_Unpriv + MPU_xStreamBufferSetTriggerLevel_Priv: + pop {r0} + b MPU_xStreamBufferSetTriggerLevelImpl + MPU_xStreamBufferSetTriggerLevel_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferSetTriggerLevelImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferNextMessageLengthBytes +MPU_xStreamBufferNextMessageLengthBytes: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xStreamBufferNextMessageLengthBytes_Unpriv + MPU_xStreamBufferNextMessageLengthBytes_Priv: + pop {r0} + b MPU_xStreamBufferNextMessageLengthBytesImpl + MPU_xStreamBufferNextMessageLengthBytes_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferNextMessageLengthBytesImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + +/* Default weak implementations in case one is not available from + * mpu_wrappers because of config options. */ + + PUBWEAK MPU_xTaskDelayUntilImpl +MPU_xTaskDelayUntilImpl: + b MPU_xTaskDelayUntilImpl + + PUBWEAK MPU_xTaskAbortDelayImpl +MPU_xTaskAbortDelayImpl: + b MPU_xTaskAbortDelayImpl + + PUBWEAK MPU_vTaskDelayImpl +MPU_vTaskDelayImpl: + b MPU_vTaskDelayImpl + + PUBWEAK MPU_uxTaskPriorityGetImpl +MPU_uxTaskPriorityGetImpl: + b MPU_uxTaskPriorityGetImpl + + PUBWEAK MPU_eTaskGetStateImpl +MPU_eTaskGetStateImpl: + b MPU_eTaskGetStateImpl + + PUBWEAK MPU_vTaskGetInfoImpl +MPU_vTaskGetInfoImpl: + b MPU_vTaskGetInfoImpl + + PUBWEAK MPU_xTaskGetIdleTaskHandleImpl +MPU_xTaskGetIdleTaskHandleImpl: + b MPU_xTaskGetIdleTaskHandleImpl + + PUBWEAK MPU_vTaskSuspendImpl +MPU_vTaskSuspendImpl: + b MPU_vTaskSuspendImpl + + PUBWEAK MPU_vTaskResumeImpl +MPU_vTaskResumeImpl: + b MPU_vTaskResumeImpl + + PUBWEAK MPU_xTaskGetTickCountImpl +MPU_xTaskGetTickCountImpl: + b MPU_xTaskGetTickCountImpl + + PUBWEAK MPU_uxTaskGetNumberOfTasksImpl +MPU_uxTaskGetNumberOfTasksImpl: + b MPU_uxTaskGetNumberOfTasksImpl + + PUBWEAK MPU_pcTaskGetNameImpl +MPU_pcTaskGetNameImpl: + b MPU_pcTaskGetNameImpl + + PUBWEAK MPU_ulTaskGetRunTimeCounterImpl +MPU_ulTaskGetRunTimeCounterImpl: + b MPU_ulTaskGetRunTimeCounterImpl + + PUBWEAK MPU_ulTaskGetRunTimePercentImpl +MPU_ulTaskGetRunTimePercentImpl: + b MPU_ulTaskGetRunTimePercentImpl + + PUBWEAK MPU_ulTaskGetIdleRunTimePercentImpl +MPU_ulTaskGetIdleRunTimePercentImpl: + b MPU_ulTaskGetIdleRunTimePercentImpl + + PUBWEAK MPU_ulTaskGetIdleRunTimeCounterImpl +MPU_ulTaskGetIdleRunTimeCounterImpl: + b MPU_ulTaskGetIdleRunTimeCounterImpl + + PUBWEAK MPU_vTaskSetApplicationTaskTagImpl +MPU_vTaskSetApplicationTaskTagImpl: + b MPU_vTaskSetApplicationTaskTagImpl + + PUBWEAK MPU_xTaskGetApplicationTaskTagImpl +MPU_xTaskGetApplicationTaskTagImpl: + b MPU_xTaskGetApplicationTaskTagImpl + + PUBWEAK MPU_vTaskSetThreadLocalStoragePointerImpl +MPU_vTaskSetThreadLocalStoragePointerImpl: + b MPU_vTaskSetThreadLocalStoragePointerImpl + + PUBWEAK MPU_pvTaskGetThreadLocalStoragePointerImpl +MPU_pvTaskGetThreadLocalStoragePointerImpl: + b MPU_pvTaskGetThreadLocalStoragePointerImpl + + PUBWEAK MPU_uxTaskGetSystemStateImpl +MPU_uxTaskGetSystemStateImpl: + b MPU_uxTaskGetSystemStateImpl + + PUBWEAK MPU_uxTaskGetStackHighWaterMarkImpl +MPU_uxTaskGetStackHighWaterMarkImpl: + b MPU_uxTaskGetStackHighWaterMarkImpl + + PUBWEAK MPU_uxTaskGetStackHighWaterMark2Impl +MPU_uxTaskGetStackHighWaterMark2Impl: + b MPU_uxTaskGetStackHighWaterMark2Impl + + PUBWEAK MPU_xTaskGetCurrentTaskHandleImpl +MPU_xTaskGetCurrentTaskHandleImpl: + b MPU_xTaskGetCurrentTaskHandleImpl + + PUBWEAK MPU_xTaskGetSchedulerStateImpl +MPU_xTaskGetSchedulerStateImpl: + b MPU_xTaskGetSchedulerStateImpl + + PUBWEAK MPU_vTaskSetTimeOutStateImpl +MPU_vTaskSetTimeOutStateImpl: + b MPU_vTaskSetTimeOutStateImpl + + PUBWEAK MPU_xTaskCheckForTimeOutImpl +MPU_xTaskCheckForTimeOutImpl: + b MPU_xTaskCheckForTimeOutImpl + + PUBWEAK MPU_xTaskGenericNotifyImpl +MPU_xTaskGenericNotifyImpl: + b MPU_xTaskGenericNotifyImpl + + PUBWEAK MPU_xTaskGenericNotifyWaitImpl +MPU_xTaskGenericNotifyWaitImpl: + b MPU_xTaskGenericNotifyWaitImpl + + PUBWEAK MPU_ulTaskGenericNotifyTakeImpl +MPU_ulTaskGenericNotifyTakeImpl: + b MPU_ulTaskGenericNotifyTakeImpl + + PUBWEAK MPU_xTaskGenericNotifyStateClearImpl +MPU_xTaskGenericNotifyStateClearImpl: + b MPU_xTaskGenericNotifyStateClearImpl + + PUBWEAK MPU_ulTaskGenericNotifyValueClearImpl +MPU_ulTaskGenericNotifyValueClearImpl: + b MPU_ulTaskGenericNotifyValueClearImpl + + PUBWEAK MPU_xQueueGenericSendImpl +MPU_xQueueGenericSendImpl: + b MPU_xQueueGenericSendImpl + + PUBWEAK MPU_uxQueueMessagesWaitingImpl +MPU_uxQueueMessagesWaitingImpl: + b MPU_uxQueueMessagesWaitingImpl + + PUBWEAK MPU_uxQueueSpacesAvailableImpl +MPU_uxQueueSpacesAvailableImpl: + b MPU_uxQueueSpacesAvailableImpl + + PUBWEAK MPU_xQueueReceiveImpl +MPU_xQueueReceiveImpl: + b MPU_xQueueReceiveImpl + + PUBWEAK MPU_xQueuePeekImpl +MPU_xQueuePeekImpl: + b MPU_xQueuePeekImpl + + PUBWEAK MPU_xQueueSemaphoreTakeImpl +MPU_xQueueSemaphoreTakeImpl: + b MPU_xQueueSemaphoreTakeImpl + + PUBWEAK MPU_xQueueGetMutexHolderImpl +MPU_xQueueGetMutexHolderImpl: + b MPU_xQueueGetMutexHolderImpl + + PUBWEAK MPU_xQueueTakeMutexRecursiveImpl +MPU_xQueueTakeMutexRecursiveImpl: + b MPU_xQueueTakeMutexRecursiveImpl + + PUBWEAK MPU_xQueueGiveMutexRecursiveImpl +MPU_xQueueGiveMutexRecursiveImpl: + b MPU_xQueueGiveMutexRecursiveImpl + + PUBWEAK MPU_xQueueSelectFromSetImpl +MPU_xQueueSelectFromSetImpl: + b MPU_xQueueSelectFromSetImpl + + PUBWEAK MPU_xQueueAddToSetImpl +MPU_xQueueAddToSetImpl: + b MPU_xQueueAddToSetImpl + + PUBWEAK MPU_vQueueAddToRegistryImpl +MPU_vQueueAddToRegistryImpl: + b MPU_vQueueAddToRegistryImpl + + PUBWEAK MPU_vQueueUnregisterQueueImpl +MPU_vQueueUnregisterQueueImpl: + b MPU_vQueueUnregisterQueueImpl + + PUBWEAK MPU_pcQueueGetNameImpl +MPU_pcQueueGetNameImpl: + b MPU_pcQueueGetNameImpl + + PUBWEAK MPU_pvTimerGetTimerIDImpl +MPU_pvTimerGetTimerIDImpl: + b MPU_pvTimerGetTimerIDImpl + + PUBWEAK MPU_vTimerSetTimerIDImpl +MPU_vTimerSetTimerIDImpl: + b MPU_vTimerSetTimerIDImpl + + PUBWEAK MPU_xTimerIsTimerActiveImpl +MPU_xTimerIsTimerActiveImpl: + b MPU_xTimerIsTimerActiveImpl + + PUBWEAK MPU_xTimerGetTimerDaemonTaskHandleImpl +MPU_xTimerGetTimerDaemonTaskHandleImpl: + b MPU_xTimerGetTimerDaemonTaskHandleImpl + + PUBWEAK MPU_xTimerGenericCommandImpl +MPU_xTimerGenericCommandImpl: + b MPU_xTimerGenericCommandImpl + + PUBWEAK MPU_pcTimerGetNameImpl +MPU_pcTimerGetNameImpl: + b MPU_pcTimerGetNameImpl + + PUBWEAK MPU_vTimerSetReloadModeImpl +MPU_vTimerSetReloadModeImpl: + b MPU_vTimerSetReloadModeImpl + + PUBWEAK MPU_xTimerGetReloadModeImpl +MPU_xTimerGetReloadModeImpl: + b MPU_xTimerGetReloadModeImpl + + PUBWEAK MPU_uxTimerGetReloadModeImpl +MPU_uxTimerGetReloadModeImpl: + b MPU_uxTimerGetReloadModeImpl + + PUBWEAK MPU_xTimerGetPeriodImpl +MPU_xTimerGetPeriodImpl: + b MPU_xTimerGetPeriodImpl + + PUBWEAK MPU_xTimerGetExpiryTimeImpl +MPU_xTimerGetExpiryTimeImpl: + b MPU_xTimerGetExpiryTimeImpl + + PUBWEAK MPU_xEventGroupWaitBitsImpl +MPU_xEventGroupWaitBitsImpl: + b MPU_xEventGroupWaitBitsImpl + + PUBWEAK MPU_xEventGroupClearBitsImpl +MPU_xEventGroupClearBitsImpl: + b MPU_xEventGroupClearBitsImpl + + PUBWEAK MPU_xEventGroupSetBitsImpl +MPU_xEventGroupSetBitsImpl: + b MPU_xEventGroupSetBitsImpl + + PUBWEAK MPU_xEventGroupSyncImpl +MPU_xEventGroupSyncImpl: + b MPU_xEventGroupSyncImpl + + PUBWEAK MPU_uxEventGroupGetNumberImpl +MPU_uxEventGroupGetNumberImpl: + b MPU_uxEventGroupGetNumberImpl + + PUBWEAK MPU_vEventGroupSetNumberImpl +MPU_vEventGroupSetNumberImpl: + b MPU_vEventGroupSetNumberImpl + + PUBWEAK MPU_xStreamBufferSendImpl +MPU_xStreamBufferSendImpl: + b MPU_xStreamBufferSendImpl + + PUBWEAK MPU_xStreamBufferReceiveImpl +MPU_xStreamBufferReceiveImpl: + b MPU_xStreamBufferReceiveImpl + + PUBWEAK MPU_xStreamBufferIsFullImpl +MPU_xStreamBufferIsFullImpl: + b MPU_xStreamBufferIsFullImpl + + PUBWEAK MPU_xStreamBufferIsEmptyImpl +MPU_xStreamBufferIsEmptyImpl: + b MPU_xStreamBufferIsEmptyImpl + + PUBWEAK MPU_xStreamBufferSpacesAvailableImpl +MPU_xStreamBufferSpacesAvailableImpl: + b MPU_xStreamBufferSpacesAvailableImpl + + PUBWEAK MPU_xStreamBufferBytesAvailableImpl +MPU_xStreamBufferBytesAvailableImpl: + b MPU_xStreamBufferBytesAvailableImpl + + PUBWEAK MPU_xStreamBufferSetTriggerLevelImpl +MPU_xStreamBufferSetTriggerLevelImpl: + b MPU_xStreamBufferSetTriggerLevelImpl + + PUBWEAK MPU_xStreamBufferNextMessageLengthBytesImpl +MPU_xStreamBufferNextMessageLengthBytesImpl: + b MPU_xStreamBufferNextMessageLengthBytesImpl + +/*-----------------------------------------------------------*/ + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + + END diff --git a/portable/IAR/ARM_CM33/non_secure/port.c b/portable/IAR/ARM_CM33/non_secure/port.c index 7bbe1b7bc53..cab1b3668bf 100644 --- a/portable/IAR/ARM_CM33/non_secure/port.c +++ b/portable/IAR/ARM_CM33/non_secure/port.c @@ -107,6 +107,13 @@ #define portPRIGROUP_SHIFT ( 8UL ) /*-----------------------------------------------------------*/ +/** + * @brief Constants used during system call enter and exit. + */ +#define portPSR_STACK_PADDING_MASK ( 1UL << 9UL ) +#define portEXC_RETURN_STACK_FRAME_TYPE_MASK ( 1UL << 4UL ) +/*-----------------------------------------------------------*/ + /** * @brief Constants required to manipulate the FPU. */ @@ -123,6 +130,14 @@ #define portFPCCR_LSPEN_MASK ( 1UL << portFPCCR_LSPEN_POS ) /*-----------------------------------------------------------*/ +/** + * @brief Offsets in the stack to the parameters when inside the SVC handler. + */ +#define portOFFSET_TO_LR ( 5 ) +#define portOFFSET_TO_PC ( 6 ) +#define portOFFSET_TO_PSR ( 7 ) +/*-----------------------------------------------------------*/ + /** * @brief Constants required to manipulate the MPU. */ @@ -148,6 +163,8 @@ #define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ #define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ +#define portMPU_RBAR_ACCESS_PERMISSIONS_MASK ( 3UL << 1UL ) + #define portMPU_MAIR_ATTR0_POS ( 0UL ) #define portMPU_MAIR_ATTR0_MASK ( 0x000000ff ) @@ -191,6 +208,30 @@ /* Expected value of the portMPU_TYPE register. */ #define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) + +/* Extract first address of the MPU region as encoded in the + * RBAR (Region Base Address Register) value. */ +#define portEXTRACT_FIRST_ADDRESS_FROM_RBAR( rbar ) \ + ( ( rbar ) & portMPU_RBAR_ADDRESS_MASK ) + +/* Extract last address of the MPU region as encoded in the + * RLAR (Region Limit Address Register) value. */ +#define portEXTRACT_LAST_ADDRESS_FROM_RLAR( rlar ) \ + ( ( ( rlar ) & portMPU_RLAR_ADDRESS_MASK ) | ~portMPU_RLAR_ADDRESS_MASK ) + +/* Does addr lies within [start, end] address range? */ +#define portIS_ADDRESS_WITHIN_RANGE( addr, start, end ) \ + ( ( ( addr ) >= ( start ) ) && ( ( addr ) <= ( end ) ) ) + +/* Is the access request satisfied by the available permissions? */ +#define portIS_AUTHORIZED( accessRequest, permissions ) \ + ( ( ( permissions ) & ( accessRequest ) ) == accessRequest ) + +/* 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 ) ) ) /*-----------------------------------------------------------*/ /** @@ -311,6 +352,19 @@ static void prvTaskExitError( void ); #if ( configENABLE_MPU == 1 ) +/** + * @brief Extract MPU region's access permissions from the Region Base Address + * Register (RBAR) value. + * + * @param ulRBARValue RBAR value for the MPU region. + * + * @return uint32_t Access permissions. + */ + static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) PRIVILEGED_FUNCTION; +#endif /* configENABLE_MPU */ + +#if ( configENABLE_MPU == 1 ) + /** * @brief Setup the Memory Protection Unit (MPU). */ @@ -365,6 +419,60 @@ void SysTick_Handler( void ) PRIVILEGED_FUNCTION; * @brief C part of SVC handler. */ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIVILEGED_FUNCTION; + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + + /** + * @brief Sets up the system call stack so that upon returning from + * SVC, the system call stack is used. + * + * It is used for the system calls with up to 4 parameters. + * + * @param pulTaskStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + */ + void vSystemCallEnter( uint32_t * pulTaskStack, uint32_t ulLR ) PRIVILEGED_FUNCTION; + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + + /** + * @brief Sets up the system call stack so that upon returning from + * SVC, the system call stack is used. + * + * It is used for the system calls with 5 parameters. + * + * @param pulTaskStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + */ + void vSystemCallEnter_1( uint32_t * pulTaskStack, uint32_t ulLR ) PRIVILEGED_FUNCTION; + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + + /** + * @brief Sets up the task stack so that upon returning from + * SVC, the task stack is used again. + * + * @param pulSystemCallStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + */ + void vSystemCallExit( uint32_t * pulSystemCallStack, uint32_t ulLR ) PRIVILEGED_FUNCTION; + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + +#if ( configENABLE_MPU == 1 ) + + /** + * @brief Checks whether or not the calling task is privileged. + * + * @return pdTRUE if the calling task is privileged, pdFALSE otherwise. + */ + BaseType_t xPortIsTaskPrivileged( void ) PRIVILEGED_FUNCTION; + +#endif /* configENABLE_MPU == 1 */ /*-----------------------------------------------------------*/ /** @@ -681,6 +789,26 @@ static void prvTaskExitError( void ) } /*-----------------------------------------------------------*/ +#if ( configENABLE_MPU == 1 ) + static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) /* PRIVILEGED_FUNCTION */ + { + uint32_t ulAccessPermissions = 0; + + if( ( ulRBARValue & portMPU_RBAR_ACCESS_PERMISSIONS_MASK ) == portMPU_REGION_READ_ONLY ) + { + ulAccessPermissions = tskMPU_READ_PERMISSION; + } + + if( ( ulRBARValue & portMPU_RBAR_ACCESS_PERMISSIONS_MASK ) == portMPU_REGION_READ_WRITE ) + { + ulAccessPermissions = ( tskMPU_READ_PERMISSION | tskMPU_WRITE_PERMISSION ); + } + + return ulAccessPermissions; + } +#endif /* configENABLE_MPU */ +/*-----------------------------------------------------------*/ + #if ( configENABLE_MPU == 1 ) static void prvSetupMPU( void ) /* PRIVILEGED_FUNCTION */ { @@ -853,7 +981,7 @@ void SysTick_Handler( void ) /* PRIVILEGED_FUNCTION */ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTION portDONT_DISCARD */ { - #if ( configENABLE_MPU == 1 ) + #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) ) #if defined( __ARMCC_VERSION ) /* Declaration when these variable are defined in code instead of being @@ -865,7 +993,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO extern uint32_t __syscalls_flash_start__[]; extern uint32_t __syscalls_flash_end__[]; #endif /* defined( __ARMCC_VERSION ) */ - #endif /* configENABLE_MPU */ + #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */ uint32_t ulPC; @@ -880,7 +1008,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO /* Register are stored on the stack in the following order - R0, R1, R2, R3, * R12, LR, PC, xPSR. */ - ulPC = pulCallerStackAddress[ 6 ]; + ulPC = pulCallerStackAddress[ portOFFSET_TO_PC ]; ucSVCNumber = ( ( uint8_t * ) ulPC )[ -2 ]; switch( ucSVCNumber ) @@ -951,18 +1079,18 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO vRestoreContextOfFirstTask(); break; - #if ( configENABLE_MPU == 1 ) - case portSVC_RAISE_PRIVILEGE: + #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) ) + case portSVC_RAISE_PRIVILEGE: - /* Only raise the privilege, if the svc was raised from any of - * the system calls. */ - if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) && - ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ) - { - vRaisePrivilege(); - } - break; - #endif /* configENABLE_MPU */ + /* Only raise the privilege, if the svc was raised from any of + * the system calls. */ + if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ) + { + vRaisePrivilege(); + } + break; + #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */ default: /* Incorrect SVC call. */ @@ -971,51 +1099,455 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } /*-----------------------------------------------------------*/ -/* *INDENT-OFF* */ -#if ( configENABLE_MPU == 1 ) - StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, - StackType_t * pxEndOfStack, - TaskFunction_t pxCode, - void * pvParameters, - BaseType_t xRunPrivileged ) /* PRIVILEGED_FUNCTION */ -#else - StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, - StackType_t * pxEndOfStack, - TaskFunction_t pxCode, - void * pvParameters ) /* PRIVILEGED_FUNCTION */ -#endif /* configENABLE_MPU */ -/* *INDENT-ON* */ +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + +void vSystemCallEnter( uint32_t * pulTaskStack, uint32_t ulLR ) /* PRIVILEGED_FUNCTION */ { - /* Simulate the stack frame as it would be created by a context switch - * interrupt. */ - #if ( portPRELOAD_REGISTERS == 0 ) + extern TaskHandle_t pxCurrentTCB; + xMPU_SETTINGS * pxMpuSettings; + uint32_t * pulSystemCallStack; + uint32_t ulStackFrameSize, ulSystemCallLocation, i; + #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being + * exported from linker scripts. */ + extern uint32_t * __syscalls_flash_start__; + extern uint32_t * __syscalls_flash_end__; + #else + /* Declaration when these variable are exported from linker scripts. */ + extern uint32_t __syscalls_flash_start__[]; + extern uint32_t __syscalls_flash_end__[]; + #endif /* #if defined( __ARMCC_VERSION ) */ + + ulSystemCallLocation = pulTaskStack[ portOFFSET_TO_PC ]; + + /* If the request did not come from the system call section, do nothing. */ + if( ( ulSystemCallLocation >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulSystemCallLocation <= ( uint32_t ) __syscalls_flash_end__ ) ) { - pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ - *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ - pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pxCode; /* PC */ - pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR */ - pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ - *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ - pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */ - *pxTopOfStack = portINITIAL_EXC_RETURN; + pxMpuSettings = xTaskGetMPUSettings( pxCurrentTCB ); + pulSystemCallStack = pxMpuSettings->xSystemCallStackInfo.pulSystemCallStack; - #if ( configENABLE_MPU == 1 ) + /* This is not NULL only for the duration of the system call. */ + configASSERT( pxMpuSettings->xSystemCallStackInfo.pulTaskStack == NULL ); + + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) { - pxTopOfStack--; + if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) + { + /* Extended frame i.e. FPU in use. */ + ulStackFrameSize = 26; + __asm volatile ( + " vpush {s0} \n" /* Trigger lazy stacking. */ + " vpop {s0} \n" /* Nullify the affect of the above instruction. */ + ::: "memory" + ); + } + else + { + /* Standard frame i.e. FPU not in use. */ + ulStackFrameSize = 8; + } + } + #else + { + ulStackFrameSize = 8; + } + #endif /* configENABLE_FPU || configENABLE_MVE */ + + /* Make space on the system call stack for the stack frame. */ + pulSystemCallStack = pulSystemCallStack - ulStackFrameSize; + + /* Copy the stack frame. */ + for( i = 0; i < ulStackFrameSize; i++ ) + { + pulSystemCallStack[ i ] = pulTaskStack[ i ]; + } + + /* Store the value of the LR and PSPLIM registers before the SVC was raised. We need to + * restore it when we exit from the system call. */ + pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; + __asm volatile ( "mrs %0, psplim" : "=r" ( pxMpuSettings->xSystemCallStackInfo.ulStackLimitRegisterAtSystemCallEntry ) ); + + /* Use the pulSystemCallStack in thread mode. */ + __asm volatile ( "msr psp, %0" : : "r" ( pulSystemCallStack ) ); + __asm volatile ( "msr psplim, %0" : : "r" ( pxMpuSettings->xSystemCallStackInfo.pulSystemCallStackLimit ) ); + + /* Remember the location where we should copy the stack frame when we exit from + * the system call. */ + pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulStackFrameSize; + + /* Record if the hardware used padding to force the stack pointer + * to be double word aligned. */ + if( ( pulTaskStack[ portOFFSET_TO_PSR ] & portPSR_STACK_PADDING_MASK ) == portPSR_STACK_PADDING_MASK ) + { + pxMpuSettings->ulTaskFlags |= portSTACK_FRAME_HAS_PADDING_FLAG; + } + else + { + pxMpuSettings->ulTaskFlags &= ( ~portSTACK_FRAME_HAS_PADDING_FLAG ); + } + + /* We ensure in pxPortInitialiseStack that the system call stack is + * double word aligned and therefore, there is no need of padding. + * Clear the bit[9] of stacked xPSR. */ + pulSystemCallStack[ portOFFSET_TO_PSR ] &= ( ~portPSR_STACK_PADDING_MASK ); + + /* Raise the privilege for the duration of the system call. */ + __asm volatile ( + " mrs r0, control \n" /* Obtain current control value. */ + " movs r1, #1 \n" /* r1 = 1. */ + " bics r0, r1 \n" /* Clear nPRIV bit. */ + " msr control, r0 \n" /* Write back new control value. */ + ::: "r0", "r1", "memory" + ); + } +} - if( xRunPrivileged == pdTRUE ) +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + +void vSystemCallEnter_1( uint32_t * pulTaskStack, uint32_t ulLR ) /* PRIVILEGED_FUNCTION */ +{ + extern TaskHandle_t pxCurrentTCB; + xMPU_SETTINGS * pxMpuSettings; + uint32_t * pulSystemCallStack; + uint32_t ulStackFrameSize, ulSystemCallLocation, i; + #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being + * exported from linker scripts. */ + extern uint32_t * __syscalls_flash_start__; + extern uint32_t * __syscalls_flash_end__; + #else + /* Declaration when these variable are exported from linker scripts. */ + extern uint32_t __syscalls_flash_start__[]; + extern uint32_t __syscalls_flash_end__[]; + #endif /* #if defined( __ARMCC_VERSION ) */ + + ulSystemCallLocation = pulTaskStack[ portOFFSET_TO_PC ]; + + /* If the request did not come from the system call section, do nothing. */ + if( ( ulSystemCallLocation >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulSystemCallLocation <= ( uint32_t ) __syscalls_flash_end__ ) ) + { + pxMpuSettings = xTaskGetMPUSettings( pxCurrentTCB ); + pulSystemCallStack = pxMpuSettings->xSystemCallStackInfo.pulSystemCallStack; + + /* This is not NULL only for the duration of the system call. */ + configASSERT( pxMpuSettings->xSystemCallStackInfo.pulTaskStack == NULL ); + + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + { + if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) { - *pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */ + /* Extended frame i.e. FPU in use. */ + ulStackFrameSize = 26; + __asm volatile ( + " vpush {s0} \n" /* Trigger lazy stacking. */ + " vpop {s0} \n" /* Nullify the affect of the above instruction. */ + ::: "memory" + ); } else { - *pxTopOfStack = portINITIAL_CONTROL_UNPRIVILEGED; /* Slot used to hold this task's CONTROL value. */ + /* Standard frame i.e. FPU not in use. */ + ulStackFrameSize = 8; } } - #endif /* configENABLE_MPU */ + #else + { + ulStackFrameSize = 8; + } + #endif /* configENABLE_FPU || configENABLE_MVE */ + + /* Make space on the system call stack for the stack frame and + * the parameter passed on the stack. We only need to copy one + * parameter but we still reserve 2 spaces to keep the stack + * double word aligned. */ + pulSystemCallStack = pulSystemCallStack - ulStackFrameSize - 2UL; + + /* Copy the stack frame. */ + for( i = 0; i < ulStackFrameSize; i++ ) + { + pulSystemCallStack[ i ] = pulTaskStack[ i ]; + } + + /* Copy the parameter which is passed the stack. */ + if( ( pulTaskStack[ portOFFSET_TO_PSR ] & portPSR_STACK_PADDING_MASK ) == portPSR_STACK_PADDING_MASK ) + { + pulSystemCallStack[ ulStackFrameSize ] = pulTaskStack[ ulStackFrameSize + 1 ]; + /* Record if the hardware used padding to force the stack pointer + * to be double word aligned. */ + pxMpuSettings->ulTaskFlags |= portSTACK_FRAME_HAS_PADDING_FLAG; + } + else + { + pulSystemCallStack[ ulStackFrameSize ] = pulTaskStack[ ulStackFrameSize ]; + /* Record if the hardware used padding to force the stack pointer + * to be double word aligned. */ + pxMpuSettings->ulTaskFlags &= ( ~portSTACK_FRAME_HAS_PADDING_FLAG ); + } + + /* Store the value of the LR and PSPLIM registers before the SVC was raised. + * We need to restore it when we exit from the system call. */ + pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; + __asm volatile ( "mrs %0, psplim" : "=r" ( pxMpuSettings->xSystemCallStackInfo.ulStackLimitRegisterAtSystemCallEntry ) ); + + /* Use the pulSystemCallStack in thread mode. */ + __asm volatile ( "msr psp, %0" : : "r" ( pulSystemCallStack ) ); + __asm volatile ( "msr psplim, %0" : : "r" ( pxMpuSettings->xSystemCallStackInfo.pulSystemCallStackLimit ) ); + + /* Remember the location where we should copy the stack frame when we exit from + * the system call. */ + pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulStackFrameSize; + + /* We ensure in pxPortInitialiseStack that the system call stack is + * double word aligned and therefore, there is no need of padding. + * Clear the bit[9] of stacked xPSR. */ + pulSystemCallStack[ portOFFSET_TO_PSR ] &= ( ~portPSR_STACK_PADDING_MASK ); + + /* Raise the privilege for the duration of the system call. */ + __asm volatile ( + " mrs r0, control \n" /* Obtain current control value. */ + " movs r1, #1 \n" /* r1 = 1. */ + " bics r0, r1 \n" /* Clear nPRIV bit. */ + " msr control, r0 \n" /* Write back new control value. */ + ::: "r0", "r1", "memory" + ); + } +} + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) +void vSystemCallExit( uint32_t * pulSystemCallStack, uint32_t ulLR ) /* PRIVILEGED_FUNCTION */ +{ + extern TaskHandle_t pxCurrentTCB; + xMPU_SETTINGS * pxMpuSettings; + uint32_t * pulTaskStack; + uint32_t ulStackFrameSize, ulSystemCallLocation, i; + #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being + * exported from linker scripts. */ + extern uint32_t * __syscalls_flash_start__; + extern uint32_t * __syscalls_flash_end__; + #else + /* Declaration when these variable are exported from linker scripts. */ + extern uint32_t __syscalls_flash_start__[]; + extern uint32_t __syscalls_flash_end__[]; + #endif /* #if defined( __ARMCC_VERSION ) */ + + ulSystemCallLocation = pulSystemCallStack[ portOFFSET_TO_PC ]; + + /* If the request did not come from the system call section, do nothing. */ + if( ( ulSystemCallLocation >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulSystemCallLocation <= ( uint32_t ) __syscalls_flash_end__ ) ) + { + pxMpuSettings = xTaskGetMPUSettings( pxCurrentTCB ); + pulTaskStack = pxMpuSettings->xSystemCallStackInfo.pulTaskStack; + + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + { + if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) + { + /* Extended frame i.e. FPU in use. */ + ulStackFrameSize = 26; + __asm volatile ( + " vpush {s0} \n" /* Trigger lazy stacking. */ + " vpop {s0} \n" /* Nullify the affect of the above instruction. */ + ::: "memory" + ); + } + else + { + /* Standard frame i.e. FPU not in use. */ + ulStackFrameSize = 8; + } + } + #else + { + ulStackFrameSize = 8; + } + #endif /* configENABLE_FPU || configENABLE_MVE */ + + /* Make space on the task stack for the stack frame. */ + pulTaskStack = pulTaskStack - ulStackFrameSize; + + /* Copy the stack frame. */ + for( i = 0; i < ulStackFrameSize; i++ ) + { + pulTaskStack[ i ] = pulSystemCallStack[ i ]; + } + + /* Use the pulTaskStack in thread mode. */ + __asm volatile ( "msr psp, %0" : : "r" ( pulTaskStack ) ); + + /* Restore the LR and PSPLIM to what they were at the time of + * system call entry. */ + pulTaskStack[ portOFFSET_TO_LR ] = pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry; + __asm volatile ( "msr psplim, %0" : : "r" ( pxMpuSettings->xSystemCallStackInfo.ulStackLimitRegisterAtSystemCallEntry ) ); + + /* If the hardware used padding to force the stack pointer + * to be double word aligned, set the stacked xPSR bit[9], + * otherwise clear it. */ + if( ( pxMpuSettings->ulTaskFlags & portSTACK_FRAME_HAS_PADDING_FLAG ) == portSTACK_FRAME_HAS_PADDING_FLAG ) + { + pulTaskStack[ portOFFSET_TO_PSR ] |= portPSR_STACK_PADDING_MASK; + } + else + { + pulTaskStack[ portOFFSET_TO_PSR ] &= ( ~portPSR_STACK_PADDING_MASK ); + } + + /* This is not NULL only for the duration of the system call. */ + pxMpuSettings->xSystemCallStackInfo.pulTaskStack = NULL; + + /* Drop the privilege before returning to the thread mode. */ + __asm volatile ( + " mrs r0, control \n" /* Obtain current control value. */ + " movs r1, #1 \n" /* r1 = 1. */ + " orrs r0, r1 \n" /* Set nPRIV bit. */ + " msr control, r0 \n" /* Write back new control value. */ + ::: "r0", "r1", "memory" + ); + } +} + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configENABLE_MPU == 1 ) + +BaseType_t xPortIsTaskPrivileged( void ) /* PRIVILEGED_FUNCTION */ +{ + BaseType_t xTaskIsPrivileged = pdFALSE; + const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */ + + if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) + { + xTaskIsPrivileged = pdTRUE; + } + + return xTaskIsPrivileged; +} + +#endif /* configENABLE_MPU == 1 */ +/*-----------------------------------------------------------*/ + +#if( configENABLE_MPU == 1 ) + +StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, + StackType_t * pxEndOfStack, + TaskFunction_t pxCode, + void * pvParameters, + BaseType_t xRunPrivileged, + xMPU_SETTINGS * xMPUSettings ) /* PRIVILEGED_FUNCTION */ +{ + uint32_t ulIndex = 0; + + xMPUSettings->ulContext[ ulIndex ] = 0x04040404; /* r4. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x05050505; /* r5. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x06060606; /* r6. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x07070707; /* r7. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x08080808; /* r8. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x09090909; /* r9. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x10101010; /* r10. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x11111111; /* r11. */ + ulIndex++; + + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pvParameters; /* r0. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x01010101; /* r1. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x02020202; /* r2. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x03030303; /* r3. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x12121212; /* r12. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portTASK_RETURN_ADDRESS; /* LR. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxCode; /* PC. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = portINITIAL_XPSR; /* xPSR. */ + ulIndex++; + + #if ( configENABLE_TRUSTZONE == 1 ) + { + xMPUSettings->ulContext[ ulIndex ] = portNO_SECURE_CONTEXT; /* xSecureContext. */ + ulIndex++; + } + #endif /* configENABLE_TRUSTZONE */ + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) ( pxTopOfStack - 8 ); /* PSP with the hardware saved stack. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */ + ulIndex++; + if( xRunPrivileged == pdTRUE ) + { + xMPUSettings->ulTaskFlags |= portTASK_IS_PRIVILEGED_FLAG; + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_PRIVILEGED; /* CONTROL. */ + ulIndex++; + } + else + { + xMPUSettings->ulTaskFlags &= ( ~portTASK_IS_PRIVILEGED_FLAG ); + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_UNPRIVILEGED; /* CONTROL. */ + ulIndex++; + } + xMPUSettings->ulContext[ ulIndex ] = portINITIAL_EXC_RETURN; /* LR (EXC_RETURN). */ + ulIndex++; + + #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + { + /* Ensure that the system call stack is double word aligned. */ + xMPUSettings->xSystemCallStackInfo.pulSystemCallStack = &( xMPUSettings->xSystemCallStackInfo.ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE - 1 ] ); + xMPUSettings->xSystemCallStackInfo.pulSystemCallStack = ( uint32_t * ) ( ( uint32_t ) ( xMPUSettings->xSystemCallStackInfo.pulSystemCallStack ) & + ( uint32_t ) ( ~( portBYTE_ALIGNMENT_MASK ) ) ); + + xMPUSettings->xSystemCallStackInfo.pulSystemCallStackLimit = &( xMPUSettings->xSystemCallStackInfo.ulSystemCallStackBuffer[ 0 ] ); + xMPUSettings->xSystemCallStackInfo.pulSystemCallStackLimit = ( uint32_t * ) ( ( ( uint32_t ) ( xMPUSettings->xSystemCallStackInfo.pulSystemCallStackLimit ) + + ( uint32_t ) ( portBYTE_ALIGNMENT - 1 ) ) & + ( uint32_t ) ( ~( portBYTE_ALIGNMENT_MASK ) ) ); + + /* This is not NULL only for the duration of a system call. */ + xMPUSettings->xSystemCallStackInfo.pulTaskStack = NULL; + } + #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + + return &( xMPUSettings->ulContext[ ulIndex ] ); +} + +#else /* configENABLE_MPU */ + +StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, + StackType_t * pxEndOfStack, + TaskFunction_t pxCode, + void * pvParameters ) /* PRIVILEGED_FUNCTION */ +{ + /* Simulate the stack frame as it would be created by a context switch + * interrupt. */ + #if ( portPRELOAD_REGISTERS == 0 ) + { + pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ + *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR. */ + pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ + pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */ + *pxTopOfStack = portINITIAL_EXC_RETURN; pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ @@ -1029,55 +1561,39 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO #else /* portPRELOAD_REGISTERS */ { pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ - *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ + *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pxCode; /* PC */ + *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR */ + *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x12121212UL; /* R12 */ + *pxTopOfStack = ( StackType_t ) 0x12121212UL; /* R12. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x03030303UL; /* R3 */ + *pxTopOfStack = ( StackType_t ) 0x03030303UL; /* R3. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x02020202UL; /* R2 */ + *pxTopOfStack = ( StackType_t ) 0x02020202UL; /* R2. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x01010101UL; /* R1 */ + *pxTopOfStack = ( StackType_t ) 0x01010101UL; /* R1. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x11111111UL; /* R11 */ + *pxTopOfStack = ( StackType_t ) 0x11111111UL; /* R11. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x10101010UL; /* R10 */ + *pxTopOfStack = ( StackType_t ) 0x10101010UL; /* R10. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x09090909UL; /* R09 */ + *pxTopOfStack = ( StackType_t ) 0x09090909UL; /* R09. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x08080808UL; /* R08 */ + *pxTopOfStack = ( StackType_t ) 0x08080808UL; /* R08. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x07070707UL; /* R07 */ + *pxTopOfStack = ( StackType_t ) 0x07070707UL; /* R07. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x06060606UL; /* R06 */ + *pxTopOfStack = ( StackType_t ) 0x06060606UL; /* R06. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x05050505UL; /* R05 */ + *pxTopOfStack = ( StackType_t ) 0x05050505UL; /* R05. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x04040404UL; /* R04 */ + *pxTopOfStack = ( StackType_t ) 0x04040404UL; /* R04. */ pxTopOfStack--; - *pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN */ - - #if ( configENABLE_MPU == 1 ) - { - pxTopOfStack--; - - if( xRunPrivileged == pdTRUE ) - { - *pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */ - } - else - { - *pxTopOfStack = portINITIAL_CONTROL_UNPRIVILEGED; /* Slot used to hold this task's CONTROL value. */ - } - } - #endif /* configENABLE_MPU */ - + *pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN. */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ @@ -1092,6 +1608,8 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO return pxTopOfStack; } + +#endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ @@ -1128,6 +1646,10 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ configASSERT( ucMaxSysCallPriority ); + /* Check that the bits not implemented in hardware are zero in + * configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & ( ~ucMaxPriorityValue ) ) == 0U ); + /* Calculate the maximum acceptable priority group value for the number * of bits read back. */ @@ -1164,35 +1686,6 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulImplementedPrioBits; } - /* The interrupt priority bits are not modelled in QEMU and the assert that - * checks the number of implemented bits and __NVIC_PRIO_BITS will always fail. - * Therefore, this assert is not adding any value for QEMU targets. The config - * option `configDISABLE_INTERRUPT_PRIO_BITS_CHECK` should be defined in the - * `FreeRTOSConfig.h` for QEMU targets. */ - #ifndef configDISABLE_INTERRUPT_PRIO_BITS_CHECK - { - #ifdef __NVIC_PRIO_BITS - { - /* - * Check that the number of implemented priority bits queried from - * hardware is equal to the CMSIS __NVIC_PRIO_BITS configuration macro. - */ - configASSERT( ulImplementedPrioBits == __NVIC_PRIO_BITS ); - } - #endif /* __NVIC_PRIO_BITS */ - - #ifdef configPRIO_BITS - { - /* - * Check that the number of implemented priority bits queried from - * hardware is equal to the FreeRTOS configPRIO_BITS configuration macro. - */ - configASSERT( ulImplementedPrioBits == configPRIO_BITS ); - } - #endif /* configPRIO_BITS */ - } - #endif /* #ifndef configDISABLE_INTERRUPT_PRIO_BITS_CHECK */ - /* Shift the priority group value back to its position within the AIRCR * register. */ ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT; @@ -1372,6 +1865,54 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ +#if ( configENABLE_MPU == 1 ) + BaseType_t xPortIsAuthorizedToAccessBuffer( const void * pvBuffer, + uint32_t ulBufferLength, + uint32_t ulAccessRequested ) /* PRIVILEGED_FUNCTION */ + + { + uint32_t i, ulBufferStartAddress, ulBufferEndAddress; + BaseType_t xAccessGranted = pdFALSE; + const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */ + + if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) + { + xAccessGranted = pdTRUE; + } + else + { + if( portADD_UINT32_WILL_OVERFLOW( ( ( uint32_t ) pvBuffer ), ( ulBufferLength - 1UL ) ) == pdFALSE ) + { + ulBufferStartAddress = ( uint32_t ) pvBuffer; + ulBufferEndAddress = ( ( ( uint32_t ) pvBuffer ) + ulBufferLength - 1UL ); + + for( i = 0; i < portTOTAL_NUM_REGIONS; i++ ) + { + /* Is the MPU region enabled? */ + if( ( xTaskMpuSettings->xRegionsSettings[ i ].ulRLAR & portMPU_RLAR_REGION_ENABLE ) == portMPU_RLAR_REGION_ENABLE ) + { + if( portIS_ADDRESS_WITHIN_RANGE( ulBufferStartAddress, + portEXTRACT_FIRST_ADDRESS_FROM_RBAR( xTaskMpuSettings->xRegionsSettings[ i ].ulRBAR ), + portEXTRACT_LAST_ADDRESS_FROM_RLAR( xTaskMpuSettings->xRegionsSettings[ i ].ulRLAR ) ) && + portIS_ADDRESS_WITHIN_RANGE( ulBufferEndAddress, + portEXTRACT_FIRST_ADDRESS_FROM_RBAR( xTaskMpuSettings->xRegionsSettings[ i ].ulRBAR ), + portEXTRACT_LAST_ADDRESS_FROM_RLAR( xTaskMpuSettings->xRegionsSettings[ i ].ulRLAR ) ) && + portIS_AUTHORIZED( ulAccessRequested, + prvGetRegionAccessPermissions( xTaskMpuSettings->xRegionsSettings[ i ].ulRBAR ) ) ) + { + xAccessGranted = pdTRUE; + break; + } + } + } + } + } + + return xAccessGranted; + } +#endif /* configENABLE_MPU */ +/*-----------------------------------------------------------*/ + BaseType_t xPortIsInsideInterrupt( void ) { uint32_t ulCurrentInterrupt; diff --git a/portable/IAR/ARM_CM33/non_secure/portasm.s b/portable/IAR/ARM_CM33/non_secure/portasm.s index a193cd7b80e..15e74ffc16b 100644 --- a/portable/IAR/ARM_CM33/non_secure/portasm.s +++ b/portable/IAR/ARM_CM33/non_secure/portasm.s @@ -32,12 +32,21 @@ the code is included in C files but excluded by the preprocessor in assembly files (__ICCARM__ is defined by the IAR C compiler but not by the IAR assembler. */ #include "FreeRTOSConfig.h" +#ifndef configUSE_MPU_WRAPPERS_V1 + #define configUSE_MPU_WRAPPERS_V1 0 +#endif + EXTERN pxCurrentTCB EXTERN xSecureContext EXTERN vTaskSwitchContext EXTERN vPortSVCHandler_C EXTERN SecureContext_SaveContext EXTERN SecureContext_LoadContext +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + EXTERN vSystemCallEnter + EXTERN vSystemCallEnter_1 + EXTERN vSystemCallExit +#endif PUBLIC xIsPrivileged PUBLIC vResetPrivilege @@ -89,50 +98,81 @@ vPortAllocateSecureContext: THUMB /*-----------------------------------------------------------*/ +#if ( configENABLE_MPU == 1 ) + +vRestoreContextOfFirstTask: + program_mpu_first_task: + ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + ldr r0, [r3] /* r0 = pxCurrentTCB. */ + + dmb /* Complete outstanding transfers before disabling MPU. */ + ldr r1, =0xe000ed94 /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + ldr r2, [r1] /* Read the value of MPU_CTRL. */ + bic r2, #1 /* r2 = r2 & ~1 i.e. Clear the bit 0 in r2. */ + str r2, [r1] /* Disable MPU. */ + + adds r0, #4 /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */ + ldr r1, [r0] /* r1 = *r0 i.e. r1 = MAIR0. */ + ldr r2, =0xe000edc0 /* r2 = 0xe000edc0 [Location of MAIR0]. */ + str r1, [r2] /* Program MAIR0. */ + + adds r0, #4 /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */ + ldr r1, =0xe000ed98 /* r1 = 0xe000ed98 [Location of RNR]. */ + ldr r2, =0xe000ed9c /* r2 = 0xe000ed9c [Location of RBAR]. */ + + movs r3, #4 /* r3 = 4. */ + str r3, [r1] /* Program RNR = 4. */ + ldmia r0!, {r4-r11} /* Read 4 set of RBAR/RLAR registers from TCB. */ + stmia r2, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ + + #if ( configTOTAL_MPU_REGIONS == 16 ) + movs r3, #8 /* r3 = 8. */ + str r3, [r1] /* Program RNR = 8. */ + ldmia r0!, {r4-r11} /* Read 4 set of RBAR/RLAR registers from TCB. */ + stmia r2, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ + movs r3, #12 /* r3 = 12. */ + str r3, [r1] /* Program RNR = 12. */ + ldmia r0!, {r4-r11} /* Read 4 set of RBAR/RLAR registers from TCB. */ + stmia r2, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ + #endif /* configTOTAL_MPU_REGIONS == 16 */ + + ldr r1, =0xe000ed94 /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + ldr r2, [r1] /* Read the value of MPU_CTRL. */ + orr r2, #1 /* r2 = r1 | 1 i.e. Set the bit 0 in r2. */ + str r2, [r1] /* Enable MPU. */ + dsb /* Force memory writes before continuing. */ + + restore_context_first_task: + ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + ldr r1, [r3] /* r1 = pxCurrentTCB.*/ + ldr r2, [r1] /* r2 = Location of saved context in TCB. */ + + restore_special_regs_first_task: + ldmdb r2!, {r0, r3-r5, lr} /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */ + msr psp, r3 + msr psplim, r4 + msr control, r5 + ldr r4, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */ + str r0, [r4] /* Restore xSecureContext. */ + + restore_general_regs_first_task: + ldmdb r2!, {r4-r11} /* r4-r11 contain hardware saved context. */ + stmia r3!, {r4-r11} /* Copy the hardware saved context on the task stack. */ + ldmdb r2!, {r4-r11} /* r4-r11 restored. */ + + restore_context_done_first_task: + str r2, [r1] /* Save the location where the context should be saved next as the first member of TCB. */ + mov r0, #0 + msr basepri, r0 /* Ensure that interrupts are enabled when the first task starts. */ + bx lr + +#else /* configENABLE_MPU */ + vRestoreContextOfFirstTask: ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r3, [r2] /* Read pxCurrentTCB. */ ldr r0, [r3] /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ -#if ( configENABLE_MPU == 1 ) - dmb /* Complete outstanding transfers before disabling MPU. */ - ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ - ldr r4, [r2] /* Read the value of MPU_CTRL. */ - bic r4, r4, #1 /* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */ - str r4, [r2] /* Disable MPU. */ - - adds r3, #4 /* r3 = r3 + 4. r3 now points to MAIR0 in TCB. */ - ldr r4, [r3] /* r4 = *r3 i.e. r4 = MAIR0. */ - ldr r2, =0xe000edc0 /* r2 = 0xe000edc0 [Location of MAIR0]. */ - str r4, [r2] /* Program MAIR0. */ - ldr r2, =0xe000ed98 /* r2 = 0xe000ed98 [Location of RNR]. */ - movs r4, #4 /* r4 = 4. */ - str r4, [r2] /* Program RNR = 4. */ - adds r3, #4 /* r3 = r3 + 4. r3 now points to first RBAR in TCB. */ - ldr r2, =0xe000ed9c /* r2 = 0xe000ed9c [Location of RBAR]. */ - ldmia r3!, {r4-r11} /* Read 4 set of RBAR/RLAR registers from TCB. */ - stmia r2!, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ - - ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ - ldr r4, [r2] /* Read the value of MPU_CTRL. */ - orr r4, r4, #1 /* r4 = r4 | 1 i.e. Set the bit 0 in r4. */ - str r4, [r2] /* Enable MPU. */ - dsb /* Force memory writes before continuing. */ -#endif /* configENABLE_MPU */ - -#if ( configENABLE_MPU == 1 ) - ldm r0!, {r1-r4} /* Read from stack - r1 = xSecureContext, r2 = PSPLIM, r3 = CONTROL and r4 = EXC_RETURN. */ - ldr r5, =xSecureContext - str r1, [r5] /* Set xSecureContext to this task's value for the same. */ - msr psplim, r2 /* Set this task's PSPLIM value. */ - msr control, r3 /* Set this task's CONTROL value. */ - adds r0, #32 /* Discard everything up to r0. */ - msr psp, r0 /* This is now the new top of stack to use in the task. */ - isb - mov r0, #0 - msr basepri, r0 /* Ensure that interrupts are enabled when the first task starts. */ - bx r4 /* Finally, branch to EXC_RETURN. */ -#else /* configENABLE_MPU */ ldm r0!, {r1-r3} /* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */ ldr r4, =xSecureContext str r1, [r4] /* Set xSecureContext to this task's value for the same. */ @@ -145,6 +185,7 @@ vRestoreContextOfFirstTask: mov r0, #0 msr basepri, r0 /* Ensure that interrupts are enabled when the first task starts. */ bx r3 /* Finally, branch to EXC_RETURN. */ + #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ @@ -183,6 +224,143 @@ vClearInterruptMask: bx lr /* Return. */ /*-----------------------------------------------------------*/ +#if ( configENABLE_MPU == 1 ) + +PendSV_Handler: + ldr r3, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */ + ldr r0, [r3] /* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */ + ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + ldr r1, [r3] /* Read pxCurrentTCB - Value of pxCurrentTCB must be in r1 as it is used as a parameter later. */ + ldr r2, [r1] /* r2 = Location in TCB where the context should be saved. */ + + cbz r0, save_ns_context /* No secure context to save. */ + save_s_context: + push {r0-r2, lr} + bl SecureContext_SaveContext /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ + pop {r0-r2, lr} + + save_ns_context: + mov r3, lr /* r3 = LR (EXC_RETURN). */ + lsls r3, r3, #25 /* r3 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ + bmi save_special_regs /* r3 < 0 ==> Bit[6] in EXC_RETURN is 1 ==> secure stack was used to store the stack frame. */ + + save_general_regs: + mrs r3, psp + + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + add r3, r3, #0x20 /* Move r3 to location where s0 is saved. */ + tst lr, #0x10 + ittt eq + vstmiaeq r2!, {s16-s31} /* Store s16-s31. */ + vldmiaeq r3, {s0-s16} /* Copy hardware saved FP context into s0-s16. */ + vstmiaeq r2!, {s0-s16} /* Store hardware saved FP context. */ + sub r3, r3, #0x20 /* Set r3 back to the location of hardware saved context. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ + + stmia r2!, {r4-r11} /* Store r4-r11. */ + ldmia r3, {r4-r11} /* Copy the hardware saved context into r4-r11. */ + stmia r2!, {r4-r11} /* Store the hardware saved context. */ + + save_special_regs: + mrs r3, psp /* r3 = PSP. */ + mrs r4, psplim /* r4 = PSPLIM. */ + mrs r5, control /* r5 = CONTROL. */ + stmia r2!, {r0, r3-r5, lr} /* Store xSecureContext, original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */ + str r2, [r1] /* Save the location from where the context should be restored as the first member of TCB. */ + + select_next_task: + mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY + msr basepri, r0 /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + dsb + isb + bl vTaskSwitchContext + mov r0, #0 /* r0 = 0. */ + msr basepri, r0 /* Enable interrupts. */ + + program_mpu: + ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + ldr r0, [r3] /* r0 = pxCurrentTCB.*/ + + dmb /* Complete outstanding transfers before disabling MPU. */ + ldr r1, =0xe000ed94 /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + ldr r2, [r1] /* Read the value of MPU_CTRL. */ + bic r2, #1 /* r2 = r2 & ~1 i.e. Clear the bit 0 in r2. */ + str r2, [r1] /* Disable MPU. */ + + adds r0, #4 /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */ + ldr r1, [r0] /* r1 = *r0 i.e. r1 = MAIR0. */ + ldr r2, =0xe000edc0 /* r2 = 0xe000edc0 [Location of MAIR0]. */ + str r1, [r2] /* Program MAIR0. */ + + adds r0, #4 /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */ + ldr r1, =0xe000ed98 /* r1 = 0xe000ed98 [Location of RNR]. */ + ldr r2, =0xe000ed9c /* r2 = 0xe000ed9c [Location of RBAR]. */ + + movs r3, #4 /* r3 = 4. */ + str r3, [r1] /* Program RNR = 4. */ + ldmia r0!, {r4-r11} /* Read 4 sets of RBAR/RLAR registers from TCB. */ + stmia r2, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ + + #if ( configTOTAL_MPU_REGIONS == 16 ) + movs r3, #8 /* r3 = 8. */ + str r3, [r1] /* Program RNR = 8. */ + ldmia r0!, {r4-r11} /* Read 4 sets of RBAR/RLAR registers from TCB. */ + stmia r2, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ + movs r3, #12 /* r3 = 12. */ + str r3, [r1] /* Program RNR = 12. */ + ldmia r0!, {r4-r11} /* Read 4 sets of RBAR/RLAR registers from TCB. */ + stmia r2, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ + #endif /* configTOTAL_MPU_REGIONS == 16 */ + + ldr r1, =0xe000ed94 /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + ldr r2, [r1] /* Read the value of MPU_CTRL. */ + orr r2, #1 /* r2 = r2 | 1 i.e. Set the bit 0 in r2. */ + str r2, [r1] /* Enable MPU. */ + dsb /* Force memory writes before continuing. */ + + restore_context: + ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + ldr r1, [r3] /* r1 = pxCurrentTCB.*/ + ldr r2, [r1] /* r2 = Location of saved context in TCB. */ + + restore_special_regs: + ldmdb r2!, {r0, r3-r5, lr} /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */ + msr psp, r3 + msr psplim, r4 + msr control, r5 + ldr r4, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */ + str r0, [r4] /* Restore xSecureContext. */ + cbz r0, restore_ns_context /* No secure context to restore. */ + + restore_s_context: + push {r1-r3, lr} + bl SecureContext_LoadContext /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ + pop {r1-r3, lr} + + restore_ns_context: + mov r0, lr /* r0 = LR (EXC_RETURN). */ + lsls r0, r0, #25 /* r0 = r0 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ + bmi restore_context_done /* r0 < 0 ==> Bit[6] in EXC_RETURN is 1 ==> secure stack was used to store the stack frame. */ + + restore_general_regs: + ldmdb r2!, {r4-r11} /* r4-r11 contain hardware saved context. */ + stmia r3!, {r4-r11} /* Copy the hardware saved context on the task stack. */ + ldmdb r2!, {r4-r11} /* r4-r11 restored. */ + + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + tst lr, #0x10 + ittt eq + vldmdbeq r2!, {s0-s16} /* s0-s16 contain hardware saved FP context. */ + vstmiaeq r3!, {s0-s16} /* Copy hardware saved FP context on the task stack. */ + vldmdbeq r2!, {s16-s31} /* Restore s16-s31. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ + + restore_context_done: + str r2, [r1] /* Save the location where the context should be saved next as the first member of TCB. */ + bx lr + +#else /* configENABLE_MPU */ + PendSV_Handler: ldr r3, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */ ldr r0, [r3] /* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */ @@ -200,20 +378,11 @@ PendSV_Handler: ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r3] /* Read pxCurrentTCB. */ -#if ( configENABLE_MPU == 1 ) - subs r2, r2, #16 /* Make space for xSecureContext, PSPLIM, CONTROL and LR on the stack. */ - str r2, [r1] /* Save the new top of stack in TCB. */ - mrs r1, psplim /* r1 = PSPLIM. */ - mrs r3, control /* r3 = CONTROL. */ - mov r4, lr /* r4 = LR/EXC_RETURN. */ - stmia r2!, {r0, r1, r3, r4} /* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */ -#else /* configENABLE_MPU */ subs r2, r2, #12 /* Make space for xSecureContext, PSPLIM and LR on the stack. */ str r2, [r1] /* Save the new top of stack in TCB. */ mrs r1, psplim /* r1 = PSPLIM. */ mov r3, lr /* r3 = LR/EXC_RETURN. */ stmia r2!, {r0, r1, r3} /* Store xSecureContext, PSPLIM and LR on the stack. */ -#endif /* configENABLE_MPU */ b select_next_task save_ns_context: @@ -224,17 +393,6 @@ PendSV_Handler: it eq vstmdbeq r2!, {s16-s31} /* Store the additional FP context registers which are not saved automatically. */ #endif /* configENABLE_FPU || configENABLE_MVE */ - #if ( configENABLE_MPU == 1 ) - subs r2, r2, #48 /* Make space for xSecureContext, PSPLIM, CONTROL, LR and the remaining registers on the stack. */ - str r2, [r1] /* Save the new top of stack in TCB. */ - adds r2, r2, #16 /* r2 = r2 + 16. */ - stm r2, {r4-r11} /* Store the registers that are not saved automatically. */ - mrs r1, psplim /* r1 = PSPLIM. */ - mrs r3, control /* r3 = CONTROL. */ - mov r4, lr /* r4 = LR/EXC_RETURN. */ - subs r2, r2, #16 /* r2 = r2 - 16. */ - stmia r2!, {r0, r1, r3, r4} /* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */ - #else /* configENABLE_MPU */ subs r2, r2, #44 /* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */ str r2, [r1] /* Save the new top of stack in TCB. */ adds r2, r2, #12 /* r2 = r2 + 12. */ @@ -243,7 +401,6 @@ PendSV_Handler: mov r3, lr /* r3 = LR/EXC_RETURN. */ subs r2, r2, #12 /* r2 = r2 - 12. */ stmia r2!, {r0, r1, r3} /* Store xSecureContext, PSPLIM and LR on the stack. */ - #endif /* configENABLE_MPU */ select_next_task: mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY @@ -258,51 +415,6 @@ PendSV_Handler: ldr r1, [r3] /* Read pxCurrentTCB. */ ldr r2, [r1] /* The first item in pxCurrentTCB is the task top of stack. r2 now points to the top of stack. */ - #if ( configENABLE_MPU == 1 ) - dmb /* Complete outstanding transfers before disabling MPU. */ - ldr r3, =0xe000ed94 /* r3 = 0xe000ed94 [Location of MPU_CTRL]. */ - ldr r4, [r3] /* Read the value of MPU_CTRL. */ - bic r4, r4, #1 /* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */ - str r4, [r3] /* Disable MPU. */ - - adds r1, #4 /* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */ - ldr r4, [r1] /* r4 = *r1 i.e. r4 = MAIR0. */ - ldr r3, =0xe000edc0 /* r3 = 0xe000edc0 [Location of MAIR0]. */ - str r4, [r3] /* Program MAIR0. */ - ldr r3, =0xe000ed98 /* r3 = 0xe000ed98 [Location of RNR]. */ - movs r4, #4 /* r4 = 4. */ - str r4, [r3] /* Program RNR = 4. */ - adds r1, #4 /* r1 = r1 + 4. r1 now points to first RBAR in TCB. */ - ldr r3, =0xe000ed9c /* r3 = 0xe000ed9c [Location of RBAR]. */ - ldmia r1!, {r4-r11} /* Read 4 sets of RBAR/RLAR registers from TCB. */ - stmia r3!, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ - - ldr r3, =0xe000ed94 /* r3 = 0xe000ed94 [Location of MPU_CTRL]. */ - ldr r4, [r3] /* Read the value of MPU_CTRL. */ - orr r4, r4, #1 /* r4 = r4 | 1 i.e. Set the bit 0 in r4. */ - str r4, [r3] /* Enable MPU. */ - dsb /* Force memory writes before continuing. */ - #endif /* configENABLE_MPU */ - - #if ( configENABLE_MPU == 1 ) - ldmia r2!, {r0, r1, r3, r4} /* Read from stack - r0 = xSecureContext, r1 = PSPLIM, r3 = CONTROL and r4 = LR. */ - msr psplim, r1 /* Restore the PSPLIM register value for the task. */ - msr control, r3 /* Restore the CONTROL register value for the task. */ - mov lr, r4 /* LR = r4. */ - ldr r3, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */ - str r0, [r3] /* Restore the task's xSecureContext. */ - cbz r0, restore_ns_context /* If there is no secure context for the task, restore the non-secure context. */ - ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - ldr r1, [r3] /* Read pxCurrentTCB. */ - push {r2, r4} - bl SecureContext_LoadContext /* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ - pop {r2, r4} - mov lr, r4 /* LR = r4. */ - lsls r1, r4, #25 /* r1 = r4 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ - bpl restore_ns_context /* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ - msr psp, r2 /* Remember the new top of stack for the task. */ - bx lr - #else /* configENABLE_MPU */ ldmia r2!, {r0, r1, r4} /* Read from stack - r0 = xSecureContext, r1 = PSPLIM and r4 = LR. */ msr psplim, r1 /* Restore the PSPLIM register value for the task. */ mov lr, r4 /* LR = r4. */ @@ -319,7 +431,6 @@ PendSV_Handler: bpl restore_ns_context /* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ msr psp, r2 /* Remember the new top of stack for the task. */ bx lr - #endif /* configENABLE_MPU */ restore_ns_context: ldmia r2!, {r4-r11} /* Restore the registers that are not automatically restored. */ @@ -330,14 +441,50 @@ PendSV_Handler: #endif /* configENABLE_FPU || configENABLE_MVE */ msr psp, r2 /* Remember the new top of stack for the task. */ bx lr + +#endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + SVC_Handler: tst lr, #4 ite eq mrseq r0, msp mrsne r0, psp + + ldr r1, [r0, #24] + ldrb r2, [r1, #-2] + cmp r2, #4 /* portSVC_SYSTEM_CALL_ENTER. */ + beq syscall_enter + cmp r2, #5 /* portSVC_SYSTEM_CALL_ENTER_1. */ + beq syscall_enter_1 + cmp r2, #6 /* portSVC_SYSTEM_CALL_EXIT. */ + beq syscall_exit b vPortSVCHandler_C + + syscall_enter: + mov r1, lr + b vSystemCallEnter + + syscall_enter_1: + mov r1, lr + b vSystemCallEnter_1 + + syscall_exit: + mov r1, lr + b vSystemCallExit + +#else /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + +SVC_Handler: + tst lr, #4 + ite eq + mrseq r0, msp + mrsne r0, psp + b vPortSVCHandler_C + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ /*-----------------------------------------------------------*/ vPortFreeSecureContext: diff --git a/portable/IAR/ARM_CM33/non_secure/portmacrocommon.h b/portable/IAR/ARM_CM33/non_secure/portmacrocommon.h index c2ca5fa7730..65ac109c802 100644 --- a/portable/IAR/ARM_CM33/non_secure/portmacrocommon.h +++ b/portable/IAR/ARM_CM33/non_secure/portmacrocommon.h @@ -186,23 +186,120 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #define portMPU_REGION_EXECUTE_NEVER ( 1UL ) /*-----------------------------------------------------------*/ -/** - * @brief Settings to define an MPU region. - */ -typedef struct MPURegionSettings -{ - uint32_t ulRBAR; /**< RBAR for the region. */ - uint32_t ulRLAR; /**< RLAR for the region. */ -} MPURegionSettings_t; +#if ( configENABLE_MPU == 1 ) -/** - * @brief MPU settings as stored in the TCB. - */ -typedef struct MPU_SETTINGS -{ - uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ - MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */ -} xMPU_SETTINGS; + /** + * @brief Settings to define an MPU region. + */ + typedef struct MPURegionSettings + { + uint32_t ulRBAR; /**< RBAR for the region. */ + uint32_t ulRLAR; /**< RLAR for the region. */ + } MPURegionSettings_t; + + #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + + #ifndef configSYSTEM_CALL_STACK_SIZE + #error configSYSTEM_CALL_STACK_SIZE must be defined to the desired size of the system call stack in words for using MPU wrappers v2. + #endif + + /** + * @brief System call stack. + */ + typedef struct SYSTEM_CALL_STACK_INFO + { + uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ]; + uint32_t * pulSystemCallStack; + uint32_t * pulSystemCallStackLimit; + uint32_t * pulTaskStack; + uint32_t ulLinkRegisterAtSystemCallEntry; + uint32_t ulStackLimitRegisterAtSystemCallEntry; + } xSYSTEM_CALL_STACK_INFO; + + #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + + /** + * @brief MPU settings as stored in the TCB. + */ + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + + #if( configENABLE_TRUSTZONE == 1 ) + + /* + * +-----------+---------------+----------+-----------------+------------------------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | + * | | | | PC, xPSR | CONTROL, EXC_RETURN | | + * +-----------+---------------+----------+-----------------+------------------------------+-----+ + * + * <-----------><--------------><---------><----------------><-----------------------------><----> + * 16 16 8 8 5 1 + */ + #define MAX_CONTEXT_SIZE 54 + + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ + + /* + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | + * | | | | PC, xPSR | EXC_RETURN | | + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * + * <-----------><--------------><---------><----------------><---------------------><----> + * 16 16 8 8 4 1 + */ + #define MAX_CONTEXT_SIZE 53 + + #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + + #else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ + + #if( configENABLE_TRUSTZONE == 1 ) + + /* + * +----------+-----------------+------------------------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | + * | | PC, xPSR | CONTROL, EXC_RETURN | | + * +----------+-----------------+------------------------------+-----+ + * + * <---------><----------------><------------------------------><----> + * 8 8 5 1 + */ + #define MAX_CONTEXT_SIZE 22 + + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ + + /* + * +----------+-----------------+----------------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | + * | | PC, xPSR | EXC_RETURN | | + * +----------+-----------------+----------------------+-----+ + * + * <---------><----------------><----------------------><----> + * 8 8 4 1 + */ + #define MAX_CONTEXT_SIZE 21 + + #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + + #endif /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ + + /* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ + #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) + #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) + + typedef struct MPU_SETTINGS + { + uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ + MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */ + uint32_t ulContext[ MAX_CONTEXT_SIZE ]; + uint32_t ulTaskFlags; + + #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo; + #endif + } xMPU_SETTINGS; + +#endif /* configENABLE_MPU == 1 */ /*-----------------------------------------------------------*/ /** @@ -223,6 +320,9 @@ typedef struct MPU_SETTINGS #define portSVC_FREE_SECURE_CONTEXT 1 #define portSVC_START_SCHEDULER 2 #define portSVC_RAISE_PRIVILEGE 3 +#define portSVC_SYSTEM_CALL_ENTER 4 /* System calls with upto 4 parameters. */ +#define portSVC_SYSTEM_CALL_ENTER_1 5 /* System calls with 5 parameters. */ +#define portSVC_SYSTEM_CALL_EXIT 6 /*-----------------------------------------------------------*/ /** @@ -315,6 +415,20 @@ typedef struct MPU_SETTINGS #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ +#if ( configENABLE_MPU == 1 ) + + extern BaseType_t xPortIsTaskPrivileged( void ); + + /** + * @brief Checks whether or not the calling task is privileged. + * + * @return pdTRUE if the calling task is privileged, pdFALSE otherwise. + */ + #define portIS_TASK_PRIVILEGED() xPortIsTaskPrivileged() + +#endif /* configENABLE_MPU == 1 */ +/*-----------------------------------------------------------*/ + /** * @brief Barriers. */ diff --git a/portable/IAR/ARM_CM33_NTZ/non_secure/mpu_wrappers_v2_asm.S b/portable/IAR/ARM_CM33_NTZ/non_secure/mpu_wrappers_v2_asm.S new file mode 100644 index 00000000000..f051a6073dd --- /dev/null +++ b/portable/IAR/ARM_CM33_NTZ/non_secure/mpu_wrappers_v2_asm.S @@ -0,0 +1,1552 @@ +/* + * FreeRTOS Kernel + * Copyright (C) 2021 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 + * + */ + + + SECTION freertos_system_calls:CODE:NOROOT(2) + THUMB +/*-----------------------------------------------------------*/ + +#include "FreeRTOSConfig.h" + +#ifndef configUSE_MPU_WRAPPERS_V1 + #define configUSE_MPU_WRAPPERS_V1 0 +#endif + +/* These must be in sync with portmacro.h. */ +#define portSVC_SYSTEM_CALL_ENTER 4 /* System calls with upto 4 parameters. */ +#define portSVC_SYSTEM_CALL_ENTER_1 5 /* System calls with 5 parameters. */ +#define portSVC_SYSTEM_CALL_EXIT 6 +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + + PUBLIC MPU_xTaskDelayUntil +MPU_xTaskDelayUntil: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskDelayUntil_Unpriv + MPU_xTaskDelayUntil_Priv: + pop {r0} + b MPU_xTaskDelayUntilImpl + MPU_xTaskDelayUntil_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskDelayUntilImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskAbortDelay +MPU_xTaskAbortDelay: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskAbortDelay_Unpriv + MPU_xTaskAbortDelay_Priv: + pop {r0} + b MPU_xTaskAbortDelayImpl + MPU_xTaskAbortDelay_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskAbortDelayImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTaskDelay +MPU_vTaskDelay: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vTaskDelay_Unpriv + MPU_vTaskDelay_Priv: + pop {r0} + b MPU_vTaskDelayImpl + MPU_vTaskDelay_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskDelayImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxTaskPriorityGet +MPU_uxTaskPriorityGet: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_uxTaskPriorityGet_Unpriv + MPU_uxTaskPriorityGet_Priv: + pop {r0} + b MPU_uxTaskPriorityGetImpl + MPU_uxTaskPriorityGet_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxTaskPriorityGetImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_eTaskGetState +MPU_eTaskGetState: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_eTaskGetState_Unpriv + MPU_eTaskGetState_Priv: + pop {r0} + b MPU_eTaskGetStateImpl + MPU_eTaskGetState_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_eTaskGetStateImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTaskGetInfo +MPU_vTaskGetInfo: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vTaskGetInfo_Unpriv + MPU_vTaskGetInfo_Priv: + pop {r0} + b MPU_vTaskGetInfoImpl + MPU_vTaskGetInfo_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskGetInfoImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGetIdleTaskHandle +MPU_xTaskGetIdleTaskHandle: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskGetIdleTaskHandle_Unpriv + MPU_xTaskGetIdleTaskHandle_Priv: + pop {r0} + b MPU_xTaskGetIdleTaskHandleImpl + MPU_xTaskGetIdleTaskHandle_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskGetIdleTaskHandleImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTaskSuspend +MPU_vTaskSuspend: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vTaskSuspend_Unpriv + MPU_vTaskSuspend_Priv: + pop {r0} + b MPU_vTaskSuspendImpl + MPU_vTaskSuspend_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskSuspendImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTaskResume +MPU_vTaskResume: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vTaskResume_Unpriv + MPU_vTaskResume_Priv: + pop {r0} + b MPU_vTaskResumeImpl + MPU_vTaskResume_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskResumeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGetTickCount +MPU_xTaskGetTickCount: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskGetTickCount_Unpriv + MPU_xTaskGetTickCount_Priv: + pop {r0} + b MPU_xTaskGetTickCountImpl + MPU_xTaskGetTickCount_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskGetTickCountImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxTaskGetNumberOfTasks +MPU_uxTaskGetNumberOfTasks: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_uxTaskGetNumberOfTasks_Unpriv + MPU_uxTaskGetNumberOfTasks_Priv: + pop {r0} + b MPU_uxTaskGetNumberOfTasksImpl + MPU_uxTaskGetNumberOfTasks_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxTaskGetNumberOfTasksImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_pcTaskGetName +MPU_pcTaskGetName: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_pcTaskGetName_Unpriv + MPU_pcTaskGetName_Priv: + pop {r0} + b MPU_pcTaskGetNameImpl + MPU_pcTaskGetName_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_pcTaskGetNameImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_ulTaskGetRunTimeCounter +MPU_ulTaskGetRunTimeCounter: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_ulTaskGetRunTimeCounter_Unpriv + MPU_ulTaskGetRunTimeCounter_Priv: + pop {r0} + b MPU_ulTaskGetRunTimeCounterImpl + MPU_ulTaskGetRunTimeCounter_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_ulTaskGetRunTimeCounterImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_ulTaskGetRunTimePercent +MPU_ulTaskGetRunTimePercent: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_ulTaskGetRunTimePercent_Unpriv + MPU_ulTaskGetRunTimePercent_Priv: + pop {r0} + b MPU_ulTaskGetRunTimePercentImpl + MPU_ulTaskGetRunTimePercent_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_ulTaskGetRunTimePercentImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_ulTaskGetIdleRunTimePercent +MPU_ulTaskGetIdleRunTimePercent: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_ulTaskGetIdleRunTimePercent_Unpriv + MPU_ulTaskGetIdleRunTimePercent_Priv: + pop {r0} + b MPU_ulTaskGetIdleRunTimePercentImpl + MPU_ulTaskGetIdleRunTimePercent_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_ulTaskGetIdleRunTimePercentImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_ulTaskGetIdleRunTimeCounter +MPU_ulTaskGetIdleRunTimeCounter: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_ulTaskGetIdleRunTimeCounter_Unpriv + MPU_ulTaskGetIdleRunTimeCounter_Priv: + pop {r0} + b MPU_ulTaskGetIdleRunTimeCounterImpl + MPU_ulTaskGetIdleRunTimeCounter_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_ulTaskGetIdleRunTimeCounterImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTaskSetApplicationTaskTag +MPU_vTaskSetApplicationTaskTag: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vTaskSetApplicationTaskTag_Unpriv + MPU_vTaskSetApplicationTaskTag_Priv: + pop {r0} + b MPU_vTaskSetApplicationTaskTagImpl + MPU_vTaskSetApplicationTaskTag_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskSetApplicationTaskTagImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGetApplicationTaskTag +MPU_xTaskGetApplicationTaskTag: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskGetApplicationTaskTag_Unpriv + MPU_xTaskGetApplicationTaskTag_Priv: + pop {r0} + b MPU_xTaskGetApplicationTaskTagImpl + MPU_xTaskGetApplicationTaskTag_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskGetApplicationTaskTagImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTaskSetThreadLocalStoragePointer +MPU_vTaskSetThreadLocalStoragePointer: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vTaskSetThreadLocalStoragePointer_Unpriv + MPU_vTaskSetThreadLocalStoragePointer_Priv: + pop {r0} + b MPU_vTaskSetThreadLocalStoragePointerImpl + MPU_vTaskSetThreadLocalStoragePointer_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskSetThreadLocalStoragePointerImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_pvTaskGetThreadLocalStoragePointer +MPU_pvTaskGetThreadLocalStoragePointer: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_pvTaskGetThreadLocalStoragePointer_Unpriv + MPU_pvTaskGetThreadLocalStoragePointer_Priv: + pop {r0} + b MPU_pvTaskGetThreadLocalStoragePointerImpl + MPU_pvTaskGetThreadLocalStoragePointer_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_pvTaskGetThreadLocalStoragePointerImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxTaskGetSystemState +MPU_uxTaskGetSystemState: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_uxTaskGetSystemState_Unpriv + MPU_uxTaskGetSystemState_Priv: + pop {r0} + b MPU_uxTaskGetSystemStateImpl + MPU_uxTaskGetSystemState_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxTaskGetSystemStateImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxTaskGetStackHighWaterMark +MPU_uxTaskGetStackHighWaterMark: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_uxTaskGetStackHighWaterMark_Unpriv + MPU_uxTaskGetStackHighWaterMark_Priv: + pop {r0} + b MPU_uxTaskGetStackHighWaterMarkImpl + MPU_uxTaskGetStackHighWaterMark_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxTaskGetStackHighWaterMarkImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxTaskGetStackHighWaterMark2 +MPU_uxTaskGetStackHighWaterMark2: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_uxTaskGetStackHighWaterMark2_Unpriv + MPU_uxTaskGetStackHighWaterMark2_Priv: + pop {r0} + b MPU_uxTaskGetStackHighWaterMark2Impl + MPU_uxTaskGetStackHighWaterMark2_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxTaskGetStackHighWaterMark2Impl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGetCurrentTaskHandle +MPU_xTaskGetCurrentTaskHandle: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskGetCurrentTaskHandle_Unpriv + MPU_xTaskGetCurrentTaskHandle_Priv: + pop {r0} + b MPU_xTaskGetCurrentTaskHandleImpl + MPU_xTaskGetCurrentTaskHandle_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskGetCurrentTaskHandleImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGetSchedulerState +MPU_xTaskGetSchedulerState: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskGetSchedulerState_Unpriv + MPU_xTaskGetSchedulerState_Priv: + pop {r0} + b MPU_xTaskGetSchedulerStateImpl + MPU_xTaskGetSchedulerState_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskGetSchedulerStateImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTaskSetTimeOutState +MPU_vTaskSetTimeOutState: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vTaskSetTimeOutState_Unpriv + MPU_vTaskSetTimeOutState_Priv: + pop {r0} + b MPU_vTaskSetTimeOutStateImpl + MPU_vTaskSetTimeOutState_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskSetTimeOutStateImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskCheckForTimeOut +MPU_xTaskCheckForTimeOut: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskCheckForTimeOut_Unpriv + MPU_xTaskCheckForTimeOut_Priv: + pop {r0} + b MPU_xTaskCheckForTimeOutImpl + MPU_xTaskCheckForTimeOut_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskCheckForTimeOutImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGenericNotify +MPU_xTaskGenericNotify: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskGenericNotify_Unpriv + MPU_xTaskGenericNotify_Priv: + pop {r0} + b MPU_xTaskGenericNotifyImpl + MPU_xTaskGenericNotify_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER_1 + bl MPU_xTaskGenericNotifyImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGenericNotifyWait +MPU_xTaskGenericNotifyWait: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskGenericNotifyWait_Unpriv + MPU_xTaskGenericNotifyWait_Priv: + pop {r0} + b MPU_xTaskGenericNotifyWaitImpl + MPU_xTaskGenericNotifyWait_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER_1 + bl MPU_xTaskGenericNotifyWaitImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_ulTaskGenericNotifyTake +MPU_ulTaskGenericNotifyTake: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_ulTaskGenericNotifyTake_Unpriv + MPU_ulTaskGenericNotifyTake_Priv: + pop {r0} + b MPU_ulTaskGenericNotifyTakeImpl + MPU_ulTaskGenericNotifyTake_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_ulTaskGenericNotifyTakeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGenericNotifyStateClear +MPU_xTaskGenericNotifyStateClear: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskGenericNotifyStateClear_Unpriv + MPU_xTaskGenericNotifyStateClear_Priv: + pop {r0} + b MPU_xTaskGenericNotifyStateClearImpl + MPU_xTaskGenericNotifyStateClear_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskGenericNotifyStateClearImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_ulTaskGenericNotifyValueClear +MPU_ulTaskGenericNotifyValueClear: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_ulTaskGenericNotifyValueClear_Unpriv + MPU_ulTaskGenericNotifyValueClear_Priv: + pop {r0} + b MPU_ulTaskGenericNotifyValueClearImpl + MPU_ulTaskGenericNotifyValueClear_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_ulTaskGenericNotifyValueClearImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueGenericSend +MPU_xQueueGenericSend: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xQueueGenericSend_Unpriv + MPU_xQueueGenericSend_Priv: + pop {r0} + b MPU_xQueueGenericSendImpl + MPU_xQueueGenericSend_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueGenericSendImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxQueueMessagesWaiting +MPU_uxQueueMessagesWaiting: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_uxQueueMessagesWaiting_Unpriv + MPU_uxQueueMessagesWaiting_Priv: + pop {r0} + b MPU_uxQueueMessagesWaitingImpl + MPU_uxQueueMessagesWaiting_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxQueueMessagesWaitingImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxQueueSpacesAvailable +MPU_uxQueueSpacesAvailable: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_uxQueueSpacesAvailable_Unpriv + MPU_uxQueueSpacesAvailable_Priv: + pop {r0} + b MPU_uxQueueSpacesAvailableImpl + MPU_uxQueueSpacesAvailable_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxQueueSpacesAvailableImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueReceive +MPU_xQueueReceive: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xQueueReceive_Unpriv + MPU_xQueueReceive_Priv: + pop {r0} + b MPU_xQueueReceiveImpl + MPU_xQueueReceive_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueReceiveImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueuePeek +MPU_xQueuePeek: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xQueuePeek_Unpriv + MPU_xQueuePeek_Priv: + pop {r0} + b MPU_xQueuePeekImpl + MPU_xQueuePeek_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueuePeekImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueSemaphoreTake +MPU_xQueueSemaphoreTake: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xQueueSemaphoreTake_Unpriv + MPU_xQueueSemaphoreTake_Priv: + pop {r0} + b MPU_xQueueSemaphoreTakeImpl + MPU_xQueueSemaphoreTake_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueSemaphoreTakeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueGetMutexHolder +MPU_xQueueGetMutexHolder: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xQueueGetMutexHolder_Unpriv + MPU_xQueueGetMutexHolder_Priv: + pop {r0} + b MPU_xQueueGetMutexHolderImpl + MPU_xQueueGetMutexHolder_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueGetMutexHolderImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueTakeMutexRecursive +MPU_xQueueTakeMutexRecursive: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xQueueTakeMutexRecursive_Unpriv + MPU_xQueueTakeMutexRecursive_Priv: + pop {r0} + b MPU_xQueueTakeMutexRecursiveImpl + MPU_xQueueTakeMutexRecursive_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueTakeMutexRecursiveImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueGiveMutexRecursive +MPU_xQueueGiveMutexRecursive: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xQueueGiveMutexRecursive_Unpriv + MPU_xQueueGiveMutexRecursive_Priv: + pop {r0} + b MPU_xQueueGiveMutexRecursiveImpl + MPU_xQueueGiveMutexRecursive_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueGiveMutexRecursiveImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueSelectFromSet +MPU_xQueueSelectFromSet: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xQueueSelectFromSet_Unpriv + MPU_xQueueSelectFromSet_Priv: + pop {r0} + b MPU_xQueueSelectFromSetImpl + MPU_xQueueSelectFromSet_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueSelectFromSetImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueAddToSet +MPU_xQueueAddToSet: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xQueueAddToSet_Unpriv + MPU_xQueueAddToSet_Priv: + pop {r0} + b MPU_xQueueAddToSetImpl + MPU_xQueueAddToSet_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueAddToSetImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vQueueAddToRegistry +MPU_vQueueAddToRegistry: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vQueueAddToRegistry_Unpriv + MPU_vQueueAddToRegistry_Priv: + pop {r0} + b MPU_vQueueAddToRegistryImpl + MPU_vQueueAddToRegistry_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vQueueAddToRegistryImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vQueueUnregisterQueue +MPU_vQueueUnregisterQueue: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vQueueUnregisterQueue_Unpriv + MPU_vQueueUnregisterQueue_Priv: + pop {r0} + b MPU_vQueueUnregisterQueueImpl + MPU_vQueueUnregisterQueue_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vQueueUnregisterQueueImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_pcQueueGetName +MPU_pcQueueGetName: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_pcQueueGetName_Unpriv + MPU_pcQueueGetName_Priv: + pop {r0} + b MPU_pcQueueGetNameImpl + MPU_pcQueueGetName_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_pcQueueGetNameImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_pvTimerGetTimerID +MPU_pvTimerGetTimerID: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_pvTimerGetTimerID_Unpriv + MPU_pvTimerGetTimerID_Priv: + pop {r0} + b MPU_pvTimerGetTimerIDImpl + MPU_pvTimerGetTimerID_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_pvTimerGetTimerIDImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTimerSetTimerID +MPU_vTimerSetTimerID: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vTimerSetTimerID_Unpriv + MPU_vTimerSetTimerID_Priv: + pop {r0} + b MPU_vTimerSetTimerIDImpl + MPU_vTimerSetTimerID_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTimerSetTimerIDImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTimerIsTimerActive +MPU_xTimerIsTimerActive: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTimerIsTimerActive_Unpriv + MPU_xTimerIsTimerActive_Priv: + pop {r0} + b MPU_xTimerIsTimerActiveImpl + MPU_xTimerIsTimerActive_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTimerIsTimerActiveImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTimerGetTimerDaemonTaskHandle +MPU_xTimerGetTimerDaemonTaskHandle: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTimerGetTimerDaemonTaskHandle_Unpriv + MPU_xTimerGetTimerDaemonTaskHandle_Priv: + pop {r0} + b MPU_xTimerGetTimerDaemonTaskHandleImpl + MPU_xTimerGetTimerDaemonTaskHandle_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTimerGetTimerDaemonTaskHandleImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTimerGenericCommand +MPU_xTimerGenericCommand: + push {r0} + /* This function can be called from ISR also and therefore, we need a check + * to take privileged path, if called from ISR. */ + mrs r0, ipsr + cmp r0, #0 + bne MPU_xTimerGenericCommand_Priv + mrs r0, control + tst r0, #1 + beq MPU_xTimerGenericCommand_Priv + MPU_xTimerGenericCommand_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER_1 + bl MPU_xTimerGenericCommandImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr + MPU_xTimerGenericCommand_Priv: + pop {r0} + b MPU_xTimerGenericCommandImpl + +/*-----------------------------------------------------------*/ + + PUBLIC MPU_pcTimerGetName +MPU_pcTimerGetName: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_pcTimerGetName_Unpriv + MPU_pcTimerGetName_Priv: + pop {r0} + b MPU_pcTimerGetNameImpl + MPU_pcTimerGetName_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_pcTimerGetNameImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTimerSetReloadMode +MPU_vTimerSetReloadMode: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vTimerSetReloadMode_Unpriv + MPU_vTimerSetReloadMode_Priv: + pop {r0} + b MPU_vTimerSetReloadModeImpl + MPU_vTimerSetReloadMode_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTimerSetReloadModeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTimerGetReloadMode +MPU_xTimerGetReloadMode: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTimerGetReloadMode_Unpriv + MPU_xTimerGetReloadMode_Priv: + pop {r0} + b MPU_xTimerGetReloadModeImpl + MPU_xTimerGetReloadMode_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTimerGetReloadModeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxTimerGetReloadMode +MPU_uxTimerGetReloadMode: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_uxTimerGetReloadMode_Unpriv + MPU_uxTimerGetReloadMode_Priv: + pop {r0} + b MPU_uxTimerGetReloadModeImpl + MPU_uxTimerGetReloadMode_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxTimerGetReloadModeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTimerGetPeriod +MPU_xTimerGetPeriod: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTimerGetPeriod_Unpriv + MPU_xTimerGetPeriod_Priv: + pop {r0} + b MPU_xTimerGetPeriodImpl + MPU_xTimerGetPeriod_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTimerGetPeriodImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTimerGetExpiryTime +MPU_xTimerGetExpiryTime: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTimerGetExpiryTime_Unpriv + MPU_xTimerGetExpiryTime_Priv: + pop {r0} + b MPU_xTimerGetExpiryTimeImpl + MPU_xTimerGetExpiryTime_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTimerGetExpiryTimeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xEventGroupWaitBits +MPU_xEventGroupWaitBits: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xEventGroupWaitBits_Unpriv + MPU_xEventGroupWaitBits_Priv: + pop {r0} + b MPU_xEventGroupWaitBitsImpl + MPU_xEventGroupWaitBits_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER_1 + bl MPU_xEventGroupWaitBitsImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xEventGroupClearBits +MPU_xEventGroupClearBits: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xEventGroupClearBits_Unpriv + MPU_xEventGroupClearBits_Priv: + pop {r0} + b MPU_xEventGroupClearBitsImpl + MPU_xEventGroupClearBits_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xEventGroupClearBitsImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xEventGroupSetBits +MPU_xEventGroupSetBits: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xEventGroupSetBits_Unpriv + MPU_xEventGroupSetBits_Priv: + pop {r0} + b MPU_xEventGroupSetBitsImpl + MPU_xEventGroupSetBits_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xEventGroupSetBitsImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xEventGroupSync +MPU_xEventGroupSync: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xEventGroupSync_Unpriv + MPU_xEventGroupSync_Priv: + pop {r0} + b MPU_xEventGroupSyncImpl + MPU_xEventGroupSync_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xEventGroupSyncImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxEventGroupGetNumber +MPU_uxEventGroupGetNumber: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_uxEventGroupGetNumber_Unpriv + MPU_uxEventGroupGetNumber_Priv: + pop {r0} + b MPU_uxEventGroupGetNumberImpl + MPU_uxEventGroupGetNumber_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxEventGroupGetNumberImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vEventGroupSetNumber +MPU_vEventGroupSetNumber: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vEventGroupSetNumber_Unpriv + MPU_vEventGroupSetNumber_Priv: + pop {r0} + b MPU_vEventGroupSetNumberImpl + MPU_vEventGroupSetNumber_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vEventGroupSetNumberImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferSend +MPU_xStreamBufferSend: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xStreamBufferSend_Unpriv + MPU_xStreamBufferSend_Priv: + pop {r0} + b MPU_xStreamBufferSendImpl + MPU_xStreamBufferSend_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferSendImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferReceive +MPU_xStreamBufferReceive: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xStreamBufferReceive_Unpriv + MPU_xStreamBufferReceive_Priv: + pop {r0} + b MPU_xStreamBufferReceiveImpl + MPU_xStreamBufferReceive_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferReceiveImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferIsFull +MPU_xStreamBufferIsFull: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xStreamBufferIsFull_Unpriv + MPU_xStreamBufferIsFull_Priv: + pop {r0} + b MPU_xStreamBufferIsFullImpl + MPU_xStreamBufferIsFull_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferIsFullImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferIsEmpty +MPU_xStreamBufferIsEmpty: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xStreamBufferIsEmpty_Unpriv + MPU_xStreamBufferIsEmpty_Priv: + pop {r0} + b MPU_xStreamBufferIsEmptyImpl + MPU_xStreamBufferIsEmpty_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferIsEmptyImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferSpacesAvailable +MPU_xStreamBufferSpacesAvailable: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xStreamBufferSpacesAvailable_Unpriv + MPU_xStreamBufferSpacesAvailable_Priv: + pop {r0} + b MPU_xStreamBufferSpacesAvailableImpl + MPU_xStreamBufferSpacesAvailable_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferSpacesAvailableImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferBytesAvailable +MPU_xStreamBufferBytesAvailable: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xStreamBufferBytesAvailable_Unpriv + MPU_xStreamBufferBytesAvailable_Priv: + pop {r0} + b MPU_xStreamBufferBytesAvailableImpl + MPU_xStreamBufferBytesAvailable_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferBytesAvailableImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferSetTriggerLevel +MPU_xStreamBufferSetTriggerLevel: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xStreamBufferSetTriggerLevel_Unpriv + MPU_xStreamBufferSetTriggerLevel_Priv: + pop {r0} + b MPU_xStreamBufferSetTriggerLevelImpl + MPU_xStreamBufferSetTriggerLevel_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferSetTriggerLevelImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferNextMessageLengthBytes +MPU_xStreamBufferNextMessageLengthBytes: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xStreamBufferNextMessageLengthBytes_Unpriv + MPU_xStreamBufferNextMessageLengthBytes_Priv: + pop {r0} + b MPU_xStreamBufferNextMessageLengthBytesImpl + MPU_xStreamBufferNextMessageLengthBytes_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferNextMessageLengthBytesImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + +/* Default weak implementations in case one is not available from + * mpu_wrappers because of config options. */ + + PUBWEAK MPU_xTaskDelayUntilImpl +MPU_xTaskDelayUntilImpl: + b MPU_xTaskDelayUntilImpl + + PUBWEAK MPU_xTaskAbortDelayImpl +MPU_xTaskAbortDelayImpl: + b MPU_xTaskAbortDelayImpl + + PUBWEAK MPU_vTaskDelayImpl +MPU_vTaskDelayImpl: + b MPU_vTaskDelayImpl + + PUBWEAK MPU_uxTaskPriorityGetImpl +MPU_uxTaskPriorityGetImpl: + b MPU_uxTaskPriorityGetImpl + + PUBWEAK MPU_eTaskGetStateImpl +MPU_eTaskGetStateImpl: + b MPU_eTaskGetStateImpl + + PUBWEAK MPU_vTaskGetInfoImpl +MPU_vTaskGetInfoImpl: + b MPU_vTaskGetInfoImpl + + PUBWEAK MPU_xTaskGetIdleTaskHandleImpl +MPU_xTaskGetIdleTaskHandleImpl: + b MPU_xTaskGetIdleTaskHandleImpl + + PUBWEAK MPU_vTaskSuspendImpl +MPU_vTaskSuspendImpl: + b MPU_vTaskSuspendImpl + + PUBWEAK MPU_vTaskResumeImpl +MPU_vTaskResumeImpl: + b MPU_vTaskResumeImpl + + PUBWEAK MPU_xTaskGetTickCountImpl +MPU_xTaskGetTickCountImpl: + b MPU_xTaskGetTickCountImpl + + PUBWEAK MPU_uxTaskGetNumberOfTasksImpl +MPU_uxTaskGetNumberOfTasksImpl: + b MPU_uxTaskGetNumberOfTasksImpl + + PUBWEAK MPU_pcTaskGetNameImpl +MPU_pcTaskGetNameImpl: + b MPU_pcTaskGetNameImpl + + PUBWEAK MPU_ulTaskGetRunTimeCounterImpl +MPU_ulTaskGetRunTimeCounterImpl: + b MPU_ulTaskGetRunTimeCounterImpl + + PUBWEAK MPU_ulTaskGetRunTimePercentImpl +MPU_ulTaskGetRunTimePercentImpl: + b MPU_ulTaskGetRunTimePercentImpl + + PUBWEAK MPU_ulTaskGetIdleRunTimePercentImpl +MPU_ulTaskGetIdleRunTimePercentImpl: + b MPU_ulTaskGetIdleRunTimePercentImpl + + PUBWEAK MPU_ulTaskGetIdleRunTimeCounterImpl +MPU_ulTaskGetIdleRunTimeCounterImpl: + b MPU_ulTaskGetIdleRunTimeCounterImpl + + PUBWEAK MPU_vTaskSetApplicationTaskTagImpl +MPU_vTaskSetApplicationTaskTagImpl: + b MPU_vTaskSetApplicationTaskTagImpl + + PUBWEAK MPU_xTaskGetApplicationTaskTagImpl +MPU_xTaskGetApplicationTaskTagImpl: + b MPU_xTaskGetApplicationTaskTagImpl + + PUBWEAK MPU_vTaskSetThreadLocalStoragePointerImpl +MPU_vTaskSetThreadLocalStoragePointerImpl: + b MPU_vTaskSetThreadLocalStoragePointerImpl + + PUBWEAK MPU_pvTaskGetThreadLocalStoragePointerImpl +MPU_pvTaskGetThreadLocalStoragePointerImpl: + b MPU_pvTaskGetThreadLocalStoragePointerImpl + + PUBWEAK MPU_uxTaskGetSystemStateImpl +MPU_uxTaskGetSystemStateImpl: + b MPU_uxTaskGetSystemStateImpl + + PUBWEAK MPU_uxTaskGetStackHighWaterMarkImpl +MPU_uxTaskGetStackHighWaterMarkImpl: + b MPU_uxTaskGetStackHighWaterMarkImpl + + PUBWEAK MPU_uxTaskGetStackHighWaterMark2Impl +MPU_uxTaskGetStackHighWaterMark2Impl: + b MPU_uxTaskGetStackHighWaterMark2Impl + + PUBWEAK MPU_xTaskGetCurrentTaskHandleImpl +MPU_xTaskGetCurrentTaskHandleImpl: + b MPU_xTaskGetCurrentTaskHandleImpl + + PUBWEAK MPU_xTaskGetSchedulerStateImpl +MPU_xTaskGetSchedulerStateImpl: + b MPU_xTaskGetSchedulerStateImpl + + PUBWEAK MPU_vTaskSetTimeOutStateImpl +MPU_vTaskSetTimeOutStateImpl: + b MPU_vTaskSetTimeOutStateImpl + + PUBWEAK MPU_xTaskCheckForTimeOutImpl +MPU_xTaskCheckForTimeOutImpl: + b MPU_xTaskCheckForTimeOutImpl + + PUBWEAK MPU_xTaskGenericNotifyImpl +MPU_xTaskGenericNotifyImpl: + b MPU_xTaskGenericNotifyImpl + + PUBWEAK MPU_xTaskGenericNotifyWaitImpl +MPU_xTaskGenericNotifyWaitImpl: + b MPU_xTaskGenericNotifyWaitImpl + + PUBWEAK MPU_ulTaskGenericNotifyTakeImpl +MPU_ulTaskGenericNotifyTakeImpl: + b MPU_ulTaskGenericNotifyTakeImpl + + PUBWEAK MPU_xTaskGenericNotifyStateClearImpl +MPU_xTaskGenericNotifyStateClearImpl: + b MPU_xTaskGenericNotifyStateClearImpl + + PUBWEAK MPU_ulTaskGenericNotifyValueClearImpl +MPU_ulTaskGenericNotifyValueClearImpl: + b MPU_ulTaskGenericNotifyValueClearImpl + + PUBWEAK MPU_xQueueGenericSendImpl +MPU_xQueueGenericSendImpl: + b MPU_xQueueGenericSendImpl + + PUBWEAK MPU_uxQueueMessagesWaitingImpl +MPU_uxQueueMessagesWaitingImpl: + b MPU_uxQueueMessagesWaitingImpl + + PUBWEAK MPU_uxQueueSpacesAvailableImpl +MPU_uxQueueSpacesAvailableImpl: + b MPU_uxQueueSpacesAvailableImpl + + PUBWEAK MPU_xQueueReceiveImpl +MPU_xQueueReceiveImpl: + b MPU_xQueueReceiveImpl + + PUBWEAK MPU_xQueuePeekImpl +MPU_xQueuePeekImpl: + b MPU_xQueuePeekImpl + + PUBWEAK MPU_xQueueSemaphoreTakeImpl +MPU_xQueueSemaphoreTakeImpl: + b MPU_xQueueSemaphoreTakeImpl + + PUBWEAK MPU_xQueueGetMutexHolderImpl +MPU_xQueueGetMutexHolderImpl: + b MPU_xQueueGetMutexHolderImpl + + PUBWEAK MPU_xQueueTakeMutexRecursiveImpl +MPU_xQueueTakeMutexRecursiveImpl: + b MPU_xQueueTakeMutexRecursiveImpl + + PUBWEAK MPU_xQueueGiveMutexRecursiveImpl +MPU_xQueueGiveMutexRecursiveImpl: + b MPU_xQueueGiveMutexRecursiveImpl + + PUBWEAK MPU_xQueueSelectFromSetImpl +MPU_xQueueSelectFromSetImpl: + b MPU_xQueueSelectFromSetImpl + + PUBWEAK MPU_xQueueAddToSetImpl +MPU_xQueueAddToSetImpl: + b MPU_xQueueAddToSetImpl + + PUBWEAK MPU_vQueueAddToRegistryImpl +MPU_vQueueAddToRegistryImpl: + b MPU_vQueueAddToRegistryImpl + + PUBWEAK MPU_vQueueUnregisterQueueImpl +MPU_vQueueUnregisterQueueImpl: + b MPU_vQueueUnregisterQueueImpl + + PUBWEAK MPU_pcQueueGetNameImpl +MPU_pcQueueGetNameImpl: + b MPU_pcQueueGetNameImpl + + PUBWEAK MPU_pvTimerGetTimerIDImpl +MPU_pvTimerGetTimerIDImpl: + b MPU_pvTimerGetTimerIDImpl + + PUBWEAK MPU_vTimerSetTimerIDImpl +MPU_vTimerSetTimerIDImpl: + b MPU_vTimerSetTimerIDImpl + + PUBWEAK MPU_xTimerIsTimerActiveImpl +MPU_xTimerIsTimerActiveImpl: + b MPU_xTimerIsTimerActiveImpl + + PUBWEAK MPU_xTimerGetTimerDaemonTaskHandleImpl +MPU_xTimerGetTimerDaemonTaskHandleImpl: + b MPU_xTimerGetTimerDaemonTaskHandleImpl + + PUBWEAK MPU_xTimerGenericCommandImpl +MPU_xTimerGenericCommandImpl: + b MPU_xTimerGenericCommandImpl + + PUBWEAK MPU_pcTimerGetNameImpl +MPU_pcTimerGetNameImpl: + b MPU_pcTimerGetNameImpl + + PUBWEAK MPU_vTimerSetReloadModeImpl +MPU_vTimerSetReloadModeImpl: + b MPU_vTimerSetReloadModeImpl + + PUBWEAK MPU_xTimerGetReloadModeImpl +MPU_xTimerGetReloadModeImpl: + b MPU_xTimerGetReloadModeImpl + + PUBWEAK MPU_uxTimerGetReloadModeImpl +MPU_uxTimerGetReloadModeImpl: + b MPU_uxTimerGetReloadModeImpl + + PUBWEAK MPU_xTimerGetPeriodImpl +MPU_xTimerGetPeriodImpl: + b MPU_xTimerGetPeriodImpl + + PUBWEAK MPU_xTimerGetExpiryTimeImpl +MPU_xTimerGetExpiryTimeImpl: + b MPU_xTimerGetExpiryTimeImpl + + PUBWEAK MPU_xEventGroupWaitBitsImpl +MPU_xEventGroupWaitBitsImpl: + b MPU_xEventGroupWaitBitsImpl + + PUBWEAK MPU_xEventGroupClearBitsImpl +MPU_xEventGroupClearBitsImpl: + b MPU_xEventGroupClearBitsImpl + + PUBWEAK MPU_xEventGroupSetBitsImpl +MPU_xEventGroupSetBitsImpl: + b MPU_xEventGroupSetBitsImpl + + PUBWEAK MPU_xEventGroupSyncImpl +MPU_xEventGroupSyncImpl: + b MPU_xEventGroupSyncImpl + + PUBWEAK MPU_uxEventGroupGetNumberImpl +MPU_uxEventGroupGetNumberImpl: + b MPU_uxEventGroupGetNumberImpl + + PUBWEAK MPU_vEventGroupSetNumberImpl +MPU_vEventGroupSetNumberImpl: + b MPU_vEventGroupSetNumberImpl + + PUBWEAK MPU_xStreamBufferSendImpl +MPU_xStreamBufferSendImpl: + b MPU_xStreamBufferSendImpl + + PUBWEAK MPU_xStreamBufferReceiveImpl +MPU_xStreamBufferReceiveImpl: + b MPU_xStreamBufferReceiveImpl + + PUBWEAK MPU_xStreamBufferIsFullImpl +MPU_xStreamBufferIsFullImpl: + b MPU_xStreamBufferIsFullImpl + + PUBWEAK MPU_xStreamBufferIsEmptyImpl +MPU_xStreamBufferIsEmptyImpl: + b MPU_xStreamBufferIsEmptyImpl + + PUBWEAK MPU_xStreamBufferSpacesAvailableImpl +MPU_xStreamBufferSpacesAvailableImpl: + b MPU_xStreamBufferSpacesAvailableImpl + + PUBWEAK MPU_xStreamBufferBytesAvailableImpl +MPU_xStreamBufferBytesAvailableImpl: + b MPU_xStreamBufferBytesAvailableImpl + + PUBWEAK MPU_xStreamBufferSetTriggerLevelImpl +MPU_xStreamBufferSetTriggerLevelImpl: + b MPU_xStreamBufferSetTriggerLevelImpl + + PUBWEAK MPU_xStreamBufferNextMessageLengthBytesImpl +MPU_xStreamBufferNextMessageLengthBytesImpl: + b MPU_xStreamBufferNextMessageLengthBytesImpl + +/*-----------------------------------------------------------*/ + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + + END diff --git a/portable/IAR/ARM_CM33_NTZ/non_secure/port.c b/portable/IAR/ARM_CM33_NTZ/non_secure/port.c index 7bbe1b7bc53..cab1b3668bf 100644 --- a/portable/IAR/ARM_CM33_NTZ/non_secure/port.c +++ b/portable/IAR/ARM_CM33_NTZ/non_secure/port.c @@ -107,6 +107,13 @@ #define portPRIGROUP_SHIFT ( 8UL ) /*-----------------------------------------------------------*/ +/** + * @brief Constants used during system call enter and exit. + */ +#define portPSR_STACK_PADDING_MASK ( 1UL << 9UL ) +#define portEXC_RETURN_STACK_FRAME_TYPE_MASK ( 1UL << 4UL ) +/*-----------------------------------------------------------*/ + /** * @brief Constants required to manipulate the FPU. */ @@ -123,6 +130,14 @@ #define portFPCCR_LSPEN_MASK ( 1UL << portFPCCR_LSPEN_POS ) /*-----------------------------------------------------------*/ +/** + * @brief Offsets in the stack to the parameters when inside the SVC handler. + */ +#define portOFFSET_TO_LR ( 5 ) +#define portOFFSET_TO_PC ( 6 ) +#define portOFFSET_TO_PSR ( 7 ) +/*-----------------------------------------------------------*/ + /** * @brief Constants required to manipulate the MPU. */ @@ -148,6 +163,8 @@ #define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ #define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ +#define portMPU_RBAR_ACCESS_PERMISSIONS_MASK ( 3UL << 1UL ) + #define portMPU_MAIR_ATTR0_POS ( 0UL ) #define portMPU_MAIR_ATTR0_MASK ( 0x000000ff ) @@ -191,6 +208,30 @@ /* Expected value of the portMPU_TYPE register. */ #define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) + +/* Extract first address of the MPU region as encoded in the + * RBAR (Region Base Address Register) value. */ +#define portEXTRACT_FIRST_ADDRESS_FROM_RBAR( rbar ) \ + ( ( rbar ) & portMPU_RBAR_ADDRESS_MASK ) + +/* Extract last address of the MPU region as encoded in the + * RLAR (Region Limit Address Register) value. */ +#define portEXTRACT_LAST_ADDRESS_FROM_RLAR( rlar ) \ + ( ( ( rlar ) & portMPU_RLAR_ADDRESS_MASK ) | ~portMPU_RLAR_ADDRESS_MASK ) + +/* Does addr lies within [start, end] address range? */ +#define portIS_ADDRESS_WITHIN_RANGE( addr, start, end ) \ + ( ( ( addr ) >= ( start ) ) && ( ( addr ) <= ( end ) ) ) + +/* Is the access request satisfied by the available permissions? */ +#define portIS_AUTHORIZED( accessRequest, permissions ) \ + ( ( ( permissions ) & ( accessRequest ) ) == accessRequest ) + +/* 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 ) ) ) /*-----------------------------------------------------------*/ /** @@ -311,6 +352,19 @@ static void prvTaskExitError( void ); #if ( configENABLE_MPU == 1 ) +/** + * @brief Extract MPU region's access permissions from the Region Base Address + * Register (RBAR) value. + * + * @param ulRBARValue RBAR value for the MPU region. + * + * @return uint32_t Access permissions. + */ + static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) PRIVILEGED_FUNCTION; +#endif /* configENABLE_MPU */ + +#if ( configENABLE_MPU == 1 ) + /** * @brief Setup the Memory Protection Unit (MPU). */ @@ -365,6 +419,60 @@ void SysTick_Handler( void ) PRIVILEGED_FUNCTION; * @brief C part of SVC handler. */ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIVILEGED_FUNCTION; + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + + /** + * @brief Sets up the system call stack so that upon returning from + * SVC, the system call stack is used. + * + * It is used for the system calls with up to 4 parameters. + * + * @param pulTaskStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + */ + void vSystemCallEnter( uint32_t * pulTaskStack, uint32_t ulLR ) PRIVILEGED_FUNCTION; + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + + /** + * @brief Sets up the system call stack so that upon returning from + * SVC, the system call stack is used. + * + * It is used for the system calls with 5 parameters. + * + * @param pulTaskStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + */ + void vSystemCallEnter_1( uint32_t * pulTaskStack, uint32_t ulLR ) PRIVILEGED_FUNCTION; + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + + /** + * @brief Sets up the task stack so that upon returning from + * SVC, the task stack is used again. + * + * @param pulSystemCallStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + */ + void vSystemCallExit( uint32_t * pulSystemCallStack, uint32_t ulLR ) PRIVILEGED_FUNCTION; + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + +#if ( configENABLE_MPU == 1 ) + + /** + * @brief Checks whether or not the calling task is privileged. + * + * @return pdTRUE if the calling task is privileged, pdFALSE otherwise. + */ + BaseType_t xPortIsTaskPrivileged( void ) PRIVILEGED_FUNCTION; + +#endif /* configENABLE_MPU == 1 */ /*-----------------------------------------------------------*/ /** @@ -681,6 +789,26 @@ static void prvTaskExitError( void ) } /*-----------------------------------------------------------*/ +#if ( configENABLE_MPU == 1 ) + static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) /* PRIVILEGED_FUNCTION */ + { + uint32_t ulAccessPermissions = 0; + + if( ( ulRBARValue & portMPU_RBAR_ACCESS_PERMISSIONS_MASK ) == portMPU_REGION_READ_ONLY ) + { + ulAccessPermissions = tskMPU_READ_PERMISSION; + } + + if( ( ulRBARValue & portMPU_RBAR_ACCESS_PERMISSIONS_MASK ) == portMPU_REGION_READ_WRITE ) + { + ulAccessPermissions = ( tskMPU_READ_PERMISSION | tskMPU_WRITE_PERMISSION ); + } + + return ulAccessPermissions; + } +#endif /* configENABLE_MPU */ +/*-----------------------------------------------------------*/ + #if ( configENABLE_MPU == 1 ) static void prvSetupMPU( void ) /* PRIVILEGED_FUNCTION */ { @@ -853,7 +981,7 @@ void SysTick_Handler( void ) /* PRIVILEGED_FUNCTION */ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTION portDONT_DISCARD */ { - #if ( configENABLE_MPU == 1 ) + #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) ) #if defined( __ARMCC_VERSION ) /* Declaration when these variable are defined in code instead of being @@ -865,7 +993,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO extern uint32_t __syscalls_flash_start__[]; extern uint32_t __syscalls_flash_end__[]; #endif /* defined( __ARMCC_VERSION ) */ - #endif /* configENABLE_MPU */ + #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */ uint32_t ulPC; @@ -880,7 +1008,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO /* Register are stored on the stack in the following order - R0, R1, R2, R3, * R12, LR, PC, xPSR. */ - ulPC = pulCallerStackAddress[ 6 ]; + ulPC = pulCallerStackAddress[ portOFFSET_TO_PC ]; ucSVCNumber = ( ( uint8_t * ) ulPC )[ -2 ]; switch( ucSVCNumber ) @@ -951,18 +1079,18 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO vRestoreContextOfFirstTask(); break; - #if ( configENABLE_MPU == 1 ) - case portSVC_RAISE_PRIVILEGE: + #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) ) + case portSVC_RAISE_PRIVILEGE: - /* Only raise the privilege, if the svc was raised from any of - * the system calls. */ - if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) && - ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ) - { - vRaisePrivilege(); - } - break; - #endif /* configENABLE_MPU */ + /* Only raise the privilege, if the svc was raised from any of + * the system calls. */ + if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ) + { + vRaisePrivilege(); + } + break; + #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */ default: /* Incorrect SVC call. */ @@ -971,51 +1099,455 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } /*-----------------------------------------------------------*/ -/* *INDENT-OFF* */ -#if ( configENABLE_MPU == 1 ) - StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, - StackType_t * pxEndOfStack, - TaskFunction_t pxCode, - void * pvParameters, - BaseType_t xRunPrivileged ) /* PRIVILEGED_FUNCTION */ -#else - StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, - StackType_t * pxEndOfStack, - TaskFunction_t pxCode, - void * pvParameters ) /* PRIVILEGED_FUNCTION */ -#endif /* configENABLE_MPU */ -/* *INDENT-ON* */ +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + +void vSystemCallEnter( uint32_t * pulTaskStack, uint32_t ulLR ) /* PRIVILEGED_FUNCTION */ { - /* Simulate the stack frame as it would be created by a context switch - * interrupt. */ - #if ( portPRELOAD_REGISTERS == 0 ) + extern TaskHandle_t pxCurrentTCB; + xMPU_SETTINGS * pxMpuSettings; + uint32_t * pulSystemCallStack; + uint32_t ulStackFrameSize, ulSystemCallLocation, i; + #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being + * exported from linker scripts. */ + extern uint32_t * __syscalls_flash_start__; + extern uint32_t * __syscalls_flash_end__; + #else + /* Declaration when these variable are exported from linker scripts. */ + extern uint32_t __syscalls_flash_start__[]; + extern uint32_t __syscalls_flash_end__[]; + #endif /* #if defined( __ARMCC_VERSION ) */ + + ulSystemCallLocation = pulTaskStack[ portOFFSET_TO_PC ]; + + /* If the request did not come from the system call section, do nothing. */ + if( ( ulSystemCallLocation >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulSystemCallLocation <= ( uint32_t ) __syscalls_flash_end__ ) ) { - pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ - *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ - pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pxCode; /* PC */ - pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR */ - pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ - *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ - pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */ - *pxTopOfStack = portINITIAL_EXC_RETURN; + pxMpuSettings = xTaskGetMPUSettings( pxCurrentTCB ); + pulSystemCallStack = pxMpuSettings->xSystemCallStackInfo.pulSystemCallStack; - #if ( configENABLE_MPU == 1 ) + /* This is not NULL only for the duration of the system call. */ + configASSERT( pxMpuSettings->xSystemCallStackInfo.pulTaskStack == NULL ); + + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) { - pxTopOfStack--; + if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) + { + /* Extended frame i.e. FPU in use. */ + ulStackFrameSize = 26; + __asm volatile ( + " vpush {s0} \n" /* Trigger lazy stacking. */ + " vpop {s0} \n" /* Nullify the affect of the above instruction. */ + ::: "memory" + ); + } + else + { + /* Standard frame i.e. FPU not in use. */ + ulStackFrameSize = 8; + } + } + #else + { + ulStackFrameSize = 8; + } + #endif /* configENABLE_FPU || configENABLE_MVE */ + + /* Make space on the system call stack for the stack frame. */ + pulSystemCallStack = pulSystemCallStack - ulStackFrameSize; + + /* Copy the stack frame. */ + for( i = 0; i < ulStackFrameSize; i++ ) + { + pulSystemCallStack[ i ] = pulTaskStack[ i ]; + } + + /* Store the value of the LR and PSPLIM registers before the SVC was raised. We need to + * restore it when we exit from the system call. */ + pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; + __asm volatile ( "mrs %0, psplim" : "=r" ( pxMpuSettings->xSystemCallStackInfo.ulStackLimitRegisterAtSystemCallEntry ) ); + + /* Use the pulSystemCallStack in thread mode. */ + __asm volatile ( "msr psp, %0" : : "r" ( pulSystemCallStack ) ); + __asm volatile ( "msr psplim, %0" : : "r" ( pxMpuSettings->xSystemCallStackInfo.pulSystemCallStackLimit ) ); + + /* Remember the location where we should copy the stack frame when we exit from + * the system call. */ + pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulStackFrameSize; + + /* Record if the hardware used padding to force the stack pointer + * to be double word aligned. */ + if( ( pulTaskStack[ portOFFSET_TO_PSR ] & portPSR_STACK_PADDING_MASK ) == portPSR_STACK_PADDING_MASK ) + { + pxMpuSettings->ulTaskFlags |= portSTACK_FRAME_HAS_PADDING_FLAG; + } + else + { + pxMpuSettings->ulTaskFlags &= ( ~portSTACK_FRAME_HAS_PADDING_FLAG ); + } + + /* We ensure in pxPortInitialiseStack that the system call stack is + * double word aligned and therefore, there is no need of padding. + * Clear the bit[9] of stacked xPSR. */ + pulSystemCallStack[ portOFFSET_TO_PSR ] &= ( ~portPSR_STACK_PADDING_MASK ); + + /* Raise the privilege for the duration of the system call. */ + __asm volatile ( + " mrs r0, control \n" /* Obtain current control value. */ + " movs r1, #1 \n" /* r1 = 1. */ + " bics r0, r1 \n" /* Clear nPRIV bit. */ + " msr control, r0 \n" /* Write back new control value. */ + ::: "r0", "r1", "memory" + ); + } +} - if( xRunPrivileged == pdTRUE ) +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + +void vSystemCallEnter_1( uint32_t * pulTaskStack, uint32_t ulLR ) /* PRIVILEGED_FUNCTION */ +{ + extern TaskHandle_t pxCurrentTCB; + xMPU_SETTINGS * pxMpuSettings; + uint32_t * pulSystemCallStack; + uint32_t ulStackFrameSize, ulSystemCallLocation, i; + #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being + * exported from linker scripts. */ + extern uint32_t * __syscalls_flash_start__; + extern uint32_t * __syscalls_flash_end__; + #else + /* Declaration when these variable are exported from linker scripts. */ + extern uint32_t __syscalls_flash_start__[]; + extern uint32_t __syscalls_flash_end__[]; + #endif /* #if defined( __ARMCC_VERSION ) */ + + ulSystemCallLocation = pulTaskStack[ portOFFSET_TO_PC ]; + + /* If the request did not come from the system call section, do nothing. */ + if( ( ulSystemCallLocation >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulSystemCallLocation <= ( uint32_t ) __syscalls_flash_end__ ) ) + { + pxMpuSettings = xTaskGetMPUSettings( pxCurrentTCB ); + pulSystemCallStack = pxMpuSettings->xSystemCallStackInfo.pulSystemCallStack; + + /* This is not NULL only for the duration of the system call. */ + configASSERT( pxMpuSettings->xSystemCallStackInfo.pulTaskStack == NULL ); + + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + { + if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) { - *pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */ + /* Extended frame i.e. FPU in use. */ + ulStackFrameSize = 26; + __asm volatile ( + " vpush {s0} \n" /* Trigger lazy stacking. */ + " vpop {s0} \n" /* Nullify the affect of the above instruction. */ + ::: "memory" + ); } else { - *pxTopOfStack = portINITIAL_CONTROL_UNPRIVILEGED; /* Slot used to hold this task's CONTROL value. */ + /* Standard frame i.e. FPU not in use. */ + ulStackFrameSize = 8; } } - #endif /* configENABLE_MPU */ + #else + { + ulStackFrameSize = 8; + } + #endif /* configENABLE_FPU || configENABLE_MVE */ + + /* Make space on the system call stack for the stack frame and + * the parameter passed on the stack. We only need to copy one + * parameter but we still reserve 2 spaces to keep the stack + * double word aligned. */ + pulSystemCallStack = pulSystemCallStack - ulStackFrameSize - 2UL; + + /* Copy the stack frame. */ + for( i = 0; i < ulStackFrameSize; i++ ) + { + pulSystemCallStack[ i ] = pulTaskStack[ i ]; + } + + /* Copy the parameter which is passed the stack. */ + if( ( pulTaskStack[ portOFFSET_TO_PSR ] & portPSR_STACK_PADDING_MASK ) == portPSR_STACK_PADDING_MASK ) + { + pulSystemCallStack[ ulStackFrameSize ] = pulTaskStack[ ulStackFrameSize + 1 ]; + /* Record if the hardware used padding to force the stack pointer + * to be double word aligned. */ + pxMpuSettings->ulTaskFlags |= portSTACK_FRAME_HAS_PADDING_FLAG; + } + else + { + pulSystemCallStack[ ulStackFrameSize ] = pulTaskStack[ ulStackFrameSize ]; + /* Record if the hardware used padding to force the stack pointer + * to be double word aligned. */ + pxMpuSettings->ulTaskFlags &= ( ~portSTACK_FRAME_HAS_PADDING_FLAG ); + } + + /* Store the value of the LR and PSPLIM registers before the SVC was raised. + * We need to restore it when we exit from the system call. */ + pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; + __asm volatile ( "mrs %0, psplim" : "=r" ( pxMpuSettings->xSystemCallStackInfo.ulStackLimitRegisterAtSystemCallEntry ) ); + + /* Use the pulSystemCallStack in thread mode. */ + __asm volatile ( "msr psp, %0" : : "r" ( pulSystemCallStack ) ); + __asm volatile ( "msr psplim, %0" : : "r" ( pxMpuSettings->xSystemCallStackInfo.pulSystemCallStackLimit ) ); + + /* Remember the location where we should copy the stack frame when we exit from + * the system call. */ + pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulStackFrameSize; + + /* We ensure in pxPortInitialiseStack that the system call stack is + * double word aligned and therefore, there is no need of padding. + * Clear the bit[9] of stacked xPSR. */ + pulSystemCallStack[ portOFFSET_TO_PSR ] &= ( ~portPSR_STACK_PADDING_MASK ); + + /* Raise the privilege for the duration of the system call. */ + __asm volatile ( + " mrs r0, control \n" /* Obtain current control value. */ + " movs r1, #1 \n" /* r1 = 1. */ + " bics r0, r1 \n" /* Clear nPRIV bit. */ + " msr control, r0 \n" /* Write back new control value. */ + ::: "r0", "r1", "memory" + ); + } +} + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) +void vSystemCallExit( uint32_t * pulSystemCallStack, uint32_t ulLR ) /* PRIVILEGED_FUNCTION */ +{ + extern TaskHandle_t pxCurrentTCB; + xMPU_SETTINGS * pxMpuSettings; + uint32_t * pulTaskStack; + uint32_t ulStackFrameSize, ulSystemCallLocation, i; + #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being + * exported from linker scripts. */ + extern uint32_t * __syscalls_flash_start__; + extern uint32_t * __syscalls_flash_end__; + #else + /* Declaration when these variable are exported from linker scripts. */ + extern uint32_t __syscalls_flash_start__[]; + extern uint32_t __syscalls_flash_end__[]; + #endif /* #if defined( __ARMCC_VERSION ) */ + + ulSystemCallLocation = pulSystemCallStack[ portOFFSET_TO_PC ]; + + /* If the request did not come from the system call section, do nothing. */ + if( ( ulSystemCallLocation >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulSystemCallLocation <= ( uint32_t ) __syscalls_flash_end__ ) ) + { + pxMpuSettings = xTaskGetMPUSettings( pxCurrentTCB ); + pulTaskStack = pxMpuSettings->xSystemCallStackInfo.pulTaskStack; + + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + { + if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) + { + /* Extended frame i.e. FPU in use. */ + ulStackFrameSize = 26; + __asm volatile ( + " vpush {s0} \n" /* Trigger lazy stacking. */ + " vpop {s0} \n" /* Nullify the affect of the above instruction. */ + ::: "memory" + ); + } + else + { + /* Standard frame i.e. FPU not in use. */ + ulStackFrameSize = 8; + } + } + #else + { + ulStackFrameSize = 8; + } + #endif /* configENABLE_FPU || configENABLE_MVE */ + + /* Make space on the task stack for the stack frame. */ + pulTaskStack = pulTaskStack - ulStackFrameSize; + + /* Copy the stack frame. */ + for( i = 0; i < ulStackFrameSize; i++ ) + { + pulTaskStack[ i ] = pulSystemCallStack[ i ]; + } + + /* Use the pulTaskStack in thread mode. */ + __asm volatile ( "msr psp, %0" : : "r" ( pulTaskStack ) ); + + /* Restore the LR and PSPLIM to what they were at the time of + * system call entry. */ + pulTaskStack[ portOFFSET_TO_LR ] = pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry; + __asm volatile ( "msr psplim, %0" : : "r" ( pxMpuSettings->xSystemCallStackInfo.ulStackLimitRegisterAtSystemCallEntry ) ); + + /* If the hardware used padding to force the stack pointer + * to be double word aligned, set the stacked xPSR bit[9], + * otherwise clear it. */ + if( ( pxMpuSettings->ulTaskFlags & portSTACK_FRAME_HAS_PADDING_FLAG ) == portSTACK_FRAME_HAS_PADDING_FLAG ) + { + pulTaskStack[ portOFFSET_TO_PSR ] |= portPSR_STACK_PADDING_MASK; + } + else + { + pulTaskStack[ portOFFSET_TO_PSR ] &= ( ~portPSR_STACK_PADDING_MASK ); + } + + /* This is not NULL only for the duration of the system call. */ + pxMpuSettings->xSystemCallStackInfo.pulTaskStack = NULL; + + /* Drop the privilege before returning to the thread mode. */ + __asm volatile ( + " mrs r0, control \n" /* Obtain current control value. */ + " movs r1, #1 \n" /* r1 = 1. */ + " orrs r0, r1 \n" /* Set nPRIV bit. */ + " msr control, r0 \n" /* Write back new control value. */ + ::: "r0", "r1", "memory" + ); + } +} + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configENABLE_MPU == 1 ) + +BaseType_t xPortIsTaskPrivileged( void ) /* PRIVILEGED_FUNCTION */ +{ + BaseType_t xTaskIsPrivileged = pdFALSE; + const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */ + + if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) + { + xTaskIsPrivileged = pdTRUE; + } + + return xTaskIsPrivileged; +} + +#endif /* configENABLE_MPU == 1 */ +/*-----------------------------------------------------------*/ + +#if( configENABLE_MPU == 1 ) + +StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, + StackType_t * pxEndOfStack, + TaskFunction_t pxCode, + void * pvParameters, + BaseType_t xRunPrivileged, + xMPU_SETTINGS * xMPUSettings ) /* PRIVILEGED_FUNCTION */ +{ + uint32_t ulIndex = 0; + + xMPUSettings->ulContext[ ulIndex ] = 0x04040404; /* r4. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x05050505; /* r5. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x06060606; /* r6. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x07070707; /* r7. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x08080808; /* r8. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x09090909; /* r9. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x10101010; /* r10. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x11111111; /* r11. */ + ulIndex++; + + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pvParameters; /* r0. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x01010101; /* r1. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x02020202; /* r2. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x03030303; /* r3. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x12121212; /* r12. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portTASK_RETURN_ADDRESS; /* LR. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxCode; /* PC. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = portINITIAL_XPSR; /* xPSR. */ + ulIndex++; + + #if ( configENABLE_TRUSTZONE == 1 ) + { + xMPUSettings->ulContext[ ulIndex ] = portNO_SECURE_CONTEXT; /* xSecureContext. */ + ulIndex++; + } + #endif /* configENABLE_TRUSTZONE */ + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) ( pxTopOfStack - 8 ); /* PSP with the hardware saved stack. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */ + ulIndex++; + if( xRunPrivileged == pdTRUE ) + { + xMPUSettings->ulTaskFlags |= portTASK_IS_PRIVILEGED_FLAG; + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_PRIVILEGED; /* CONTROL. */ + ulIndex++; + } + else + { + xMPUSettings->ulTaskFlags &= ( ~portTASK_IS_PRIVILEGED_FLAG ); + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_UNPRIVILEGED; /* CONTROL. */ + ulIndex++; + } + xMPUSettings->ulContext[ ulIndex ] = portINITIAL_EXC_RETURN; /* LR (EXC_RETURN). */ + ulIndex++; + + #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + { + /* Ensure that the system call stack is double word aligned. */ + xMPUSettings->xSystemCallStackInfo.pulSystemCallStack = &( xMPUSettings->xSystemCallStackInfo.ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE - 1 ] ); + xMPUSettings->xSystemCallStackInfo.pulSystemCallStack = ( uint32_t * ) ( ( uint32_t ) ( xMPUSettings->xSystemCallStackInfo.pulSystemCallStack ) & + ( uint32_t ) ( ~( portBYTE_ALIGNMENT_MASK ) ) ); + + xMPUSettings->xSystemCallStackInfo.pulSystemCallStackLimit = &( xMPUSettings->xSystemCallStackInfo.ulSystemCallStackBuffer[ 0 ] ); + xMPUSettings->xSystemCallStackInfo.pulSystemCallStackLimit = ( uint32_t * ) ( ( ( uint32_t ) ( xMPUSettings->xSystemCallStackInfo.pulSystemCallStackLimit ) + + ( uint32_t ) ( portBYTE_ALIGNMENT - 1 ) ) & + ( uint32_t ) ( ~( portBYTE_ALIGNMENT_MASK ) ) ); + + /* This is not NULL only for the duration of a system call. */ + xMPUSettings->xSystemCallStackInfo.pulTaskStack = NULL; + } + #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + + return &( xMPUSettings->ulContext[ ulIndex ] ); +} + +#else /* configENABLE_MPU */ + +StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, + StackType_t * pxEndOfStack, + TaskFunction_t pxCode, + void * pvParameters ) /* PRIVILEGED_FUNCTION */ +{ + /* Simulate the stack frame as it would be created by a context switch + * interrupt. */ + #if ( portPRELOAD_REGISTERS == 0 ) + { + pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ + *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR. */ + pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ + pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */ + *pxTopOfStack = portINITIAL_EXC_RETURN; pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ @@ -1029,55 +1561,39 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO #else /* portPRELOAD_REGISTERS */ { pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ - *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ + *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pxCode; /* PC */ + *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR */ + *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x12121212UL; /* R12 */ + *pxTopOfStack = ( StackType_t ) 0x12121212UL; /* R12. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x03030303UL; /* R3 */ + *pxTopOfStack = ( StackType_t ) 0x03030303UL; /* R3. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x02020202UL; /* R2 */ + *pxTopOfStack = ( StackType_t ) 0x02020202UL; /* R2. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x01010101UL; /* R1 */ + *pxTopOfStack = ( StackType_t ) 0x01010101UL; /* R1. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x11111111UL; /* R11 */ + *pxTopOfStack = ( StackType_t ) 0x11111111UL; /* R11. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x10101010UL; /* R10 */ + *pxTopOfStack = ( StackType_t ) 0x10101010UL; /* R10. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x09090909UL; /* R09 */ + *pxTopOfStack = ( StackType_t ) 0x09090909UL; /* R09. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x08080808UL; /* R08 */ + *pxTopOfStack = ( StackType_t ) 0x08080808UL; /* R08. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x07070707UL; /* R07 */ + *pxTopOfStack = ( StackType_t ) 0x07070707UL; /* R07. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x06060606UL; /* R06 */ + *pxTopOfStack = ( StackType_t ) 0x06060606UL; /* R06. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x05050505UL; /* R05 */ + *pxTopOfStack = ( StackType_t ) 0x05050505UL; /* R05. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x04040404UL; /* R04 */ + *pxTopOfStack = ( StackType_t ) 0x04040404UL; /* R04. */ pxTopOfStack--; - *pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN */ - - #if ( configENABLE_MPU == 1 ) - { - pxTopOfStack--; - - if( xRunPrivileged == pdTRUE ) - { - *pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */ - } - else - { - *pxTopOfStack = portINITIAL_CONTROL_UNPRIVILEGED; /* Slot used to hold this task's CONTROL value. */ - } - } - #endif /* configENABLE_MPU */ - + *pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN. */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ @@ -1092,6 +1608,8 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO return pxTopOfStack; } + +#endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ @@ -1128,6 +1646,10 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ configASSERT( ucMaxSysCallPriority ); + /* Check that the bits not implemented in hardware are zero in + * configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & ( ~ucMaxPriorityValue ) ) == 0U ); + /* Calculate the maximum acceptable priority group value for the number * of bits read back. */ @@ -1164,35 +1686,6 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulImplementedPrioBits; } - /* The interrupt priority bits are not modelled in QEMU and the assert that - * checks the number of implemented bits and __NVIC_PRIO_BITS will always fail. - * Therefore, this assert is not adding any value for QEMU targets. The config - * option `configDISABLE_INTERRUPT_PRIO_BITS_CHECK` should be defined in the - * `FreeRTOSConfig.h` for QEMU targets. */ - #ifndef configDISABLE_INTERRUPT_PRIO_BITS_CHECK - { - #ifdef __NVIC_PRIO_BITS - { - /* - * Check that the number of implemented priority bits queried from - * hardware is equal to the CMSIS __NVIC_PRIO_BITS configuration macro. - */ - configASSERT( ulImplementedPrioBits == __NVIC_PRIO_BITS ); - } - #endif /* __NVIC_PRIO_BITS */ - - #ifdef configPRIO_BITS - { - /* - * Check that the number of implemented priority bits queried from - * hardware is equal to the FreeRTOS configPRIO_BITS configuration macro. - */ - configASSERT( ulImplementedPrioBits == configPRIO_BITS ); - } - #endif /* configPRIO_BITS */ - } - #endif /* #ifndef configDISABLE_INTERRUPT_PRIO_BITS_CHECK */ - /* Shift the priority group value back to its position within the AIRCR * register. */ ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT; @@ -1372,6 +1865,54 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ +#if ( configENABLE_MPU == 1 ) + BaseType_t xPortIsAuthorizedToAccessBuffer( const void * pvBuffer, + uint32_t ulBufferLength, + uint32_t ulAccessRequested ) /* PRIVILEGED_FUNCTION */ + + { + uint32_t i, ulBufferStartAddress, ulBufferEndAddress; + BaseType_t xAccessGranted = pdFALSE; + const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */ + + if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) + { + xAccessGranted = pdTRUE; + } + else + { + if( portADD_UINT32_WILL_OVERFLOW( ( ( uint32_t ) pvBuffer ), ( ulBufferLength - 1UL ) ) == pdFALSE ) + { + ulBufferStartAddress = ( uint32_t ) pvBuffer; + ulBufferEndAddress = ( ( ( uint32_t ) pvBuffer ) + ulBufferLength - 1UL ); + + for( i = 0; i < portTOTAL_NUM_REGIONS; i++ ) + { + /* Is the MPU region enabled? */ + if( ( xTaskMpuSettings->xRegionsSettings[ i ].ulRLAR & portMPU_RLAR_REGION_ENABLE ) == portMPU_RLAR_REGION_ENABLE ) + { + if( portIS_ADDRESS_WITHIN_RANGE( ulBufferStartAddress, + portEXTRACT_FIRST_ADDRESS_FROM_RBAR( xTaskMpuSettings->xRegionsSettings[ i ].ulRBAR ), + portEXTRACT_LAST_ADDRESS_FROM_RLAR( xTaskMpuSettings->xRegionsSettings[ i ].ulRLAR ) ) && + portIS_ADDRESS_WITHIN_RANGE( ulBufferEndAddress, + portEXTRACT_FIRST_ADDRESS_FROM_RBAR( xTaskMpuSettings->xRegionsSettings[ i ].ulRBAR ), + portEXTRACT_LAST_ADDRESS_FROM_RLAR( xTaskMpuSettings->xRegionsSettings[ i ].ulRLAR ) ) && + portIS_AUTHORIZED( ulAccessRequested, + prvGetRegionAccessPermissions( xTaskMpuSettings->xRegionsSettings[ i ].ulRBAR ) ) ) + { + xAccessGranted = pdTRUE; + break; + } + } + } + } + } + + return xAccessGranted; + } +#endif /* configENABLE_MPU */ +/*-----------------------------------------------------------*/ + BaseType_t xPortIsInsideInterrupt( void ) { uint32_t ulCurrentInterrupt; diff --git a/portable/IAR/ARM_CM33_NTZ/non_secure/portasm.s b/portable/IAR/ARM_CM33_NTZ/non_secure/portasm.s index 581b84d4951..ec52025270b 100644 --- a/portable/IAR/ARM_CM33_NTZ/non_secure/portasm.s +++ b/portable/IAR/ARM_CM33_NTZ/non_secure/portasm.s @@ -32,9 +32,18 @@ the code is included in C files but excluded by the preprocessor in assembly files (__ICCARM__ is defined by the IAR C compiler but not by the IAR assembler. */ #include "FreeRTOSConfig.h" +#ifndef configUSE_MPU_WRAPPERS_V1 + #define configUSE_MPU_WRAPPERS_V1 0 +#endif + EXTERN pxCurrentTCB EXTERN vTaskSwitchContext EXTERN vPortSVCHandler_C +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + EXTERN vSystemCallEnter + EXTERN vSystemCallEnter_1 + EXTERN vSystemCallExit +#endif PUBLIC xIsPrivileged PUBLIC vResetPrivilege @@ -79,48 +88,79 @@ vResetPrivilege: THUMB /*-----------------------------------------------------------*/ +#if ( configENABLE_MPU == 1 ) + +vRestoreContextOfFirstTask: + program_mpu_first_task: + ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + ldr r0, [r2] /* r0 = pxCurrentTCB. */ + + dmb /* Complete outstanding transfers before disabling MPU. */ + ldr r1, =0xe000ed94 /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + ldr r2, [r1] /* Read the value of MPU_CTRL. */ + bic r2, #1 /* r2 = r2 & ~1 i.e. Clear the bit 0 in r2. */ + str r2, [r1] /* Disable MPU. */ + + adds r0, #4 /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */ + ldr r1, [r0] /* r1 = *r0 i.e. r1 = MAIR0. */ + ldr r2, =0xe000edc0 /* r2 = 0xe000edc0 [Location of MAIR0]. */ + str r1, [r2] /* Program MAIR0. */ + + adds r0, #4 /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */ + ldr r1, =0xe000ed98 /* r1 = 0xe000ed98 [Location of RNR]. */ + ldr r2, =0xe000ed9c /* r2 = 0xe000ed9c [Location of RBAR]. */ + + movs r3, #4 /* r3 = 4. */ + str r3, [r1] /* Program RNR = 4. */ + ldmia r0!, {r4-r11} /* Read 4 sets of RBAR/RLAR registers from TCB. */ + stmia r2, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ + + #if ( configTOTAL_MPU_REGIONS == 16 ) + movs r3, #8 /* r3 = 8. */ + str r3, [r1] /* Program RNR = 8. */ + ldmia r0!, {r4-r11} /* Read 4 sets of RBAR/RLAR registers from TCB. */ + stmia r2, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ + movs r3, #12 /* r3 = 12. */ + str r3, [r1] /* Program RNR = 12. */ + ldmia r0!, {r4-r11} /* Read 4 sets of RBAR/RLAR registers from TCB. */ + stmia r2, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ + #endif /* configTOTAL_MPU_REGIONS == 16 */ + + ldr r1, =0xe000ed94 /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + ldr r2, [r1] /* Read the value of MPU_CTRL. */ + orr r2, #1 /* r2 = r2 | 1 i.e. Set the bit 0 in r2. */ + str r2, [r1] /* Enable MPU. */ + dsb /* Force memory writes before continuing. */ + + restore_context_first_task: + ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + ldr r0, [r2] /* r0 = pxCurrentTCB.*/ + ldr r1, [r0] /* r1 = Location of saved context in TCB. */ + + restore_special_regs_first_task: + ldmdb r1!, {r2-r4, lr} /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */ + msr psp, r2 + msr psplim, r3 + msr control, r4 + + restore_general_regs_first_task: + ldmdb r1!, {r4-r11} /* r4-r11 contain hardware saved context. */ + stmia r2!, {r4-r11} /* Copy the hardware saved context on the task stack. */ + ldmdb r1!, {r4-r11} /* r4-r11 restored. */ + + restore_context_done_first_task: + str r1, [r0] /* Save the location where the context should be saved next as the first member of TCB. */ + mov r0, #0 + msr basepri, r0 /* Ensure that interrupts are enabled when the first task starts. */ + bx lr + +#else /* configENABLE_MPU */ + vRestoreContextOfFirstTask: ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r2] /* Read pxCurrentTCB. */ ldr r0, [r1] /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ -#if ( configENABLE_MPU == 1 ) - dmb /* Complete outstanding transfers before disabling MPU. */ - ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ - ldr r4, [r2] /* Read the value of MPU_CTRL. */ - bic r4, r4, #1 /* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */ - str r4, [r2] /* Disable MPU. */ - - adds r1, #4 /* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */ - ldr r3, [r1] /* r3 = *r1 i.e. r3 = MAIR0. */ - ldr r2, =0xe000edc0 /* r2 = 0xe000edc0 [Location of MAIR0]. */ - str r3, [r2] /* Program MAIR0. */ - ldr r2, =0xe000ed98 /* r2 = 0xe000ed98 [Location of RNR]. */ - movs r3, #4 /* r3 = 4. */ - str r3, [r2] /* Program RNR = 4. */ - adds r1, #4 /* r1 = r1 + 4. r1 now points to first RBAR in TCB. */ - ldr r2, =0xe000ed9c /* r2 = 0xe000ed9c [Location of RBAR]. */ - ldmia r1!, {r4-r11} /* Read 4 sets of RBAR/RLAR registers from TCB. */ - stmia r2!, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ - - ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ - ldr r4, [r2] /* Read the value of MPU_CTRL. */ - orr r4, r4, #1 /* r4 = r4 | 1 i.e. Set the bit 0 in r4. */ - str r4, [r2] /* Enable MPU. */ - dsb /* Force memory writes before continuing. */ -#endif /* configENABLE_MPU */ - -#if ( configENABLE_MPU == 1 ) - ldm r0!, {r1-r3} /* Read from stack - r1 = PSPLIM, r2 = CONTROL and r3 = EXC_RETURN. */ - msr psplim, r1 /* Set this task's PSPLIM value. */ - msr control, r2 /* Set this task's CONTROL value. */ - adds r0, #32 /* Discard everything up to r0. */ - msr psp, r0 /* This is now the new top of stack to use in the task. */ - isb - mov r0, #0 - msr basepri, r0 /* Ensure that interrupts are enabled when the first task starts. */ - bx r3 /* Finally, branch to EXC_RETURN. */ -#else /* configENABLE_MPU */ ldm r0!, {r1-r2} /* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */ msr psplim, r1 /* Set this task's PSPLIM value. */ movs r1, #2 /* r1 = 2. */ @@ -131,6 +171,7 @@ vRestoreContextOfFirstTask: mov r0, #0 msr basepri, r0 /* Ensure that interrupts are enabled when the first task starts. */ bx r2 /* Finally, branch to EXC_RETURN. */ + #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ @@ -169,6 +210,114 @@ vClearInterruptMask: bx lr /* Return. */ /*-----------------------------------------------------------*/ +#if ( configENABLE_MPU == 1 ) + +PendSV_Handler: + ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + ldr r0, [r2] /* r0 = pxCurrentTCB. */ + ldr r1, [r0] /* r1 = Location in TCB where the context should be saved. */ + mrs r2, psp /* r2 = PSP. */ + + save_general_regs: + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + add r2, r2, #0x20 /* Move r2 to location where s0 is saved. */ + tst lr, #0x10 + ittt eq + vstmiaeq r1!, {s16-s31} /* Store s16-s31. */ + vldmiaeq r2, {s0-s16} /* Copy hardware saved FP context into s0-s16. */ + vstmiaeq r1!, {s0-s16} /* Store hardware saved FP context. */ + sub r2, r2, #0x20 /* Set r2 back to the location of hardware saved context. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ + + stmia r1!, {r4-r11} /* Store r4-r11. */ + ldmia r2, {r4-r11} /* Copy the hardware saved context into r4-r11. */ + stmia r1!, {r4-r11} /* Store the hardware saved context. */ + + save_special_regs: + mrs r3, psplim /* r3 = PSPLIM. */ + mrs r4, control /* r4 = CONTROL. */ + stmia r1!, {r2-r4, lr} /* Store original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */ + str r1, [r0] /* Save the location from where the context should be restored as the first member of TCB. */ + + select_next_task: + mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY + msr basepri, r0 /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + dsb + isb + bl vTaskSwitchContext + mov r0, #0 /* r0 = 0. */ + msr basepri, r0 /* Enable interrupts. */ + + program_mpu: + ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + ldr r0, [r2] /* r0 = pxCurrentTCB. */ + + dmb /* Complete outstanding transfers before disabling MPU. */ + ldr r1, =0xe000ed94 /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + ldr r2, [r1] /* Read the value of MPU_CTRL. */ + bic r2, #1 /* r2 = r2 & ~1 i.e. Clear the bit 0 in r2. */ + str r2, [r1] /* Disable MPU. */ + + adds r0, #4 /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */ + ldr r1, [r0] /* r1 = *r0 i.e. r1 = MAIR0. */ + ldr r2, =0xe000edc0 /* r2 = 0xe000edc0 [Location of MAIR0]. */ + str r1, [r2] /* Program MAIR0. */ + + adds r0, #4 /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */ + ldr r1, =0xe000ed98 /* r1 = 0xe000ed98 [Location of RNR]. */ + ldr r2, =0xe000ed9c /* r2 = 0xe000ed9c [Location of RBAR]. */ + + movs r3, #4 /* r3 = 4. */ + str r3, [r1] /* Program RNR = 4. */ + ldmia r0!, {r4-r11} /* Read 4 sets of RBAR/RLAR registers from TCB. */ + stmia r2, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ + + #if ( configTOTAL_MPU_REGIONS == 16 ) + movs r3, #8 /* r3 = 8. */ + str r3, [r1] /* Program RNR = 8. */ + ldmia r0!, {r4-r11} /* Read 4 sets of RBAR/RLAR registers from TCB. */ + stmia r2, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ + movs r3, #12 /* r3 = 12. */ + str r3, [r1] /* Program RNR = 12. */ + ldmia r0!, {r4-r11} /* Read 4 sets of RBAR/RLAR registers from TCB. */ + stmia r2, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ + #endif /* configTOTAL_MPU_REGIONS == 16 */ + + ldr r1, =0xe000ed94 /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + ldr r2, [r1] /* Read the value of MPU_CTRL. */ + orr r2, #1 /* r2 = r2 | 1 i.e. Set the bit 0 in r2. */ + str r2, [r1] /* Enable MPU. */ + dsb /* Force memory writes before continuing. */ + + restore_context: + ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + ldr r0, [r2] /* r0 = pxCurrentTCB.*/ + ldr r1, [r0] /* r1 = Location of saved context in TCB. */ + + restore_special_regs: + ldmdb r1!, {r2-r4, lr} /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */ + msr psp, r2 + msr psplim, r3 + msr control, r4 + + restore_general_regs: + ldmdb r1!, {r4-r11} /* r4-r11 contain hardware saved context. */ + stmia r2!, {r4-r11} /* Copy the hardware saved context on the task stack. */ + ldmdb r1!, {r4-r11} /* r4-r11 restored. */ + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + tst lr, #0x10 + ittt eq + vldmdbeq r1!, {s0-s16} /* s0-s16 contain hardware saved FP context. */ + vstmiaeq r2!, {s0-s16} /* Copy hardware saved FP context on the task stack. */ + vldmdbeq r1!, {s16-s31} /* Restore s16-s31. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ + + restore_context_done: + str r1, [r0] /* Save the location where the context should be saved next as the first member of TCB. */ + bx lr + +#else /* configENABLE_MPU */ + PendSV_Handler: mrs r0, psp /* Read PSP in r0. */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) @@ -176,16 +325,10 @@ PendSV_Handler: it eq vstmdbeq r0!, {s16-s31} /* Store the additional FP context registers which are not saved automatically. */ #endif /* configENABLE_FPU || configENABLE_MVE */ -#if ( configENABLE_MPU == 1 ) - mrs r1, psplim /* r1 = PSPLIM. */ - mrs r2, control /* r2 = CONTROL. */ - mov r3, lr /* r3 = LR/EXC_RETURN. */ - stmdb r0!, {r1-r11} /* Store on the stack - PSPLIM, CONTROL, LR and registers that are not automatically saved. */ -#else /* configENABLE_MPU */ + mrs r2, psplim /* r2 = PSPLIM. */ mov r3, lr /* r3 = LR/EXC_RETURN. */ stmdb r0!, {r2-r11} /* Store on the stack - PSPLIM, LR and registers that are not automatically. */ -#endif /* configENABLE_MPU */ ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r2] /* Read pxCurrentTCB. */ @@ -203,37 +346,7 @@ PendSV_Handler: ldr r1, [r2] /* Read pxCurrentTCB. */ ldr r0, [r1] /* The first item in pxCurrentTCB is the task top of stack. r0 now points to the top of stack. */ -#if ( configENABLE_MPU == 1 ) - dmb /* Complete outstanding transfers before disabling MPU. */ - ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ - ldr r4, [r2] /* Read the value of MPU_CTRL. */ - bic r4, r4, #1 /* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */ - str r4, [r2] /* Disable MPU. */ - - adds r1, #4 /* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */ - ldr r3, [r1] /* r3 = *r1 i.e. r3 = MAIR0. */ - ldr r2, =0xe000edc0 /* r2 = 0xe000edc0 [Location of MAIR0]. */ - str r3, [r2] /* Program MAIR0. */ - ldr r2, =0xe000ed98 /* r2 = 0xe000ed98 [Location of RNR]. */ - movs r3, #4 /* r3 = 4. */ - str r3, [r2] /* Program RNR = 4. */ - adds r1, #4 /* r1 = r1 + 4. r1 now points to first RBAR in TCB. */ - ldr r2, =0xe000ed9c /* r2 = 0xe000ed9c [Location of RBAR]. */ - ldmia r1!, {r4-r11} /* Read 4 sets of RBAR/RLAR registers from TCB. */ - stmia r2!, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ - - ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ - ldr r4, [r2] /* Read the value of MPU_CTRL. */ - orr r4, r4, #1 /* r4 = r4 | 1 i.e. Set the bit 0 in r4. */ - str r4, [r2] /* Enable MPU. */ - dsb /* Force memory writes before continuing. */ -#endif /* configENABLE_MPU */ - -#if ( configENABLE_MPU == 1 ) - ldmia r0!, {r1-r11} /* Read from stack - r1 = PSPLIM, r2 = CONTROL, r3 = LR and r4-r11 restored. */ -#else /* configENABLE_MPU */ ldmia r0!, {r2-r11} /* Read from stack - r2 = PSPLIM, r3 = LR and r4-r11 restored. */ -#endif /* configENABLE_MPU */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) tst r3, #0x10 /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ @@ -241,22 +354,53 @@ PendSV_Handler: vldmiaeq r0!, {s16-s31} /* Restore the additional FP context registers which are not restored automatically. */ #endif /* configENABLE_FPU || configENABLE_MVE */ - #if ( configENABLE_MPU == 1 ) - msr psplim, r1 /* Restore the PSPLIM register value for the task. */ - msr control, r2 /* Restore the CONTROL register value for the task. */ -#else /* configENABLE_MPU */ msr psplim, r2 /* Restore the PSPLIM register value for the task. */ -#endif /* configENABLE_MPU */ msr psp, r0 /* Remember the new top of stack for the task. */ bx r3 + +#endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + +SVC_Handler: + tst lr, #4 + ite eq + mrseq r0, msp + mrsne r0, psp + + ldr r1, [r0, #24] + ldrb r2, [r1, #-2] + cmp r2, #4 /* portSVC_SYSTEM_CALL_ENTER. */ + beq syscall_enter + cmp r2, #5 /* portSVC_SYSTEM_CALL_ENTER_1. */ + beq syscall_enter_1 + cmp r2, #6 /* portSVC_SYSTEM_CALL_EXIT. */ + beq syscall_exit + b vPortSVCHandler_C + + syscall_enter: + mov r1, lr + b vSystemCallEnter + + syscall_enter_1: + mov r1, lr + b vSystemCallEnter_1 + + syscall_exit: + mov r1, lr + b vSystemCallExit + +#else /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + SVC_Handler: tst lr, #4 ite eq mrseq r0, msp mrsne r0, psp b vPortSVCHandler_C + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ /*-----------------------------------------------------------*/ END diff --git a/portable/IAR/ARM_CM33_NTZ/non_secure/portmacrocommon.h b/portable/IAR/ARM_CM33_NTZ/non_secure/portmacrocommon.h index c2ca5fa7730..65ac109c802 100644 --- a/portable/IAR/ARM_CM33_NTZ/non_secure/portmacrocommon.h +++ b/portable/IAR/ARM_CM33_NTZ/non_secure/portmacrocommon.h @@ -186,23 +186,120 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #define portMPU_REGION_EXECUTE_NEVER ( 1UL ) /*-----------------------------------------------------------*/ -/** - * @brief Settings to define an MPU region. - */ -typedef struct MPURegionSettings -{ - uint32_t ulRBAR; /**< RBAR for the region. */ - uint32_t ulRLAR; /**< RLAR for the region. */ -} MPURegionSettings_t; +#if ( configENABLE_MPU == 1 ) -/** - * @brief MPU settings as stored in the TCB. - */ -typedef struct MPU_SETTINGS -{ - uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ - MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */ -} xMPU_SETTINGS; + /** + * @brief Settings to define an MPU region. + */ + typedef struct MPURegionSettings + { + uint32_t ulRBAR; /**< RBAR for the region. */ + uint32_t ulRLAR; /**< RLAR for the region. */ + } MPURegionSettings_t; + + #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + + #ifndef configSYSTEM_CALL_STACK_SIZE + #error configSYSTEM_CALL_STACK_SIZE must be defined to the desired size of the system call stack in words for using MPU wrappers v2. + #endif + + /** + * @brief System call stack. + */ + typedef struct SYSTEM_CALL_STACK_INFO + { + uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ]; + uint32_t * pulSystemCallStack; + uint32_t * pulSystemCallStackLimit; + uint32_t * pulTaskStack; + uint32_t ulLinkRegisterAtSystemCallEntry; + uint32_t ulStackLimitRegisterAtSystemCallEntry; + } xSYSTEM_CALL_STACK_INFO; + + #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + + /** + * @brief MPU settings as stored in the TCB. + */ + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + + #if( configENABLE_TRUSTZONE == 1 ) + + /* + * +-----------+---------------+----------+-----------------+------------------------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | + * | | | | PC, xPSR | CONTROL, EXC_RETURN | | + * +-----------+---------------+----------+-----------------+------------------------------+-----+ + * + * <-----------><--------------><---------><----------------><-----------------------------><----> + * 16 16 8 8 5 1 + */ + #define MAX_CONTEXT_SIZE 54 + + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ + + /* + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | + * | | | | PC, xPSR | EXC_RETURN | | + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * + * <-----------><--------------><---------><----------------><---------------------><----> + * 16 16 8 8 4 1 + */ + #define MAX_CONTEXT_SIZE 53 + + #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + + #else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ + + #if( configENABLE_TRUSTZONE == 1 ) + + /* + * +----------+-----------------+------------------------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | + * | | PC, xPSR | CONTROL, EXC_RETURN | | + * +----------+-----------------+------------------------------+-----+ + * + * <---------><----------------><------------------------------><----> + * 8 8 5 1 + */ + #define MAX_CONTEXT_SIZE 22 + + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ + + /* + * +----------+-----------------+----------------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | + * | | PC, xPSR | EXC_RETURN | | + * +----------+-----------------+----------------------+-----+ + * + * <---------><----------------><----------------------><----> + * 8 8 4 1 + */ + #define MAX_CONTEXT_SIZE 21 + + #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + + #endif /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ + + /* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ + #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) + #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) + + typedef struct MPU_SETTINGS + { + uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ + MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */ + uint32_t ulContext[ MAX_CONTEXT_SIZE ]; + uint32_t ulTaskFlags; + + #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo; + #endif + } xMPU_SETTINGS; + +#endif /* configENABLE_MPU == 1 */ /*-----------------------------------------------------------*/ /** @@ -223,6 +320,9 @@ typedef struct MPU_SETTINGS #define portSVC_FREE_SECURE_CONTEXT 1 #define portSVC_START_SCHEDULER 2 #define portSVC_RAISE_PRIVILEGE 3 +#define portSVC_SYSTEM_CALL_ENTER 4 /* System calls with upto 4 parameters. */ +#define portSVC_SYSTEM_CALL_ENTER_1 5 /* System calls with 5 parameters. */ +#define portSVC_SYSTEM_CALL_EXIT 6 /*-----------------------------------------------------------*/ /** @@ -315,6 +415,20 @@ typedef struct MPU_SETTINGS #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ +#if ( configENABLE_MPU == 1 ) + + extern BaseType_t xPortIsTaskPrivileged( void ); + + /** + * @brief Checks whether or not the calling task is privileged. + * + * @return pdTRUE if the calling task is privileged, pdFALSE otherwise. + */ + #define portIS_TASK_PRIVILEGED() xPortIsTaskPrivileged() + +#endif /* configENABLE_MPU == 1 */ +/*-----------------------------------------------------------*/ + /** * @brief Barriers. */ diff --git a/portable/IAR/ARM_CM35P/non_secure/mpu_wrappers_v2_asm.S b/portable/IAR/ARM_CM35P/non_secure/mpu_wrappers_v2_asm.S new file mode 100644 index 00000000000..f051a6073dd --- /dev/null +++ b/portable/IAR/ARM_CM35P/non_secure/mpu_wrappers_v2_asm.S @@ -0,0 +1,1552 @@ +/* + * FreeRTOS Kernel + * Copyright (C) 2021 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 + * + */ + + + SECTION freertos_system_calls:CODE:NOROOT(2) + THUMB +/*-----------------------------------------------------------*/ + +#include "FreeRTOSConfig.h" + +#ifndef configUSE_MPU_WRAPPERS_V1 + #define configUSE_MPU_WRAPPERS_V1 0 +#endif + +/* These must be in sync with portmacro.h. */ +#define portSVC_SYSTEM_CALL_ENTER 4 /* System calls with upto 4 parameters. */ +#define portSVC_SYSTEM_CALL_ENTER_1 5 /* System calls with 5 parameters. */ +#define portSVC_SYSTEM_CALL_EXIT 6 +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + + PUBLIC MPU_xTaskDelayUntil +MPU_xTaskDelayUntil: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskDelayUntil_Unpriv + MPU_xTaskDelayUntil_Priv: + pop {r0} + b MPU_xTaskDelayUntilImpl + MPU_xTaskDelayUntil_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskDelayUntilImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskAbortDelay +MPU_xTaskAbortDelay: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskAbortDelay_Unpriv + MPU_xTaskAbortDelay_Priv: + pop {r0} + b MPU_xTaskAbortDelayImpl + MPU_xTaskAbortDelay_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskAbortDelayImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTaskDelay +MPU_vTaskDelay: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vTaskDelay_Unpriv + MPU_vTaskDelay_Priv: + pop {r0} + b MPU_vTaskDelayImpl + MPU_vTaskDelay_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskDelayImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxTaskPriorityGet +MPU_uxTaskPriorityGet: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_uxTaskPriorityGet_Unpriv + MPU_uxTaskPriorityGet_Priv: + pop {r0} + b MPU_uxTaskPriorityGetImpl + MPU_uxTaskPriorityGet_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxTaskPriorityGetImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_eTaskGetState +MPU_eTaskGetState: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_eTaskGetState_Unpriv + MPU_eTaskGetState_Priv: + pop {r0} + b MPU_eTaskGetStateImpl + MPU_eTaskGetState_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_eTaskGetStateImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTaskGetInfo +MPU_vTaskGetInfo: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vTaskGetInfo_Unpriv + MPU_vTaskGetInfo_Priv: + pop {r0} + b MPU_vTaskGetInfoImpl + MPU_vTaskGetInfo_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskGetInfoImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGetIdleTaskHandle +MPU_xTaskGetIdleTaskHandle: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskGetIdleTaskHandle_Unpriv + MPU_xTaskGetIdleTaskHandle_Priv: + pop {r0} + b MPU_xTaskGetIdleTaskHandleImpl + MPU_xTaskGetIdleTaskHandle_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskGetIdleTaskHandleImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTaskSuspend +MPU_vTaskSuspend: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vTaskSuspend_Unpriv + MPU_vTaskSuspend_Priv: + pop {r0} + b MPU_vTaskSuspendImpl + MPU_vTaskSuspend_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskSuspendImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTaskResume +MPU_vTaskResume: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vTaskResume_Unpriv + MPU_vTaskResume_Priv: + pop {r0} + b MPU_vTaskResumeImpl + MPU_vTaskResume_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskResumeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGetTickCount +MPU_xTaskGetTickCount: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskGetTickCount_Unpriv + MPU_xTaskGetTickCount_Priv: + pop {r0} + b MPU_xTaskGetTickCountImpl + MPU_xTaskGetTickCount_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskGetTickCountImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxTaskGetNumberOfTasks +MPU_uxTaskGetNumberOfTasks: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_uxTaskGetNumberOfTasks_Unpriv + MPU_uxTaskGetNumberOfTasks_Priv: + pop {r0} + b MPU_uxTaskGetNumberOfTasksImpl + MPU_uxTaskGetNumberOfTasks_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxTaskGetNumberOfTasksImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_pcTaskGetName +MPU_pcTaskGetName: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_pcTaskGetName_Unpriv + MPU_pcTaskGetName_Priv: + pop {r0} + b MPU_pcTaskGetNameImpl + MPU_pcTaskGetName_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_pcTaskGetNameImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_ulTaskGetRunTimeCounter +MPU_ulTaskGetRunTimeCounter: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_ulTaskGetRunTimeCounter_Unpriv + MPU_ulTaskGetRunTimeCounter_Priv: + pop {r0} + b MPU_ulTaskGetRunTimeCounterImpl + MPU_ulTaskGetRunTimeCounter_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_ulTaskGetRunTimeCounterImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_ulTaskGetRunTimePercent +MPU_ulTaskGetRunTimePercent: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_ulTaskGetRunTimePercent_Unpriv + MPU_ulTaskGetRunTimePercent_Priv: + pop {r0} + b MPU_ulTaskGetRunTimePercentImpl + MPU_ulTaskGetRunTimePercent_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_ulTaskGetRunTimePercentImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_ulTaskGetIdleRunTimePercent +MPU_ulTaskGetIdleRunTimePercent: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_ulTaskGetIdleRunTimePercent_Unpriv + MPU_ulTaskGetIdleRunTimePercent_Priv: + pop {r0} + b MPU_ulTaskGetIdleRunTimePercentImpl + MPU_ulTaskGetIdleRunTimePercent_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_ulTaskGetIdleRunTimePercentImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_ulTaskGetIdleRunTimeCounter +MPU_ulTaskGetIdleRunTimeCounter: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_ulTaskGetIdleRunTimeCounter_Unpriv + MPU_ulTaskGetIdleRunTimeCounter_Priv: + pop {r0} + b MPU_ulTaskGetIdleRunTimeCounterImpl + MPU_ulTaskGetIdleRunTimeCounter_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_ulTaskGetIdleRunTimeCounterImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTaskSetApplicationTaskTag +MPU_vTaskSetApplicationTaskTag: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vTaskSetApplicationTaskTag_Unpriv + MPU_vTaskSetApplicationTaskTag_Priv: + pop {r0} + b MPU_vTaskSetApplicationTaskTagImpl + MPU_vTaskSetApplicationTaskTag_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskSetApplicationTaskTagImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGetApplicationTaskTag +MPU_xTaskGetApplicationTaskTag: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskGetApplicationTaskTag_Unpriv + MPU_xTaskGetApplicationTaskTag_Priv: + pop {r0} + b MPU_xTaskGetApplicationTaskTagImpl + MPU_xTaskGetApplicationTaskTag_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskGetApplicationTaskTagImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTaskSetThreadLocalStoragePointer +MPU_vTaskSetThreadLocalStoragePointer: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vTaskSetThreadLocalStoragePointer_Unpriv + MPU_vTaskSetThreadLocalStoragePointer_Priv: + pop {r0} + b MPU_vTaskSetThreadLocalStoragePointerImpl + MPU_vTaskSetThreadLocalStoragePointer_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskSetThreadLocalStoragePointerImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_pvTaskGetThreadLocalStoragePointer +MPU_pvTaskGetThreadLocalStoragePointer: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_pvTaskGetThreadLocalStoragePointer_Unpriv + MPU_pvTaskGetThreadLocalStoragePointer_Priv: + pop {r0} + b MPU_pvTaskGetThreadLocalStoragePointerImpl + MPU_pvTaskGetThreadLocalStoragePointer_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_pvTaskGetThreadLocalStoragePointerImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxTaskGetSystemState +MPU_uxTaskGetSystemState: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_uxTaskGetSystemState_Unpriv + MPU_uxTaskGetSystemState_Priv: + pop {r0} + b MPU_uxTaskGetSystemStateImpl + MPU_uxTaskGetSystemState_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxTaskGetSystemStateImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxTaskGetStackHighWaterMark +MPU_uxTaskGetStackHighWaterMark: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_uxTaskGetStackHighWaterMark_Unpriv + MPU_uxTaskGetStackHighWaterMark_Priv: + pop {r0} + b MPU_uxTaskGetStackHighWaterMarkImpl + MPU_uxTaskGetStackHighWaterMark_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxTaskGetStackHighWaterMarkImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxTaskGetStackHighWaterMark2 +MPU_uxTaskGetStackHighWaterMark2: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_uxTaskGetStackHighWaterMark2_Unpriv + MPU_uxTaskGetStackHighWaterMark2_Priv: + pop {r0} + b MPU_uxTaskGetStackHighWaterMark2Impl + MPU_uxTaskGetStackHighWaterMark2_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxTaskGetStackHighWaterMark2Impl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGetCurrentTaskHandle +MPU_xTaskGetCurrentTaskHandle: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskGetCurrentTaskHandle_Unpriv + MPU_xTaskGetCurrentTaskHandle_Priv: + pop {r0} + b MPU_xTaskGetCurrentTaskHandleImpl + MPU_xTaskGetCurrentTaskHandle_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskGetCurrentTaskHandleImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGetSchedulerState +MPU_xTaskGetSchedulerState: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskGetSchedulerState_Unpriv + MPU_xTaskGetSchedulerState_Priv: + pop {r0} + b MPU_xTaskGetSchedulerStateImpl + MPU_xTaskGetSchedulerState_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskGetSchedulerStateImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTaskSetTimeOutState +MPU_vTaskSetTimeOutState: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vTaskSetTimeOutState_Unpriv + MPU_vTaskSetTimeOutState_Priv: + pop {r0} + b MPU_vTaskSetTimeOutStateImpl + MPU_vTaskSetTimeOutState_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskSetTimeOutStateImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskCheckForTimeOut +MPU_xTaskCheckForTimeOut: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskCheckForTimeOut_Unpriv + MPU_xTaskCheckForTimeOut_Priv: + pop {r0} + b MPU_xTaskCheckForTimeOutImpl + MPU_xTaskCheckForTimeOut_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskCheckForTimeOutImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGenericNotify +MPU_xTaskGenericNotify: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskGenericNotify_Unpriv + MPU_xTaskGenericNotify_Priv: + pop {r0} + b MPU_xTaskGenericNotifyImpl + MPU_xTaskGenericNotify_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER_1 + bl MPU_xTaskGenericNotifyImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGenericNotifyWait +MPU_xTaskGenericNotifyWait: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskGenericNotifyWait_Unpriv + MPU_xTaskGenericNotifyWait_Priv: + pop {r0} + b MPU_xTaskGenericNotifyWaitImpl + MPU_xTaskGenericNotifyWait_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER_1 + bl MPU_xTaskGenericNotifyWaitImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_ulTaskGenericNotifyTake +MPU_ulTaskGenericNotifyTake: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_ulTaskGenericNotifyTake_Unpriv + MPU_ulTaskGenericNotifyTake_Priv: + pop {r0} + b MPU_ulTaskGenericNotifyTakeImpl + MPU_ulTaskGenericNotifyTake_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_ulTaskGenericNotifyTakeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGenericNotifyStateClear +MPU_xTaskGenericNotifyStateClear: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskGenericNotifyStateClear_Unpriv + MPU_xTaskGenericNotifyStateClear_Priv: + pop {r0} + b MPU_xTaskGenericNotifyStateClearImpl + MPU_xTaskGenericNotifyStateClear_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskGenericNotifyStateClearImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_ulTaskGenericNotifyValueClear +MPU_ulTaskGenericNotifyValueClear: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_ulTaskGenericNotifyValueClear_Unpriv + MPU_ulTaskGenericNotifyValueClear_Priv: + pop {r0} + b MPU_ulTaskGenericNotifyValueClearImpl + MPU_ulTaskGenericNotifyValueClear_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_ulTaskGenericNotifyValueClearImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueGenericSend +MPU_xQueueGenericSend: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xQueueGenericSend_Unpriv + MPU_xQueueGenericSend_Priv: + pop {r0} + b MPU_xQueueGenericSendImpl + MPU_xQueueGenericSend_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueGenericSendImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxQueueMessagesWaiting +MPU_uxQueueMessagesWaiting: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_uxQueueMessagesWaiting_Unpriv + MPU_uxQueueMessagesWaiting_Priv: + pop {r0} + b MPU_uxQueueMessagesWaitingImpl + MPU_uxQueueMessagesWaiting_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxQueueMessagesWaitingImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxQueueSpacesAvailable +MPU_uxQueueSpacesAvailable: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_uxQueueSpacesAvailable_Unpriv + MPU_uxQueueSpacesAvailable_Priv: + pop {r0} + b MPU_uxQueueSpacesAvailableImpl + MPU_uxQueueSpacesAvailable_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxQueueSpacesAvailableImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueReceive +MPU_xQueueReceive: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xQueueReceive_Unpriv + MPU_xQueueReceive_Priv: + pop {r0} + b MPU_xQueueReceiveImpl + MPU_xQueueReceive_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueReceiveImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueuePeek +MPU_xQueuePeek: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xQueuePeek_Unpriv + MPU_xQueuePeek_Priv: + pop {r0} + b MPU_xQueuePeekImpl + MPU_xQueuePeek_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueuePeekImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueSemaphoreTake +MPU_xQueueSemaphoreTake: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xQueueSemaphoreTake_Unpriv + MPU_xQueueSemaphoreTake_Priv: + pop {r0} + b MPU_xQueueSemaphoreTakeImpl + MPU_xQueueSemaphoreTake_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueSemaphoreTakeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueGetMutexHolder +MPU_xQueueGetMutexHolder: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xQueueGetMutexHolder_Unpriv + MPU_xQueueGetMutexHolder_Priv: + pop {r0} + b MPU_xQueueGetMutexHolderImpl + MPU_xQueueGetMutexHolder_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueGetMutexHolderImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueTakeMutexRecursive +MPU_xQueueTakeMutexRecursive: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xQueueTakeMutexRecursive_Unpriv + MPU_xQueueTakeMutexRecursive_Priv: + pop {r0} + b MPU_xQueueTakeMutexRecursiveImpl + MPU_xQueueTakeMutexRecursive_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueTakeMutexRecursiveImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueGiveMutexRecursive +MPU_xQueueGiveMutexRecursive: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xQueueGiveMutexRecursive_Unpriv + MPU_xQueueGiveMutexRecursive_Priv: + pop {r0} + b MPU_xQueueGiveMutexRecursiveImpl + MPU_xQueueGiveMutexRecursive_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueGiveMutexRecursiveImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueSelectFromSet +MPU_xQueueSelectFromSet: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xQueueSelectFromSet_Unpriv + MPU_xQueueSelectFromSet_Priv: + pop {r0} + b MPU_xQueueSelectFromSetImpl + MPU_xQueueSelectFromSet_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueSelectFromSetImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueAddToSet +MPU_xQueueAddToSet: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xQueueAddToSet_Unpriv + MPU_xQueueAddToSet_Priv: + pop {r0} + b MPU_xQueueAddToSetImpl + MPU_xQueueAddToSet_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueAddToSetImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vQueueAddToRegistry +MPU_vQueueAddToRegistry: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vQueueAddToRegistry_Unpriv + MPU_vQueueAddToRegistry_Priv: + pop {r0} + b MPU_vQueueAddToRegistryImpl + MPU_vQueueAddToRegistry_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vQueueAddToRegistryImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vQueueUnregisterQueue +MPU_vQueueUnregisterQueue: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vQueueUnregisterQueue_Unpriv + MPU_vQueueUnregisterQueue_Priv: + pop {r0} + b MPU_vQueueUnregisterQueueImpl + MPU_vQueueUnregisterQueue_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vQueueUnregisterQueueImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_pcQueueGetName +MPU_pcQueueGetName: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_pcQueueGetName_Unpriv + MPU_pcQueueGetName_Priv: + pop {r0} + b MPU_pcQueueGetNameImpl + MPU_pcQueueGetName_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_pcQueueGetNameImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_pvTimerGetTimerID +MPU_pvTimerGetTimerID: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_pvTimerGetTimerID_Unpriv + MPU_pvTimerGetTimerID_Priv: + pop {r0} + b MPU_pvTimerGetTimerIDImpl + MPU_pvTimerGetTimerID_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_pvTimerGetTimerIDImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTimerSetTimerID +MPU_vTimerSetTimerID: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vTimerSetTimerID_Unpriv + MPU_vTimerSetTimerID_Priv: + pop {r0} + b MPU_vTimerSetTimerIDImpl + MPU_vTimerSetTimerID_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTimerSetTimerIDImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTimerIsTimerActive +MPU_xTimerIsTimerActive: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTimerIsTimerActive_Unpriv + MPU_xTimerIsTimerActive_Priv: + pop {r0} + b MPU_xTimerIsTimerActiveImpl + MPU_xTimerIsTimerActive_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTimerIsTimerActiveImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTimerGetTimerDaemonTaskHandle +MPU_xTimerGetTimerDaemonTaskHandle: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTimerGetTimerDaemonTaskHandle_Unpriv + MPU_xTimerGetTimerDaemonTaskHandle_Priv: + pop {r0} + b MPU_xTimerGetTimerDaemonTaskHandleImpl + MPU_xTimerGetTimerDaemonTaskHandle_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTimerGetTimerDaemonTaskHandleImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTimerGenericCommand +MPU_xTimerGenericCommand: + push {r0} + /* This function can be called from ISR also and therefore, we need a check + * to take privileged path, if called from ISR. */ + mrs r0, ipsr + cmp r0, #0 + bne MPU_xTimerGenericCommand_Priv + mrs r0, control + tst r0, #1 + beq MPU_xTimerGenericCommand_Priv + MPU_xTimerGenericCommand_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER_1 + bl MPU_xTimerGenericCommandImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr + MPU_xTimerGenericCommand_Priv: + pop {r0} + b MPU_xTimerGenericCommandImpl + +/*-----------------------------------------------------------*/ + + PUBLIC MPU_pcTimerGetName +MPU_pcTimerGetName: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_pcTimerGetName_Unpriv + MPU_pcTimerGetName_Priv: + pop {r0} + b MPU_pcTimerGetNameImpl + MPU_pcTimerGetName_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_pcTimerGetNameImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTimerSetReloadMode +MPU_vTimerSetReloadMode: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vTimerSetReloadMode_Unpriv + MPU_vTimerSetReloadMode_Priv: + pop {r0} + b MPU_vTimerSetReloadModeImpl + MPU_vTimerSetReloadMode_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTimerSetReloadModeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTimerGetReloadMode +MPU_xTimerGetReloadMode: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTimerGetReloadMode_Unpriv + MPU_xTimerGetReloadMode_Priv: + pop {r0} + b MPU_xTimerGetReloadModeImpl + MPU_xTimerGetReloadMode_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTimerGetReloadModeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxTimerGetReloadMode +MPU_uxTimerGetReloadMode: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_uxTimerGetReloadMode_Unpriv + MPU_uxTimerGetReloadMode_Priv: + pop {r0} + b MPU_uxTimerGetReloadModeImpl + MPU_uxTimerGetReloadMode_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxTimerGetReloadModeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTimerGetPeriod +MPU_xTimerGetPeriod: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTimerGetPeriod_Unpriv + MPU_xTimerGetPeriod_Priv: + pop {r0} + b MPU_xTimerGetPeriodImpl + MPU_xTimerGetPeriod_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTimerGetPeriodImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTimerGetExpiryTime +MPU_xTimerGetExpiryTime: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTimerGetExpiryTime_Unpriv + MPU_xTimerGetExpiryTime_Priv: + pop {r0} + b MPU_xTimerGetExpiryTimeImpl + MPU_xTimerGetExpiryTime_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTimerGetExpiryTimeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xEventGroupWaitBits +MPU_xEventGroupWaitBits: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xEventGroupWaitBits_Unpriv + MPU_xEventGroupWaitBits_Priv: + pop {r0} + b MPU_xEventGroupWaitBitsImpl + MPU_xEventGroupWaitBits_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER_1 + bl MPU_xEventGroupWaitBitsImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xEventGroupClearBits +MPU_xEventGroupClearBits: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xEventGroupClearBits_Unpriv + MPU_xEventGroupClearBits_Priv: + pop {r0} + b MPU_xEventGroupClearBitsImpl + MPU_xEventGroupClearBits_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xEventGroupClearBitsImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xEventGroupSetBits +MPU_xEventGroupSetBits: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xEventGroupSetBits_Unpriv + MPU_xEventGroupSetBits_Priv: + pop {r0} + b MPU_xEventGroupSetBitsImpl + MPU_xEventGroupSetBits_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xEventGroupSetBitsImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xEventGroupSync +MPU_xEventGroupSync: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xEventGroupSync_Unpriv + MPU_xEventGroupSync_Priv: + pop {r0} + b MPU_xEventGroupSyncImpl + MPU_xEventGroupSync_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xEventGroupSyncImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxEventGroupGetNumber +MPU_uxEventGroupGetNumber: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_uxEventGroupGetNumber_Unpriv + MPU_uxEventGroupGetNumber_Priv: + pop {r0} + b MPU_uxEventGroupGetNumberImpl + MPU_uxEventGroupGetNumber_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxEventGroupGetNumberImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vEventGroupSetNumber +MPU_vEventGroupSetNumber: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vEventGroupSetNumber_Unpriv + MPU_vEventGroupSetNumber_Priv: + pop {r0} + b MPU_vEventGroupSetNumberImpl + MPU_vEventGroupSetNumber_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vEventGroupSetNumberImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferSend +MPU_xStreamBufferSend: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xStreamBufferSend_Unpriv + MPU_xStreamBufferSend_Priv: + pop {r0} + b MPU_xStreamBufferSendImpl + MPU_xStreamBufferSend_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferSendImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferReceive +MPU_xStreamBufferReceive: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xStreamBufferReceive_Unpriv + MPU_xStreamBufferReceive_Priv: + pop {r0} + b MPU_xStreamBufferReceiveImpl + MPU_xStreamBufferReceive_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferReceiveImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferIsFull +MPU_xStreamBufferIsFull: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xStreamBufferIsFull_Unpriv + MPU_xStreamBufferIsFull_Priv: + pop {r0} + b MPU_xStreamBufferIsFullImpl + MPU_xStreamBufferIsFull_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferIsFullImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferIsEmpty +MPU_xStreamBufferIsEmpty: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xStreamBufferIsEmpty_Unpriv + MPU_xStreamBufferIsEmpty_Priv: + pop {r0} + b MPU_xStreamBufferIsEmptyImpl + MPU_xStreamBufferIsEmpty_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferIsEmptyImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferSpacesAvailable +MPU_xStreamBufferSpacesAvailable: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xStreamBufferSpacesAvailable_Unpriv + MPU_xStreamBufferSpacesAvailable_Priv: + pop {r0} + b MPU_xStreamBufferSpacesAvailableImpl + MPU_xStreamBufferSpacesAvailable_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferSpacesAvailableImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferBytesAvailable +MPU_xStreamBufferBytesAvailable: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xStreamBufferBytesAvailable_Unpriv + MPU_xStreamBufferBytesAvailable_Priv: + pop {r0} + b MPU_xStreamBufferBytesAvailableImpl + MPU_xStreamBufferBytesAvailable_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferBytesAvailableImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferSetTriggerLevel +MPU_xStreamBufferSetTriggerLevel: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xStreamBufferSetTriggerLevel_Unpriv + MPU_xStreamBufferSetTriggerLevel_Priv: + pop {r0} + b MPU_xStreamBufferSetTriggerLevelImpl + MPU_xStreamBufferSetTriggerLevel_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferSetTriggerLevelImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferNextMessageLengthBytes +MPU_xStreamBufferNextMessageLengthBytes: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xStreamBufferNextMessageLengthBytes_Unpriv + MPU_xStreamBufferNextMessageLengthBytes_Priv: + pop {r0} + b MPU_xStreamBufferNextMessageLengthBytesImpl + MPU_xStreamBufferNextMessageLengthBytes_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferNextMessageLengthBytesImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + +/* Default weak implementations in case one is not available from + * mpu_wrappers because of config options. */ + + PUBWEAK MPU_xTaskDelayUntilImpl +MPU_xTaskDelayUntilImpl: + b MPU_xTaskDelayUntilImpl + + PUBWEAK MPU_xTaskAbortDelayImpl +MPU_xTaskAbortDelayImpl: + b MPU_xTaskAbortDelayImpl + + PUBWEAK MPU_vTaskDelayImpl +MPU_vTaskDelayImpl: + b MPU_vTaskDelayImpl + + PUBWEAK MPU_uxTaskPriorityGetImpl +MPU_uxTaskPriorityGetImpl: + b MPU_uxTaskPriorityGetImpl + + PUBWEAK MPU_eTaskGetStateImpl +MPU_eTaskGetStateImpl: + b MPU_eTaskGetStateImpl + + PUBWEAK MPU_vTaskGetInfoImpl +MPU_vTaskGetInfoImpl: + b MPU_vTaskGetInfoImpl + + PUBWEAK MPU_xTaskGetIdleTaskHandleImpl +MPU_xTaskGetIdleTaskHandleImpl: + b MPU_xTaskGetIdleTaskHandleImpl + + PUBWEAK MPU_vTaskSuspendImpl +MPU_vTaskSuspendImpl: + b MPU_vTaskSuspendImpl + + PUBWEAK MPU_vTaskResumeImpl +MPU_vTaskResumeImpl: + b MPU_vTaskResumeImpl + + PUBWEAK MPU_xTaskGetTickCountImpl +MPU_xTaskGetTickCountImpl: + b MPU_xTaskGetTickCountImpl + + PUBWEAK MPU_uxTaskGetNumberOfTasksImpl +MPU_uxTaskGetNumberOfTasksImpl: + b MPU_uxTaskGetNumberOfTasksImpl + + PUBWEAK MPU_pcTaskGetNameImpl +MPU_pcTaskGetNameImpl: + b MPU_pcTaskGetNameImpl + + PUBWEAK MPU_ulTaskGetRunTimeCounterImpl +MPU_ulTaskGetRunTimeCounterImpl: + b MPU_ulTaskGetRunTimeCounterImpl + + PUBWEAK MPU_ulTaskGetRunTimePercentImpl +MPU_ulTaskGetRunTimePercentImpl: + b MPU_ulTaskGetRunTimePercentImpl + + PUBWEAK MPU_ulTaskGetIdleRunTimePercentImpl +MPU_ulTaskGetIdleRunTimePercentImpl: + b MPU_ulTaskGetIdleRunTimePercentImpl + + PUBWEAK MPU_ulTaskGetIdleRunTimeCounterImpl +MPU_ulTaskGetIdleRunTimeCounterImpl: + b MPU_ulTaskGetIdleRunTimeCounterImpl + + PUBWEAK MPU_vTaskSetApplicationTaskTagImpl +MPU_vTaskSetApplicationTaskTagImpl: + b MPU_vTaskSetApplicationTaskTagImpl + + PUBWEAK MPU_xTaskGetApplicationTaskTagImpl +MPU_xTaskGetApplicationTaskTagImpl: + b MPU_xTaskGetApplicationTaskTagImpl + + PUBWEAK MPU_vTaskSetThreadLocalStoragePointerImpl +MPU_vTaskSetThreadLocalStoragePointerImpl: + b MPU_vTaskSetThreadLocalStoragePointerImpl + + PUBWEAK MPU_pvTaskGetThreadLocalStoragePointerImpl +MPU_pvTaskGetThreadLocalStoragePointerImpl: + b MPU_pvTaskGetThreadLocalStoragePointerImpl + + PUBWEAK MPU_uxTaskGetSystemStateImpl +MPU_uxTaskGetSystemStateImpl: + b MPU_uxTaskGetSystemStateImpl + + PUBWEAK MPU_uxTaskGetStackHighWaterMarkImpl +MPU_uxTaskGetStackHighWaterMarkImpl: + b MPU_uxTaskGetStackHighWaterMarkImpl + + PUBWEAK MPU_uxTaskGetStackHighWaterMark2Impl +MPU_uxTaskGetStackHighWaterMark2Impl: + b MPU_uxTaskGetStackHighWaterMark2Impl + + PUBWEAK MPU_xTaskGetCurrentTaskHandleImpl +MPU_xTaskGetCurrentTaskHandleImpl: + b MPU_xTaskGetCurrentTaskHandleImpl + + PUBWEAK MPU_xTaskGetSchedulerStateImpl +MPU_xTaskGetSchedulerStateImpl: + b MPU_xTaskGetSchedulerStateImpl + + PUBWEAK MPU_vTaskSetTimeOutStateImpl +MPU_vTaskSetTimeOutStateImpl: + b MPU_vTaskSetTimeOutStateImpl + + PUBWEAK MPU_xTaskCheckForTimeOutImpl +MPU_xTaskCheckForTimeOutImpl: + b MPU_xTaskCheckForTimeOutImpl + + PUBWEAK MPU_xTaskGenericNotifyImpl +MPU_xTaskGenericNotifyImpl: + b MPU_xTaskGenericNotifyImpl + + PUBWEAK MPU_xTaskGenericNotifyWaitImpl +MPU_xTaskGenericNotifyWaitImpl: + b MPU_xTaskGenericNotifyWaitImpl + + PUBWEAK MPU_ulTaskGenericNotifyTakeImpl +MPU_ulTaskGenericNotifyTakeImpl: + b MPU_ulTaskGenericNotifyTakeImpl + + PUBWEAK MPU_xTaskGenericNotifyStateClearImpl +MPU_xTaskGenericNotifyStateClearImpl: + b MPU_xTaskGenericNotifyStateClearImpl + + PUBWEAK MPU_ulTaskGenericNotifyValueClearImpl +MPU_ulTaskGenericNotifyValueClearImpl: + b MPU_ulTaskGenericNotifyValueClearImpl + + PUBWEAK MPU_xQueueGenericSendImpl +MPU_xQueueGenericSendImpl: + b MPU_xQueueGenericSendImpl + + PUBWEAK MPU_uxQueueMessagesWaitingImpl +MPU_uxQueueMessagesWaitingImpl: + b MPU_uxQueueMessagesWaitingImpl + + PUBWEAK MPU_uxQueueSpacesAvailableImpl +MPU_uxQueueSpacesAvailableImpl: + b MPU_uxQueueSpacesAvailableImpl + + PUBWEAK MPU_xQueueReceiveImpl +MPU_xQueueReceiveImpl: + b MPU_xQueueReceiveImpl + + PUBWEAK MPU_xQueuePeekImpl +MPU_xQueuePeekImpl: + b MPU_xQueuePeekImpl + + PUBWEAK MPU_xQueueSemaphoreTakeImpl +MPU_xQueueSemaphoreTakeImpl: + b MPU_xQueueSemaphoreTakeImpl + + PUBWEAK MPU_xQueueGetMutexHolderImpl +MPU_xQueueGetMutexHolderImpl: + b MPU_xQueueGetMutexHolderImpl + + PUBWEAK MPU_xQueueTakeMutexRecursiveImpl +MPU_xQueueTakeMutexRecursiveImpl: + b MPU_xQueueTakeMutexRecursiveImpl + + PUBWEAK MPU_xQueueGiveMutexRecursiveImpl +MPU_xQueueGiveMutexRecursiveImpl: + b MPU_xQueueGiveMutexRecursiveImpl + + PUBWEAK MPU_xQueueSelectFromSetImpl +MPU_xQueueSelectFromSetImpl: + b MPU_xQueueSelectFromSetImpl + + PUBWEAK MPU_xQueueAddToSetImpl +MPU_xQueueAddToSetImpl: + b MPU_xQueueAddToSetImpl + + PUBWEAK MPU_vQueueAddToRegistryImpl +MPU_vQueueAddToRegistryImpl: + b MPU_vQueueAddToRegistryImpl + + PUBWEAK MPU_vQueueUnregisterQueueImpl +MPU_vQueueUnregisterQueueImpl: + b MPU_vQueueUnregisterQueueImpl + + PUBWEAK MPU_pcQueueGetNameImpl +MPU_pcQueueGetNameImpl: + b MPU_pcQueueGetNameImpl + + PUBWEAK MPU_pvTimerGetTimerIDImpl +MPU_pvTimerGetTimerIDImpl: + b MPU_pvTimerGetTimerIDImpl + + PUBWEAK MPU_vTimerSetTimerIDImpl +MPU_vTimerSetTimerIDImpl: + b MPU_vTimerSetTimerIDImpl + + PUBWEAK MPU_xTimerIsTimerActiveImpl +MPU_xTimerIsTimerActiveImpl: + b MPU_xTimerIsTimerActiveImpl + + PUBWEAK MPU_xTimerGetTimerDaemonTaskHandleImpl +MPU_xTimerGetTimerDaemonTaskHandleImpl: + b MPU_xTimerGetTimerDaemonTaskHandleImpl + + PUBWEAK MPU_xTimerGenericCommandImpl +MPU_xTimerGenericCommandImpl: + b MPU_xTimerGenericCommandImpl + + PUBWEAK MPU_pcTimerGetNameImpl +MPU_pcTimerGetNameImpl: + b MPU_pcTimerGetNameImpl + + PUBWEAK MPU_vTimerSetReloadModeImpl +MPU_vTimerSetReloadModeImpl: + b MPU_vTimerSetReloadModeImpl + + PUBWEAK MPU_xTimerGetReloadModeImpl +MPU_xTimerGetReloadModeImpl: + b MPU_xTimerGetReloadModeImpl + + PUBWEAK MPU_uxTimerGetReloadModeImpl +MPU_uxTimerGetReloadModeImpl: + b MPU_uxTimerGetReloadModeImpl + + PUBWEAK MPU_xTimerGetPeriodImpl +MPU_xTimerGetPeriodImpl: + b MPU_xTimerGetPeriodImpl + + PUBWEAK MPU_xTimerGetExpiryTimeImpl +MPU_xTimerGetExpiryTimeImpl: + b MPU_xTimerGetExpiryTimeImpl + + PUBWEAK MPU_xEventGroupWaitBitsImpl +MPU_xEventGroupWaitBitsImpl: + b MPU_xEventGroupWaitBitsImpl + + PUBWEAK MPU_xEventGroupClearBitsImpl +MPU_xEventGroupClearBitsImpl: + b MPU_xEventGroupClearBitsImpl + + PUBWEAK MPU_xEventGroupSetBitsImpl +MPU_xEventGroupSetBitsImpl: + b MPU_xEventGroupSetBitsImpl + + PUBWEAK MPU_xEventGroupSyncImpl +MPU_xEventGroupSyncImpl: + b MPU_xEventGroupSyncImpl + + PUBWEAK MPU_uxEventGroupGetNumberImpl +MPU_uxEventGroupGetNumberImpl: + b MPU_uxEventGroupGetNumberImpl + + PUBWEAK MPU_vEventGroupSetNumberImpl +MPU_vEventGroupSetNumberImpl: + b MPU_vEventGroupSetNumberImpl + + PUBWEAK MPU_xStreamBufferSendImpl +MPU_xStreamBufferSendImpl: + b MPU_xStreamBufferSendImpl + + PUBWEAK MPU_xStreamBufferReceiveImpl +MPU_xStreamBufferReceiveImpl: + b MPU_xStreamBufferReceiveImpl + + PUBWEAK MPU_xStreamBufferIsFullImpl +MPU_xStreamBufferIsFullImpl: + b MPU_xStreamBufferIsFullImpl + + PUBWEAK MPU_xStreamBufferIsEmptyImpl +MPU_xStreamBufferIsEmptyImpl: + b MPU_xStreamBufferIsEmptyImpl + + PUBWEAK MPU_xStreamBufferSpacesAvailableImpl +MPU_xStreamBufferSpacesAvailableImpl: + b MPU_xStreamBufferSpacesAvailableImpl + + PUBWEAK MPU_xStreamBufferBytesAvailableImpl +MPU_xStreamBufferBytesAvailableImpl: + b MPU_xStreamBufferBytesAvailableImpl + + PUBWEAK MPU_xStreamBufferSetTriggerLevelImpl +MPU_xStreamBufferSetTriggerLevelImpl: + b MPU_xStreamBufferSetTriggerLevelImpl + + PUBWEAK MPU_xStreamBufferNextMessageLengthBytesImpl +MPU_xStreamBufferNextMessageLengthBytesImpl: + b MPU_xStreamBufferNextMessageLengthBytesImpl + +/*-----------------------------------------------------------*/ + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + + END diff --git a/portable/IAR/ARM_CM35P/non_secure/port.c b/portable/IAR/ARM_CM35P/non_secure/port.c index 7bbe1b7bc53..cab1b3668bf 100644 --- a/portable/IAR/ARM_CM35P/non_secure/port.c +++ b/portable/IAR/ARM_CM35P/non_secure/port.c @@ -107,6 +107,13 @@ #define portPRIGROUP_SHIFT ( 8UL ) /*-----------------------------------------------------------*/ +/** + * @brief Constants used during system call enter and exit. + */ +#define portPSR_STACK_PADDING_MASK ( 1UL << 9UL ) +#define portEXC_RETURN_STACK_FRAME_TYPE_MASK ( 1UL << 4UL ) +/*-----------------------------------------------------------*/ + /** * @brief Constants required to manipulate the FPU. */ @@ -123,6 +130,14 @@ #define portFPCCR_LSPEN_MASK ( 1UL << portFPCCR_LSPEN_POS ) /*-----------------------------------------------------------*/ +/** + * @brief Offsets in the stack to the parameters when inside the SVC handler. + */ +#define portOFFSET_TO_LR ( 5 ) +#define portOFFSET_TO_PC ( 6 ) +#define portOFFSET_TO_PSR ( 7 ) +/*-----------------------------------------------------------*/ + /** * @brief Constants required to manipulate the MPU. */ @@ -148,6 +163,8 @@ #define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ #define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ +#define portMPU_RBAR_ACCESS_PERMISSIONS_MASK ( 3UL << 1UL ) + #define portMPU_MAIR_ATTR0_POS ( 0UL ) #define portMPU_MAIR_ATTR0_MASK ( 0x000000ff ) @@ -191,6 +208,30 @@ /* Expected value of the portMPU_TYPE register. */ #define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) + +/* Extract first address of the MPU region as encoded in the + * RBAR (Region Base Address Register) value. */ +#define portEXTRACT_FIRST_ADDRESS_FROM_RBAR( rbar ) \ + ( ( rbar ) & portMPU_RBAR_ADDRESS_MASK ) + +/* Extract last address of the MPU region as encoded in the + * RLAR (Region Limit Address Register) value. */ +#define portEXTRACT_LAST_ADDRESS_FROM_RLAR( rlar ) \ + ( ( ( rlar ) & portMPU_RLAR_ADDRESS_MASK ) | ~portMPU_RLAR_ADDRESS_MASK ) + +/* Does addr lies within [start, end] address range? */ +#define portIS_ADDRESS_WITHIN_RANGE( addr, start, end ) \ + ( ( ( addr ) >= ( start ) ) && ( ( addr ) <= ( end ) ) ) + +/* Is the access request satisfied by the available permissions? */ +#define portIS_AUTHORIZED( accessRequest, permissions ) \ + ( ( ( permissions ) & ( accessRequest ) ) == accessRequest ) + +/* 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 ) ) ) /*-----------------------------------------------------------*/ /** @@ -311,6 +352,19 @@ static void prvTaskExitError( void ); #if ( configENABLE_MPU == 1 ) +/** + * @brief Extract MPU region's access permissions from the Region Base Address + * Register (RBAR) value. + * + * @param ulRBARValue RBAR value for the MPU region. + * + * @return uint32_t Access permissions. + */ + static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) PRIVILEGED_FUNCTION; +#endif /* configENABLE_MPU */ + +#if ( configENABLE_MPU == 1 ) + /** * @brief Setup the Memory Protection Unit (MPU). */ @@ -365,6 +419,60 @@ void SysTick_Handler( void ) PRIVILEGED_FUNCTION; * @brief C part of SVC handler. */ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIVILEGED_FUNCTION; + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + + /** + * @brief Sets up the system call stack so that upon returning from + * SVC, the system call stack is used. + * + * It is used for the system calls with up to 4 parameters. + * + * @param pulTaskStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + */ + void vSystemCallEnter( uint32_t * pulTaskStack, uint32_t ulLR ) PRIVILEGED_FUNCTION; + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + + /** + * @brief Sets up the system call stack so that upon returning from + * SVC, the system call stack is used. + * + * It is used for the system calls with 5 parameters. + * + * @param pulTaskStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + */ + void vSystemCallEnter_1( uint32_t * pulTaskStack, uint32_t ulLR ) PRIVILEGED_FUNCTION; + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + + /** + * @brief Sets up the task stack so that upon returning from + * SVC, the task stack is used again. + * + * @param pulSystemCallStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + */ + void vSystemCallExit( uint32_t * pulSystemCallStack, uint32_t ulLR ) PRIVILEGED_FUNCTION; + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + +#if ( configENABLE_MPU == 1 ) + + /** + * @brief Checks whether or not the calling task is privileged. + * + * @return pdTRUE if the calling task is privileged, pdFALSE otherwise. + */ + BaseType_t xPortIsTaskPrivileged( void ) PRIVILEGED_FUNCTION; + +#endif /* configENABLE_MPU == 1 */ /*-----------------------------------------------------------*/ /** @@ -681,6 +789,26 @@ static void prvTaskExitError( void ) } /*-----------------------------------------------------------*/ +#if ( configENABLE_MPU == 1 ) + static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) /* PRIVILEGED_FUNCTION */ + { + uint32_t ulAccessPermissions = 0; + + if( ( ulRBARValue & portMPU_RBAR_ACCESS_PERMISSIONS_MASK ) == portMPU_REGION_READ_ONLY ) + { + ulAccessPermissions = tskMPU_READ_PERMISSION; + } + + if( ( ulRBARValue & portMPU_RBAR_ACCESS_PERMISSIONS_MASK ) == portMPU_REGION_READ_WRITE ) + { + ulAccessPermissions = ( tskMPU_READ_PERMISSION | tskMPU_WRITE_PERMISSION ); + } + + return ulAccessPermissions; + } +#endif /* configENABLE_MPU */ +/*-----------------------------------------------------------*/ + #if ( configENABLE_MPU == 1 ) static void prvSetupMPU( void ) /* PRIVILEGED_FUNCTION */ { @@ -853,7 +981,7 @@ void SysTick_Handler( void ) /* PRIVILEGED_FUNCTION */ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTION portDONT_DISCARD */ { - #if ( configENABLE_MPU == 1 ) + #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) ) #if defined( __ARMCC_VERSION ) /* Declaration when these variable are defined in code instead of being @@ -865,7 +993,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO extern uint32_t __syscalls_flash_start__[]; extern uint32_t __syscalls_flash_end__[]; #endif /* defined( __ARMCC_VERSION ) */ - #endif /* configENABLE_MPU */ + #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */ uint32_t ulPC; @@ -880,7 +1008,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO /* Register are stored on the stack in the following order - R0, R1, R2, R3, * R12, LR, PC, xPSR. */ - ulPC = pulCallerStackAddress[ 6 ]; + ulPC = pulCallerStackAddress[ portOFFSET_TO_PC ]; ucSVCNumber = ( ( uint8_t * ) ulPC )[ -2 ]; switch( ucSVCNumber ) @@ -951,18 +1079,18 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO vRestoreContextOfFirstTask(); break; - #if ( configENABLE_MPU == 1 ) - case portSVC_RAISE_PRIVILEGE: + #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) ) + case portSVC_RAISE_PRIVILEGE: - /* Only raise the privilege, if the svc was raised from any of - * the system calls. */ - if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) && - ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ) - { - vRaisePrivilege(); - } - break; - #endif /* configENABLE_MPU */ + /* Only raise the privilege, if the svc was raised from any of + * the system calls. */ + if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ) + { + vRaisePrivilege(); + } + break; + #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */ default: /* Incorrect SVC call. */ @@ -971,51 +1099,455 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } /*-----------------------------------------------------------*/ -/* *INDENT-OFF* */ -#if ( configENABLE_MPU == 1 ) - StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, - StackType_t * pxEndOfStack, - TaskFunction_t pxCode, - void * pvParameters, - BaseType_t xRunPrivileged ) /* PRIVILEGED_FUNCTION */ -#else - StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, - StackType_t * pxEndOfStack, - TaskFunction_t pxCode, - void * pvParameters ) /* PRIVILEGED_FUNCTION */ -#endif /* configENABLE_MPU */ -/* *INDENT-ON* */ +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + +void vSystemCallEnter( uint32_t * pulTaskStack, uint32_t ulLR ) /* PRIVILEGED_FUNCTION */ { - /* Simulate the stack frame as it would be created by a context switch - * interrupt. */ - #if ( portPRELOAD_REGISTERS == 0 ) + extern TaskHandle_t pxCurrentTCB; + xMPU_SETTINGS * pxMpuSettings; + uint32_t * pulSystemCallStack; + uint32_t ulStackFrameSize, ulSystemCallLocation, i; + #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being + * exported from linker scripts. */ + extern uint32_t * __syscalls_flash_start__; + extern uint32_t * __syscalls_flash_end__; + #else + /* Declaration when these variable are exported from linker scripts. */ + extern uint32_t __syscalls_flash_start__[]; + extern uint32_t __syscalls_flash_end__[]; + #endif /* #if defined( __ARMCC_VERSION ) */ + + ulSystemCallLocation = pulTaskStack[ portOFFSET_TO_PC ]; + + /* If the request did not come from the system call section, do nothing. */ + if( ( ulSystemCallLocation >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulSystemCallLocation <= ( uint32_t ) __syscalls_flash_end__ ) ) { - pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ - *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ - pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pxCode; /* PC */ - pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR */ - pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ - *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ - pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */ - *pxTopOfStack = portINITIAL_EXC_RETURN; + pxMpuSettings = xTaskGetMPUSettings( pxCurrentTCB ); + pulSystemCallStack = pxMpuSettings->xSystemCallStackInfo.pulSystemCallStack; - #if ( configENABLE_MPU == 1 ) + /* This is not NULL only for the duration of the system call. */ + configASSERT( pxMpuSettings->xSystemCallStackInfo.pulTaskStack == NULL ); + + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) { - pxTopOfStack--; + if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) + { + /* Extended frame i.e. FPU in use. */ + ulStackFrameSize = 26; + __asm volatile ( + " vpush {s0} \n" /* Trigger lazy stacking. */ + " vpop {s0} \n" /* Nullify the affect of the above instruction. */ + ::: "memory" + ); + } + else + { + /* Standard frame i.e. FPU not in use. */ + ulStackFrameSize = 8; + } + } + #else + { + ulStackFrameSize = 8; + } + #endif /* configENABLE_FPU || configENABLE_MVE */ + + /* Make space on the system call stack for the stack frame. */ + pulSystemCallStack = pulSystemCallStack - ulStackFrameSize; + + /* Copy the stack frame. */ + for( i = 0; i < ulStackFrameSize; i++ ) + { + pulSystemCallStack[ i ] = pulTaskStack[ i ]; + } + + /* Store the value of the LR and PSPLIM registers before the SVC was raised. We need to + * restore it when we exit from the system call. */ + pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; + __asm volatile ( "mrs %0, psplim" : "=r" ( pxMpuSettings->xSystemCallStackInfo.ulStackLimitRegisterAtSystemCallEntry ) ); + + /* Use the pulSystemCallStack in thread mode. */ + __asm volatile ( "msr psp, %0" : : "r" ( pulSystemCallStack ) ); + __asm volatile ( "msr psplim, %0" : : "r" ( pxMpuSettings->xSystemCallStackInfo.pulSystemCallStackLimit ) ); + + /* Remember the location where we should copy the stack frame when we exit from + * the system call. */ + pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulStackFrameSize; + + /* Record if the hardware used padding to force the stack pointer + * to be double word aligned. */ + if( ( pulTaskStack[ portOFFSET_TO_PSR ] & portPSR_STACK_PADDING_MASK ) == portPSR_STACK_PADDING_MASK ) + { + pxMpuSettings->ulTaskFlags |= portSTACK_FRAME_HAS_PADDING_FLAG; + } + else + { + pxMpuSettings->ulTaskFlags &= ( ~portSTACK_FRAME_HAS_PADDING_FLAG ); + } + + /* We ensure in pxPortInitialiseStack that the system call stack is + * double word aligned and therefore, there is no need of padding. + * Clear the bit[9] of stacked xPSR. */ + pulSystemCallStack[ portOFFSET_TO_PSR ] &= ( ~portPSR_STACK_PADDING_MASK ); + + /* Raise the privilege for the duration of the system call. */ + __asm volatile ( + " mrs r0, control \n" /* Obtain current control value. */ + " movs r1, #1 \n" /* r1 = 1. */ + " bics r0, r1 \n" /* Clear nPRIV bit. */ + " msr control, r0 \n" /* Write back new control value. */ + ::: "r0", "r1", "memory" + ); + } +} - if( xRunPrivileged == pdTRUE ) +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + +void vSystemCallEnter_1( uint32_t * pulTaskStack, uint32_t ulLR ) /* PRIVILEGED_FUNCTION */ +{ + extern TaskHandle_t pxCurrentTCB; + xMPU_SETTINGS * pxMpuSettings; + uint32_t * pulSystemCallStack; + uint32_t ulStackFrameSize, ulSystemCallLocation, i; + #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being + * exported from linker scripts. */ + extern uint32_t * __syscalls_flash_start__; + extern uint32_t * __syscalls_flash_end__; + #else + /* Declaration when these variable are exported from linker scripts. */ + extern uint32_t __syscalls_flash_start__[]; + extern uint32_t __syscalls_flash_end__[]; + #endif /* #if defined( __ARMCC_VERSION ) */ + + ulSystemCallLocation = pulTaskStack[ portOFFSET_TO_PC ]; + + /* If the request did not come from the system call section, do nothing. */ + if( ( ulSystemCallLocation >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulSystemCallLocation <= ( uint32_t ) __syscalls_flash_end__ ) ) + { + pxMpuSettings = xTaskGetMPUSettings( pxCurrentTCB ); + pulSystemCallStack = pxMpuSettings->xSystemCallStackInfo.pulSystemCallStack; + + /* This is not NULL only for the duration of the system call. */ + configASSERT( pxMpuSettings->xSystemCallStackInfo.pulTaskStack == NULL ); + + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + { + if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) { - *pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */ + /* Extended frame i.e. FPU in use. */ + ulStackFrameSize = 26; + __asm volatile ( + " vpush {s0} \n" /* Trigger lazy stacking. */ + " vpop {s0} \n" /* Nullify the affect of the above instruction. */ + ::: "memory" + ); } else { - *pxTopOfStack = portINITIAL_CONTROL_UNPRIVILEGED; /* Slot used to hold this task's CONTROL value. */ + /* Standard frame i.e. FPU not in use. */ + ulStackFrameSize = 8; } } - #endif /* configENABLE_MPU */ + #else + { + ulStackFrameSize = 8; + } + #endif /* configENABLE_FPU || configENABLE_MVE */ + + /* Make space on the system call stack for the stack frame and + * the parameter passed on the stack. We only need to copy one + * parameter but we still reserve 2 spaces to keep the stack + * double word aligned. */ + pulSystemCallStack = pulSystemCallStack - ulStackFrameSize - 2UL; + + /* Copy the stack frame. */ + for( i = 0; i < ulStackFrameSize; i++ ) + { + pulSystemCallStack[ i ] = pulTaskStack[ i ]; + } + + /* Copy the parameter which is passed the stack. */ + if( ( pulTaskStack[ portOFFSET_TO_PSR ] & portPSR_STACK_PADDING_MASK ) == portPSR_STACK_PADDING_MASK ) + { + pulSystemCallStack[ ulStackFrameSize ] = pulTaskStack[ ulStackFrameSize + 1 ]; + /* Record if the hardware used padding to force the stack pointer + * to be double word aligned. */ + pxMpuSettings->ulTaskFlags |= portSTACK_FRAME_HAS_PADDING_FLAG; + } + else + { + pulSystemCallStack[ ulStackFrameSize ] = pulTaskStack[ ulStackFrameSize ]; + /* Record if the hardware used padding to force the stack pointer + * to be double word aligned. */ + pxMpuSettings->ulTaskFlags &= ( ~portSTACK_FRAME_HAS_PADDING_FLAG ); + } + + /* Store the value of the LR and PSPLIM registers before the SVC was raised. + * We need to restore it when we exit from the system call. */ + pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; + __asm volatile ( "mrs %0, psplim" : "=r" ( pxMpuSettings->xSystemCallStackInfo.ulStackLimitRegisterAtSystemCallEntry ) ); + + /* Use the pulSystemCallStack in thread mode. */ + __asm volatile ( "msr psp, %0" : : "r" ( pulSystemCallStack ) ); + __asm volatile ( "msr psplim, %0" : : "r" ( pxMpuSettings->xSystemCallStackInfo.pulSystemCallStackLimit ) ); + + /* Remember the location where we should copy the stack frame when we exit from + * the system call. */ + pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulStackFrameSize; + + /* We ensure in pxPortInitialiseStack that the system call stack is + * double word aligned and therefore, there is no need of padding. + * Clear the bit[9] of stacked xPSR. */ + pulSystemCallStack[ portOFFSET_TO_PSR ] &= ( ~portPSR_STACK_PADDING_MASK ); + + /* Raise the privilege for the duration of the system call. */ + __asm volatile ( + " mrs r0, control \n" /* Obtain current control value. */ + " movs r1, #1 \n" /* r1 = 1. */ + " bics r0, r1 \n" /* Clear nPRIV bit. */ + " msr control, r0 \n" /* Write back new control value. */ + ::: "r0", "r1", "memory" + ); + } +} + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) +void vSystemCallExit( uint32_t * pulSystemCallStack, uint32_t ulLR ) /* PRIVILEGED_FUNCTION */ +{ + extern TaskHandle_t pxCurrentTCB; + xMPU_SETTINGS * pxMpuSettings; + uint32_t * pulTaskStack; + uint32_t ulStackFrameSize, ulSystemCallLocation, i; + #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being + * exported from linker scripts. */ + extern uint32_t * __syscalls_flash_start__; + extern uint32_t * __syscalls_flash_end__; + #else + /* Declaration when these variable are exported from linker scripts. */ + extern uint32_t __syscalls_flash_start__[]; + extern uint32_t __syscalls_flash_end__[]; + #endif /* #if defined( __ARMCC_VERSION ) */ + + ulSystemCallLocation = pulSystemCallStack[ portOFFSET_TO_PC ]; + + /* If the request did not come from the system call section, do nothing. */ + if( ( ulSystemCallLocation >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulSystemCallLocation <= ( uint32_t ) __syscalls_flash_end__ ) ) + { + pxMpuSettings = xTaskGetMPUSettings( pxCurrentTCB ); + pulTaskStack = pxMpuSettings->xSystemCallStackInfo.pulTaskStack; + + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + { + if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) + { + /* Extended frame i.e. FPU in use. */ + ulStackFrameSize = 26; + __asm volatile ( + " vpush {s0} \n" /* Trigger lazy stacking. */ + " vpop {s0} \n" /* Nullify the affect of the above instruction. */ + ::: "memory" + ); + } + else + { + /* Standard frame i.e. FPU not in use. */ + ulStackFrameSize = 8; + } + } + #else + { + ulStackFrameSize = 8; + } + #endif /* configENABLE_FPU || configENABLE_MVE */ + + /* Make space on the task stack for the stack frame. */ + pulTaskStack = pulTaskStack - ulStackFrameSize; + + /* Copy the stack frame. */ + for( i = 0; i < ulStackFrameSize; i++ ) + { + pulTaskStack[ i ] = pulSystemCallStack[ i ]; + } + + /* Use the pulTaskStack in thread mode. */ + __asm volatile ( "msr psp, %0" : : "r" ( pulTaskStack ) ); + + /* Restore the LR and PSPLIM to what they were at the time of + * system call entry. */ + pulTaskStack[ portOFFSET_TO_LR ] = pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry; + __asm volatile ( "msr psplim, %0" : : "r" ( pxMpuSettings->xSystemCallStackInfo.ulStackLimitRegisterAtSystemCallEntry ) ); + + /* If the hardware used padding to force the stack pointer + * to be double word aligned, set the stacked xPSR bit[9], + * otherwise clear it. */ + if( ( pxMpuSettings->ulTaskFlags & portSTACK_FRAME_HAS_PADDING_FLAG ) == portSTACK_FRAME_HAS_PADDING_FLAG ) + { + pulTaskStack[ portOFFSET_TO_PSR ] |= portPSR_STACK_PADDING_MASK; + } + else + { + pulTaskStack[ portOFFSET_TO_PSR ] &= ( ~portPSR_STACK_PADDING_MASK ); + } + + /* This is not NULL only for the duration of the system call. */ + pxMpuSettings->xSystemCallStackInfo.pulTaskStack = NULL; + + /* Drop the privilege before returning to the thread mode. */ + __asm volatile ( + " mrs r0, control \n" /* Obtain current control value. */ + " movs r1, #1 \n" /* r1 = 1. */ + " orrs r0, r1 \n" /* Set nPRIV bit. */ + " msr control, r0 \n" /* Write back new control value. */ + ::: "r0", "r1", "memory" + ); + } +} + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configENABLE_MPU == 1 ) + +BaseType_t xPortIsTaskPrivileged( void ) /* PRIVILEGED_FUNCTION */ +{ + BaseType_t xTaskIsPrivileged = pdFALSE; + const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */ + + if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) + { + xTaskIsPrivileged = pdTRUE; + } + + return xTaskIsPrivileged; +} + +#endif /* configENABLE_MPU == 1 */ +/*-----------------------------------------------------------*/ + +#if( configENABLE_MPU == 1 ) + +StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, + StackType_t * pxEndOfStack, + TaskFunction_t pxCode, + void * pvParameters, + BaseType_t xRunPrivileged, + xMPU_SETTINGS * xMPUSettings ) /* PRIVILEGED_FUNCTION */ +{ + uint32_t ulIndex = 0; + + xMPUSettings->ulContext[ ulIndex ] = 0x04040404; /* r4. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x05050505; /* r5. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x06060606; /* r6. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x07070707; /* r7. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x08080808; /* r8. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x09090909; /* r9. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x10101010; /* r10. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x11111111; /* r11. */ + ulIndex++; + + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pvParameters; /* r0. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x01010101; /* r1. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x02020202; /* r2. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x03030303; /* r3. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x12121212; /* r12. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portTASK_RETURN_ADDRESS; /* LR. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxCode; /* PC. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = portINITIAL_XPSR; /* xPSR. */ + ulIndex++; + + #if ( configENABLE_TRUSTZONE == 1 ) + { + xMPUSettings->ulContext[ ulIndex ] = portNO_SECURE_CONTEXT; /* xSecureContext. */ + ulIndex++; + } + #endif /* configENABLE_TRUSTZONE */ + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) ( pxTopOfStack - 8 ); /* PSP with the hardware saved stack. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */ + ulIndex++; + if( xRunPrivileged == pdTRUE ) + { + xMPUSettings->ulTaskFlags |= portTASK_IS_PRIVILEGED_FLAG; + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_PRIVILEGED; /* CONTROL. */ + ulIndex++; + } + else + { + xMPUSettings->ulTaskFlags &= ( ~portTASK_IS_PRIVILEGED_FLAG ); + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_UNPRIVILEGED; /* CONTROL. */ + ulIndex++; + } + xMPUSettings->ulContext[ ulIndex ] = portINITIAL_EXC_RETURN; /* LR (EXC_RETURN). */ + ulIndex++; + + #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + { + /* Ensure that the system call stack is double word aligned. */ + xMPUSettings->xSystemCallStackInfo.pulSystemCallStack = &( xMPUSettings->xSystemCallStackInfo.ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE - 1 ] ); + xMPUSettings->xSystemCallStackInfo.pulSystemCallStack = ( uint32_t * ) ( ( uint32_t ) ( xMPUSettings->xSystemCallStackInfo.pulSystemCallStack ) & + ( uint32_t ) ( ~( portBYTE_ALIGNMENT_MASK ) ) ); + + xMPUSettings->xSystemCallStackInfo.pulSystemCallStackLimit = &( xMPUSettings->xSystemCallStackInfo.ulSystemCallStackBuffer[ 0 ] ); + xMPUSettings->xSystemCallStackInfo.pulSystemCallStackLimit = ( uint32_t * ) ( ( ( uint32_t ) ( xMPUSettings->xSystemCallStackInfo.pulSystemCallStackLimit ) + + ( uint32_t ) ( portBYTE_ALIGNMENT - 1 ) ) & + ( uint32_t ) ( ~( portBYTE_ALIGNMENT_MASK ) ) ); + + /* This is not NULL only for the duration of a system call. */ + xMPUSettings->xSystemCallStackInfo.pulTaskStack = NULL; + } + #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + + return &( xMPUSettings->ulContext[ ulIndex ] ); +} + +#else /* configENABLE_MPU */ + +StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, + StackType_t * pxEndOfStack, + TaskFunction_t pxCode, + void * pvParameters ) /* PRIVILEGED_FUNCTION */ +{ + /* Simulate the stack frame as it would be created by a context switch + * interrupt. */ + #if ( portPRELOAD_REGISTERS == 0 ) + { + pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ + *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR. */ + pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ + pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */ + *pxTopOfStack = portINITIAL_EXC_RETURN; pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ @@ -1029,55 +1561,39 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO #else /* portPRELOAD_REGISTERS */ { pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ - *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ + *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pxCode; /* PC */ + *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR */ + *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x12121212UL; /* R12 */ + *pxTopOfStack = ( StackType_t ) 0x12121212UL; /* R12. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x03030303UL; /* R3 */ + *pxTopOfStack = ( StackType_t ) 0x03030303UL; /* R3. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x02020202UL; /* R2 */ + *pxTopOfStack = ( StackType_t ) 0x02020202UL; /* R2. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x01010101UL; /* R1 */ + *pxTopOfStack = ( StackType_t ) 0x01010101UL; /* R1. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x11111111UL; /* R11 */ + *pxTopOfStack = ( StackType_t ) 0x11111111UL; /* R11. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x10101010UL; /* R10 */ + *pxTopOfStack = ( StackType_t ) 0x10101010UL; /* R10. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x09090909UL; /* R09 */ + *pxTopOfStack = ( StackType_t ) 0x09090909UL; /* R09. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x08080808UL; /* R08 */ + *pxTopOfStack = ( StackType_t ) 0x08080808UL; /* R08. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x07070707UL; /* R07 */ + *pxTopOfStack = ( StackType_t ) 0x07070707UL; /* R07. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x06060606UL; /* R06 */ + *pxTopOfStack = ( StackType_t ) 0x06060606UL; /* R06. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x05050505UL; /* R05 */ + *pxTopOfStack = ( StackType_t ) 0x05050505UL; /* R05. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x04040404UL; /* R04 */ + *pxTopOfStack = ( StackType_t ) 0x04040404UL; /* R04. */ pxTopOfStack--; - *pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN */ - - #if ( configENABLE_MPU == 1 ) - { - pxTopOfStack--; - - if( xRunPrivileged == pdTRUE ) - { - *pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */ - } - else - { - *pxTopOfStack = portINITIAL_CONTROL_UNPRIVILEGED; /* Slot used to hold this task's CONTROL value. */ - } - } - #endif /* configENABLE_MPU */ - + *pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN. */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ @@ -1092,6 +1608,8 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO return pxTopOfStack; } + +#endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ @@ -1128,6 +1646,10 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ configASSERT( ucMaxSysCallPriority ); + /* Check that the bits not implemented in hardware are zero in + * configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & ( ~ucMaxPriorityValue ) ) == 0U ); + /* Calculate the maximum acceptable priority group value for the number * of bits read back. */ @@ -1164,35 +1686,6 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulImplementedPrioBits; } - /* The interrupt priority bits are not modelled in QEMU and the assert that - * checks the number of implemented bits and __NVIC_PRIO_BITS will always fail. - * Therefore, this assert is not adding any value for QEMU targets. The config - * option `configDISABLE_INTERRUPT_PRIO_BITS_CHECK` should be defined in the - * `FreeRTOSConfig.h` for QEMU targets. */ - #ifndef configDISABLE_INTERRUPT_PRIO_BITS_CHECK - { - #ifdef __NVIC_PRIO_BITS - { - /* - * Check that the number of implemented priority bits queried from - * hardware is equal to the CMSIS __NVIC_PRIO_BITS configuration macro. - */ - configASSERT( ulImplementedPrioBits == __NVIC_PRIO_BITS ); - } - #endif /* __NVIC_PRIO_BITS */ - - #ifdef configPRIO_BITS - { - /* - * Check that the number of implemented priority bits queried from - * hardware is equal to the FreeRTOS configPRIO_BITS configuration macro. - */ - configASSERT( ulImplementedPrioBits == configPRIO_BITS ); - } - #endif /* configPRIO_BITS */ - } - #endif /* #ifndef configDISABLE_INTERRUPT_PRIO_BITS_CHECK */ - /* Shift the priority group value back to its position within the AIRCR * register. */ ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT; @@ -1372,6 +1865,54 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ +#if ( configENABLE_MPU == 1 ) + BaseType_t xPortIsAuthorizedToAccessBuffer( const void * pvBuffer, + uint32_t ulBufferLength, + uint32_t ulAccessRequested ) /* PRIVILEGED_FUNCTION */ + + { + uint32_t i, ulBufferStartAddress, ulBufferEndAddress; + BaseType_t xAccessGranted = pdFALSE; + const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */ + + if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) + { + xAccessGranted = pdTRUE; + } + else + { + if( portADD_UINT32_WILL_OVERFLOW( ( ( uint32_t ) pvBuffer ), ( ulBufferLength - 1UL ) ) == pdFALSE ) + { + ulBufferStartAddress = ( uint32_t ) pvBuffer; + ulBufferEndAddress = ( ( ( uint32_t ) pvBuffer ) + ulBufferLength - 1UL ); + + for( i = 0; i < portTOTAL_NUM_REGIONS; i++ ) + { + /* Is the MPU region enabled? */ + if( ( xTaskMpuSettings->xRegionsSettings[ i ].ulRLAR & portMPU_RLAR_REGION_ENABLE ) == portMPU_RLAR_REGION_ENABLE ) + { + if( portIS_ADDRESS_WITHIN_RANGE( ulBufferStartAddress, + portEXTRACT_FIRST_ADDRESS_FROM_RBAR( xTaskMpuSettings->xRegionsSettings[ i ].ulRBAR ), + portEXTRACT_LAST_ADDRESS_FROM_RLAR( xTaskMpuSettings->xRegionsSettings[ i ].ulRLAR ) ) && + portIS_ADDRESS_WITHIN_RANGE( ulBufferEndAddress, + portEXTRACT_FIRST_ADDRESS_FROM_RBAR( xTaskMpuSettings->xRegionsSettings[ i ].ulRBAR ), + portEXTRACT_LAST_ADDRESS_FROM_RLAR( xTaskMpuSettings->xRegionsSettings[ i ].ulRLAR ) ) && + portIS_AUTHORIZED( ulAccessRequested, + prvGetRegionAccessPermissions( xTaskMpuSettings->xRegionsSettings[ i ].ulRBAR ) ) ) + { + xAccessGranted = pdTRUE; + break; + } + } + } + } + } + + return xAccessGranted; + } +#endif /* configENABLE_MPU */ +/*-----------------------------------------------------------*/ + BaseType_t xPortIsInsideInterrupt( void ) { uint32_t ulCurrentInterrupt; diff --git a/portable/IAR/ARM_CM35P/non_secure/portasm.s b/portable/IAR/ARM_CM35P/non_secure/portasm.s index a193cd7b80e..15e74ffc16b 100644 --- a/portable/IAR/ARM_CM35P/non_secure/portasm.s +++ b/portable/IAR/ARM_CM35P/non_secure/portasm.s @@ -32,12 +32,21 @@ the code is included in C files but excluded by the preprocessor in assembly files (__ICCARM__ is defined by the IAR C compiler but not by the IAR assembler. */ #include "FreeRTOSConfig.h" +#ifndef configUSE_MPU_WRAPPERS_V1 + #define configUSE_MPU_WRAPPERS_V1 0 +#endif + EXTERN pxCurrentTCB EXTERN xSecureContext EXTERN vTaskSwitchContext EXTERN vPortSVCHandler_C EXTERN SecureContext_SaveContext EXTERN SecureContext_LoadContext +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + EXTERN vSystemCallEnter + EXTERN vSystemCallEnter_1 + EXTERN vSystemCallExit +#endif PUBLIC xIsPrivileged PUBLIC vResetPrivilege @@ -89,50 +98,81 @@ vPortAllocateSecureContext: THUMB /*-----------------------------------------------------------*/ +#if ( configENABLE_MPU == 1 ) + +vRestoreContextOfFirstTask: + program_mpu_first_task: + ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + ldr r0, [r3] /* r0 = pxCurrentTCB. */ + + dmb /* Complete outstanding transfers before disabling MPU. */ + ldr r1, =0xe000ed94 /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + ldr r2, [r1] /* Read the value of MPU_CTRL. */ + bic r2, #1 /* r2 = r2 & ~1 i.e. Clear the bit 0 in r2. */ + str r2, [r1] /* Disable MPU. */ + + adds r0, #4 /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */ + ldr r1, [r0] /* r1 = *r0 i.e. r1 = MAIR0. */ + ldr r2, =0xe000edc0 /* r2 = 0xe000edc0 [Location of MAIR0]. */ + str r1, [r2] /* Program MAIR0. */ + + adds r0, #4 /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */ + ldr r1, =0xe000ed98 /* r1 = 0xe000ed98 [Location of RNR]. */ + ldr r2, =0xe000ed9c /* r2 = 0xe000ed9c [Location of RBAR]. */ + + movs r3, #4 /* r3 = 4. */ + str r3, [r1] /* Program RNR = 4. */ + ldmia r0!, {r4-r11} /* Read 4 set of RBAR/RLAR registers from TCB. */ + stmia r2, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ + + #if ( configTOTAL_MPU_REGIONS == 16 ) + movs r3, #8 /* r3 = 8. */ + str r3, [r1] /* Program RNR = 8. */ + ldmia r0!, {r4-r11} /* Read 4 set of RBAR/RLAR registers from TCB. */ + stmia r2, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ + movs r3, #12 /* r3 = 12. */ + str r3, [r1] /* Program RNR = 12. */ + ldmia r0!, {r4-r11} /* Read 4 set of RBAR/RLAR registers from TCB. */ + stmia r2, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ + #endif /* configTOTAL_MPU_REGIONS == 16 */ + + ldr r1, =0xe000ed94 /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + ldr r2, [r1] /* Read the value of MPU_CTRL. */ + orr r2, #1 /* r2 = r1 | 1 i.e. Set the bit 0 in r2. */ + str r2, [r1] /* Enable MPU. */ + dsb /* Force memory writes before continuing. */ + + restore_context_first_task: + ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + ldr r1, [r3] /* r1 = pxCurrentTCB.*/ + ldr r2, [r1] /* r2 = Location of saved context in TCB. */ + + restore_special_regs_first_task: + ldmdb r2!, {r0, r3-r5, lr} /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */ + msr psp, r3 + msr psplim, r4 + msr control, r5 + ldr r4, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */ + str r0, [r4] /* Restore xSecureContext. */ + + restore_general_regs_first_task: + ldmdb r2!, {r4-r11} /* r4-r11 contain hardware saved context. */ + stmia r3!, {r4-r11} /* Copy the hardware saved context on the task stack. */ + ldmdb r2!, {r4-r11} /* r4-r11 restored. */ + + restore_context_done_first_task: + str r2, [r1] /* Save the location where the context should be saved next as the first member of TCB. */ + mov r0, #0 + msr basepri, r0 /* Ensure that interrupts are enabled when the first task starts. */ + bx lr + +#else /* configENABLE_MPU */ + vRestoreContextOfFirstTask: ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r3, [r2] /* Read pxCurrentTCB. */ ldr r0, [r3] /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ -#if ( configENABLE_MPU == 1 ) - dmb /* Complete outstanding transfers before disabling MPU. */ - ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ - ldr r4, [r2] /* Read the value of MPU_CTRL. */ - bic r4, r4, #1 /* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */ - str r4, [r2] /* Disable MPU. */ - - adds r3, #4 /* r3 = r3 + 4. r3 now points to MAIR0 in TCB. */ - ldr r4, [r3] /* r4 = *r3 i.e. r4 = MAIR0. */ - ldr r2, =0xe000edc0 /* r2 = 0xe000edc0 [Location of MAIR0]. */ - str r4, [r2] /* Program MAIR0. */ - ldr r2, =0xe000ed98 /* r2 = 0xe000ed98 [Location of RNR]. */ - movs r4, #4 /* r4 = 4. */ - str r4, [r2] /* Program RNR = 4. */ - adds r3, #4 /* r3 = r3 + 4. r3 now points to first RBAR in TCB. */ - ldr r2, =0xe000ed9c /* r2 = 0xe000ed9c [Location of RBAR]. */ - ldmia r3!, {r4-r11} /* Read 4 set of RBAR/RLAR registers from TCB. */ - stmia r2!, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ - - ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ - ldr r4, [r2] /* Read the value of MPU_CTRL. */ - orr r4, r4, #1 /* r4 = r4 | 1 i.e. Set the bit 0 in r4. */ - str r4, [r2] /* Enable MPU. */ - dsb /* Force memory writes before continuing. */ -#endif /* configENABLE_MPU */ - -#if ( configENABLE_MPU == 1 ) - ldm r0!, {r1-r4} /* Read from stack - r1 = xSecureContext, r2 = PSPLIM, r3 = CONTROL and r4 = EXC_RETURN. */ - ldr r5, =xSecureContext - str r1, [r5] /* Set xSecureContext to this task's value for the same. */ - msr psplim, r2 /* Set this task's PSPLIM value. */ - msr control, r3 /* Set this task's CONTROL value. */ - adds r0, #32 /* Discard everything up to r0. */ - msr psp, r0 /* This is now the new top of stack to use in the task. */ - isb - mov r0, #0 - msr basepri, r0 /* Ensure that interrupts are enabled when the first task starts. */ - bx r4 /* Finally, branch to EXC_RETURN. */ -#else /* configENABLE_MPU */ ldm r0!, {r1-r3} /* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */ ldr r4, =xSecureContext str r1, [r4] /* Set xSecureContext to this task's value for the same. */ @@ -145,6 +185,7 @@ vRestoreContextOfFirstTask: mov r0, #0 msr basepri, r0 /* Ensure that interrupts are enabled when the first task starts. */ bx r3 /* Finally, branch to EXC_RETURN. */ + #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ @@ -183,6 +224,143 @@ vClearInterruptMask: bx lr /* Return. */ /*-----------------------------------------------------------*/ +#if ( configENABLE_MPU == 1 ) + +PendSV_Handler: + ldr r3, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */ + ldr r0, [r3] /* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */ + ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + ldr r1, [r3] /* Read pxCurrentTCB - Value of pxCurrentTCB must be in r1 as it is used as a parameter later. */ + ldr r2, [r1] /* r2 = Location in TCB where the context should be saved. */ + + cbz r0, save_ns_context /* No secure context to save. */ + save_s_context: + push {r0-r2, lr} + bl SecureContext_SaveContext /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ + pop {r0-r2, lr} + + save_ns_context: + mov r3, lr /* r3 = LR (EXC_RETURN). */ + lsls r3, r3, #25 /* r3 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ + bmi save_special_regs /* r3 < 0 ==> Bit[6] in EXC_RETURN is 1 ==> secure stack was used to store the stack frame. */ + + save_general_regs: + mrs r3, psp + + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + add r3, r3, #0x20 /* Move r3 to location where s0 is saved. */ + tst lr, #0x10 + ittt eq + vstmiaeq r2!, {s16-s31} /* Store s16-s31. */ + vldmiaeq r3, {s0-s16} /* Copy hardware saved FP context into s0-s16. */ + vstmiaeq r2!, {s0-s16} /* Store hardware saved FP context. */ + sub r3, r3, #0x20 /* Set r3 back to the location of hardware saved context. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ + + stmia r2!, {r4-r11} /* Store r4-r11. */ + ldmia r3, {r4-r11} /* Copy the hardware saved context into r4-r11. */ + stmia r2!, {r4-r11} /* Store the hardware saved context. */ + + save_special_regs: + mrs r3, psp /* r3 = PSP. */ + mrs r4, psplim /* r4 = PSPLIM. */ + mrs r5, control /* r5 = CONTROL. */ + stmia r2!, {r0, r3-r5, lr} /* Store xSecureContext, original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */ + str r2, [r1] /* Save the location from where the context should be restored as the first member of TCB. */ + + select_next_task: + mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY + msr basepri, r0 /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + dsb + isb + bl vTaskSwitchContext + mov r0, #0 /* r0 = 0. */ + msr basepri, r0 /* Enable interrupts. */ + + program_mpu: + ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + ldr r0, [r3] /* r0 = pxCurrentTCB.*/ + + dmb /* Complete outstanding transfers before disabling MPU. */ + ldr r1, =0xe000ed94 /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + ldr r2, [r1] /* Read the value of MPU_CTRL. */ + bic r2, #1 /* r2 = r2 & ~1 i.e. Clear the bit 0 in r2. */ + str r2, [r1] /* Disable MPU. */ + + adds r0, #4 /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */ + ldr r1, [r0] /* r1 = *r0 i.e. r1 = MAIR0. */ + ldr r2, =0xe000edc0 /* r2 = 0xe000edc0 [Location of MAIR0]. */ + str r1, [r2] /* Program MAIR0. */ + + adds r0, #4 /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */ + ldr r1, =0xe000ed98 /* r1 = 0xe000ed98 [Location of RNR]. */ + ldr r2, =0xe000ed9c /* r2 = 0xe000ed9c [Location of RBAR]. */ + + movs r3, #4 /* r3 = 4. */ + str r3, [r1] /* Program RNR = 4. */ + ldmia r0!, {r4-r11} /* Read 4 sets of RBAR/RLAR registers from TCB. */ + stmia r2, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ + + #if ( configTOTAL_MPU_REGIONS == 16 ) + movs r3, #8 /* r3 = 8. */ + str r3, [r1] /* Program RNR = 8. */ + ldmia r0!, {r4-r11} /* Read 4 sets of RBAR/RLAR registers from TCB. */ + stmia r2, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ + movs r3, #12 /* r3 = 12. */ + str r3, [r1] /* Program RNR = 12. */ + ldmia r0!, {r4-r11} /* Read 4 sets of RBAR/RLAR registers from TCB. */ + stmia r2, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ + #endif /* configTOTAL_MPU_REGIONS == 16 */ + + ldr r1, =0xe000ed94 /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + ldr r2, [r1] /* Read the value of MPU_CTRL. */ + orr r2, #1 /* r2 = r2 | 1 i.e. Set the bit 0 in r2. */ + str r2, [r1] /* Enable MPU. */ + dsb /* Force memory writes before continuing. */ + + restore_context: + ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + ldr r1, [r3] /* r1 = pxCurrentTCB.*/ + ldr r2, [r1] /* r2 = Location of saved context in TCB. */ + + restore_special_regs: + ldmdb r2!, {r0, r3-r5, lr} /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */ + msr psp, r3 + msr psplim, r4 + msr control, r5 + ldr r4, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */ + str r0, [r4] /* Restore xSecureContext. */ + cbz r0, restore_ns_context /* No secure context to restore. */ + + restore_s_context: + push {r1-r3, lr} + bl SecureContext_LoadContext /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ + pop {r1-r3, lr} + + restore_ns_context: + mov r0, lr /* r0 = LR (EXC_RETURN). */ + lsls r0, r0, #25 /* r0 = r0 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ + bmi restore_context_done /* r0 < 0 ==> Bit[6] in EXC_RETURN is 1 ==> secure stack was used to store the stack frame. */ + + restore_general_regs: + ldmdb r2!, {r4-r11} /* r4-r11 contain hardware saved context. */ + stmia r3!, {r4-r11} /* Copy the hardware saved context on the task stack. */ + ldmdb r2!, {r4-r11} /* r4-r11 restored. */ + + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + tst lr, #0x10 + ittt eq + vldmdbeq r2!, {s0-s16} /* s0-s16 contain hardware saved FP context. */ + vstmiaeq r3!, {s0-s16} /* Copy hardware saved FP context on the task stack. */ + vldmdbeq r2!, {s16-s31} /* Restore s16-s31. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ + + restore_context_done: + str r2, [r1] /* Save the location where the context should be saved next as the first member of TCB. */ + bx lr + +#else /* configENABLE_MPU */ + PendSV_Handler: ldr r3, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */ ldr r0, [r3] /* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */ @@ -200,20 +378,11 @@ PendSV_Handler: ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r3] /* Read pxCurrentTCB. */ -#if ( configENABLE_MPU == 1 ) - subs r2, r2, #16 /* Make space for xSecureContext, PSPLIM, CONTROL and LR on the stack. */ - str r2, [r1] /* Save the new top of stack in TCB. */ - mrs r1, psplim /* r1 = PSPLIM. */ - mrs r3, control /* r3 = CONTROL. */ - mov r4, lr /* r4 = LR/EXC_RETURN. */ - stmia r2!, {r0, r1, r3, r4} /* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */ -#else /* configENABLE_MPU */ subs r2, r2, #12 /* Make space for xSecureContext, PSPLIM and LR on the stack. */ str r2, [r1] /* Save the new top of stack in TCB. */ mrs r1, psplim /* r1 = PSPLIM. */ mov r3, lr /* r3 = LR/EXC_RETURN. */ stmia r2!, {r0, r1, r3} /* Store xSecureContext, PSPLIM and LR on the stack. */ -#endif /* configENABLE_MPU */ b select_next_task save_ns_context: @@ -224,17 +393,6 @@ PendSV_Handler: it eq vstmdbeq r2!, {s16-s31} /* Store the additional FP context registers which are not saved automatically. */ #endif /* configENABLE_FPU || configENABLE_MVE */ - #if ( configENABLE_MPU == 1 ) - subs r2, r2, #48 /* Make space for xSecureContext, PSPLIM, CONTROL, LR and the remaining registers on the stack. */ - str r2, [r1] /* Save the new top of stack in TCB. */ - adds r2, r2, #16 /* r2 = r2 + 16. */ - stm r2, {r4-r11} /* Store the registers that are not saved automatically. */ - mrs r1, psplim /* r1 = PSPLIM. */ - mrs r3, control /* r3 = CONTROL. */ - mov r4, lr /* r4 = LR/EXC_RETURN. */ - subs r2, r2, #16 /* r2 = r2 - 16. */ - stmia r2!, {r0, r1, r3, r4} /* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */ - #else /* configENABLE_MPU */ subs r2, r2, #44 /* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */ str r2, [r1] /* Save the new top of stack in TCB. */ adds r2, r2, #12 /* r2 = r2 + 12. */ @@ -243,7 +401,6 @@ PendSV_Handler: mov r3, lr /* r3 = LR/EXC_RETURN. */ subs r2, r2, #12 /* r2 = r2 - 12. */ stmia r2!, {r0, r1, r3} /* Store xSecureContext, PSPLIM and LR on the stack. */ - #endif /* configENABLE_MPU */ select_next_task: mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY @@ -258,51 +415,6 @@ PendSV_Handler: ldr r1, [r3] /* Read pxCurrentTCB. */ ldr r2, [r1] /* The first item in pxCurrentTCB is the task top of stack. r2 now points to the top of stack. */ - #if ( configENABLE_MPU == 1 ) - dmb /* Complete outstanding transfers before disabling MPU. */ - ldr r3, =0xe000ed94 /* r3 = 0xe000ed94 [Location of MPU_CTRL]. */ - ldr r4, [r3] /* Read the value of MPU_CTRL. */ - bic r4, r4, #1 /* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */ - str r4, [r3] /* Disable MPU. */ - - adds r1, #4 /* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */ - ldr r4, [r1] /* r4 = *r1 i.e. r4 = MAIR0. */ - ldr r3, =0xe000edc0 /* r3 = 0xe000edc0 [Location of MAIR0]. */ - str r4, [r3] /* Program MAIR0. */ - ldr r3, =0xe000ed98 /* r3 = 0xe000ed98 [Location of RNR]. */ - movs r4, #4 /* r4 = 4. */ - str r4, [r3] /* Program RNR = 4. */ - adds r1, #4 /* r1 = r1 + 4. r1 now points to first RBAR in TCB. */ - ldr r3, =0xe000ed9c /* r3 = 0xe000ed9c [Location of RBAR]. */ - ldmia r1!, {r4-r11} /* Read 4 sets of RBAR/RLAR registers from TCB. */ - stmia r3!, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ - - ldr r3, =0xe000ed94 /* r3 = 0xe000ed94 [Location of MPU_CTRL]. */ - ldr r4, [r3] /* Read the value of MPU_CTRL. */ - orr r4, r4, #1 /* r4 = r4 | 1 i.e. Set the bit 0 in r4. */ - str r4, [r3] /* Enable MPU. */ - dsb /* Force memory writes before continuing. */ - #endif /* configENABLE_MPU */ - - #if ( configENABLE_MPU == 1 ) - ldmia r2!, {r0, r1, r3, r4} /* Read from stack - r0 = xSecureContext, r1 = PSPLIM, r3 = CONTROL and r4 = LR. */ - msr psplim, r1 /* Restore the PSPLIM register value for the task. */ - msr control, r3 /* Restore the CONTROL register value for the task. */ - mov lr, r4 /* LR = r4. */ - ldr r3, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */ - str r0, [r3] /* Restore the task's xSecureContext. */ - cbz r0, restore_ns_context /* If there is no secure context for the task, restore the non-secure context. */ - ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - ldr r1, [r3] /* Read pxCurrentTCB. */ - push {r2, r4} - bl SecureContext_LoadContext /* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ - pop {r2, r4} - mov lr, r4 /* LR = r4. */ - lsls r1, r4, #25 /* r1 = r4 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ - bpl restore_ns_context /* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ - msr psp, r2 /* Remember the new top of stack for the task. */ - bx lr - #else /* configENABLE_MPU */ ldmia r2!, {r0, r1, r4} /* Read from stack - r0 = xSecureContext, r1 = PSPLIM and r4 = LR. */ msr psplim, r1 /* Restore the PSPLIM register value for the task. */ mov lr, r4 /* LR = r4. */ @@ -319,7 +431,6 @@ PendSV_Handler: bpl restore_ns_context /* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ msr psp, r2 /* Remember the new top of stack for the task. */ bx lr - #endif /* configENABLE_MPU */ restore_ns_context: ldmia r2!, {r4-r11} /* Restore the registers that are not automatically restored. */ @@ -330,14 +441,50 @@ PendSV_Handler: #endif /* configENABLE_FPU || configENABLE_MVE */ msr psp, r2 /* Remember the new top of stack for the task. */ bx lr + +#endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + SVC_Handler: tst lr, #4 ite eq mrseq r0, msp mrsne r0, psp + + ldr r1, [r0, #24] + ldrb r2, [r1, #-2] + cmp r2, #4 /* portSVC_SYSTEM_CALL_ENTER. */ + beq syscall_enter + cmp r2, #5 /* portSVC_SYSTEM_CALL_ENTER_1. */ + beq syscall_enter_1 + cmp r2, #6 /* portSVC_SYSTEM_CALL_EXIT. */ + beq syscall_exit b vPortSVCHandler_C + + syscall_enter: + mov r1, lr + b vSystemCallEnter + + syscall_enter_1: + mov r1, lr + b vSystemCallEnter_1 + + syscall_exit: + mov r1, lr + b vSystemCallExit + +#else /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + +SVC_Handler: + tst lr, #4 + ite eq + mrseq r0, msp + mrsne r0, psp + b vPortSVCHandler_C + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ /*-----------------------------------------------------------*/ vPortFreeSecureContext: diff --git a/portable/IAR/ARM_CM35P/non_secure/portmacrocommon.h b/portable/IAR/ARM_CM35P/non_secure/portmacrocommon.h index c2ca5fa7730..65ac109c802 100644 --- a/portable/IAR/ARM_CM35P/non_secure/portmacrocommon.h +++ b/portable/IAR/ARM_CM35P/non_secure/portmacrocommon.h @@ -186,23 +186,120 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #define portMPU_REGION_EXECUTE_NEVER ( 1UL ) /*-----------------------------------------------------------*/ -/** - * @brief Settings to define an MPU region. - */ -typedef struct MPURegionSettings -{ - uint32_t ulRBAR; /**< RBAR for the region. */ - uint32_t ulRLAR; /**< RLAR for the region. */ -} MPURegionSettings_t; +#if ( configENABLE_MPU == 1 ) -/** - * @brief MPU settings as stored in the TCB. - */ -typedef struct MPU_SETTINGS -{ - uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ - MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */ -} xMPU_SETTINGS; + /** + * @brief Settings to define an MPU region. + */ + typedef struct MPURegionSettings + { + uint32_t ulRBAR; /**< RBAR for the region. */ + uint32_t ulRLAR; /**< RLAR for the region. */ + } MPURegionSettings_t; + + #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + + #ifndef configSYSTEM_CALL_STACK_SIZE + #error configSYSTEM_CALL_STACK_SIZE must be defined to the desired size of the system call stack in words for using MPU wrappers v2. + #endif + + /** + * @brief System call stack. + */ + typedef struct SYSTEM_CALL_STACK_INFO + { + uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ]; + uint32_t * pulSystemCallStack; + uint32_t * pulSystemCallStackLimit; + uint32_t * pulTaskStack; + uint32_t ulLinkRegisterAtSystemCallEntry; + uint32_t ulStackLimitRegisterAtSystemCallEntry; + } xSYSTEM_CALL_STACK_INFO; + + #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + + /** + * @brief MPU settings as stored in the TCB. + */ + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + + #if( configENABLE_TRUSTZONE == 1 ) + + /* + * +-----------+---------------+----------+-----------------+------------------------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | + * | | | | PC, xPSR | CONTROL, EXC_RETURN | | + * +-----------+---------------+----------+-----------------+------------------------------+-----+ + * + * <-----------><--------------><---------><----------------><-----------------------------><----> + * 16 16 8 8 5 1 + */ + #define MAX_CONTEXT_SIZE 54 + + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ + + /* + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | + * | | | | PC, xPSR | EXC_RETURN | | + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * + * <-----------><--------------><---------><----------------><---------------------><----> + * 16 16 8 8 4 1 + */ + #define MAX_CONTEXT_SIZE 53 + + #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + + #else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ + + #if( configENABLE_TRUSTZONE == 1 ) + + /* + * +----------+-----------------+------------------------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | + * | | PC, xPSR | CONTROL, EXC_RETURN | | + * +----------+-----------------+------------------------------+-----+ + * + * <---------><----------------><------------------------------><----> + * 8 8 5 1 + */ + #define MAX_CONTEXT_SIZE 22 + + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ + + /* + * +----------+-----------------+----------------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | + * | | PC, xPSR | EXC_RETURN | | + * +----------+-----------------+----------------------+-----+ + * + * <---------><----------------><----------------------><----> + * 8 8 4 1 + */ + #define MAX_CONTEXT_SIZE 21 + + #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + + #endif /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ + + /* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ + #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) + #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) + + typedef struct MPU_SETTINGS + { + uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ + MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */ + uint32_t ulContext[ MAX_CONTEXT_SIZE ]; + uint32_t ulTaskFlags; + + #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo; + #endif + } xMPU_SETTINGS; + +#endif /* configENABLE_MPU == 1 */ /*-----------------------------------------------------------*/ /** @@ -223,6 +320,9 @@ typedef struct MPU_SETTINGS #define portSVC_FREE_SECURE_CONTEXT 1 #define portSVC_START_SCHEDULER 2 #define portSVC_RAISE_PRIVILEGE 3 +#define portSVC_SYSTEM_CALL_ENTER 4 /* System calls with upto 4 parameters. */ +#define portSVC_SYSTEM_CALL_ENTER_1 5 /* System calls with 5 parameters. */ +#define portSVC_SYSTEM_CALL_EXIT 6 /*-----------------------------------------------------------*/ /** @@ -315,6 +415,20 @@ typedef struct MPU_SETTINGS #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ +#if ( configENABLE_MPU == 1 ) + + extern BaseType_t xPortIsTaskPrivileged( void ); + + /** + * @brief Checks whether or not the calling task is privileged. + * + * @return pdTRUE if the calling task is privileged, pdFALSE otherwise. + */ + #define portIS_TASK_PRIVILEGED() xPortIsTaskPrivileged() + +#endif /* configENABLE_MPU == 1 */ +/*-----------------------------------------------------------*/ + /** * @brief Barriers. */ diff --git a/portable/IAR/ARM_CM35P_NTZ/non_secure/mpu_wrappers_v2_asm.S b/portable/IAR/ARM_CM35P_NTZ/non_secure/mpu_wrappers_v2_asm.S new file mode 100644 index 00000000000..f051a6073dd --- /dev/null +++ b/portable/IAR/ARM_CM35P_NTZ/non_secure/mpu_wrappers_v2_asm.S @@ -0,0 +1,1552 @@ +/* + * FreeRTOS Kernel + * Copyright (C) 2021 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 + * + */ + + + SECTION freertos_system_calls:CODE:NOROOT(2) + THUMB +/*-----------------------------------------------------------*/ + +#include "FreeRTOSConfig.h" + +#ifndef configUSE_MPU_WRAPPERS_V1 + #define configUSE_MPU_WRAPPERS_V1 0 +#endif + +/* These must be in sync with portmacro.h. */ +#define portSVC_SYSTEM_CALL_ENTER 4 /* System calls with upto 4 parameters. */ +#define portSVC_SYSTEM_CALL_ENTER_1 5 /* System calls with 5 parameters. */ +#define portSVC_SYSTEM_CALL_EXIT 6 +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + + PUBLIC MPU_xTaskDelayUntil +MPU_xTaskDelayUntil: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskDelayUntil_Unpriv + MPU_xTaskDelayUntil_Priv: + pop {r0} + b MPU_xTaskDelayUntilImpl + MPU_xTaskDelayUntil_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskDelayUntilImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskAbortDelay +MPU_xTaskAbortDelay: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskAbortDelay_Unpriv + MPU_xTaskAbortDelay_Priv: + pop {r0} + b MPU_xTaskAbortDelayImpl + MPU_xTaskAbortDelay_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskAbortDelayImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTaskDelay +MPU_vTaskDelay: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vTaskDelay_Unpriv + MPU_vTaskDelay_Priv: + pop {r0} + b MPU_vTaskDelayImpl + MPU_vTaskDelay_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskDelayImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxTaskPriorityGet +MPU_uxTaskPriorityGet: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_uxTaskPriorityGet_Unpriv + MPU_uxTaskPriorityGet_Priv: + pop {r0} + b MPU_uxTaskPriorityGetImpl + MPU_uxTaskPriorityGet_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxTaskPriorityGetImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_eTaskGetState +MPU_eTaskGetState: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_eTaskGetState_Unpriv + MPU_eTaskGetState_Priv: + pop {r0} + b MPU_eTaskGetStateImpl + MPU_eTaskGetState_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_eTaskGetStateImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTaskGetInfo +MPU_vTaskGetInfo: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vTaskGetInfo_Unpriv + MPU_vTaskGetInfo_Priv: + pop {r0} + b MPU_vTaskGetInfoImpl + MPU_vTaskGetInfo_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskGetInfoImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGetIdleTaskHandle +MPU_xTaskGetIdleTaskHandle: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskGetIdleTaskHandle_Unpriv + MPU_xTaskGetIdleTaskHandle_Priv: + pop {r0} + b MPU_xTaskGetIdleTaskHandleImpl + MPU_xTaskGetIdleTaskHandle_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskGetIdleTaskHandleImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTaskSuspend +MPU_vTaskSuspend: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vTaskSuspend_Unpriv + MPU_vTaskSuspend_Priv: + pop {r0} + b MPU_vTaskSuspendImpl + MPU_vTaskSuspend_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskSuspendImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTaskResume +MPU_vTaskResume: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vTaskResume_Unpriv + MPU_vTaskResume_Priv: + pop {r0} + b MPU_vTaskResumeImpl + MPU_vTaskResume_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskResumeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGetTickCount +MPU_xTaskGetTickCount: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskGetTickCount_Unpriv + MPU_xTaskGetTickCount_Priv: + pop {r0} + b MPU_xTaskGetTickCountImpl + MPU_xTaskGetTickCount_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskGetTickCountImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxTaskGetNumberOfTasks +MPU_uxTaskGetNumberOfTasks: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_uxTaskGetNumberOfTasks_Unpriv + MPU_uxTaskGetNumberOfTasks_Priv: + pop {r0} + b MPU_uxTaskGetNumberOfTasksImpl + MPU_uxTaskGetNumberOfTasks_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxTaskGetNumberOfTasksImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_pcTaskGetName +MPU_pcTaskGetName: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_pcTaskGetName_Unpriv + MPU_pcTaskGetName_Priv: + pop {r0} + b MPU_pcTaskGetNameImpl + MPU_pcTaskGetName_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_pcTaskGetNameImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_ulTaskGetRunTimeCounter +MPU_ulTaskGetRunTimeCounter: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_ulTaskGetRunTimeCounter_Unpriv + MPU_ulTaskGetRunTimeCounter_Priv: + pop {r0} + b MPU_ulTaskGetRunTimeCounterImpl + MPU_ulTaskGetRunTimeCounter_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_ulTaskGetRunTimeCounterImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_ulTaskGetRunTimePercent +MPU_ulTaskGetRunTimePercent: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_ulTaskGetRunTimePercent_Unpriv + MPU_ulTaskGetRunTimePercent_Priv: + pop {r0} + b MPU_ulTaskGetRunTimePercentImpl + MPU_ulTaskGetRunTimePercent_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_ulTaskGetRunTimePercentImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_ulTaskGetIdleRunTimePercent +MPU_ulTaskGetIdleRunTimePercent: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_ulTaskGetIdleRunTimePercent_Unpriv + MPU_ulTaskGetIdleRunTimePercent_Priv: + pop {r0} + b MPU_ulTaskGetIdleRunTimePercentImpl + MPU_ulTaskGetIdleRunTimePercent_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_ulTaskGetIdleRunTimePercentImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_ulTaskGetIdleRunTimeCounter +MPU_ulTaskGetIdleRunTimeCounter: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_ulTaskGetIdleRunTimeCounter_Unpriv + MPU_ulTaskGetIdleRunTimeCounter_Priv: + pop {r0} + b MPU_ulTaskGetIdleRunTimeCounterImpl + MPU_ulTaskGetIdleRunTimeCounter_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_ulTaskGetIdleRunTimeCounterImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTaskSetApplicationTaskTag +MPU_vTaskSetApplicationTaskTag: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vTaskSetApplicationTaskTag_Unpriv + MPU_vTaskSetApplicationTaskTag_Priv: + pop {r0} + b MPU_vTaskSetApplicationTaskTagImpl + MPU_vTaskSetApplicationTaskTag_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskSetApplicationTaskTagImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGetApplicationTaskTag +MPU_xTaskGetApplicationTaskTag: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskGetApplicationTaskTag_Unpriv + MPU_xTaskGetApplicationTaskTag_Priv: + pop {r0} + b MPU_xTaskGetApplicationTaskTagImpl + MPU_xTaskGetApplicationTaskTag_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskGetApplicationTaskTagImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTaskSetThreadLocalStoragePointer +MPU_vTaskSetThreadLocalStoragePointer: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vTaskSetThreadLocalStoragePointer_Unpriv + MPU_vTaskSetThreadLocalStoragePointer_Priv: + pop {r0} + b MPU_vTaskSetThreadLocalStoragePointerImpl + MPU_vTaskSetThreadLocalStoragePointer_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskSetThreadLocalStoragePointerImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_pvTaskGetThreadLocalStoragePointer +MPU_pvTaskGetThreadLocalStoragePointer: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_pvTaskGetThreadLocalStoragePointer_Unpriv + MPU_pvTaskGetThreadLocalStoragePointer_Priv: + pop {r0} + b MPU_pvTaskGetThreadLocalStoragePointerImpl + MPU_pvTaskGetThreadLocalStoragePointer_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_pvTaskGetThreadLocalStoragePointerImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxTaskGetSystemState +MPU_uxTaskGetSystemState: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_uxTaskGetSystemState_Unpriv + MPU_uxTaskGetSystemState_Priv: + pop {r0} + b MPU_uxTaskGetSystemStateImpl + MPU_uxTaskGetSystemState_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxTaskGetSystemStateImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxTaskGetStackHighWaterMark +MPU_uxTaskGetStackHighWaterMark: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_uxTaskGetStackHighWaterMark_Unpriv + MPU_uxTaskGetStackHighWaterMark_Priv: + pop {r0} + b MPU_uxTaskGetStackHighWaterMarkImpl + MPU_uxTaskGetStackHighWaterMark_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxTaskGetStackHighWaterMarkImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxTaskGetStackHighWaterMark2 +MPU_uxTaskGetStackHighWaterMark2: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_uxTaskGetStackHighWaterMark2_Unpriv + MPU_uxTaskGetStackHighWaterMark2_Priv: + pop {r0} + b MPU_uxTaskGetStackHighWaterMark2Impl + MPU_uxTaskGetStackHighWaterMark2_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxTaskGetStackHighWaterMark2Impl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGetCurrentTaskHandle +MPU_xTaskGetCurrentTaskHandle: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskGetCurrentTaskHandle_Unpriv + MPU_xTaskGetCurrentTaskHandle_Priv: + pop {r0} + b MPU_xTaskGetCurrentTaskHandleImpl + MPU_xTaskGetCurrentTaskHandle_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskGetCurrentTaskHandleImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGetSchedulerState +MPU_xTaskGetSchedulerState: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskGetSchedulerState_Unpriv + MPU_xTaskGetSchedulerState_Priv: + pop {r0} + b MPU_xTaskGetSchedulerStateImpl + MPU_xTaskGetSchedulerState_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskGetSchedulerStateImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTaskSetTimeOutState +MPU_vTaskSetTimeOutState: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vTaskSetTimeOutState_Unpriv + MPU_vTaskSetTimeOutState_Priv: + pop {r0} + b MPU_vTaskSetTimeOutStateImpl + MPU_vTaskSetTimeOutState_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskSetTimeOutStateImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskCheckForTimeOut +MPU_xTaskCheckForTimeOut: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskCheckForTimeOut_Unpriv + MPU_xTaskCheckForTimeOut_Priv: + pop {r0} + b MPU_xTaskCheckForTimeOutImpl + MPU_xTaskCheckForTimeOut_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskCheckForTimeOutImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGenericNotify +MPU_xTaskGenericNotify: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskGenericNotify_Unpriv + MPU_xTaskGenericNotify_Priv: + pop {r0} + b MPU_xTaskGenericNotifyImpl + MPU_xTaskGenericNotify_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER_1 + bl MPU_xTaskGenericNotifyImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGenericNotifyWait +MPU_xTaskGenericNotifyWait: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskGenericNotifyWait_Unpriv + MPU_xTaskGenericNotifyWait_Priv: + pop {r0} + b MPU_xTaskGenericNotifyWaitImpl + MPU_xTaskGenericNotifyWait_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER_1 + bl MPU_xTaskGenericNotifyWaitImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_ulTaskGenericNotifyTake +MPU_ulTaskGenericNotifyTake: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_ulTaskGenericNotifyTake_Unpriv + MPU_ulTaskGenericNotifyTake_Priv: + pop {r0} + b MPU_ulTaskGenericNotifyTakeImpl + MPU_ulTaskGenericNotifyTake_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_ulTaskGenericNotifyTakeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGenericNotifyStateClear +MPU_xTaskGenericNotifyStateClear: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskGenericNotifyStateClear_Unpriv + MPU_xTaskGenericNotifyStateClear_Priv: + pop {r0} + b MPU_xTaskGenericNotifyStateClearImpl + MPU_xTaskGenericNotifyStateClear_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskGenericNotifyStateClearImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_ulTaskGenericNotifyValueClear +MPU_ulTaskGenericNotifyValueClear: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_ulTaskGenericNotifyValueClear_Unpriv + MPU_ulTaskGenericNotifyValueClear_Priv: + pop {r0} + b MPU_ulTaskGenericNotifyValueClearImpl + MPU_ulTaskGenericNotifyValueClear_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_ulTaskGenericNotifyValueClearImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueGenericSend +MPU_xQueueGenericSend: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xQueueGenericSend_Unpriv + MPU_xQueueGenericSend_Priv: + pop {r0} + b MPU_xQueueGenericSendImpl + MPU_xQueueGenericSend_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueGenericSendImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxQueueMessagesWaiting +MPU_uxQueueMessagesWaiting: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_uxQueueMessagesWaiting_Unpriv + MPU_uxQueueMessagesWaiting_Priv: + pop {r0} + b MPU_uxQueueMessagesWaitingImpl + MPU_uxQueueMessagesWaiting_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxQueueMessagesWaitingImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxQueueSpacesAvailable +MPU_uxQueueSpacesAvailable: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_uxQueueSpacesAvailable_Unpriv + MPU_uxQueueSpacesAvailable_Priv: + pop {r0} + b MPU_uxQueueSpacesAvailableImpl + MPU_uxQueueSpacesAvailable_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxQueueSpacesAvailableImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueReceive +MPU_xQueueReceive: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xQueueReceive_Unpriv + MPU_xQueueReceive_Priv: + pop {r0} + b MPU_xQueueReceiveImpl + MPU_xQueueReceive_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueReceiveImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueuePeek +MPU_xQueuePeek: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xQueuePeek_Unpriv + MPU_xQueuePeek_Priv: + pop {r0} + b MPU_xQueuePeekImpl + MPU_xQueuePeek_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueuePeekImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueSemaphoreTake +MPU_xQueueSemaphoreTake: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xQueueSemaphoreTake_Unpriv + MPU_xQueueSemaphoreTake_Priv: + pop {r0} + b MPU_xQueueSemaphoreTakeImpl + MPU_xQueueSemaphoreTake_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueSemaphoreTakeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueGetMutexHolder +MPU_xQueueGetMutexHolder: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xQueueGetMutexHolder_Unpriv + MPU_xQueueGetMutexHolder_Priv: + pop {r0} + b MPU_xQueueGetMutexHolderImpl + MPU_xQueueGetMutexHolder_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueGetMutexHolderImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueTakeMutexRecursive +MPU_xQueueTakeMutexRecursive: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xQueueTakeMutexRecursive_Unpriv + MPU_xQueueTakeMutexRecursive_Priv: + pop {r0} + b MPU_xQueueTakeMutexRecursiveImpl + MPU_xQueueTakeMutexRecursive_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueTakeMutexRecursiveImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueGiveMutexRecursive +MPU_xQueueGiveMutexRecursive: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xQueueGiveMutexRecursive_Unpriv + MPU_xQueueGiveMutexRecursive_Priv: + pop {r0} + b MPU_xQueueGiveMutexRecursiveImpl + MPU_xQueueGiveMutexRecursive_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueGiveMutexRecursiveImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueSelectFromSet +MPU_xQueueSelectFromSet: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xQueueSelectFromSet_Unpriv + MPU_xQueueSelectFromSet_Priv: + pop {r0} + b MPU_xQueueSelectFromSetImpl + MPU_xQueueSelectFromSet_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueSelectFromSetImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueAddToSet +MPU_xQueueAddToSet: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xQueueAddToSet_Unpriv + MPU_xQueueAddToSet_Priv: + pop {r0} + b MPU_xQueueAddToSetImpl + MPU_xQueueAddToSet_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueAddToSetImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vQueueAddToRegistry +MPU_vQueueAddToRegistry: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vQueueAddToRegistry_Unpriv + MPU_vQueueAddToRegistry_Priv: + pop {r0} + b MPU_vQueueAddToRegistryImpl + MPU_vQueueAddToRegistry_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vQueueAddToRegistryImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vQueueUnregisterQueue +MPU_vQueueUnregisterQueue: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vQueueUnregisterQueue_Unpriv + MPU_vQueueUnregisterQueue_Priv: + pop {r0} + b MPU_vQueueUnregisterQueueImpl + MPU_vQueueUnregisterQueue_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vQueueUnregisterQueueImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_pcQueueGetName +MPU_pcQueueGetName: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_pcQueueGetName_Unpriv + MPU_pcQueueGetName_Priv: + pop {r0} + b MPU_pcQueueGetNameImpl + MPU_pcQueueGetName_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_pcQueueGetNameImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_pvTimerGetTimerID +MPU_pvTimerGetTimerID: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_pvTimerGetTimerID_Unpriv + MPU_pvTimerGetTimerID_Priv: + pop {r0} + b MPU_pvTimerGetTimerIDImpl + MPU_pvTimerGetTimerID_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_pvTimerGetTimerIDImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTimerSetTimerID +MPU_vTimerSetTimerID: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vTimerSetTimerID_Unpriv + MPU_vTimerSetTimerID_Priv: + pop {r0} + b MPU_vTimerSetTimerIDImpl + MPU_vTimerSetTimerID_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTimerSetTimerIDImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTimerIsTimerActive +MPU_xTimerIsTimerActive: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTimerIsTimerActive_Unpriv + MPU_xTimerIsTimerActive_Priv: + pop {r0} + b MPU_xTimerIsTimerActiveImpl + MPU_xTimerIsTimerActive_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTimerIsTimerActiveImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTimerGetTimerDaemonTaskHandle +MPU_xTimerGetTimerDaemonTaskHandle: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTimerGetTimerDaemonTaskHandle_Unpriv + MPU_xTimerGetTimerDaemonTaskHandle_Priv: + pop {r0} + b MPU_xTimerGetTimerDaemonTaskHandleImpl + MPU_xTimerGetTimerDaemonTaskHandle_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTimerGetTimerDaemonTaskHandleImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTimerGenericCommand +MPU_xTimerGenericCommand: + push {r0} + /* This function can be called from ISR also and therefore, we need a check + * to take privileged path, if called from ISR. */ + mrs r0, ipsr + cmp r0, #0 + bne MPU_xTimerGenericCommand_Priv + mrs r0, control + tst r0, #1 + beq MPU_xTimerGenericCommand_Priv + MPU_xTimerGenericCommand_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER_1 + bl MPU_xTimerGenericCommandImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr + MPU_xTimerGenericCommand_Priv: + pop {r0} + b MPU_xTimerGenericCommandImpl + +/*-----------------------------------------------------------*/ + + PUBLIC MPU_pcTimerGetName +MPU_pcTimerGetName: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_pcTimerGetName_Unpriv + MPU_pcTimerGetName_Priv: + pop {r0} + b MPU_pcTimerGetNameImpl + MPU_pcTimerGetName_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_pcTimerGetNameImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTimerSetReloadMode +MPU_vTimerSetReloadMode: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vTimerSetReloadMode_Unpriv + MPU_vTimerSetReloadMode_Priv: + pop {r0} + b MPU_vTimerSetReloadModeImpl + MPU_vTimerSetReloadMode_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTimerSetReloadModeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTimerGetReloadMode +MPU_xTimerGetReloadMode: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTimerGetReloadMode_Unpriv + MPU_xTimerGetReloadMode_Priv: + pop {r0} + b MPU_xTimerGetReloadModeImpl + MPU_xTimerGetReloadMode_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTimerGetReloadModeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxTimerGetReloadMode +MPU_uxTimerGetReloadMode: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_uxTimerGetReloadMode_Unpriv + MPU_uxTimerGetReloadMode_Priv: + pop {r0} + b MPU_uxTimerGetReloadModeImpl + MPU_uxTimerGetReloadMode_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxTimerGetReloadModeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTimerGetPeriod +MPU_xTimerGetPeriod: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTimerGetPeriod_Unpriv + MPU_xTimerGetPeriod_Priv: + pop {r0} + b MPU_xTimerGetPeriodImpl + MPU_xTimerGetPeriod_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTimerGetPeriodImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTimerGetExpiryTime +MPU_xTimerGetExpiryTime: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTimerGetExpiryTime_Unpriv + MPU_xTimerGetExpiryTime_Priv: + pop {r0} + b MPU_xTimerGetExpiryTimeImpl + MPU_xTimerGetExpiryTime_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTimerGetExpiryTimeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xEventGroupWaitBits +MPU_xEventGroupWaitBits: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xEventGroupWaitBits_Unpriv + MPU_xEventGroupWaitBits_Priv: + pop {r0} + b MPU_xEventGroupWaitBitsImpl + MPU_xEventGroupWaitBits_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER_1 + bl MPU_xEventGroupWaitBitsImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xEventGroupClearBits +MPU_xEventGroupClearBits: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xEventGroupClearBits_Unpriv + MPU_xEventGroupClearBits_Priv: + pop {r0} + b MPU_xEventGroupClearBitsImpl + MPU_xEventGroupClearBits_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xEventGroupClearBitsImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xEventGroupSetBits +MPU_xEventGroupSetBits: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xEventGroupSetBits_Unpriv + MPU_xEventGroupSetBits_Priv: + pop {r0} + b MPU_xEventGroupSetBitsImpl + MPU_xEventGroupSetBits_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xEventGroupSetBitsImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xEventGroupSync +MPU_xEventGroupSync: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xEventGroupSync_Unpriv + MPU_xEventGroupSync_Priv: + pop {r0} + b MPU_xEventGroupSyncImpl + MPU_xEventGroupSync_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xEventGroupSyncImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxEventGroupGetNumber +MPU_uxEventGroupGetNumber: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_uxEventGroupGetNumber_Unpriv + MPU_uxEventGroupGetNumber_Priv: + pop {r0} + b MPU_uxEventGroupGetNumberImpl + MPU_uxEventGroupGetNumber_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxEventGroupGetNumberImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vEventGroupSetNumber +MPU_vEventGroupSetNumber: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vEventGroupSetNumber_Unpriv + MPU_vEventGroupSetNumber_Priv: + pop {r0} + b MPU_vEventGroupSetNumberImpl + MPU_vEventGroupSetNumber_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vEventGroupSetNumberImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferSend +MPU_xStreamBufferSend: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xStreamBufferSend_Unpriv + MPU_xStreamBufferSend_Priv: + pop {r0} + b MPU_xStreamBufferSendImpl + MPU_xStreamBufferSend_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferSendImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferReceive +MPU_xStreamBufferReceive: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xStreamBufferReceive_Unpriv + MPU_xStreamBufferReceive_Priv: + pop {r0} + b MPU_xStreamBufferReceiveImpl + MPU_xStreamBufferReceive_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferReceiveImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferIsFull +MPU_xStreamBufferIsFull: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xStreamBufferIsFull_Unpriv + MPU_xStreamBufferIsFull_Priv: + pop {r0} + b MPU_xStreamBufferIsFullImpl + MPU_xStreamBufferIsFull_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferIsFullImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferIsEmpty +MPU_xStreamBufferIsEmpty: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xStreamBufferIsEmpty_Unpriv + MPU_xStreamBufferIsEmpty_Priv: + pop {r0} + b MPU_xStreamBufferIsEmptyImpl + MPU_xStreamBufferIsEmpty_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferIsEmptyImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferSpacesAvailable +MPU_xStreamBufferSpacesAvailable: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xStreamBufferSpacesAvailable_Unpriv + MPU_xStreamBufferSpacesAvailable_Priv: + pop {r0} + b MPU_xStreamBufferSpacesAvailableImpl + MPU_xStreamBufferSpacesAvailable_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferSpacesAvailableImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferBytesAvailable +MPU_xStreamBufferBytesAvailable: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xStreamBufferBytesAvailable_Unpriv + MPU_xStreamBufferBytesAvailable_Priv: + pop {r0} + b MPU_xStreamBufferBytesAvailableImpl + MPU_xStreamBufferBytesAvailable_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferBytesAvailableImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferSetTriggerLevel +MPU_xStreamBufferSetTriggerLevel: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xStreamBufferSetTriggerLevel_Unpriv + MPU_xStreamBufferSetTriggerLevel_Priv: + pop {r0} + b MPU_xStreamBufferSetTriggerLevelImpl + MPU_xStreamBufferSetTriggerLevel_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferSetTriggerLevelImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferNextMessageLengthBytes +MPU_xStreamBufferNextMessageLengthBytes: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xStreamBufferNextMessageLengthBytes_Unpriv + MPU_xStreamBufferNextMessageLengthBytes_Priv: + pop {r0} + b MPU_xStreamBufferNextMessageLengthBytesImpl + MPU_xStreamBufferNextMessageLengthBytes_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferNextMessageLengthBytesImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + +/* Default weak implementations in case one is not available from + * mpu_wrappers because of config options. */ + + PUBWEAK MPU_xTaskDelayUntilImpl +MPU_xTaskDelayUntilImpl: + b MPU_xTaskDelayUntilImpl + + PUBWEAK MPU_xTaskAbortDelayImpl +MPU_xTaskAbortDelayImpl: + b MPU_xTaskAbortDelayImpl + + PUBWEAK MPU_vTaskDelayImpl +MPU_vTaskDelayImpl: + b MPU_vTaskDelayImpl + + PUBWEAK MPU_uxTaskPriorityGetImpl +MPU_uxTaskPriorityGetImpl: + b MPU_uxTaskPriorityGetImpl + + PUBWEAK MPU_eTaskGetStateImpl +MPU_eTaskGetStateImpl: + b MPU_eTaskGetStateImpl + + PUBWEAK MPU_vTaskGetInfoImpl +MPU_vTaskGetInfoImpl: + b MPU_vTaskGetInfoImpl + + PUBWEAK MPU_xTaskGetIdleTaskHandleImpl +MPU_xTaskGetIdleTaskHandleImpl: + b MPU_xTaskGetIdleTaskHandleImpl + + PUBWEAK MPU_vTaskSuspendImpl +MPU_vTaskSuspendImpl: + b MPU_vTaskSuspendImpl + + PUBWEAK MPU_vTaskResumeImpl +MPU_vTaskResumeImpl: + b MPU_vTaskResumeImpl + + PUBWEAK MPU_xTaskGetTickCountImpl +MPU_xTaskGetTickCountImpl: + b MPU_xTaskGetTickCountImpl + + PUBWEAK MPU_uxTaskGetNumberOfTasksImpl +MPU_uxTaskGetNumberOfTasksImpl: + b MPU_uxTaskGetNumberOfTasksImpl + + PUBWEAK MPU_pcTaskGetNameImpl +MPU_pcTaskGetNameImpl: + b MPU_pcTaskGetNameImpl + + PUBWEAK MPU_ulTaskGetRunTimeCounterImpl +MPU_ulTaskGetRunTimeCounterImpl: + b MPU_ulTaskGetRunTimeCounterImpl + + PUBWEAK MPU_ulTaskGetRunTimePercentImpl +MPU_ulTaskGetRunTimePercentImpl: + b MPU_ulTaskGetRunTimePercentImpl + + PUBWEAK MPU_ulTaskGetIdleRunTimePercentImpl +MPU_ulTaskGetIdleRunTimePercentImpl: + b MPU_ulTaskGetIdleRunTimePercentImpl + + PUBWEAK MPU_ulTaskGetIdleRunTimeCounterImpl +MPU_ulTaskGetIdleRunTimeCounterImpl: + b MPU_ulTaskGetIdleRunTimeCounterImpl + + PUBWEAK MPU_vTaskSetApplicationTaskTagImpl +MPU_vTaskSetApplicationTaskTagImpl: + b MPU_vTaskSetApplicationTaskTagImpl + + PUBWEAK MPU_xTaskGetApplicationTaskTagImpl +MPU_xTaskGetApplicationTaskTagImpl: + b MPU_xTaskGetApplicationTaskTagImpl + + PUBWEAK MPU_vTaskSetThreadLocalStoragePointerImpl +MPU_vTaskSetThreadLocalStoragePointerImpl: + b MPU_vTaskSetThreadLocalStoragePointerImpl + + PUBWEAK MPU_pvTaskGetThreadLocalStoragePointerImpl +MPU_pvTaskGetThreadLocalStoragePointerImpl: + b MPU_pvTaskGetThreadLocalStoragePointerImpl + + PUBWEAK MPU_uxTaskGetSystemStateImpl +MPU_uxTaskGetSystemStateImpl: + b MPU_uxTaskGetSystemStateImpl + + PUBWEAK MPU_uxTaskGetStackHighWaterMarkImpl +MPU_uxTaskGetStackHighWaterMarkImpl: + b MPU_uxTaskGetStackHighWaterMarkImpl + + PUBWEAK MPU_uxTaskGetStackHighWaterMark2Impl +MPU_uxTaskGetStackHighWaterMark2Impl: + b MPU_uxTaskGetStackHighWaterMark2Impl + + PUBWEAK MPU_xTaskGetCurrentTaskHandleImpl +MPU_xTaskGetCurrentTaskHandleImpl: + b MPU_xTaskGetCurrentTaskHandleImpl + + PUBWEAK MPU_xTaskGetSchedulerStateImpl +MPU_xTaskGetSchedulerStateImpl: + b MPU_xTaskGetSchedulerStateImpl + + PUBWEAK MPU_vTaskSetTimeOutStateImpl +MPU_vTaskSetTimeOutStateImpl: + b MPU_vTaskSetTimeOutStateImpl + + PUBWEAK MPU_xTaskCheckForTimeOutImpl +MPU_xTaskCheckForTimeOutImpl: + b MPU_xTaskCheckForTimeOutImpl + + PUBWEAK MPU_xTaskGenericNotifyImpl +MPU_xTaskGenericNotifyImpl: + b MPU_xTaskGenericNotifyImpl + + PUBWEAK MPU_xTaskGenericNotifyWaitImpl +MPU_xTaskGenericNotifyWaitImpl: + b MPU_xTaskGenericNotifyWaitImpl + + PUBWEAK MPU_ulTaskGenericNotifyTakeImpl +MPU_ulTaskGenericNotifyTakeImpl: + b MPU_ulTaskGenericNotifyTakeImpl + + PUBWEAK MPU_xTaskGenericNotifyStateClearImpl +MPU_xTaskGenericNotifyStateClearImpl: + b MPU_xTaskGenericNotifyStateClearImpl + + PUBWEAK MPU_ulTaskGenericNotifyValueClearImpl +MPU_ulTaskGenericNotifyValueClearImpl: + b MPU_ulTaskGenericNotifyValueClearImpl + + PUBWEAK MPU_xQueueGenericSendImpl +MPU_xQueueGenericSendImpl: + b MPU_xQueueGenericSendImpl + + PUBWEAK MPU_uxQueueMessagesWaitingImpl +MPU_uxQueueMessagesWaitingImpl: + b MPU_uxQueueMessagesWaitingImpl + + PUBWEAK MPU_uxQueueSpacesAvailableImpl +MPU_uxQueueSpacesAvailableImpl: + b MPU_uxQueueSpacesAvailableImpl + + PUBWEAK MPU_xQueueReceiveImpl +MPU_xQueueReceiveImpl: + b MPU_xQueueReceiveImpl + + PUBWEAK MPU_xQueuePeekImpl +MPU_xQueuePeekImpl: + b MPU_xQueuePeekImpl + + PUBWEAK MPU_xQueueSemaphoreTakeImpl +MPU_xQueueSemaphoreTakeImpl: + b MPU_xQueueSemaphoreTakeImpl + + PUBWEAK MPU_xQueueGetMutexHolderImpl +MPU_xQueueGetMutexHolderImpl: + b MPU_xQueueGetMutexHolderImpl + + PUBWEAK MPU_xQueueTakeMutexRecursiveImpl +MPU_xQueueTakeMutexRecursiveImpl: + b MPU_xQueueTakeMutexRecursiveImpl + + PUBWEAK MPU_xQueueGiveMutexRecursiveImpl +MPU_xQueueGiveMutexRecursiveImpl: + b MPU_xQueueGiveMutexRecursiveImpl + + PUBWEAK MPU_xQueueSelectFromSetImpl +MPU_xQueueSelectFromSetImpl: + b MPU_xQueueSelectFromSetImpl + + PUBWEAK MPU_xQueueAddToSetImpl +MPU_xQueueAddToSetImpl: + b MPU_xQueueAddToSetImpl + + PUBWEAK MPU_vQueueAddToRegistryImpl +MPU_vQueueAddToRegistryImpl: + b MPU_vQueueAddToRegistryImpl + + PUBWEAK MPU_vQueueUnregisterQueueImpl +MPU_vQueueUnregisterQueueImpl: + b MPU_vQueueUnregisterQueueImpl + + PUBWEAK MPU_pcQueueGetNameImpl +MPU_pcQueueGetNameImpl: + b MPU_pcQueueGetNameImpl + + PUBWEAK MPU_pvTimerGetTimerIDImpl +MPU_pvTimerGetTimerIDImpl: + b MPU_pvTimerGetTimerIDImpl + + PUBWEAK MPU_vTimerSetTimerIDImpl +MPU_vTimerSetTimerIDImpl: + b MPU_vTimerSetTimerIDImpl + + PUBWEAK MPU_xTimerIsTimerActiveImpl +MPU_xTimerIsTimerActiveImpl: + b MPU_xTimerIsTimerActiveImpl + + PUBWEAK MPU_xTimerGetTimerDaemonTaskHandleImpl +MPU_xTimerGetTimerDaemonTaskHandleImpl: + b MPU_xTimerGetTimerDaemonTaskHandleImpl + + PUBWEAK MPU_xTimerGenericCommandImpl +MPU_xTimerGenericCommandImpl: + b MPU_xTimerGenericCommandImpl + + PUBWEAK MPU_pcTimerGetNameImpl +MPU_pcTimerGetNameImpl: + b MPU_pcTimerGetNameImpl + + PUBWEAK MPU_vTimerSetReloadModeImpl +MPU_vTimerSetReloadModeImpl: + b MPU_vTimerSetReloadModeImpl + + PUBWEAK MPU_xTimerGetReloadModeImpl +MPU_xTimerGetReloadModeImpl: + b MPU_xTimerGetReloadModeImpl + + PUBWEAK MPU_uxTimerGetReloadModeImpl +MPU_uxTimerGetReloadModeImpl: + b MPU_uxTimerGetReloadModeImpl + + PUBWEAK MPU_xTimerGetPeriodImpl +MPU_xTimerGetPeriodImpl: + b MPU_xTimerGetPeriodImpl + + PUBWEAK MPU_xTimerGetExpiryTimeImpl +MPU_xTimerGetExpiryTimeImpl: + b MPU_xTimerGetExpiryTimeImpl + + PUBWEAK MPU_xEventGroupWaitBitsImpl +MPU_xEventGroupWaitBitsImpl: + b MPU_xEventGroupWaitBitsImpl + + PUBWEAK MPU_xEventGroupClearBitsImpl +MPU_xEventGroupClearBitsImpl: + b MPU_xEventGroupClearBitsImpl + + PUBWEAK MPU_xEventGroupSetBitsImpl +MPU_xEventGroupSetBitsImpl: + b MPU_xEventGroupSetBitsImpl + + PUBWEAK MPU_xEventGroupSyncImpl +MPU_xEventGroupSyncImpl: + b MPU_xEventGroupSyncImpl + + PUBWEAK MPU_uxEventGroupGetNumberImpl +MPU_uxEventGroupGetNumberImpl: + b MPU_uxEventGroupGetNumberImpl + + PUBWEAK MPU_vEventGroupSetNumberImpl +MPU_vEventGroupSetNumberImpl: + b MPU_vEventGroupSetNumberImpl + + PUBWEAK MPU_xStreamBufferSendImpl +MPU_xStreamBufferSendImpl: + b MPU_xStreamBufferSendImpl + + PUBWEAK MPU_xStreamBufferReceiveImpl +MPU_xStreamBufferReceiveImpl: + b MPU_xStreamBufferReceiveImpl + + PUBWEAK MPU_xStreamBufferIsFullImpl +MPU_xStreamBufferIsFullImpl: + b MPU_xStreamBufferIsFullImpl + + PUBWEAK MPU_xStreamBufferIsEmptyImpl +MPU_xStreamBufferIsEmptyImpl: + b MPU_xStreamBufferIsEmptyImpl + + PUBWEAK MPU_xStreamBufferSpacesAvailableImpl +MPU_xStreamBufferSpacesAvailableImpl: + b MPU_xStreamBufferSpacesAvailableImpl + + PUBWEAK MPU_xStreamBufferBytesAvailableImpl +MPU_xStreamBufferBytesAvailableImpl: + b MPU_xStreamBufferBytesAvailableImpl + + PUBWEAK MPU_xStreamBufferSetTriggerLevelImpl +MPU_xStreamBufferSetTriggerLevelImpl: + b MPU_xStreamBufferSetTriggerLevelImpl + + PUBWEAK MPU_xStreamBufferNextMessageLengthBytesImpl +MPU_xStreamBufferNextMessageLengthBytesImpl: + b MPU_xStreamBufferNextMessageLengthBytesImpl + +/*-----------------------------------------------------------*/ + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + + END diff --git a/portable/IAR/ARM_CM35P_NTZ/non_secure/port.c b/portable/IAR/ARM_CM35P_NTZ/non_secure/port.c index 7bbe1b7bc53..cab1b3668bf 100644 --- a/portable/IAR/ARM_CM35P_NTZ/non_secure/port.c +++ b/portable/IAR/ARM_CM35P_NTZ/non_secure/port.c @@ -107,6 +107,13 @@ #define portPRIGROUP_SHIFT ( 8UL ) /*-----------------------------------------------------------*/ +/** + * @brief Constants used during system call enter and exit. + */ +#define portPSR_STACK_PADDING_MASK ( 1UL << 9UL ) +#define portEXC_RETURN_STACK_FRAME_TYPE_MASK ( 1UL << 4UL ) +/*-----------------------------------------------------------*/ + /** * @brief Constants required to manipulate the FPU. */ @@ -123,6 +130,14 @@ #define portFPCCR_LSPEN_MASK ( 1UL << portFPCCR_LSPEN_POS ) /*-----------------------------------------------------------*/ +/** + * @brief Offsets in the stack to the parameters when inside the SVC handler. + */ +#define portOFFSET_TO_LR ( 5 ) +#define portOFFSET_TO_PC ( 6 ) +#define portOFFSET_TO_PSR ( 7 ) +/*-----------------------------------------------------------*/ + /** * @brief Constants required to manipulate the MPU. */ @@ -148,6 +163,8 @@ #define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ #define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ +#define portMPU_RBAR_ACCESS_PERMISSIONS_MASK ( 3UL << 1UL ) + #define portMPU_MAIR_ATTR0_POS ( 0UL ) #define portMPU_MAIR_ATTR0_MASK ( 0x000000ff ) @@ -191,6 +208,30 @@ /* Expected value of the portMPU_TYPE register. */ #define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) + +/* Extract first address of the MPU region as encoded in the + * RBAR (Region Base Address Register) value. */ +#define portEXTRACT_FIRST_ADDRESS_FROM_RBAR( rbar ) \ + ( ( rbar ) & portMPU_RBAR_ADDRESS_MASK ) + +/* Extract last address of the MPU region as encoded in the + * RLAR (Region Limit Address Register) value. */ +#define portEXTRACT_LAST_ADDRESS_FROM_RLAR( rlar ) \ + ( ( ( rlar ) & portMPU_RLAR_ADDRESS_MASK ) | ~portMPU_RLAR_ADDRESS_MASK ) + +/* Does addr lies within [start, end] address range? */ +#define portIS_ADDRESS_WITHIN_RANGE( addr, start, end ) \ + ( ( ( addr ) >= ( start ) ) && ( ( addr ) <= ( end ) ) ) + +/* Is the access request satisfied by the available permissions? */ +#define portIS_AUTHORIZED( accessRequest, permissions ) \ + ( ( ( permissions ) & ( accessRequest ) ) == accessRequest ) + +/* 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 ) ) ) /*-----------------------------------------------------------*/ /** @@ -311,6 +352,19 @@ static void prvTaskExitError( void ); #if ( configENABLE_MPU == 1 ) +/** + * @brief Extract MPU region's access permissions from the Region Base Address + * Register (RBAR) value. + * + * @param ulRBARValue RBAR value for the MPU region. + * + * @return uint32_t Access permissions. + */ + static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) PRIVILEGED_FUNCTION; +#endif /* configENABLE_MPU */ + +#if ( configENABLE_MPU == 1 ) + /** * @brief Setup the Memory Protection Unit (MPU). */ @@ -365,6 +419,60 @@ void SysTick_Handler( void ) PRIVILEGED_FUNCTION; * @brief C part of SVC handler. */ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIVILEGED_FUNCTION; + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + + /** + * @brief Sets up the system call stack so that upon returning from + * SVC, the system call stack is used. + * + * It is used for the system calls with up to 4 parameters. + * + * @param pulTaskStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + */ + void vSystemCallEnter( uint32_t * pulTaskStack, uint32_t ulLR ) PRIVILEGED_FUNCTION; + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + + /** + * @brief Sets up the system call stack so that upon returning from + * SVC, the system call stack is used. + * + * It is used for the system calls with 5 parameters. + * + * @param pulTaskStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + */ + void vSystemCallEnter_1( uint32_t * pulTaskStack, uint32_t ulLR ) PRIVILEGED_FUNCTION; + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + + /** + * @brief Sets up the task stack so that upon returning from + * SVC, the task stack is used again. + * + * @param pulSystemCallStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + */ + void vSystemCallExit( uint32_t * pulSystemCallStack, uint32_t ulLR ) PRIVILEGED_FUNCTION; + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + +#if ( configENABLE_MPU == 1 ) + + /** + * @brief Checks whether or not the calling task is privileged. + * + * @return pdTRUE if the calling task is privileged, pdFALSE otherwise. + */ + BaseType_t xPortIsTaskPrivileged( void ) PRIVILEGED_FUNCTION; + +#endif /* configENABLE_MPU == 1 */ /*-----------------------------------------------------------*/ /** @@ -681,6 +789,26 @@ static void prvTaskExitError( void ) } /*-----------------------------------------------------------*/ +#if ( configENABLE_MPU == 1 ) + static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) /* PRIVILEGED_FUNCTION */ + { + uint32_t ulAccessPermissions = 0; + + if( ( ulRBARValue & portMPU_RBAR_ACCESS_PERMISSIONS_MASK ) == portMPU_REGION_READ_ONLY ) + { + ulAccessPermissions = tskMPU_READ_PERMISSION; + } + + if( ( ulRBARValue & portMPU_RBAR_ACCESS_PERMISSIONS_MASK ) == portMPU_REGION_READ_WRITE ) + { + ulAccessPermissions = ( tskMPU_READ_PERMISSION | tskMPU_WRITE_PERMISSION ); + } + + return ulAccessPermissions; + } +#endif /* configENABLE_MPU */ +/*-----------------------------------------------------------*/ + #if ( configENABLE_MPU == 1 ) static void prvSetupMPU( void ) /* PRIVILEGED_FUNCTION */ { @@ -853,7 +981,7 @@ void SysTick_Handler( void ) /* PRIVILEGED_FUNCTION */ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTION portDONT_DISCARD */ { - #if ( configENABLE_MPU == 1 ) + #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) ) #if defined( __ARMCC_VERSION ) /* Declaration when these variable are defined in code instead of being @@ -865,7 +993,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO extern uint32_t __syscalls_flash_start__[]; extern uint32_t __syscalls_flash_end__[]; #endif /* defined( __ARMCC_VERSION ) */ - #endif /* configENABLE_MPU */ + #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */ uint32_t ulPC; @@ -880,7 +1008,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO /* Register are stored on the stack in the following order - R0, R1, R2, R3, * R12, LR, PC, xPSR. */ - ulPC = pulCallerStackAddress[ 6 ]; + ulPC = pulCallerStackAddress[ portOFFSET_TO_PC ]; ucSVCNumber = ( ( uint8_t * ) ulPC )[ -2 ]; switch( ucSVCNumber ) @@ -951,18 +1079,18 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO vRestoreContextOfFirstTask(); break; - #if ( configENABLE_MPU == 1 ) - case portSVC_RAISE_PRIVILEGE: + #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) ) + case portSVC_RAISE_PRIVILEGE: - /* Only raise the privilege, if the svc was raised from any of - * the system calls. */ - if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) && - ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ) - { - vRaisePrivilege(); - } - break; - #endif /* configENABLE_MPU */ + /* Only raise the privilege, if the svc was raised from any of + * the system calls. */ + if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ) + { + vRaisePrivilege(); + } + break; + #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */ default: /* Incorrect SVC call. */ @@ -971,51 +1099,455 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } /*-----------------------------------------------------------*/ -/* *INDENT-OFF* */ -#if ( configENABLE_MPU == 1 ) - StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, - StackType_t * pxEndOfStack, - TaskFunction_t pxCode, - void * pvParameters, - BaseType_t xRunPrivileged ) /* PRIVILEGED_FUNCTION */ -#else - StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, - StackType_t * pxEndOfStack, - TaskFunction_t pxCode, - void * pvParameters ) /* PRIVILEGED_FUNCTION */ -#endif /* configENABLE_MPU */ -/* *INDENT-ON* */ +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + +void vSystemCallEnter( uint32_t * pulTaskStack, uint32_t ulLR ) /* PRIVILEGED_FUNCTION */ { - /* Simulate the stack frame as it would be created by a context switch - * interrupt. */ - #if ( portPRELOAD_REGISTERS == 0 ) + extern TaskHandle_t pxCurrentTCB; + xMPU_SETTINGS * pxMpuSettings; + uint32_t * pulSystemCallStack; + uint32_t ulStackFrameSize, ulSystemCallLocation, i; + #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being + * exported from linker scripts. */ + extern uint32_t * __syscalls_flash_start__; + extern uint32_t * __syscalls_flash_end__; + #else + /* Declaration when these variable are exported from linker scripts. */ + extern uint32_t __syscalls_flash_start__[]; + extern uint32_t __syscalls_flash_end__[]; + #endif /* #if defined( __ARMCC_VERSION ) */ + + ulSystemCallLocation = pulTaskStack[ portOFFSET_TO_PC ]; + + /* If the request did not come from the system call section, do nothing. */ + if( ( ulSystemCallLocation >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulSystemCallLocation <= ( uint32_t ) __syscalls_flash_end__ ) ) { - pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ - *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ - pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pxCode; /* PC */ - pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR */ - pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ - *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ - pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */ - *pxTopOfStack = portINITIAL_EXC_RETURN; + pxMpuSettings = xTaskGetMPUSettings( pxCurrentTCB ); + pulSystemCallStack = pxMpuSettings->xSystemCallStackInfo.pulSystemCallStack; - #if ( configENABLE_MPU == 1 ) + /* This is not NULL only for the duration of the system call. */ + configASSERT( pxMpuSettings->xSystemCallStackInfo.pulTaskStack == NULL ); + + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) { - pxTopOfStack--; + if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) + { + /* Extended frame i.e. FPU in use. */ + ulStackFrameSize = 26; + __asm volatile ( + " vpush {s0} \n" /* Trigger lazy stacking. */ + " vpop {s0} \n" /* Nullify the affect of the above instruction. */ + ::: "memory" + ); + } + else + { + /* Standard frame i.e. FPU not in use. */ + ulStackFrameSize = 8; + } + } + #else + { + ulStackFrameSize = 8; + } + #endif /* configENABLE_FPU || configENABLE_MVE */ + + /* Make space on the system call stack for the stack frame. */ + pulSystemCallStack = pulSystemCallStack - ulStackFrameSize; + + /* Copy the stack frame. */ + for( i = 0; i < ulStackFrameSize; i++ ) + { + pulSystemCallStack[ i ] = pulTaskStack[ i ]; + } + + /* Store the value of the LR and PSPLIM registers before the SVC was raised. We need to + * restore it when we exit from the system call. */ + pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; + __asm volatile ( "mrs %0, psplim" : "=r" ( pxMpuSettings->xSystemCallStackInfo.ulStackLimitRegisterAtSystemCallEntry ) ); + + /* Use the pulSystemCallStack in thread mode. */ + __asm volatile ( "msr psp, %0" : : "r" ( pulSystemCallStack ) ); + __asm volatile ( "msr psplim, %0" : : "r" ( pxMpuSettings->xSystemCallStackInfo.pulSystemCallStackLimit ) ); + + /* Remember the location where we should copy the stack frame when we exit from + * the system call. */ + pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulStackFrameSize; + + /* Record if the hardware used padding to force the stack pointer + * to be double word aligned. */ + if( ( pulTaskStack[ portOFFSET_TO_PSR ] & portPSR_STACK_PADDING_MASK ) == portPSR_STACK_PADDING_MASK ) + { + pxMpuSettings->ulTaskFlags |= portSTACK_FRAME_HAS_PADDING_FLAG; + } + else + { + pxMpuSettings->ulTaskFlags &= ( ~portSTACK_FRAME_HAS_PADDING_FLAG ); + } + + /* We ensure in pxPortInitialiseStack that the system call stack is + * double word aligned and therefore, there is no need of padding. + * Clear the bit[9] of stacked xPSR. */ + pulSystemCallStack[ portOFFSET_TO_PSR ] &= ( ~portPSR_STACK_PADDING_MASK ); + + /* Raise the privilege for the duration of the system call. */ + __asm volatile ( + " mrs r0, control \n" /* Obtain current control value. */ + " movs r1, #1 \n" /* r1 = 1. */ + " bics r0, r1 \n" /* Clear nPRIV bit. */ + " msr control, r0 \n" /* Write back new control value. */ + ::: "r0", "r1", "memory" + ); + } +} - if( xRunPrivileged == pdTRUE ) +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + +void vSystemCallEnter_1( uint32_t * pulTaskStack, uint32_t ulLR ) /* PRIVILEGED_FUNCTION */ +{ + extern TaskHandle_t pxCurrentTCB; + xMPU_SETTINGS * pxMpuSettings; + uint32_t * pulSystemCallStack; + uint32_t ulStackFrameSize, ulSystemCallLocation, i; + #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being + * exported from linker scripts. */ + extern uint32_t * __syscalls_flash_start__; + extern uint32_t * __syscalls_flash_end__; + #else + /* Declaration when these variable are exported from linker scripts. */ + extern uint32_t __syscalls_flash_start__[]; + extern uint32_t __syscalls_flash_end__[]; + #endif /* #if defined( __ARMCC_VERSION ) */ + + ulSystemCallLocation = pulTaskStack[ portOFFSET_TO_PC ]; + + /* If the request did not come from the system call section, do nothing. */ + if( ( ulSystemCallLocation >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulSystemCallLocation <= ( uint32_t ) __syscalls_flash_end__ ) ) + { + pxMpuSettings = xTaskGetMPUSettings( pxCurrentTCB ); + pulSystemCallStack = pxMpuSettings->xSystemCallStackInfo.pulSystemCallStack; + + /* This is not NULL only for the duration of the system call. */ + configASSERT( pxMpuSettings->xSystemCallStackInfo.pulTaskStack == NULL ); + + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + { + if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) { - *pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */ + /* Extended frame i.e. FPU in use. */ + ulStackFrameSize = 26; + __asm volatile ( + " vpush {s0} \n" /* Trigger lazy stacking. */ + " vpop {s0} \n" /* Nullify the affect of the above instruction. */ + ::: "memory" + ); } else { - *pxTopOfStack = portINITIAL_CONTROL_UNPRIVILEGED; /* Slot used to hold this task's CONTROL value. */ + /* Standard frame i.e. FPU not in use. */ + ulStackFrameSize = 8; } } - #endif /* configENABLE_MPU */ + #else + { + ulStackFrameSize = 8; + } + #endif /* configENABLE_FPU || configENABLE_MVE */ + + /* Make space on the system call stack for the stack frame and + * the parameter passed on the stack. We only need to copy one + * parameter but we still reserve 2 spaces to keep the stack + * double word aligned. */ + pulSystemCallStack = pulSystemCallStack - ulStackFrameSize - 2UL; + + /* Copy the stack frame. */ + for( i = 0; i < ulStackFrameSize; i++ ) + { + pulSystemCallStack[ i ] = pulTaskStack[ i ]; + } + + /* Copy the parameter which is passed the stack. */ + if( ( pulTaskStack[ portOFFSET_TO_PSR ] & portPSR_STACK_PADDING_MASK ) == portPSR_STACK_PADDING_MASK ) + { + pulSystemCallStack[ ulStackFrameSize ] = pulTaskStack[ ulStackFrameSize + 1 ]; + /* Record if the hardware used padding to force the stack pointer + * to be double word aligned. */ + pxMpuSettings->ulTaskFlags |= portSTACK_FRAME_HAS_PADDING_FLAG; + } + else + { + pulSystemCallStack[ ulStackFrameSize ] = pulTaskStack[ ulStackFrameSize ]; + /* Record if the hardware used padding to force the stack pointer + * to be double word aligned. */ + pxMpuSettings->ulTaskFlags &= ( ~portSTACK_FRAME_HAS_PADDING_FLAG ); + } + + /* Store the value of the LR and PSPLIM registers before the SVC was raised. + * We need to restore it when we exit from the system call. */ + pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; + __asm volatile ( "mrs %0, psplim" : "=r" ( pxMpuSettings->xSystemCallStackInfo.ulStackLimitRegisterAtSystemCallEntry ) ); + + /* Use the pulSystemCallStack in thread mode. */ + __asm volatile ( "msr psp, %0" : : "r" ( pulSystemCallStack ) ); + __asm volatile ( "msr psplim, %0" : : "r" ( pxMpuSettings->xSystemCallStackInfo.pulSystemCallStackLimit ) ); + + /* Remember the location where we should copy the stack frame when we exit from + * the system call. */ + pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulStackFrameSize; + + /* We ensure in pxPortInitialiseStack that the system call stack is + * double word aligned and therefore, there is no need of padding. + * Clear the bit[9] of stacked xPSR. */ + pulSystemCallStack[ portOFFSET_TO_PSR ] &= ( ~portPSR_STACK_PADDING_MASK ); + + /* Raise the privilege for the duration of the system call. */ + __asm volatile ( + " mrs r0, control \n" /* Obtain current control value. */ + " movs r1, #1 \n" /* r1 = 1. */ + " bics r0, r1 \n" /* Clear nPRIV bit. */ + " msr control, r0 \n" /* Write back new control value. */ + ::: "r0", "r1", "memory" + ); + } +} + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) +void vSystemCallExit( uint32_t * pulSystemCallStack, uint32_t ulLR ) /* PRIVILEGED_FUNCTION */ +{ + extern TaskHandle_t pxCurrentTCB; + xMPU_SETTINGS * pxMpuSettings; + uint32_t * pulTaskStack; + uint32_t ulStackFrameSize, ulSystemCallLocation, i; + #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being + * exported from linker scripts. */ + extern uint32_t * __syscalls_flash_start__; + extern uint32_t * __syscalls_flash_end__; + #else + /* Declaration when these variable are exported from linker scripts. */ + extern uint32_t __syscalls_flash_start__[]; + extern uint32_t __syscalls_flash_end__[]; + #endif /* #if defined( __ARMCC_VERSION ) */ + + ulSystemCallLocation = pulSystemCallStack[ portOFFSET_TO_PC ]; + + /* If the request did not come from the system call section, do nothing. */ + if( ( ulSystemCallLocation >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulSystemCallLocation <= ( uint32_t ) __syscalls_flash_end__ ) ) + { + pxMpuSettings = xTaskGetMPUSettings( pxCurrentTCB ); + pulTaskStack = pxMpuSettings->xSystemCallStackInfo.pulTaskStack; + + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + { + if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) + { + /* Extended frame i.e. FPU in use. */ + ulStackFrameSize = 26; + __asm volatile ( + " vpush {s0} \n" /* Trigger lazy stacking. */ + " vpop {s0} \n" /* Nullify the affect of the above instruction. */ + ::: "memory" + ); + } + else + { + /* Standard frame i.e. FPU not in use. */ + ulStackFrameSize = 8; + } + } + #else + { + ulStackFrameSize = 8; + } + #endif /* configENABLE_FPU || configENABLE_MVE */ + + /* Make space on the task stack for the stack frame. */ + pulTaskStack = pulTaskStack - ulStackFrameSize; + + /* Copy the stack frame. */ + for( i = 0; i < ulStackFrameSize; i++ ) + { + pulTaskStack[ i ] = pulSystemCallStack[ i ]; + } + + /* Use the pulTaskStack in thread mode. */ + __asm volatile ( "msr psp, %0" : : "r" ( pulTaskStack ) ); + + /* Restore the LR and PSPLIM to what they were at the time of + * system call entry. */ + pulTaskStack[ portOFFSET_TO_LR ] = pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry; + __asm volatile ( "msr psplim, %0" : : "r" ( pxMpuSettings->xSystemCallStackInfo.ulStackLimitRegisterAtSystemCallEntry ) ); + + /* If the hardware used padding to force the stack pointer + * to be double word aligned, set the stacked xPSR bit[9], + * otherwise clear it. */ + if( ( pxMpuSettings->ulTaskFlags & portSTACK_FRAME_HAS_PADDING_FLAG ) == portSTACK_FRAME_HAS_PADDING_FLAG ) + { + pulTaskStack[ portOFFSET_TO_PSR ] |= portPSR_STACK_PADDING_MASK; + } + else + { + pulTaskStack[ portOFFSET_TO_PSR ] &= ( ~portPSR_STACK_PADDING_MASK ); + } + + /* This is not NULL only for the duration of the system call. */ + pxMpuSettings->xSystemCallStackInfo.pulTaskStack = NULL; + + /* Drop the privilege before returning to the thread mode. */ + __asm volatile ( + " mrs r0, control \n" /* Obtain current control value. */ + " movs r1, #1 \n" /* r1 = 1. */ + " orrs r0, r1 \n" /* Set nPRIV bit. */ + " msr control, r0 \n" /* Write back new control value. */ + ::: "r0", "r1", "memory" + ); + } +} + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configENABLE_MPU == 1 ) + +BaseType_t xPortIsTaskPrivileged( void ) /* PRIVILEGED_FUNCTION */ +{ + BaseType_t xTaskIsPrivileged = pdFALSE; + const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */ + + if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) + { + xTaskIsPrivileged = pdTRUE; + } + + return xTaskIsPrivileged; +} + +#endif /* configENABLE_MPU == 1 */ +/*-----------------------------------------------------------*/ + +#if( configENABLE_MPU == 1 ) + +StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, + StackType_t * pxEndOfStack, + TaskFunction_t pxCode, + void * pvParameters, + BaseType_t xRunPrivileged, + xMPU_SETTINGS * xMPUSettings ) /* PRIVILEGED_FUNCTION */ +{ + uint32_t ulIndex = 0; + + xMPUSettings->ulContext[ ulIndex ] = 0x04040404; /* r4. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x05050505; /* r5. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x06060606; /* r6. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x07070707; /* r7. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x08080808; /* r8. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x09090909; /* r9. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x10101010; /* r10. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x11111111; /* r11. */ + ulIndex++; + + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pvParameters; /* r0. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x01010101; /* r1. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x02020202; /* r2. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x03030303; /* r3. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x12121212; /* r12. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portTASK_RETURN_ADDRESS; /* LR. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxCode; /* PC. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = portINITIAL_XPSR; /* xPSR. */ + ulIndex++; + + #if ( configENABLE_TRUSTZONE == 1 ) + { + xMPUSettings->ulContext[ ulIndex ] = portNO_SECURE_CONTEXT; /* xSecureContext. */ + ulIndex++; + } + #endif /* configENABLE_TRUSTZONE */ + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) ( pxTopOfStack - 8 ); /* PSP with the hardware saved stack. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */ + ulIndex++; + if( xRunPrivileged == pdTRUE ) + { + xMPUSettings->ulTaskFlags |= portTASK_IS_PRIVILEGED_FLAG; + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_PRIVILEGED; /* CONTROL. */ + ulIndex++; + } + else + { + xMPUSettings->ulTaskFlags &= ( ~portTASK_IS_PRIVILEGED_FLAG ); + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_UNPRIVILEGED; /* CONTROL. */ + ulIndex++; + } + xMPUSettings->ulContext[ ulIndex ] = portINITIAL_EXC_RETURN; /* LR (EXC_RETURN). */ + ulIndex++; + + #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + { + /* Ensure that the system call stack is double word aligned. */ + xMPUSettings->xSystemCallStackInfo.pulSystemCallStack = &( xMPUSettings->xSystemCallStackInfo.ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE - 1 ] ); + xMPUSettings->xSystemCallStackInfo.pulSystemCallStack = ( uint32_t * ) ( ( uint32_t ) ( xMPUSettings->xSystemCallStackInfo.pulSystemCallStack ) & + ( uint32_t ) ( ~( portBYTE_ALIGNMENT_MASK ) ) ); + + xMPUSettings->xSystemCallStackInfo.pulSystemCallStackLimit = &( xMPUSettings->xSystemCallStackInfo.ulSystemCallStackBuffer[ 0 ] ); + xMPUSettings->xSystemCallStackInfo.pulSystemCallStackLimit = ( uint32_t * ) ( ( ( uint32_t ) ( xMPUSettings->xSystemCallStackInfo.pulSystemCallStackLimit ) + + ( uint32_t ) ( portBYTE_ALIGNMENT - 1 ) ) & + ( uint32_t ) ( ~( portBYTE_ALIGNMENT_MASK ) ) ); + + /* This is not NULL only for the duration of a system call. */ + xMPUSettings->xSystemCallStackInfo.pulTaskStack = NULL; + } + #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + + return &( xMPUSettings->ulContext[ ulIndex ] ); +} + +#else /* configENABLE_MPU */ + +StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, + StackType_t * pxEndOfStack, + TaskFunction_t pxCode, + void * pvParameters ) /* PRIVILEGED_FUNCTION */ +{ + /* Simulate the stack frame as it would be created by a context switch + * interrupt. */ + #if ( portPRELOAD_REGISTERS == 0 ) + { + pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ + *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR. */ + pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ + pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */ + *pxTopOfStack = portINITIAL_EXC_RETURN; pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ @@ -1029,55 +1561,39 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO #else /* portPRELOAD_REGISTERS */ { pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ - *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ + *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pxCode; /* PC */ + *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR */ + *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x12121212UL; /* R12 */ + *pxTopOfStack = ( StackType_t ) 0x12121212UL; /* R12. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x03030303UL; /* R3 */ + *pxTopOfStack = ( StackType_t ) 0x03030303UL; /* R3. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x02020202UL; /* R2 */ + *pxTopOfStack = ( StackType_t ) 0x02020202UL; /* R2. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x01010101UL; /* R1 */ + *pxTopOfStack = ( StackType_t ) 0x01010101UL; /* R1. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x11111111UL; /* R11 */ + *pxTopOfStack = ( StackType_t ) 0x11111111UL; /* R11. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x10101010UL; /* R10 */ + *pxTopOfStack = ( StackType_t ) 0x10101010UL; /* R10. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x09090909UL; /* R09 */ + *pxTopOfStack = ( StackType_t ) 0x09090909UL; /* R09. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x08080808UL; /* R08 */ + *pxTopOfStack = ( StackType_t ) 0x08080808UL; /* R08. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x07070707UL; /* R07 */ + *pxTopOfStack = ( StackType_t ) 0x07070707UL; /* R07. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x06060606UL; /* R06 */ + *pxTopOfStack = ( StackType_t ) 0x06060606UL; /* R06. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x05050505UL; /* R05 */ + *pxTopOfStack = ( StackType_t ) 0x05050505UL; /* R05. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x04040404UL; /* R04 */ + *pxTopOfStack = ( StackType_t ) 0x04040404UL; /* R04. */ pxTopOfStack--; - *pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN */ - - #if ( configENABLE_MPU == 1 ) - { - pxTopOfStack--; - - if( xRunPrivileged == pdTRUE ) - { - *pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */ - } - else - { - *pxTopOfStack = portINITIAL_CONTROL_UNPRIVILEGED; /* Slot used to hold this task's CONTROL value. */ - } - } - #endif /* configENABLE_MPU */ - + *pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN. */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ @@ -1092,6 +1608,8 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO return pxTopOfStack; } + +#endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ @@ -1128,6 +1646,10 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ configASSERT( ucMaxSysCallPriority ); + /* Check that the bits not implemented in hardware are zero in + * configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & ( ~ucMaxPriorityValue ) ) == 0U ); + /* Calculate the maximum acceptable priority group value for the number * of bits read back. */ @@ -1164,35 +1686,6 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulImplementedPrioBits; } - /* The interrupt priority bits are not modelled in QEMU and the assert that - * checks the number of implemented bits and __NVIC_PRIO_BITS will always fail. - * Therefore, this assert is not adding any value for QEMU targets. The config - * option `configDISABLE_INTERRUPT_PRIO_BITS_CHECK` should be defined in the - * `FreeRTOSConfig.h` for QEMU targets. */ - #ifndef configDISABLE_INTERRUPT_PRIO_BITS_CHECK - { - #ifdef __NVIC_PRIO_BITS - { - /* - * Check that the number of implemented priority bits queried from - * hardware is equal to the CMSIS __NVIC_PRIO_BITS configuration macro. - */ - configASSERT( ulImplementedPrioBits == __NVIC_PRIO_BITS ); - } - #endif /* __NVIC_PRIO_BITS */ - - #ifdef configPRIO_BITS - { - /* - * Check that the number of implemented priority bits queried from - * hardware is equal to the FreeRTOS configPRIO_BITS configuration macro. - */ - configASSERT( ulImplementedPrioBits == configPRIO_BITS ); - } - #endif /* configPRIO_BITS */ - } - #endif /* #ifndef configDISABLE_INTERRUPT_PRIO_BITS_CHECK */ - /* Shift the priority group value back to its position within the AIRCR * register. */ ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT; @@ -1372,6 +1865,54 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ +#if ( configENABLE_MPU == 1 ) + BaseType_t xPortIsAuthorizedToAccessBuffer( const void * pvBuffer, + uint32_t ulBufferLength, + uint32_t ulAccessRequested ) /* PRIVILEGED_FUNCTION */ + + { + uint32_t i, ulBufferStartAddress, ulBufferEndAddress; + BaseType_t xAccessGranted = pdFALSE; + const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */ + + if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) + { + xAccessGranted = pdTRUE; + } + else + { + if( portADD_UINT32_WILL_OVERFLOW( ( ( uint32_t ) pvBuffer ), ( ulBufferLength - 1UL ) ) == pdFALSE ) + { + ulBufferStartAddress = ( uint32_t ) pvBuffer; + ulBufferEndAddress = ( ( ( uint32_t ) pvBuffer ) + ulBufferLength - 1UL ); + + for( i = 0; i < portTOTAL_NUM_REGIONS; i++ ) + { + /* Is the MPU region enabled? */ + if( ( xTaskMpuSettings->xRegionsSettings[ i ].ulRLAR & portMPU_RLAR_REGION_ENABLE ) == portMPU_RLAR_REGION_ENABLE ) + { + if( portIS_ADDRESS_WITHIN_RANGE( ulBufferStartAddress, + portEXTRACT_FIRST_ADDRESS_FROM_RBAR( xTaskMpuSettings->xRegionsSettings[ i ].ulRBAR ), + portEXTRACT_LAST_ADDRESS_FROM_RLAR( xTaskMpuSettings->xRegionsSettings[ i ].ulRLAR ) ) && + portIS_ADDRESS_WITHIN_RANGE( ulBufferEndAddress, + portEXTRACT_FIRST_ADDRESS_FROM_RBAR( xTaskMpuSettings->xRegionsSettings[ i ].ulRBAR ), + portEXTRACT_LAST_ADDRESS_FROM_RLAR( xTaskMpuSettings->xRegionsSettings[ i ].ulRLAR ) ) && + portIS_AUTHORIZED( ulAccessRequested, + prvGetRegionAccessPermissions( xTaskMpuSettings->xRegionsSettings[ i ].ulRBAR ) ) ) + { + xAccessGranted = pdTRUE; + break; + } + } + } + } + } + + return xAccessGranted; + } +#endif /* configENABLE_MPU */ +/*-----------------------------------------------------------*/ + BaseType_t xPortIsInsideInterrupt( void ) { uint32_t ulCurrentInterrupt; diff --git a/portable/IAR/ARM_CM35P_NTZ/non_secure/portasm.s b/portable/IAR/ARM_CM35P_NTZ/non_secure/portasm.s index 581b84d4951..ec52025270b 100644 --- a/portable/IAR/ARM_CM35P_NTZ/non_secure/portasm.s +++ b/portable/IAR/ARM_CM35P_NTZ/non_secure/portasm.s @@ -32,9 +32,18 @@ the code is included in C files but excluded by the preprocessor in assembly files (__ICCARM__ is defined by the IAR C compiler but not by the IAR assembler. */ #include "FreeRTOSConfig.h" +#ifndef configUSE_MPU_WRAPPERS_V1 + #define configUSE_MPU_WRAPPERS_V1 0 +#endif + EXTERN pxCurrentTCB EXTERN vTaskSwitchContext EXTERN vPortSVCHandler_C +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + EXTERN vSystemCallEnter + EXTERN vSystemCallEnter_1 + EXTERN vSystemCallExit +#endif PUBLIC xIsPrivileged PUBLIC vResetPrivilege @@ -79,48 +88,79 @@ vResetPrivilege: THUMB /*-----------------------------------------------------------*/ +#if ( configENABLE_MPU == 1 ) + +vRestoreContextOfFirstTask: + program_mpu_first_task: + ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + ldr r0, [r2] /* r0 = pxCurrentTCB. */ + + dmb /* Complete outstanding transfers before disabling MPU. */ + ldr r1, =0xe000ed94 /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + ldr r2, [r1] /* Read the value of MPU_CTRL. */ + bic r2, #1 /* r2 = r2 & ~1 i.e. Clear the bit 0 in r2. */ + str r2, [r1] /* Disable MPU. */ + + adds r0, #4 /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */ + ldr r1, [r0] /* r1 = *r0 i.e. r1 = MAIR0. */ + ldr r2, =0xe000edc0 /* r2 = 0xe000edc0 [Location of MAIR0]. */ + str r1, [r2] /* Program MAIR0. */ + + adds r0, #4 /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */ + ldr r1, =0xe000ed98 /* r1 = 0xe000ed98 [Location of RNR]. */ + ldr r2, =0xe000ed9c /* r2 = 0xe000ed9c [Location of RBAR]. */ + + movs r3, #4 /* r3 = 4. */ + str r3, [r1] /* Program RNR = 4. */ + ldmia r0!, {r4-r11} /* Read 4 sets of RBAR/RLAR registers from TCB. */ + stmia r2, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ + + #if ( configTOTAL_MPU_REGIONS == 16 ) + movs r3, #8 /* r3 = 8. */ + str r3, [r1] /* Program RNR = 8. */ + ldmia r0!, {r4-r11} /* Read 4 sets of RBAR/RLAR registers from TCB. */ + stmia r2, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ + movs r3, #12 /* r3 = 12. */ + str r3, [r1] /* Program RNR = 12. */ + ldmia r0!, {r4-r11} /* Read 4 sets of RBAR/RLAR registers from TCB. */ + stmia r2, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ + #endif /* configTOTAL_MPU_REGIONS == 16 */ + + ldr r1, =0xe000ed94 /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + ldr r2, [r1] /* Read the value of MPU_CTRL. */ + orr r2, #1 /* r2 = r2 | 1 i.e. Set the bit 0 in r2. */ + str r2, [r1] /* Enable MPU. */ + dsb /* Force memory writes before continuing. */ + + restore_context_first_task: + ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + ldr r0, [r2] /* r0 = pxCurrentTCB.*/ + ldr r1, [r0] /* r1 = Location of saved context in TCB. */ + + restore_special_regs_first_task: + ldmdb r1!, {r2-r4, lr} /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */ + msr psp, r2 + msr psplim, r3 + msr control, r4 + + restore_general_regs_first_task: + ldmdb r1!, {r4-r11} /* r4-r11 contain hardware saved context. */ + stmia r2!, {r4-r11} /* Copy the hardware saved context on the task stack. */ + ldmdb r1!, {r4-r11} /* r4-r11 restored. */ + + restore_context_done_first_task: + str r1, [r0] /* Save the location where the context should be saved next as the first member of TCB. */ + mov r0, #0 + msr basepri, r0 /* Ensure that interrupts are enabled when the first task starts. */ + bx lr + +#else /* configENABLE_MPU */ + vRestoreContextOfFirstTask: ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r2] /* Read pxCurrentTCB. */ ldr r0, [r1] /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ -#if ( configENABLE_MPU == 1 ) - dmb /* Complete outstanding transfers before disabling MPU. */ - ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ - ldr r4, [r2] /* Read the value of MPU_CTRL. */ - bic r4, r4, #1 /* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */ - str r4, [r2] /* Disable MPU. */ - - adds r1, #4 /* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */ - ldr r3, [r1] /* r3 = *r1 i.e. r3 = MAIR0. */ - ldr r2, =0xe000edc0 /* r2 = 0xe000edc0 [Location of MAIR0]. */ - str r3, [r2] /* Program MAIR0. */ - ldr r2, =0xe000ed98 /* r2 = 0xe000ed98 [Location of RNR]. */ - movs r3, #4 /* r3 = 4. */ - str r3, [r2] /* Program RNR = 4. */ - adds r1, #4 /* r1 = r1 + 4. r1 now points to first RBAR in TCB. */ - ldr r2, =0xe000ed9c /* r2 = 0xe000ed9c [Location of RBAR]. */ - ldmia r1!, {r4-r11} /* Read 4 sets of RBAR/RLAR registers from TCB. */ - stmia r2!, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ - - ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ - ldr r4, [r2] /* Read the value of MPU_CTRL. */ - orr r4, r4, #1 /* r4 = r4 | 1 i.e. Set the bit 0 in r4. */ - str r4, [r2] /* Enable MPU. */ - dsb /* Force memory writes before continuing. */ -#endif /* configENABLE_MPU */ - -#if ( configENABLE_MPU == 1 ) - ldm r0!, {r1-r3} /* Read from stack - r1 = PSPLIM, r2 = CONTROL and r3 = EXC_RETURN. */ - msr psplim, r1 /* Set this task's PSPLIM value. */ - msr control, r2 /* Set this task's CONTROL value. */ - adds r0, #32 /* Discard everything up to r0. */ - msr psp, r0 /* This is now the new top of stack to use in the task. */ - isb - mov r0, #0 - msr basepri, r0 /* Ensure that interrupts are enabled when the first task starts. */ - bx r3 /* Finally, branch to EXC_RETURN. */ -#else /* configENABLE_MPU */ ldm r0!, {r1-r2} /* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */ msr psplim, r1 /* Set this task's PSPLIM value. */ movs r1, #2 /* r1 = 2. */ @@ -131,6 +171,7 @@ vRestoreContextOfFirstTask: mov r0, #0 msr basepri, r0 /* Ensure that interrupts are enabled when the first task starts. */ bx r2 /* Finally, branch to EXC_RETURN. */ + #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ @@ -169,6 +210,114 @@ vClearInterruptMask: bx lr /* Return. */ /*-----------------------------------------------------------*/ +#if ( configENABLE_MPU == 1 ) + +PendSV_Handler: + ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + ldr r0, [r2] /* r0 = pxCurrentTCB. */ + ldr r1, [r0] /* r1 = Location in TCB where the context should be saved. */ + mrs r2, psp /* r2 = PSP. */ + + save_general_regs: + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + add r2, r2, #0x20 /* Move r2 to location where s0 is saved. */ + tst lr, #0x10 + ittt eq + vstmiaeq r1!, {s16-s31} /* Store s16-s31. */ + vldmiaeq r2, {s0-s16} /* Copy hardware saved FP context into s0-s16. */ + vstmiaeq r1!, {s0-s16} /* Store hardware saved FP context. */ + sub r2, r2, #0x20 /* Set r2 back to the location of hardware saved context. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ + + stmia r1!, {r4-r11} /* Store r4-r11. */ + ldmia r2, {r4-r11} /* Copy the hardware saved context into r4-r11. */ + stmia r1!, {r4-r11} /* Store the hardware saved context. */ + + save_special_regs: + mrs r3, psplim /* r3 = PSPLIM. */ + mrs r4, control /* r4 = CONTROL. */ + stmia r1!, {r2-r4, lr} /* Store original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */ + str r1, [r0] /* Save the location from where the context should be restored as the first member of TCB. */ + + select_next_task: + mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY + msr basepri, r0 /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + dsb + isb + bl vTaskSwitchContext + mov r0, #0 /* r0 = 0. */ + msr basepri, r0 /* Enable interrupts. */ + + program_mpu: + ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + ldr r0, [r2] /* r0 = pxCurrentTCB. */ + + dmb /* Complete outstanding transfers before disabling MPU. */ + ldr r1, =0xe000ed94 /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + ldr r2, [r1] /* Read the value of MPU_CTRL. */ + bic r2, #1 /* r2 = r2 & ~1 i.e. Clear the bit 0 in r2. */ + str r2, [r1] /* Disable MPU. */ + + adds r0, #4 /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */ + ldr r1, [r0] /* r1 = *r0 i.e. r1 = MAIR0. */ + ldr r2, =0xe000edc0 /* r2 = 0xe000edc0 [Location of MAIR0]. */ + str r1, [r2] /* Program MAIR0. */ + + adds r0, #4 /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */ + ldr r1, =0xe000ed98 /* r1 = 0xe000ed98 [Location of RNR]. */ + ldr r2, =0xe000ed9c /* r2 = 0xe000ed9c [Location of RBAR]. */ + + movs r3, #4 /* r3 = 4. */ + str r3, [r1] /* Program RNR = 4. */ + ldmia r0!, {r4-r11} /* Read 4 sets of RBAR/RLAR registers from TCB. */ + stmia r2, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ + + #if ( configTOTAL_MPU_REGIONS == 16 ) + movs r3, #8 /* r3 = 8. */ + str r3, [r1] /* Program RNR = 8. */ + ldmia r0!, {r4-r11} /* Read 4 sets of RBAR/RLAR registers from TCB. */ + stmia r2, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ + movs r3, #12 /* r3 = 12. */ + str r3, [r1] /* Program RNR = 12. */ + ldmia r0!, {r4-r11} /* Read 4 sets of RBAR/RLAR registers from TCB. */ + stmia r2, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ + #endif /* configTOTAL_MPU_REGIONS == 16 */ + + ldr r1, =0xe000ed94 /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + ldr r2, [r1] /* Read the value of MPU_CTRL. */ + orr r2, #1 /* r2 = r2 | 1 i.e. Set the bit 0 in r2. */ + str r2, [r1] /* Enable MPU. */ + dsb /* Force memory writes before continuing. */ + + restore_context: + ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + ldr r0, [r2] /* r0 = pxCurrentTCB.*/ + ldr r1, [r0] /* r1 = Location of saved context in TCB. */ + + restore_special_regs: + ldmdb r1!, {r2-r4, lr} /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */ + msr psp, r2 + msr psplim, r3 + msr control, r4 + + restore_general_regs: + ldmdb r1!, {r4-r11} /* r4-r11 contain hardware saved context. */ + stmia r2!, {r4-r11} /* Copy the hardware saved context on the task stack. */ + ldmdb r1!, {r4-r11} /* r4-r11 restored. */ + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + tst lr, #0x10 + ittt eq + vldmdbeq r1!, {s0-s16} /* s0-s16 contain hardware saved FP context. */ + vstmiaeq r2!, {s0-s16} /* Copy hardware saved FP context on the task stack. */ + vldmdbeq r1!, {s16-s31} /* Restore s16-s31. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ + + restore_context_done: + str r1, [r0] /* Save the location where the context should be saved next as the first member of TCB. */ + bx lr + +#else /* configENABLE_MPU */ + PendSV_Handler: mrs r0, psp /* Read PSP in r0. */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) @@ -176,16 +325,10 @@ PendSV_Handler: it eq vstmdbeq r0!, {s16-s31} /* Store the additional FP context registers which are not saved automatically. */ #endif /* configENABLE_FPU || configENABLE_MVE */ -#if ( configENABLE_MPU == 1 ) - mrs r1, psplim /* r1 = PSPLIM. */ - mrs r2, control /* r2 = CONTROL. */ - mov r3, lr /* r3 = LR/EXC_RETURN. */ - stmdb r0!, {r1-r11} /* Store on the stack - PSPLIM, CONTROL, LR and registers that are not automatically saved. */ -#else /* configENABLE_MPU */ + mrs r2, psplim /* r2 = PSPLIM. */ mov r3, lr /* r3 = LR/EXC_RETURN. */ stmdb r0!, {r2-r11} /* Store on the stack - PSPLIM, LR and registers that are not automatically. */ -#endif /* configENABLE_MPU */ ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r2] /* Read pxCurrentTCB. */ @@ -203,37 +346,7 @@ PendSV_Handler: ldr r1, [r2] /* Read pxCurrentTCB. */ ldr r0, [r1] /* The first item in pxCurrentTCB is the task top of stack. r0 now points to the top of stack. */ -#if ( configENABLE_MPU == 1 ) - dmb /* Complete outstanding transfers before disabling MPU. */ - ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ - ldr r4, [r2] /* Read the value of MPU_CTRL. */ - bic r4, r4, #1 /* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */ - str r4, [r2] /* Disable MPU. */ - - adds r1, #4 /* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */ - ldr r3, [r1] /* r3 = *r1 i.e. r3 = MAIR0. */ - ldr r2, =0xe000edc0 /* r2 = 0xe000edc0 [Location of MAIR0]. */ - str r3, [r2] /* Program MAIR0. */ - ldr r2, =0xe000ed98 /* r2 = 0xe000ed98 [Location of RNR]. */ - movs r3, #4 /* r3 = 4. */ - str r3, [r2] /* Program RNR = 4. */ - adds r1, #4 /* r1 = r1 + 4. r1 now points to first RBAR in TCB. */ - ldr r2, =0xe000ed9c /* r2 = 0xe000ed9c [Location of RBAR]. */ - ldmia r1!, {r4-r11} /* Read 4 sets of RBAR/RLAR registers from TCB. */ - stmia r2!, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ - - ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ - ldr r4, [r2] /* Read the value of MPU_CTRL. */ - orr r4, r4, #1 /* r4 = r4 | 1 i.e. Set the bit 0 in r4. */ - str r4, [r2] /* Enable MPU. */ - dsb /* Force memory writes before continuing. */ -#endif /* configENABLE_MPU */ - -#if ( configENABLE_MPU == 1 ) - ldmia r0!, {r1-r11} /* Read from stack - r1 = PSPLIM, r2 = CONTROL, r3 = LR and r4-r11 restored. */ -#else /* configENABLE_MPU */ ldmia r0!, {r2-r11} /* Read from stack - r2 = PSPLIM, r3 = LR and r4-r11 restored. */ -#endif /* configENABLE_MPU */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) tst r3, #0x10 /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ @@ -241,22 +354,53 @@ PendSV_Handler: vldmiaeq r0!, {s16-s31} /* Restore the additional FP context registers which are not restored automatically. */ #endif /* configENABLE_FPU || configENABLE_MVE */ - #if ( configENABLE_MPU == 1 ) - msr psplim, r1 /* Restore the PSPLIM register value for the task. */ - msr control, r2 /* Restore the CONTROL register value for the task. */ -#else /* configENABLE_MPU */ msr psplim, r2 /* Restore the PSPLIM register value for the task. */ -#endif /* configENABLE_MPU */ msr psp, r0 /* Remember the new top of stack for the task. */ bx r3 + +#endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + +SVC_Handler: + tst lr, #4 + ite eq + mrseq r0, msp + mrsne r0, psp + + ldr r1, [r0, #24] + ldrb r2, [r1, #-2] + cmp r2, #4 /* portSVC_SYSTEM_CALL_ENTER. */ + beq syscall_enter + cmp r2, #5 /* portSVC_SYSTEM_CALL_ENTER_1. */ + beq syscall_enter_1 + cmp r2, #6 /* portSVC_SYSTEM_CALL_EXIT. */ + beq syscall_exit + b vPortSVCHandler_C + + syscall_enter: + mov r1, lr + b vSystemCallEnter + + syscall_enter_1: + mov r1, lr + b vSystemCallEnter_1 + + syscall_exit: + mov r1, lr + b vSystemCallExit + +#else /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + SVC_Handler: tst lr, #4 ite eq mrseq r0, msp mrsne r0, psp b vPortSVCHandler_C + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ /*-----------------------------------------------------------*/ END diff --git a/portable/IAR/ARM_CM35P_NTZ/non_secure/portmacrocommon.h b/portable/IAR/ARM_CM35P_NTZ/non_secure/portmacrocommon.h index c2ca5fa7730..65ac109c802 100644 --- a/portable/IAR/ARM_CM35P_NTZ/non_secure/portmacrocommon.h +++ b/portable/IAR/ARM_CM35P_NTZ/non_secure/portmacrocommon.h @@ -186,23 +186,120 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #define portMPU_REGION_EXECUTE_NEVER ( 1UL ) /*-----------------------------------------------------------*/ -/** - * @brief Settings to define an MPU region. - */ -typedef struct MPURegionSettings -{ - uint32_t ulRBAR; /**< RBAR for the region. */ - uint32_t ulRLAR; /**< RLAR for the region. */ -} MPURegionSettings_t; +#if ( configENABLE_MPU == 1 ) -/** - * @brief MPU settings as stored in the TCB. - */ -typedef struct MPU_SETTINGS -{ - uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ - MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */ -} xMPU_SETTINGS; + /** + * @brief Settings to define an MPU region. + */ + typedef struct MPURegionSettings + { + uint32_t ulRBAR; /**< RBAR for the region. */ + uint32_t ulRLAR; /**< RLAR for the region. */ + } MPURegionSettings_t; + + #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + + #ifndef configSYSTEM_CALL_STACK_SIZE + #error configSYSTEM_CALL_STACK_SIZE must be defined to the desired size of the system call stack in words for using MPU wrappers v2. + #endif + + /** + * @brief System call stack. + */ + typedef struct SYSTEM_CALL_STACK_INFO + { + uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ]; + uint32_t * pulSystemCallStack; + uint32_t * pulSystemCallStackLimit; + uint32_t * pulTaskStack; + uint32_t ulLinkRegisterAtSystemCallEntry; + uint32_t ulStackLimitRegisterAtSystemCallEntry; + } xSYSTEM_CALL_STACK_INFO; + + #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + + /** + * @brief MPU settings as stored in the TCB. + */ + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + + #if( configENABLE_TRUSTZONE == 1 ) + + /* + * +-----------+---------------+----------+-----------------+------------------------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | + * | | | | PC, xPSR | CONTROL, EXC_RETURN | | + * +-----------+---------------+----------+-----------------+------------------------------+-----+ + * + * <-----------><--------------><---------><----------------><-----------------------------><----> + * 16 16 8 8 5 1 + */ + #define MAX_CONTEXT_SIZE 54 + + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ + + /* + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | + * | | | | PC, xPSR | EXC_RETURN | | + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * + * <-----------><--------------><---------><----------------><---------------------><----> + * 16 16 8 8 4 1 + */ + #define MAX_CONTEXT_SIZE 53 + + #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + + #else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ + + #if( configENABLE_TRUSTZONE == 1 ) + + /* + * +----------+-----------------+------------------------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | + * | | PC, xPSR | CONTROL, EXC_RETURN | | + * +----------+-----------------+------------------------------+-----+ + * + * <---------><----------------><------------------------------><----> + * 8 8 5 1 + */ + #define MAX_CONTEXT_SIZE 22 + + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ + + /* + * +----------+-----------------+----------------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | + * | | PC, xPSR | EXC_RETURN | | + * +----------+-----------------+----------------------+-----+ + * + * <---------><----------------><----------------------><----> + * 8 8 4 1 + */ + #define MAX_CONTEXT_SIZE 21 + + #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + + #endif /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ + + /* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ + #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) + #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) + + typedef struct MPU_SETTINGS + { + uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ + MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */ + uint32_t ulContext[ MAX_CONTEXT_SIZE ]; + uint32_t ulTaskFlags; + + #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo; + #endif + } xMPU_SETTINGS; + +#endif /* configENABLE_MPU == 1 */ /*-----------------------------------------------------------*/ /** @@ -223,6 +320,9 @@ typedef struct MPU_SETTINGS #define portSVC_FREE_SECURE_CONTEXT 1 #define portSVC_START_SCHEDULER 2 #define portSVC_RAISE_PRIVILEGE 3 +#define portSVC_SYSTEM_CALL_ENTER 4 /* System calls with upto 4 parameters. */ +#define portSVC_SYSTEM_CALL_ENTER_1 5 /* System calls with 5 parameters. */ +#define portSVC_SYSTEM_CALL_EXIT 6 /*-----------------------------------------------------------*/ /** @@ -315,6 +415,20 @@ typedef struct MPU_SETTINGS #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ +#if ( configENABLE_MPU == 1 ) + + extern BaseType_t xPortIsTaskPrivileged( void ); + + /** + * @brief Checks whether or not the calling task is privileged. + * + * @return pdTRUE if the calling task is privileged, pdFALSE otherwise. + */ + #define portIS_TASK_PRIVILEGED() xPortIsTaskPrivileged() + +#endif /* configENABLE_MPU == 1 */ +/*-----------------------------------------------------------*/ + /** * @brief Barriers. */ diff --git a/portable/IAR/ARM_CM4F/port.c b/portable/IAR/ARM_CM4F/port.c index e0deaf12840..52f5ac28709 100755 --- a/portable/IAR/ARM_CM4F/port.c +++ b/portable/IAR/ARM_CM4F/port.c @@ -279,6 +279,10 @@ BaseType_t xPortStartScheduler( void ) * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ configASSERT( ucMaxSysCallPriority ); + /* Check that the bits not implemented in hardware are zero in + * configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & ( ~ucMaxPriorityValue ) ) == 0U ); + /* Calculate the maximum acceptable priority group value for the number * of bits read back. */ @@ -315,28 +319,6 @@ BaseType_t xPortStartScheduler( void ) ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulImplementedPrioBits; } - #ifdef __NVIC_PRIO_BITS - { - /* - * Check that the number of implemented priority bits queried from - * hardware is at least as many as specified in the CMSIS - * __NVIC_PRIO_BITS configuration macro. - */ - configASSERT( ulImplementedPrioBits >= __NVIC_PRIO_BITS ); - } - #endif - - #ifdef configPRIO_BITS - { - /* - * Check that the number of implemented priority bits queried from - * hardware is at least as many as specified in the FreeRTOS - * configPRIO_BITS configuration macro. - */ - configASSERT( ulImplementedPrioBits >= configPRIO_BITS ); - } - #endif - /* Shift the priority group value back to its position within the AIRCR * register. */ ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT; diff --git a/portable/IAR/ARM_CM4F_MPU/mpu_wrappers_v2_asm.S b/portable/IAR/ARM_CM4F_MPU/mpu_wrappers_v2_asm.S new file mode 100644 index 00000000000..a0541f790ba --- /dev/null +++ b/portable/IAR/ARM_CM4F_MPU/mpu_wrappers_v2_asm.S @@ -0,0 +1,1556 @@ +/* + * FreeRTOS Kernel + * Copyright (C) 2021 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 + * + */ + +/* Including FreeRTOSConfig.h here will cause build errors if the header file + * contains code not understood by the assembler - for example the 'extern' keyword. + * To avoid errors place any such code inside a #ifdef __ICCARM__/#endif block so + * the code is included in C files but excluded by the preprocessor in assembly + * files (__ICCARM__ is defined by the IAR C compiler but not by the IAR assembler. */ +#include "FreeRTOSConfig.h" + + SECTION freertos_system_calls:CODE:NOROOT(2) + THUMB +/*-----------------------------------------------------------*/ + +#ifndef configUSE_MPU_WRAPPERS_V1 + #define configUSE_MPU_WRAPPERS_V1 0 +#endif + +/* These must be in sync with portmacro.h. */ +#define portSVC_SYSTEM_CALL_ENTER 3 /* System calls with upto 4 parameters. */ +#define portSVC_SYSTEM_CALL_ENTER_1 4 /* System calls with 5 parameters. */ +#define portSVC_SYSTEM_CALL_EXIT 5 +/*-----------------------------------------------------------*/ + +#if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + + PUBLIC MPU_xTaskDelayUntil +MPU_xTaskDelayUntil: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskDelayUntil_Unpriv + MPU_xTaskDelayUntil_Priv: + pop {r0} + b MPU_xTaskDelayUntilImpl + MPU_xTaskDelayUntil_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskDelayUntilImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskAbortDelay +MPU_xTaskAbortDelay: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskAbortDelay_Unpriv + MPU_xTaskAbortDelay_Priv: + pop {r0} + b MPU_xTaskAbortDelayImpl + MPU_xTaskAbortDelay_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskAbortDelayImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTaskDelay +MPU_vTaskDelay: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vTaskDelay_Unpriv + MPU_vTaskDelay_Priv: + pop {r0} + b MPU_vTaskDelayImpl + MPU_vTaskDelay_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskDelayImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxTaskPriorityGet +MPU_uxTaskPriorityGet: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_uxTaskPriorityGet_Unpriv + MPU_uxTaskPriorityGet_Priv: + pop {r0} + b MPU_uxTaskPriorityGetImpl + MPU_uxTaskPriorityGet_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxTaskPriorityGetImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_eTaskGetState +MPU_eTaskGetState: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_eTaskGetState_Unpriv + MPU_eTaskGetState_Priv: + pop {r0} + b MPU_eTaskGetStateImpl + MPU_eTaskGetState_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_eTaskGetStateImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTaskGetInfo +MPU_vTaskGetInfo: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vTaskGetInfo_Unpriv + MPU_vTaskGetInfo_Priv: + pop {r0} + b MPU_vTaskGetInfoImpl + MPU_vTaskGetInfo_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskGetInfoImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGetIdleTaskHandle +MPU_xTaskGetIdleTaskHandle: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskGetIdleTaskHandle_Unpriv + MPU_xTaskGetIdleTaskHandle_Priv: + pop {r0} + b MPU_xTaskGetIdleTaskHandleImpl + MPU_xTaskGetIdleTaskHandle_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskGetIdleTaskHandleImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTaskSuspend +MPU_vTaskSuspend: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vTaskSuspend_Unpriv + MPU_vTaskSuspend_Priv: + pop {r0} + b MPU_vTaskSuspendImpl + MPU_vTaskSuspend_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskSuspendImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTaskResume +MPU_vTaskResume: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vTaskResume_Unpriv + MPU_vTaskResume_Priv: + pop {r0} + b MPU_vTaskResumeImpl + MPU_vTaskResume_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskResumeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGetTickCount +MPU_xTaskGetTickCount: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskGetTickCount_Unpriv + MPU_xTaskGetTickCount_Priv: + pop {r0} + b MPU_xTaskGetTickCountImpl + MPU_xTaskGetTickCount_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskGetTickCountImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxTaskGetNumberOfTasks +MPU_uxTaskGetNumberOfTasks: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_uxTaskGetNumberOfTasks_Unpriv + MPU_uxTaskGetNumberOfTasks_Priv: + pop {r0} + b MPU_uxTaskGetNumberOfTasksImpl + MPU_uxTaskGetNumberOfTasks_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxTaskGetNumberOfTasksImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_pcTaskGetName +MPU_pcTaskGetName: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_pcTaskGetName_Unpriv + MPU_pcTaskGetName_Priv: + pop {r0} + b MPU_pcTaskGetNameImpl + MPU_pcTaskGetName_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_pcTaskGetNameImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_ulTaskGetRunTimeCounter +MPU_ulTaskGetRunTimeCounter: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_ulTaskGetRunTimeCounter_Unpriv + MPU_ulTaskGetRunTimeCounter_Priv: + pop {r0} + b MPU_ulTaskGetRunTimeCounterImpl + MPU_ulTaskGetRunTimeCounter_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_ulTaskGetRunTimeCounterImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_ulTaskGetRunTimePercent +MPU_ulTaskGetRunTimePercent: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_ulTaskGetRunTimePercent_Unpriv + MPU_ulTaskGetRunTimePercent_Priv: + pop {r0} + b MPU_ulTaskGetRunTimePercentImpl + MPU_ulTaskGetRunTimePercent_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_ulTaskGetRunTimePercentImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_ulTaskGetIdleRunTimePercent +MPU_ulTaskGetIdleRunTimePercent: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_ulTaskGetIdleRunTimePercent_Unpriv + MPU_ulTaskGetIdleRunTimePercent_Priv: + pop {r0} + b MPU_ulTaskGetIdleRunTimePercentImpl + MPU_ulTaskGetIdleRunTimePercent_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_ulTaskGetIdleRunTimePercentImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_ulTaskGetIdleRunTimeCounter +MPU_ulTaskGetIdleRunTimeCounter: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_ulTaskGetIdleRunTimeCounter_Unpriv + MPU_ulTaskGetIdleRunTimeCounter_Priv: + pop {r0} + b MPU_ulTaskGetIdleRunTimeCounterImpl + MPU_ulTaskGetIdleRunTimeCounter_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_ulTaskGetIdleRunTimeCounterImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTaskSetApplicationTaskTag +MPU_vTaskSetApplicationTaskTag: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vTaskSetApplicationTaskTag_Unpriv + MPU_vTaskSetApplicationTaskTag_Priv: + pop {r0} + b MPU_vTaskSetApplicationTaskTagImpl + MPU_vTaskSetApplicationTaskTag_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskSetApplicationTaskTagImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGetApplicationTaskTag +MPU_xTaskGetApplicationTaskTag: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskGetApplicationTaskTag_Unpriv + MPU_xTaskGetApplicationTaskTag_Priv: + pop {r0} + b MPU_xTaskGetApplicationTaskTagImpl + MPU_xTaskGetApplicationTaskTag_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskGetApplicationTaskTagImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTaskSetThreadLocalStoragePointer +MPU_vTaskSetThreadLocalStoragePointer: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vTaskSetThreadLocalStoragePointer_Unpriv + MPU_vTaskSetThreadLocalStoragePointer_Priv: + pop {r0} + b MPU_vTaskSetThreadLocalStoragePointerImpl + MPU_vTaskSetThreadLocalStoragePointer_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskSetThreadLocalStoragePointerImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_pvTaskGetThreadLocalStoragePointer +MPU_pvTaskGetThreadLocalStoragePointer: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_pvTaskGetThreadLocalStoragePointer_Unpriv + MPU_pvTaskGetThreadLocalStoragePointer_Priv: + pop {r0} + b MPU_pvTaskGetThreadLocalStoragePointerImpl + MPU_pvTaskGetThreadLocalStoragePointer_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_pvTaskGetThreadLocalStoragePointerImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxTaskGetSystemState +MPU_uxTaskGetSystemState: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_uxTaskGetSystemState_Unpriv + MPU_uxTaskGetSystemState_Priv: + pop {r0} + b MPU_uxTaskGetSystemStateImpl + MPU_uxTaskGetSystemState_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxTaskGetSystemStateImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxTaskGetStackHighWaterMark +MPU_uxTaskGetStackHighWaterMark: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_uxTaskGetStackHighWaterMark_Unpriv + MPU_uxTaskGetStackHighWaterMark_Priv: + pop {r0} + b MPU_uxTaskGetStackHighWaterMarkImpl + MPU_uxTaskGetStackHighWaterMark_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxTaskGetStackHighWaterMarkImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxTaskGetStackHighWaterMark2 +MPU_uxTaskGetStackHighWaterMark2: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_uxTaskGetStackHighWaterMark2_Unpriv + MPU_uxTaskGetStackHighWaterMark2_Priv: + pop {r0} + b MPU_uxTaskGetStackHighWaterMark2Impl + MPU_uxTaskGetStackHighWaterMark2_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxTaskGetStackHighWaterMark2Impl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGetCurrentTaskHandle +MPU_xTaskGetCurrentTaskHandle: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskGetCurrentTaskHandle_Unpriv + MPU_xTaskGetCurrentTaskHandle_Priv: + pop {r0} + b MPU_xTaskGetCurrentTaskHandleImpl + MPU_xTaskGetCurrentTaskHandle_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskGetCurrentTaskHandleImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGetSchedulerState +MPU_xTaskGetSchedulerState: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskGetSchedulerState_Unpriv + MPU_xTaskGetSchedulerState_Priv: + pop {r0} + b MPU_xTaskGetSchedulerStateImpl + MPU_xTaskGetSchedulerState_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskGetSchedulerStateImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTaskSetTimeOutState +MPU_vTaskSetTimeOutState: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vTaskSetTimeOutState_Unpriv + MPU_vTaskSetTimeOutState_Priv: + pop {r0} + b MPU_vTaskSetTimeOutStateImpl + MPU_vTaskSetTimeOutState_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskSetTimeOutStateImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskCheckForTimeOut +MPU_xTaskCheckForTimeOut: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskCheckForTimeOut_Unpriv + MPU_xTaskCheckForTimeOut_Priv: + pop {r0} + b MPU_xTaskCheckForTimeOutImpl + MPU_xTaskCheckForTimeOut_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskCheckForTimeOutImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGenericNotify +MPU_xTaskGenericNotify: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskGenericNotify_Unpriv + MPU_xTaskGenericNotify_Priv: + pop {r0} + b MPU_xTaskGenericNotifyImpl + MPU_xTaskGenericNotify_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER_1 + bl MPU_xTaskGenericNotifyImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGenericNotifyWait +MPU_xTaskGenericNotifyWait: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskGenericNotifyWait_Unpriv + MPU_xTaskGenericNotifyWait_Priv: + pop {r0} + b MPU_xTaskGenericNotifyWaitImpl + MPU_xTaskGenericNotifyWait_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER_1 + bl MPU_xTaskGenericNotifyWaitImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_ulTaskGenericNotifyTake +MPU_ulTaskGenericNotifyTake: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_ulTaskGenericNotifyTake_Unpriv + MPU_ulTaskGenericNotifyTake_Priv: + pop {r0} + b MPU_ulTaskGenericNotifyTakeImpl + MPU_ulTaskGenericNotifyTake_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_ulTaskGenericNotifyTakeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGenericNotifyStateClear +MPU_xTaskGenericNotifyStateClear: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskGenericNotifyStateClear_Unpriv + MPU_xTaskGenericNotifyStateClear_Priv: + pop {r0} + b MPU_xTaskGenericNotifyStateClearImpl + MPU_xTaskGenericNotifyStateClear_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskGenericNotifyStateClearImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_ulTaskGenericNotifyValueClear +MPU_ulTaskGenericNotifyValueClear: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_ulTaskGenericNotifyValueClear_Unpriv + MPU_ulTaskGenericNotifyValueClear_Priv: + pop {r0} + b MPU_ulTaskGenericNotifyValueClearImpl + MPU_ulTaskGenericNotifyValueClear_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_ulTaskGenericNotifyValueClearImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueGenericSend +MPU_xQueueGenericSend: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xQueueGenericSend_Unpriv + MPU_xQueueGenericSend_Priv: + pop {r0} + b MPU_xQueueGenericSendImpl + MPU_xQueueGenericSend_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueGenericSendImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxQueueMessagesWaiting +MPU_uxQueueMessagesWaiting: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_uxQueueMessagesWaiting_Unpriv + MPU_uxQueueMessagesWaiting_Priv: + pop {r0} + b MPU_uxQueueMessagesWaitingImpl + MPU_uxQueueMessagesWaiting_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxQueueMessagesWaitingImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxQueueSpacesAvailable +MPU_uxQueueSpacesAvailable: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_uxQueueSpacesAvailable_Unpriv + MPU_uxQueueSpacesAvailable_Priv: + pop {r0} + b MPU_uxQueueSpacesAvailableImpl + MPU_uxQueueSpacesAvailable_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxQueueSpacesAvailableImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueReceive +MPU_xQueueReceive: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xQueueReceive_Unpriv + MPU_xQueueReceive_Priv: + pop {r0} + b MPU_xQueueReceiveImpl + MPU_xQueueReceive_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueReceiveImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueuePeek +MPU_xQueuePeek: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xQueuePeek_Unpriv + MPU_xQueuePeek_Priv: + pop {r0} + b MPU_xQueuePeekImpl + MPU_xQueuePeek_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueuePeekImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueSemaphoreTake +MPU_xQueueSemaphoreTake: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xQueueSemaphoreTake_Unpriv + MPU_xQueueSemaphoreTake_Priv: + pop {r0} + b MPU_xQueueSemaphoreTakeImpl + MPU_xQueueSemaphoreTake_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueSemaphoreTakeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueGetMutexHolder +MPU_xQueueGetMutexHolder: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xQueueGetMutexHolder_Unpriv + MPU_xQueueGetMutexHolder_Priv: + pop {r0} + b MPU_xQueueGetMutexHolderImpl + MPU_xQueueGetMutexHolder_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueGetMutexHolderImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueTakeMutexRecursive +MPU_xQueueTakeMutexRecursive: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xQueueTakeMutexRecursive_Unpriv + MPU_xQueueTakeMutexRecursive_Priv: + pop {r0} + b MPU_xQueueTakeMutexRecursiveImpl + MPU_xQueueTakeMutexRecursive_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueTakeMutexRecursiveImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueGiveMutexRecursive +MPU_xQueueGiveMutexRecursive: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xQueueGiveMutexRecursive_Unpriv + MPU_xQueueGiveMutexRecursive_Priv: + pop {r0} + b MPU_xQueueGiveMutexRecursiveImpl + MPU_xQueueGiveMutexRecursive_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueGiveMutexRecursiveImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueSelectFromSet +MPU_xQueueSelectFromSet: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xQueueSelectFromSet_Unpriv + MPU_xQueueSelectFromSet_Priv: + pop {r0} + b MPU_xQueueSelectFromSetImpl + MPU_xQueueSelectFromSet_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueSelectFromSetImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueAddToSet +MPU_xQueueAddToSet: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xQueueAddToSet_Unpriv + MPU_xQueueAddToSet_Priv: + pop {r0} + b MPU_xQueueAddToSetImpl + MPU_xQueueAddToSet_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueAddToSetImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vQueueAddToRegistry +MPU_vQueueAddToRegistry: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vQueueAddToRegistry_Unpriv + MPU_vQueueAddToRegistry_Priv: + pop {r0} + b MPU_vQueueAddToRegistryImpl + MPU_vQueueAddToRegistry_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vQueueAddToRegistryImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vQueueUnregisterQueue +MPU_vQueueUnregisterQueue: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vQueueUnregisterQueue_Unpriv + MPU_vQueueUnregisterQueue_Priv: + pop {r0} + b MPU_vQueueUnregisterQueueImpl + MPU_vQueueUnregisterQueue_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vQueueUnregisterQueueImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_pcQueueGetName +MPU_pcQueueGetName: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_pcQueueGetName_Unpriv + MPU_pcQueueGetName_Priv: + pop {r0} + b MPU_pcQueueGetNameImpl + MPU_pcQueueGetName_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_pcQueueGetNameImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_pvTimerGetTimerID +MPU_pvTimerGetTimerID: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_pvTimerGetTimerID_Unpriv + MPU_pvTimerGetTimerID_Priv: + pop {r0} + b MPU_pvTimerGetTimerIDImpl + MPU_pvTimerGetTimerID_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_pvTimerGetTimerIDImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTimerSetTimerID +MPU_vTimerSetTimerID: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vTimerSetTimerID_Unpriv + MPU_vTimerSetTimerID_Priv: + pop {r0} + b MPU_vTimerSetTimerIDImpl + MPU_vTimerSetTimerID_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTimerSetTimerIDImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTimerIsTimerActive +MPU_xTimerIsTimerActive: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTimerIsTimerActive_Unpriv + MPU_xTimerIsTimerActive_Priv: + pop {r0} + b MPU_xTimerIsTimerActiveImpl + MPU_xTimerIsTimerActive_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTimerIsTimerActiveImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTimerGetTimerDaemonTaskHandle +MPU_xTimerGetTimerDaemonTaskHandle: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTimerGetTimerDaemonTaskHandle_Unpriv + MPU_xTimerGetTimerDaemonTaskHandle_Priv: + pop {r0} + b MPU_xTimerGetTimerDaemonTaskHandleImpl + MPU_xTimerGetTimerDaemonTaskHandle_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTimerGetTimerDaemonTaskHandleImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTimerGenericCommand +MPU_xTimerGenericCommand: + push {r0} + /* This function can be called from ISR also and therefore, we need a check + * to take privileged path, if called from ISR. */ + mrs r0, ipsr + cmp r0, #0 + bne MPU_xTimerGenericCommand_Priv + mrs r0, control + tst r0, #1 + beq MPU_xTimerGenericCommand_Priv + MPU_xTimerGenericCommand_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER_1 + bl MPU_xTimerGenericCommandImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr + MPU_xTimerGenericCommand_Priv: + pop {r0} + b MPU_xTimerGenericCommandImpl + +/*-----------------------------------------------------------*/ + + PUBLIC MPU_pcTimerGetName +MPU_pcTimerGetName: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_pcTimerGetName_Unpriv + MPU_pcTimerGetName_Priv: + pop {r0} + b MPU_pcTimerGetNameImpl + MPU_pcTimerGetName_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_pcTimerGetNameImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTimerSetReloadMode +MPU_vTimerSetReloadMode: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vTimerSetReloadMode_Unpriv + MPU_vTimerSetReloadMode_Priv: + pop {r0} + b MPU_vTimerSetReloadModeImpl + MPU_vTimerSetReloadMode_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTimerSetReloadModeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTimerGetReloadMode +MPU_xTimerGetReloadMode: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTimerGetReloadMode_Unpriv + MPU_xTimerGetReloadMode_Priv: + pop {r0} + b MPU_xTimerGetReloadModeImpl + MPU_xTimerGetReloadMode_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTimerGetReloadModeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxTimerGetReloadMode +MPU_uxTimerGetReloadMode: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_uxTimerGetReloadMode_Unpriv + MPU_uxTimerGetReloadMode_Priv: + pop {r0} + b MPU_uxTimerGetReloadModeImpl + MPU_uxTimerGetReloadMode_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxTimerGetReloadModeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTimerGetPeriod +MPU_xTimerGetPeriod: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTimerGetPeriod_Unpriv + MPU_xTimerGetPeriod_Priv: + pop {r0} + b MPU_xTimerGetPeriodImpl + MPU_xTimerGetPeriod_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTimerGetPeriodImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTimerGetExpiryTime +MPU_xTimerGetExpiryTime: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTimerGetExpiryTime_Unpriv + MPU_xTimerGetExpiryTime_Priv: + pop {r0} + b MPU_xTimerGetExpiryTimeImpl + MPU_xTimerGetExpiryTime_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTimerGetExpiryTimeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xEventGroupWaitBits +MPU_xEventGroupWaitBits: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xEventGroupWaitBits_Unpriv + MPU_xEventGroupWaitBits_Priv: + pop {r0} + b MPU_xEventGroupWaitBitsImpl + MPU_xEventGroupWaitBits_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER_1 + bl MPU_xEventGroupWaitBitsImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xEventGroupClearBits +MPU_xEventGroupClearBits: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xEventGroupClearBits_Unpriv + MPU_xEventGroupClearBits_Priv: + pop {r0} + b MPU_xEventGroupClearBitsImpl + MPU_xEventGroupClearBits_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xEventGroupClearBitsImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xEventGroupSetBits +MPU_xEventGroupSetBits: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xEventGroupSetBits_Unpriv + MPU_xEventGroupSetBits_Priv: + pop {r0} + b MPU_xEventGroupSetBitsImpl + MPU_xEventGroupSetBits_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xEventGroupSetBitsImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xEventGroupSync +MPU_xEventGroupSync: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xEventGroupSync_Unpriv + MPU_xEventGroupSync_Priv: + pop {r0} + b MPU_xEventGroupSyncImpl + MPU_xEventGroupSync_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xEventGroupSyncImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxEventGroupGetNumber +MPU_uxEventGroupGetNumber: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_uxEventGroupGetNumber_Unpriv + MPU_uxEventGroupGetNumber_Priv: + pop {r0} + b MPU_uxEventGroupGetNumberImpl + MPU_uxEventGroupGetNumber_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxEventGroupGetNumberImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vEventGroupSetNumber +MPU_vEventGroupSetNumber: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vEventGroupSetNumber_Unpriv + MPU_vEventGroupSetNumber_Priv: + pop {r0} + b MPU_vEventGroupSetNumberImpl + MPU_vEventGroupSetNumber_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vEventGroupSetNumberImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferSend +MPU_xStreamBufferSend: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xStreamBufferSend_Unpriv + MPU_xStreamBufferSend_Priv: + pop {r0} + b MPU_xStreamBufferSendImpl + MPU_xStreamBufferSend_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferSendImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferReceive +MPU_xStreamBufferReceive: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xStreamBufferReceive_Unpriv + MPU_xStreamBufferReceive_Priv: + pop {r0} + b MPU_xStreamBufferReceiveImpl + MPU_xStreamBufferReceive_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferReceiveImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferIsFull +MPU_xStreamBufferIsFull: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xStreamBufferIsFull_Unpriv + MPU_xStreamBufferIsFull_Priv: + pop {r0} + b MPU_xStreamBufferIsFullImpl + MPU_xStreamBufferIsFull_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferIsFullImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferIsEmpty +MPU_xStreamBufferIsEmpty: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xStreamBufferIsEmpty_Unpriv + MPU_xStreamBufferIsEmpty_Priv: + pop {r0} + b MPU_xStreamBufferIsEmptyImpl + MPU_xStreamBufferIsEmpty_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferIsEmptyImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferSpacesAvailable +MPU_xStreamBufferSpacesAvailable: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xStreamBufferSpacesAvailable_Unpriv + MPU_xStreamBufferSpacesAvailable_Priv: + pop {r0} + b MPU_xStreamBufferSpacesAvailableImpl + MPU_xStreamBufferSpacesAvailable_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferSpacesAvailableImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferBytesAvailable +MPU_xStreamBufferBytesAvailable: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xStreamBufferBytesAvailable_Unpriv + MPU_xStreamBufferBytesAvailable_Priv: + pop {r0} + b MPU_xStreamBufferBytesAvailableImpl + MPU_xStreamBufferBytesAvailable_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferBytesAvailableImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferSetTriggerLevel +MPU_xStreamBufferSetTriggerLevel: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xStreamBufferSetTriggerLevel_Unpriv + MPU_xStreamBufferSetTriggerLevel_Priv: + pop {r0} + b MPU_xStreamBufferSetTriggerLevelImpl + MPU_xStreamBufferSetTriggerLevel_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferSetTriggerLevelImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferNextMessageLengthBytes +MPU_xStreamBufferNextMessageLengthBytes: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xStreamBufferNextMessageLengthBytes_Unpriv + MPU_xStreamBufferNextMessageLengthBytes_Priv: + pop {r0} + b MPU_xStreamBufferNextMessageLengthBytesImpl + MPU_xStreamBufferNextMessageLengthBytes_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferNextMessageLengthBytesImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + +/* Default weak implementations in case one is not available from + * mpu_wrappers because of config options. */ + + PUBWEAK MPU_xTaskDelayUntilImpl +MPU_xTaskDelayUntilImpl: + b MPU_xTaskDelayUntilImpl + + PUBWEAK MPU_xTaskAbortDelayImpl +MPU_xTaskAbortDelayImpl: + b MPU_xTaskAbortDelayImpl + + PUBWEAK MPU_vTaskDelayImpl +MPU_vTaskDelayImpl: + b MPU_vTaskDelayImpl + + PUBWEAK MPU_uxTaskPriorityGetImpl +MPU_uxTaskPriorityGetImpl: + b MPU_uxTaskPriorityGetImpl + + PUBWEAK MPU_eTaskGetStateImpl +MPU_eTaskGetStateImpl: + b MPU_eTaskGetStateImpl + + PUBWEAK MPU_vTaskGetInfoImpl +MPU_vTaskGetInfoImpl: + b MPU_vTaskGetInfoImpl + + PUBWEAK MPU_xTaskGetIdleTaskHandleImpl +MPU_xTaskGetIdleTaskHandleImpl: + b MPU_xTaskGetIdleTaskHandleImpl + + PUBWEAK MPU_vTaskSuspendImpl +MPU_vTaskSuspendImpl: + b MPU_vTaskSuspendImpl + + PUBWEAK MPU_vTaskResumeImpl +MPU_vTaskResumeImpl: + b MPU_vTaskResumeImpl + + PUBWEAK MPU_xTaskGetTickCountImpl +MPU_xTaskGetTickCountImpl: + b MPU_xTaskGetTickCountImpl + + PUBWEAK MPU_uxTaskGetNumberOfTasksImpl +MPU_uxTaskGetNumberOfTasksImpl: + b MPU_uxTaskGetNumberOfTasksImpl + + PUBWEAK MPU_pcTaskGetNameImpl +MPU_pcTaskGetNameImpl: + b MPU_pcTaskGetNameImpl + + PUBWEAK MPU_ulTaskGetRunTimeCounterImpl +MPU_ulTaskGetRunTimeCounterImpl: + b MPU_ulTaskGetRunTimeCounterImpl + + PUBWEAK MPU_ulTaskGetRunTimePercentImpl +MPU_ulTaskGetRunTimePercentImpl: + b MPU_ulTaskGetRunTimePercentImpl + + PUBWEAK MPU_ulTaskGetIdleRunTimePercentImpl +MPU_ulTaskGetIdleRunTimePercentImpl: + b MPU_ulTaskGetIdleRunTimePercentImpl + + PUBWEAK MPU_ulTaskGetIdleRunTimeCounterImpl +MPU_ulTaskGetIdleRunTimeCounterImpl: + b MPU_ulTaskGetIdleRunTimeCounterImpl + + PUBWEAK MPU_vTaskSetApplicationTaskTagImpl +MPU_vTaskSetApplicationTaskTagImpl: + b MPU_vTaskSetApplicationTaskTagImpl + + PUBWEAK MPU_xTaskGetApplicationTaskTagImpl +MPU_xTaskGetApplicationTaskTagImpl: + b MPU_xTaskGetApplicationTaskTagImpl + + PUBWEAK MPU_vTaskSetThreadLocalStoragePointerImpl +MPU_vTaskSetThreadLocalStoragePointerImpl: + b MPU_vTaskSetThreadLocalStoragePointerImpl + + PUBWEAK MPU_pvTaskGetThreadLocalStoragePointerImpl +MPU_pvTaskGetThreadLocalStoragePointerImpl: + b MPU_pvTaskGetThreadLocalStoragePointerImpl + + PUBWEAK MPU_uxTaskGetSystemStateImpl +MPU_uxTaskGetSystemStateImpl: + b MPU_uxTaskGetSystemStateImpl + + PUBWEAK MPU_uxTaskGetStackHighWaterMarkImpl +MPU_uxTaskGetStackHighWaterMarkImpl: + b MPU_uxTaskGetStackHighWaterMarkImpl + + PUBWEAK MPU_uxTaskGetStackHighWaterMark2Impl +MPU_uxTaskGetStackHighWaterMark2Impl: + b MPU_uxTaskGetStackHighWaterMark2Impl + + PUBWEAK MPU_xTaskGetCurrentTaskHandleImpl +MPU_xTaskGetCurrentTaskHandleImpl: + b MPU_xTaskGetCurrentTaskHandleImpl + + PUBWEAK MPU_xTaskGetSchedulerStateImpl +MPU_xTaskGetSchedulerStateImpl: + b MPU_xTaskGetSchedulerStateImpl + + PUBWEAK MPU_vTaskSetTimeOutStateImpl +MPU_vTaskSetTimeOutStateImpl: + b MPU_vTaskSetTimeOutStateImpl + + PUBWEAK MPU_xTaskCheckForTimeOutImpl +MPU_xTaskCheckForTimeOutImpl: + b MPU_xTaskCheckForTimeOutImpl + + PUBWEAK MPU_xTaskGenericNotifyImpl +MPU_xTaskGenericNotifyImpl: + b MPU_xTaskGenericNotifyImpl + + PUBWEAK MPU_xTaskGenericNotifyWaitImpl +MPU_xTaskGenericNotifyWaitImpl: + b MPU_xTaskGenericNotifyWaitImpl + + PUBWEAK MPU_ulTaskGenericNotifyTakeImpl +MPU_ulTaskGenericNotifyTakeImpl: + b MPU_ulTaskGenericNotifyTakeImpl + + PUBWEAK MPU_xTaskGenericNotifyStateClearImpl +MPU_xTaskGenericNotifyStateClearImpl: + b MPU_xTaskGenericNotifyStateClearImpl + + PUBWEAK MPU_ulTaskGenericNotifyValueClearImpl +MPU_ulTaskGenericNotifyValueClearImpl: + b MPU_ulTaskGenericNotifyValueClearImpl + + PUBWEAK MPU_xQueueGenericSendImpl +MPU_xQueueGenericSendImpl: + b MPU_xQueueGenericSendImpl + + PUBWEAK MPU_uxQueueMessagesWaitingImpl +MPU_uxQueueMessagesWaitingImpl: + b MPU_uxQueueMessagesWaitingImpl + + PUBWEAK MPU_uxQueueSpacesAvailableImpl +MPU_uxQueueSpacesAvailableImpl: + b MPU_uxQueueSpacesAvailableImpl + + PUBWEAK MPU_xQueueReceiveImpl +MPU_xQueueReceiveImpl: + b MPU_xQueueReceiveImpl + + PUBWEAK MPU_xQueuePeekImpl +MPU_xQueuePeekImpl: + b MPU_xQueuePeekImpl + + PUBWEAK MPU_xQueueSemaphoreTakeImpl +MPU_xQueueSemaphoreTakeImpl: + b MPU_xQueueSemaphoreTakeImpl + + PUBWEAK MPU_xQueueGetMutexHolderImpl +MPU_xQueueGetMutexHolderImpl: + b MPU_xQueueGetMutexHolderImpl + + PUBWEAK MPU_xQueueTakeMutexRecursiveImpl +MPU_xQueueTakeMutexRecursiveImpl: + b MPU_xQueueTakeMutexRecursiveImpl + + PUBWEAK MPU_xQueueGiveMutexRecursiveImpl +MPU_xQueueGiveMutexRecursiveImpl: + b MPU_xQueueGiveMutexRecursiveImpl + + PUBWEAK MPU_xQueueSelectFromSetImpl +MPU_xQueueSelectFromSetImpl: + b MPU_xQueueSelectFromSetImpl + + PUBWEAK MPU_xQueueAddToSetImpl +MPU_xQueueAddToSetImpl: + b MPU_xQueueAddToSetImpl + + PUBWEAK MPU_vQueueAddToRegistryImpl +MPU_vQueueAddToRegistryImpl: + b MPU_vQueueAddToRegistryImpl + + PUBWEAK MPU_vQueueUnregisterQueueImpl +MPU_vQueueUnregisterQueueImpl: + b MPU_vQueueUnregisterQueueImpl + + PUBWEAK MPU_pcQueueGetNameImpl +MPU_pcQueueGetNameImpl: + b MPU_pcQueueGetNameImpl + + PUBWEAK MPU_pvTimerGetTimerIDImpl +MPU_pvTimerGetTimerIDImpl: + b MPU_pvTimerGetTimerIDImpl + + PUBWEAK MPU_vTimerSetTimerIDImpl +MPU_vTimerSetTimerIDImpl: + b MPU_vTimerSetTimerIDImpl + + PUBWEAK MPU_xTimerIsTimerActiveImpl +MPU_xTimerIsTimerActiveImpl: + b MPU_xTimerIsTimerActiveImpl + + PUBWEAK MPU_xTimerGetTimerDaemonTaskHandleImpl +MPU_xTimerGetTimerDaemonTaskHandleImpl: + b MPU_xTimerGetTimerDaemonTaskHandleImpl + + PUBWEAK MPU_xTimerGenericCommandImpl +MPU_xTimerGenericCommandImpl: + b MPU_xTimerGenericCommandImpl + + PUBWEAK MPU_pcTimerGetNameImpl +MPU_pcTimerGetNameImpl: + b MPU_pcTimerGetNameImpl + + PUBWEAK MPU_vTimerSetReloadModeImpl +MPU_vTimerSetReloadModeImpl: + b MPU_vTimerSetReloadModeImpl + + PUBWEAK MPU_xTimerGetReloadModeImpl +MPU_xTimerGetReloadModeImpl: + b MPU_xTimerGetReloadModeImpl + + PUBWEAK MPU_uxTimerGetReloadModeImpl +MPU_uxTimerGetReloadModeImpl: + b MPU_uxTimerGetReloadModeImpl + + PUBWEAK MPU_xTimerGetPeriodImpl +MPU_xTimerGetPeriodImpl: + b MPU_xTimerGetPeriodImpl + + PUBWEAK MPU_xTimerGetExpiryTimeImpl +MPU_xTimerGetExpiryTimeImpl: + b MPU_xTimerGetExpiryTimeImpl + + PUBWEAK MPU_xEventGroupWaitBitsImpl +MPU_xEventGroupWaitBitsImpl: + b MPU_xEventGroupWaitBitsImpl + + PUBWEAK MPU_xEventGroupClearBitsImpl +MPU_xEventGroupClearBitsImpl: + b MPU_xEventGroupClearBitsImpl + + PUBWEAK MPU_xEventGroupSetBitsImpl +MPU_xEventGroupSetBitsImpl: + b MPU_xEventGroupSetBitsImpl + + PUBWEAK MPU_xEventGroupSyncImpl +MPU_xEventGroupSyncImpl: + b MPU_xEventGroupSyncImpl + + PUBWEAK MPU_uxEventGroupGetNumberImpl +MPU_uxEventGroupGetNumberImpl: + b MPU_uxEventGroupGetNumberImpl + + PUBWEAK MPU_vEventGroupSetNumberImpl +MPU_vEventGroupSetNumberImpl: + b MPU_vEventGroupSetNumberImpl + + PUBWEAK MPU_xStreamBufferSendImpl +MPU_xStreamBufferSendImpl: + b MPU_xStreamBufferSendImpl + + PUBWEAK MPU_xStreamBufferReceiveImpl +MPU_xStreamBufferReceiveImpl: + b MPU_xStreamBufferReceiveImpl + + PUBWEAK MPU_xStreamBufferIsFullImpl +MPU_xStreamBufferIsFullImpl: + b MPU_xStreamBufferIsFullImpl + + PUBWEAK MPU_xStreamBufferIsEmptyImpl +MPU_xStreamBufferIsEmptyImpl: + b MPU_xStreamBufferIsEmptyImpl + + PUBWEAK MPU_xStreamBufferSpacesAvailableImpl +MPU_xStreamBufferSpacesAvailableImpl: + b MPU_xStreamBufferSpacesAvailableImpl + + PUBWEAK MPU_xStreamBufferBytesAvailableImpl +MPU_xStreamBufferBytesAvailableImpl: + b MPU_xStreamBufferBytesAvailableImpl + + PUBWEAK MPU_xStreamBufferSetTriggerLevelImpl +MPU_xStreamBufferSetTriggerLevelImpl: + b MPU_xStreamBufferSetTriggerLevelImpl + + PUBWEAK MPU_xStreamBufferNextMessageLengthBytesImpl +MPU_xStreamBufferNextMessageLengthBytesImpl: + b MPU_xStreamBufferNextMessageLengthBytesImpl + +/*-----------------------------------------------------------*/ + +#endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + + END diff --git a/portable/IAR/ARM_CM4F_MPU/port.c b/portable/IAR/ARM_CM4F_MPU/port.c index 1b7cca65c86..27f6f0d6c9a 100755 --- a/portable/IAR/ARM_CM4F_MPU/port.c +++ b/portable/IAR/ARM_CM4F_MPU/port.c @@ -132,8 +132,14 @@ #define portINITIAL_CONTROL_IF_UNPRIVILEGED ( 0x03 ) #define portINITIAL_CONTROL_IF_PRIVILEGED ( 0x02 ) +/* Constants used during system call enter and exit. */ +#define portPSR_STACK_PADDING_MASK ( 1UL << 9UL ) +#define portEXC_RETURN_STACK_FRAME_TYPE_MASK ( 1UL << 4UL ) + /* Offsets in the stack to the parameters when inside the SVC handler. */ +#define portOFFSET_TO_LR ( 5 ) #define portOFFSET_TO_PC ( 6 ) +#define portOFFSET_TO_PSR ( 7 ) /* The systick is a 24-bit counter. */ #define portMAX_24_BIT_NUMBER ( 0xffffffUL ) @@ -147,6 +153,21 @@ * have bit-0 clear, as it is loaded into the PC on exit from an ISR. */ #define portSTART_ADDRESS_MASK ( ( StackType_t ) 0xfffffffeUL ) +/* Does addr lie within [start, end] address range? */ +#define portIS_ADDRESS_WITHIN_RANGE( addr, start, end ) \ + ( ( ( addr ) >= ( start ) ) && ( ( addr ) <= ( end ) ) ) + +/* Is the access request satisfied by the available permissions? */ +#define portIS_AUTHORIZED( accessRequest, permissions ) \ + ( ( ( permissions ) & ( accessRequest ) ) == accessRequest ) + +/* 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 ) ) ) +/*-----------------------------------------------------------*/ + /* * Configure a number of standard MPU regions that are used by all tasks. */ @@ -184,7 +205,7 @@ extern void vPortEnableVFP( void ); /* * The C portion of the SVC handler. */ -void vPortSVCHandler_C( uint32_t * pulParam ); +void vPortSVCHandler_C( uint32_t * pulParam ) PRIVILEGED_FUNCTION; /* * Called from the SVC handler used to start the scheduler. @@ -208,6 +229,57 @@ extern void vPortRestoreContextOfFirstTask( void ) PRIVILEGED_FUNCTION; #else void vPortExitCritical( void ) PRIVILEGED_FUNCTION; #endif + +#if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + + /** + * @brief Sets up the system call stack so that upon returning from + * SVC, the system call stack is used. + * + * It is used for the system calls with up to 4 parameters. + * + * @param pulTaskStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + */ + void vSystemCallEnter( uint32_t * pulTaskStack, uint32_t ulLR ) PRIVILEGED_FUNCTION; + +#endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + +#if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + + /** + * @brief Sets up the system call stack so that upon returning from + * SVC, the system call stack is used. + * + * It is used for the system calls with 5 parameters. + * + * @param pulTaskStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + */ + void vSystemCallEnter_1( uint32_t * pulTaskStack, uint32_t ulLR ) PRIVILEGED_FUNCTION; + +#endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + +#if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + + /** + * @brief Sets up the task stack so that upon returning from + * SVC, the task stack is used again. + * + * @param pulSystemCallStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + */ + void vSystemCallExit( uint32_t * pulSystemCallStack, uint32_t ulLR ) PRIVILEGED_FUNCTION; + +#endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + +/** + * @brief Checks whether or not the calling task is privileged. + * + * @return pdTRUE if the calling task is privileged, pdFALSE otherwise. + */ +BaseType_t xPortIsTaskPrivileged( void ) PRIVILEGED_FUNCTION; + /*-----------------------------------------------------------*/ /* Each task maintains its own interrupt status in the critical nesting @@ -233,46 +305,56 @@ static UBaseType_t uxCriticalNesting = 0xaaaaaaaa; StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, TaskFunction_t pxCode, void * pvParameters, - BaseType_t xRunPrivileged ) + BaseType_t xRunPrivileged, + xMPU_SETTINGS * xMPUSettings ) { - /* Simulate the stack frame as it would be created by a context switch - * interrupt. */ - - /* Offset added to account for the way the MCU uses the stack on entry/exit - * of interrupts, and to ensure alignment. */ - pxTopOfStack--; - - *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ - pxTopOfStack--; - *pxTopOfStack = ( ( StackType_t ) pxCode ) & portSTART_ADDRESS_MASK; /* PC */ - pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0; /* LR */ - - /* Save code space by skipping register initialisation. */ - pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ - *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ - - /* A save method is being used that requires each task to maintain its - * own exec return value. */ - pxTopOfStack--; - *pxTopOfStack = portINITIAL_EXC_RETURN; - - pxTopOfStack -= 9; /* R11, R10, R9, R8, R7, R6, R5 and R4. */ - if( xRunPrivileged == pdTRUE ) { - *pxTopOfStack = portINITIAL_CONTROL_IF_PRIVILEGED; + xMPUSettings->ulTaskFlags |= portTASK_IS_PRIVILEGED_FLAG; + xMPUSettings->ulContext[ 0 ] = portINITIAL_CONTROL_IF_PRIVILEGED; } else { - *pxTopOfStack = portINITIAL_CONTROL_IF_UNPRIVILEGED; + xMPUSettings->ulTaskFlags &= ( ~portTASK_IS_PRIVILEGED_FLAG ); + xMPUSettings->ulContext[ 0 ] = portINITIAL_CONTROL_IF_UNPRIVILEGED; } + xMPUSettings->ulContext[ 1 ] = 0x04040404; /* r4. */ + xMPUSettings->ulContext[ 2 ] = 0x05050505; /* r5. */ + xMPUSettings->ulContext[ 3 ] = 0x06060606; /* r6. */ + xMPUSettings->ulContext[ 4 ] = 0x07070707; /* r7. */ + xMPUSettings->ulContext[ 5 ] = 0x08080808; /* r8. */ + xMPUSettings->ulContext[ 6 ] = 0x09090909; /* r9. */ + xMPUSettings->ulContext[ 7 ] = 0x10101010; /* r10. */ + xMPUSettings->ulContext[ 8 ] = 0x11111111; /* r11. */ + xMPUSettings->ulContext[ 9 ] = portINITIAL_EXC_RETURN; /* EXC_RETURN. */ + + xMPUSettings->ulContext[ 10 ] = ( uint32_t ) ( pxTopOfStack - 8 ); /* PSP with the hardware saved stack. */ + xMPUSettings->ulContext[ 11 ] = ( uint32_t ) pvParameters; /* r0. */ + xMPUSettings->ulContext[ 12 ] = 0x01010101; /* r1. */ + xMPUSettings->ulContext[ 13 ] = 0x02020202; /* r2. */ + xMPUSettings->ulContext[ 14 ] = 0x03030303; /* r3. */ + xMPUSettings->ulContext[ 15 ] = 0x12121212; /* r12. */ + xMPUSettings->ulContext[ 16 ] = 0; /* LR. */ + xMPUSettings->ulContext[ 17 ] = ( ( uint32_t ) pxCode ) & portSTART_ADDRESS_MASK; /* PC. */ + xMPUSettings->ulContext[ 18 ] = portINITIAL_XPSR; /* xPSR. */ + + #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + { + /* Ensure that the system call stack is double word aligned. */ + xMPUSettings->xSystemCallStackInfo.pulSystemCallStack = &( xMPUSettings->xSystemCallStackInfo.ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE - 1 ] ); + xMPUSettings->xSystemCallStackInfo.pulSystemCallStack = ( uint32_t * ) ( ( uint32_t ) ( xMPUSettings->xSystemCallStackInfo.pulSystemCallStack ) & + ( uint32_t ) ( ~( portBYTE_ALIGNMENT_MASK ) ) ); - return pxTopOfStack; + /* This is not NULL only for the duration of a system call. */ + xMPUSettings->xSystemCallStackInfo.pulTaskStack = NULL; + } + #endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + + return &( xMPUSettings->ulContext[ 19 ] ); } /*-----------------------------------------------------------*/ -void vPortSVCHandler_C( uint32_t * pulParam ) +void vPortSVCHandler_C( uint32_t * pulParam ) /* PRIVILEGED_FUNCTION */ { uint8_t ucSVCNumber; uint32_t ulPC; @@ -334,7 +416,7 @@ void vPortSVCHandler_C( uint32_t * pulParam ) ::: "r1", "memory" ); break; - #endif /* #if( configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY == 1 ) */ + #endif /* #if( configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY == 1 ) */ default: /* Unknown SVC call. */ break; @@ -342,6 +424,308 @@ void vPortSVCHandler_C( uint32_t * pulParam ) } /*-----------------------------------------------------------*/ +#if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + +void vSystemCallEnter( uint32_t * pulTaskStack, uint32_t ulLR ) /* PRIVILEGED_FUNCTION */ +{ + extern TaskHandle_t pxCurrentTCB; + xMPU_SETTINGS * pxMpuSettings; + uint32_t * pulSystemCallStack; + uint32_t ulStackFrameSize, ulSystemCallLocation, i; + #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being + * exported from linker scripts. */ + extern uint32_t * __syscalls_flash_start__; + extern uint32_t * __syscalls_flash_end__; + #else + /* Declaration when these variable are exported from linker scripts. */ + extern uint32_t __syscalls_flash_start__[]; + extern uint32_t __syscalls_flash_end__[]; + #endif /* #if defined( __ARMCC_VERSION ) */ + + ulSystemCallLocation = pulTaskStack[ portOFFSET_TO_PC ]; + + /* If the request did not come from the system call section, do nothing. */ + if( ( ulSystemCallLocation >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulSystemCallLocation <= ( uint32_t ) __syscalls_flash_end__ ) ) + { + pxMpuSettings = xTaskGetMPUSettings( pxCurrentTCB ); + pulSystemCallStack = pxMpuSettings->xSystemCallStackInfo.pulSystemCallStack; + + /* This is not NULL only for the duration of the system call. */ + configASSERT( pxMpuSettings->xSystemCallStackInfo.pulTaskStack == NULL ); + + if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) + { + /* Extended frame i.e. FPU in use. */ + ulStackFrameSize = 26; + __asm volatile ( + " vpush {s0} \n" /* Trigger lazy stacking. */ + " vpop {s0} \n" /* Nullify the affect of the above instruction. */ + ::: "memory" + ); + } + else + { + /* Standard frame i.e. FPU not in use. */ + ulStackFrameSize = 8; + } + + /* Make space on the system call stack for the stack frame. */ + pulSystemCallStack = pulSystemCallStack - ulStackFrameSize; + + /* Copy the stack frame. */ + for( i = 0; i < ulStackFrameSize; i++ ) + { + pulSystemCallStack[ i ] = pulTaskStack[ i ]; + } + + /* Use the pulSystemCallStack in thread mode. */ + __asm volatile ( "msr psp, %0" : : "r" ( pulSystemCallStack ) ); + + /* Raise the privilege for the duration of the system call. */ + __asm volatile ( + " mrs r1, control \n" /* Obtain current control value. */ + " bic r1, #1 \n" /* Clear nPRIV bit. */ + " msr control, r1 \n" /* Write back new control value. */ + ::: "r1", "memory" + ); + + /* Remember the location where we should copy the stack frame when we exit from + * the system call. */ + pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulStackFrameSize; + + /* Store the value of the Link Register before the SVC was raised. We need to + * restore it when we exit from the system call. */ + pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; + + /* Record if the hardware used padding to force the stack pointer + * to be double word aligned. */ + if( ( pulTaskStack[ portOFFSET_TO_PSR ] & portPSR_STACK_PADDING_MASK ) == portPSR_STACK_PADDING_MASK ) + { + pxMpuSettings->ulTaskFlags |= portSTACK_FRAME_HAS_PADDING_FLAG; + } + else + { + pxMpuSettings->ulTaskFlags &= ( ~portSTACK_FRAME_HAS_PADDING_FLAG ); + } + + /* We ensure in pxPortInitialiseStack that the system call stack is + * double word aligned and therefore, there is no need of padding. + * Clear the bit[9] of stacked xPSR. */ + pulSystemCallStack[ portOFFSET_TO_PSR ] &= ( ~portPSR_STACK_PADDING_MASK ); + } +} + +#endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + +void vSystemCallEnter_1( uint32_t * pulTaskStack, uint32_t ulLR ) /* PRIVILEGED_FUNCTION */ +{ + extern TaskHandle_t pxCurrentTCB; + xMPU_SETTINGS * pxMpuSettings; + uint32_t * pulSystemCallStack; + uint32_t ulStackFrameSize, ulSystemCallLocation, i; + #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being + * exported from linker scripts. */ + extern uint32_t * __syscalls_flash_start__; + extern uint32_t * __syscalls_flash_end__; + #else + /* Declaration when these variable are exported from linker scripts. */ + extern uint32_t __syscalls_flash_start__[]; + extern uint32_t __syscalls_flash_end__[]; + #endif /* #if defined( __ARMCC_VERSION ) */ + + ulSystemCallLocation = pulTaskStack[ portOFFSET_TO_PC ]; + + /* If the request did not come from the system call section, do nothing. */ + if( ( ulSystemCallLocation >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulSystemCallLocation <= ( uint32_t ) __syscalls_flash_end__ ) ) + { + pxMpuSettings = xTaskGetMPUSettings( pxCurrentTCB ); + pulSystemCallStack = pxMpuSettings->xSystemCallStackInfo.pulSystemCallStack; + + /* This is not NULL only for the duration of the system call. */ + configASSERT( pxMpuSettings->xSystemCallStackInfo.pulTaskStack == NULL ); + + if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) + { + /* Extended frame i.e. FPU in use. */ + ulStackFrameSize = 26; + __asm volatile ( + " vpush {s0} \n" /* Trigger lazy stacking. */ + " vpop {s0} \n" /* Nullify the affect of the above instruction. */ + ::: "memory" + ); + } + else + { + /* Standard frame i.e. FPU not in use. */ + ulStackFrameSize = 8; + } + + /* Make space on the system call stack for the stack frame and + * the parameter passed on the stack. We only need to copy one + * parameter but we still reserve 2 spaces to keep the stack + * double word aligned. */ + pulSystemCallStack = pulSystemCallStack - ulStackFrameSize - 2UL; + + /* Copy the stack frame. */ + for( i = 0; i < ulStackFrameSize; i++ ) + { + pulSystemCallStack[ i ] = pulTaskStack[ i ]; + } + + /* Copy the parameter which is passed the stack. */ + if( ( pulTaskStack[ portOFFSET_TO_PSR ] & portPSR_STACK_PADDING_MASK ) == portPSR_STACK_PADDING_MASK ) + { + pulSystemCallStack[ ulStackFrameSize ] = pulTaskStack[ ulStackFrameSize + 1 ]; + /* Record if the hardware used padding to force the stack pointer + * to be double word aligned. */ + pxMpuSettings->ulTaskFlags |= portSTACK_FRAME_HAS_PADDING_FLAG; + } + else + { + pulSystemCallStack[ ulStackFrameSize ] = pulTaskStack[ ulStackFrameSize ]; + /* Record if the hardware used padding to force the stack pointer + * to be double word aligned. */ + pxMpuSettings->ulTaskFlags &= ( ~portSTACK_FRAME_HAS_PADDING_FLAG ); + } + + /* Use the pulSystemCallStack in thread mode. */ + __asm volatile ( "msr psp, %0" : : "r" ( pulSystemCallStack ) ); + + /* Raise the privilege for the duration of the system call. */ + __asm volatile ( + " mrs r1, control \n" /* Obtain current control value. */ + " bic r1, #1 \n" /* Clear nPRIV bit. */ + " msr control, r1 \n" /* Write back new control value. */ + ::: "r1", "memory" + ); + + /* Remember the location where we should copy the stack frame when we exit from + * the system call. */ + pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulStackFrameSize; + + /* Store the value of the Link Register before the SVC was raised. We need to + * restore it when we exit from the system call. */ + pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; + + /* We ensure in pxPortInitialiseStack that the system call stack is + * double word aligned and therefore, there is no need of padding. + * Clear the bit[9] of stacked xPSR. */ + pulSystemCallStack[ portOFFSET_TO_PSR ] &= ( ~portPSR_STACK_PADDING_MASK ); + } +} + +#endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + +void vSystemCallExit( uint32_t * pulSystemCallStack, uint32_t ulLR ) /* PRIVILEGED_FUNCTION */ +{ + extern TaskHandle_t pxCurrentTCB; + xMPU_SETTINGS * pxMpuSettings; + uint32_t * pulTaskStack; + uint32_t ulStackFrameSize, ulSystemCallLocation, i; + #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being + * exported from linker scripts. */ + extern uint32_t * __syscalls_flash_start__; + extern uint32_t * __syscalls_flash_end__; + #else + /* Declaration when these variable are exported from linker scripts. */ + extern uint32_t __syscalls_flash_start__[]; + extern uint32_t __syscalls_flash_end__[]; + #endif /* #if defined( __ARMCC_VERSION ) */ + + ulSystemCallLocation = pulSystemCallStack[ portOFFSET_TO_PC ]; + + /* If the request did not come from the system call section, do nothing. */ + if( ( ulSystemCallLocation >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulSystemCallLocation <= ( uint32_t ) __syscalls_flash_end__ ) ) + { + pxMpuSettings = xTaskGetMPUSettings( pxCurrentTCB ); + pulTaskStack = pxMpuSettings->xSystemCallStackInfo.pulTaskStack; + + if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) + { + /* Extended frame i.e. FPU in use. */ + ulStackFrameSize = 26; + __asm volatile ( + " vpush {s0} \n" /* Trigger lazy stacking. */ + " vpop {s0} \n" /* Nullify the affect of the above instruction. */ + ::: "memory" + ); + } + else + { + /* Standard frame i.e. FPU not in use. */ + ulStackFrameSize = 8; + } + + /* Make space on the task stack for the stack frame. */ + pulTaskStack = pulTaskStack - ulStackFrameSize; + + /* Copy the stack frame. */ + for( i = 0; i < ulStackFrameSize; i++ ) + { + pulTaskStack[ i ] = pulSystemCallStack[ i ]; + } + + /* Use the pulTaskStack in thread mode. */ + __asm volatile ( "msr psp, %0" : : "r" ( pulTaskStack ) ); + + /* Drop the privilege before returning to the thread mode. */ + __asm volatile ( + " mrs r1, control \n" /* Obtain current control value. */ + " orr r1, #1 \n" /* Set nPRIV bit. */ + " msr control, r1 \n" /* Write back new control value. */ + ::: "r1", "memory" + ); + + /* Restore the stacked link register to what it was at the time of + * system call entry. */ + pulTaskStack[ portOFFSET_TO_LR ] = pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry; + + /* If the hardware used padding to force the stack pointer + * to be double word aligned, set the stacked xPSR bit[9], + * otherwise clear it. */ + if( ( pxMpuSettings->ulTaskFlags & portSTACK_FRAME_HAS_PADDING_FLAG ) == portSTACK_FRAME_HAS_PADDING_FLAG ) + { + pulTaskStack[ portOFFSET_TO_PSR ] |= portPSR_STACK_PADDING_MASK; + } + else + { + pulTaskStack[ portOFFSET_TO_PSR ] &= ( ~portPSR_STACK_PADDING_MASK ); + } + + /* This is not NULL only for the duration of the system call. */ + pxMpuSettings->xSystemCallStackInfo.pulTaskStack = NULL; + } +} + +#endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ +/*-----------------------------------------------------------*/ + +BaseType_t xPortIsTaskPrivileged( void ) /* PRIVILEGED_FUNCTION */ +{ + BaseType_t xTaskIsPrivileged = pdFALSE; + const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */ + + if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) + { + xTaskIsPrivileged = pdTRUE; + } + + return xTaskIsPrivileged; +} +/*-----------------------------------------------------------*/ + /* * See header file for description. */ @@ -393,6 +777,10 @@ BaseType_t xPortStartScheduler( void ) * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ configASSERT( ucMaxSysCallPriority ); + /* Check that the bits not implemented in hardware are zero in + * configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & ( ~ucMaxPriorityValue ) ) == 0U ); + /* Calculate the maximum acceptable priority group value for the number * of bits read back. */ @@ -429,28 +817,6 @@ BaseType_t xPortStartScheduler( void ) ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulImplementedPrioBits; } - #ifdef __NVIC_PRIO_BITS - { - /* - * Check that the number of implemented priority bits queried from - * hardware is at least as many as specified in the CMSIS - * __NVIC_PRIO_BITS configuration macro. - */ - configASSERT( ulImplementedPrioBits >= __NVIC_PRIO_BITS ); - } - #endif - - #ifdef configPRIO_BITS - { - /* - * Check that the number of implemented priority bits queried from - * hardware is at least as many as specified in the FreeRTOS - * configPRIO_BITS configuration macro. - */ - configASSERT( ulImplementedPrioBits >= configPRIO_BITS ); - } - #endif - /* Shift the priority group value back to its position within the AIRCR * register. */ ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT; @@ -756,11 +1122,19 @@ void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings, ( prvGetMPURegionSizeSetting( ( uint32_t ) __SRAM_segment_end__ - ( uint32_t ) __SRAM_segment_start__ ) ) | ( portMPU_REGION_ENABLE ); + xMPUSettings->xRegionSettings[ 0 ].ulRegionStartAddress = ( uint32_t ) __SRAM_segment_start__; + xMPUSettings->xRegionSettings[ 0 ].ulRegionEndAddress = ( uint32_t ) __SRAM_segment_end__; + xMPUSettings->xRegionSettings[ 0 ].ulRegionPermissions = ( tskMPU_READ_PERMISSION | + tskMPU_WRITE_PERMISSION ); + /* Invalidate user configurable regions. */ for( ul = 1UL; ul <= portNUM_CONFIGURABLE_REGIONS; ul++ ) { xMPUSettings->xRegion[ ul ].ulRegionBaseAddress = ( ( ul - 1UL ) | portMPU_REGION_VALID ); xMPUSettings->xRegion[ ul ].ulRegionAttribute = 0UL; + xMPUSettings->xRegionSettings[ ul ].ulRegionStartAddress = 0UL; + xMPUSettings->xRegionSettings[ ul ].ulRegionEndAddress = 0UL; + xMPUSettings->xRegionSettings[ ul ].ulRegionPermissions = 0UL; } } else @@ -783,6 +1157,13 @@ void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings, ( prvGetMPURegionSizeSetting( ulStackDepth * ( uint32_t ) sizeof( StackType_t ) ) ) | ( ( configTEX_S_C_B_SRAM & portMPU_RASR_TEX_S_C_B_MASK ) << portMPU_RASR_TEX_S_C_B_LOCATION ) | ( portMPU_REGION_ENABLE ); + + xMPUSettings->xRegionSettings[ 0 ].ulRegionStartAddress = ( uint32_t ) pxBottomOfStack; + xMPUSettings->xRegionSettings[ 0 ].ulRegionEndAddress = ( uint32_t ) ( ( uint32_t ) ( pxBottomOfStack ) + + ( ulStackDepth * ( uint32_t ) sizeof( StackType_t ) ) - 1UL ); + xMPUSettings->xRegionSettings[ 0 ].ulRegionPermissions = ( tskMPU_READ_PERMISSION | + tskMPU_WRITE_PERMISSION ); + } lIndex = 0; @@ -803,12 +1184,28 @@ void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings, ( prvGetMPURegionSizeSetting( xRegions[ lIndex ].ulLengthInBytes ) ) | ( xRegions[ lIndex ].ulParameters ) | ( portMPU_REGION_ENABLE ); + + xMPUSettings->xRegionSettings[ ul ].ulRegionStartAddress = ( uint32_t) xRegions[ lIndex ].pvBaseAddress; + xMPUSettings->xRegionSettings[ ul ].ulRegionEndAddress = ( uint32_t ) ( ( uint32_t ) xRegions[ lIndex ].pvBaseAddress + xRegions[ lIndex ].ulLengthInBytes - 1UL ); + xMPUSettings->xRegionSettings[ ul ].ulRegionPermissions = 0UL; + if( ( ( xRegions[ lIndex ].ulParameters & portMPU_REGION_READ_ONLY ) == portMPU_REGION_READ_ONLY ) || + ( ( xRegions[ lIndex ].ulParameters & portMPU_REGION_PRIVILEGED_READ_WRITE_UNPRIV_READ_ONLY ) == portMPU_REGION_PRIVILEGED_READ_WRITE_UNPRIV_READ_ONLY ) ) + { + xMPUSettings->xRegionSettings[ ul ].ulRegionPermissions = tskMPU_READ_PERMISSION; + } + if( ( xRegions[ lIndex ].ulParameters & portMPU_REGION_READ_WRITE ) == portMPU_REGION_READ_WRITE ) + { + xMPUSettings->xRegionSettings[ ul ].ulRegionPermissions = ( tskMPU_READ_PERMISSION | tskMPU_WRITE_PERMISSION ); + } } else { /* Invalidate the region. */ xMPUSettings->xRegion[ ul ].ulRegionBaseAddress = ( ( ul - 1UL ) | portMPU_REGION_VALID ); xMPUSettings->xRegion[ ul ].ulRegionAttribute = 0UL; + xMPUSettings->xRegionSettings[ ul ].ulRegionStartAddress = 0UL; + xMPUSettings->xRegionSettings[ ul ].ulRegionEndAddress = 0UL; + xMPUSettings->xRegionSettings[ ul ].ulRegionPermissions = 0UL; } lIndex++; @@ -817,6 +1214,48 @@ void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings, } /*-----------------------------------------------------------*/ +BaseType_t xPortIsAuthorizedToAccessBuffer( const void * pvBuffer, + uint32_t ulBufferLength, + uint32_t ulAccessRequested ) /* PRIVILEGED_FUNCTION */ + +{ + uint32_t i, ulBufferStartAddress, ulBufferEndAddress; + BaseType_t xAccessGranted = pdFALSE; + const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */ + + if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) + { + xAccessGranted = pdTRUE; + } + else + { + if( portADD_UINT32_WILL_OVERFLOW( ( ( uint32_t ) pvBuffer ), ( ulBufferLength - 1UL ) ) == pdFALSE ) + { + ulBufferStartAddress = ( uint32_t ) pvBuffer; + ulBufferEndAddress = ( ( ( uint32_t ) pvBuffer ) + ulBufferLength - 1UL ); + + for( i = 0; i < portTOTAL_NUM_REGIONS_IN_TCB; i++ ) + { + if( portIS_ADDRESS_WITHIN_RANGE( ulBufferStartAddress, + xTaskMpuSettings->xRegionSettings[ i ].ulRegionStartAddress, + xTaskMpuSettings->xRegionSettings[ i ].ulRegionEndAddress ) && + portIS_ADDRESS_WITHIN_RANGE( ulBufferEndAddress, + xTaskMpuSettings->xRegionSettings[ i ].ulRegionStartAddress, + xTaskMpuSettings->xRegionSettings[ i ].ulRegionEndAddress ) && + portIS_AUTHORIZED( ulAccessRequested, xTaskMpuSettings->xRegionSettings[ i ].ulRegionPermissions ) ) + { + xAccessGranted = pdTRUE; + break; + } + } + } + } + + return xAccessGranted; +} +/*-----------------------------------------------------------*/ + + #if ( configASSERT_DEFINED == 1 ) void vPortValidateInterruptPriority( void ) diff --git a/portable/IAR/ARM_CM4F_MPU/portasm.s b/portable/IAR/ARM_CM4F_MPU/portasm.s index db751f6e5ef..a0cf8baa2f4 100644 --- a/portable/IAR/ARM_CM4F_MPU/portasm.s +++ b/portable/IAR/ARM_CM4F_MPU/portasm.s @@ -25,6 +25,7 @@ * https://github.com/FreeRTOS * */ + /* Including FreeRTOSConfig.h here will cause build errors if the header file contains code not understood by the assembler - for example the 'extern' keyword. To avoid errors place any such code inside a #ifdef __ICCARM__/#endif block so @@ -38,6 +39,9 @@ files (__ICCARM__ is defined by the IAR C compiler but not by the IAR assembler. EXTERN pxCurrentTCB EXTERN vTaskSwitchContext EXTERN vPortSVCHandler_C + EXTERN vSystemCallEnter + EXTERN vSystemCallEnter_1 + EXTERN vSystemCallExit PUBLIC xPortPendSVHandler PUBLIC vPortSVCHandler @@ -49,99 +53,141 @@ files (__ICCARM__ is defined by the IAR C compiler but not by the IAR assembler. /*-----------------------------------------------------------*/ +#ifndef configUSE_MPU_WRAPPERS_V1 + #define configUSE_MPU_WRAPPERS_V1 0 +#endif + +/* These must be in sync with portmacro.h. */ +#define portSVC_SYSTEM_CALL_ENTER 3 +#define portSVC_SYSTEM_CALL_ENTER_1 4 +#define portSVC_SYSTEM_CALL_EXIT 5 +/*-----------------------------------------------------------*/ + xPortPendSVHandler: - mrs r0, psp - isb - /* Get the location of the current TCB. */ + ldr r3, =pxCurrentTCB - ldr r2, [r3] + ldr r2, [r3] /* r2 = pxCurrentTCB. */ + ldr r1, [r2] /* r1 = Location where the context should be saved. */ - /* Is the task using the FPU context? If so, push high vfp registers. */ - tst r14, #0x10 - it eq - vstmdbeq r0!, {s16-s31} + /*------------ Save Context. ----------- */ + mrs r3, control + mrs r0, psp + isb - /* Save the core registers. */ - mrs r1, control - stmdb r0!, {r1, r4-r11, r14} + add r0, r0, #0x20 /* Move r0 to location where s0 is saved. */ + tst lr, #0x10 + ittt eq + vstmiaeq r1!, {s16-s31} /* Store s16-s31. */ + vldmiaeq r0, {s0-s16} /* Copy hardware saved FP context into s0-s16. */ + vstmiaeq r1!, {s0-s16} /* Store hardware saved FP context. */ + sub r0, r0, #0x20 /* Set r0 back to the location of hardware saved context. */ - /* Save the new top of stack into the first member of the TCB. */ - str r0, [r2] + stmia r1!, {r3-r11, lr} /* Store CONTROL register, r4-r11 and LR. */ + ldmia r0, {r4-r11} /* Copy hardware saved context into r4-r11. */ + stmia r1!, {r0, r4-r11} /* Store original PSP (after hardware has saved context) and the hardware saved context. */ + str r1, [r2] /* Save the location from where the context should be restored as the first member of TCB. */ - stmdb sp!, {r0, r3} + /*---------- Select next task. --------- */ mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY - #if ( configENABLE_ERRATA_837070_WORKAROUND == 1 ) - cpsid i /* ARM Cortex-M7 r0p1 Errata 837070 workaround. */ - #endif +#if ( configENABLE_ERRATA_837070_WORKAROUND == 1 ) + cpsid i /* ARM Cortex-M7 r0p1 Errata 837070 workaround. */ +#endif msr basepri, r0 dsb isb - #if ( configENABLE_ERRATA_837070_WORKAROUND == 1 ) - cpsie i /* ARM Cortex-M7 r0p1 Errata 837070 workaround. */ - #endif +#if ( configENABLE_ERRATA_837070_WORKAROUND == 1 ) + cpsie i /* ARM Cortex-M7 r0p1 Errata 837070 workaround. */ +#endif bl vTaskSwitchContext mov r0, #0 msr basepri, r0 - ldmia sp!, {r0, r3} - - /* The first item in pxCurrentTCB is the task top of stack. */ - ldr r1, [r3] - ldr r0, [r1] - /* Move onto the second item in the TCB... */ - add r1, r1, #4 - - dmb /* Complete outstanding transfers before disabling MPU. */ - ldr r2, =0xe000ed94 /* MPU_CTRL register. */ - ldr r3, [r2] /* Read the value of MPU_CTRL. */ - bic r3, r3, #1 /* r3 = r3 & ~1 i.e. Clear the bit 0 in r3. */ - str r3, [r2] /* Disable MPU. */ - - /* Region Base Address register. */ - ldr r2, =0xe000ed9c - /* Read 4 sets of MPU registers [MPU Region # 4 - 7]. */ - ldmia r1!, {r4-r11} - /* Write 4 sets of MPU registers [MPU Region # 4 - 7]. */ - stmia r2, {r4-r11} - - #ifdef configTOTAL_MPU_REGIONS - #if ( configTOTAL_MPU_REGIONS == 16 ) - /* Read 4 sets of MPU registers [MPU Region # 8 - 11]. */ - ldmia r1!, {r4-r11} - /* Write 4 sets of MPU registers. [MPU Region # 8 - 11]. */ - stmia r2, {r4-r11} - /* Read 4 sets of MPU registers [MPU Region # 12 - 15]. */ - ldmia r1!, {r4-r11} - /* Write 4 sets of MPU registers. [MPU Region # 12 - 15]. */ - stmia r2, {r4-r11} - #endif /* configTOTAL_MPU_REGIONS == 16. */ - #endif /* configTOTAL_MPU_REGIONS */ - - ldr r2, =0xe000ed94 /* MPU_CTRL register. */ - ldr r3, [r2] /* Read the value of MPU_CTRL. */ - orr r3, r3, #1 /* r3 = r3 | 1 i.e. Set the bit 0 in r3. */ - str r3, [r2] /* Enable MPU. */ - dsb /* Force memory writes before continuing. */ - - /* Pop the registers that are not automatically saved on exception entry. */ - ldmia r0!, {r3-r11, r14} - msr control, r3 - /* Is the task using the FPU context? If so, pop the high vfp registers - too. */ - tst r14, #0x10 - it eq - vldmiaeq r0!, {s16-s31} + /*------------ Program MPU. ------------ */ + ldr r3, =pxCurrentTCB + ldr r2, [r3] /* r2 = pxCurrentTCB. */ + add r2, r2, #4 /* r2 = Second item in the TCB which is xMPUSettings. */ + + dmb /* Complete outstanding transfers before disabling MPU. */ + ldr r0, =0xe000ed94 /* MPU_CTRL register. */ + ldr r3, [r0] /* Read the value of MPU_CTRL. */ + bic r3, #1 /* r3 = r3 & ~1 i.e. Clear the bit 0 in r3. */ + str r3, [r0] /* Disable MPU. */ + + ldr r0, =0xe000ed9c /* Region Base Address register. */ + ldmia r2!, {r4-r11} /* Read 4 sets of MPU registers [MPU Region # 0 - 3]. */ + stmia r0, {r4-r11} /* Write 4 sets of MPU registers [MPU Region # 0 - 3]. */ + +#ifdef configTOTAL_MPU_REGIONS + #if ( configTOTAL_MPU_REGIONS == 16 ) + ldmia r2!, {r4-r11} /* Read 4 sets of MPU registers [MPU Region # 4 - 7]. */ + stmia r0, {r4-r11} /* Write 4 sets of MPU registers. [MPU Region # 4 - 7]. */ + ldmia r2!, {r4-r11} /* Read 4 sets of MPU registers [MPU Region # 8 - 11]. */ + stmia r0, {r4-r11} /* Write 4 sets of MPU registers. [MPU Region # 8 - 11]. */ + #endif /* configTOTAL_MPU_REGIONS == 16. */ +#endif + + ldr r0, =0xe000ed94 /* MPU_CTRL register. */ + ldr r3, [r0] /* Read the value of MPU_CTRL. */ + orr r3, #1 /* r3 = r3 | 1 i.e. Set the bit 0 in r3. */ + str r3, [r0] /* Enable MPU. */ + dsb /* Force memory writes before continuing. */ + + /*---------- Restore Context. ---------- */ + ldr r3, =pxCurrentTCB + ldr r2, [r3] /* r2 = pxCurrentTCB. */ + ldr r1, [r2] /* r1 = Location of saved context in TCB. */ + ldmdb r1!, {r0, r4-r11} /* r0 contains PSP after the hardware had saved context. r4-r11 contain hardware saved context. */ msr psp, r0 - isb + stmia r0!, {r4-r11} /* Copy the hardware saved context on the task stack. */ + ldmdb r1!, {r3-r11, lr} /* r3 contains CONTROL register. r4-r11 and LR restored. */ + msr control, r3 - bx r14 + tst lr, #0x10 + ittt eq + vldmdbeq r1!, {s0-s16} /* s0-s16 contain hardware saved FP context. */ + vstmiaeq r0!, {s0-s16} /* Copy hardware saved FP context on the task stack. */ + vldmdbeq r1!, {s16-s31} /* Restore s16-s31. */ + str r1, [r2] /* Save the location where the context should be saved next as the first member of TCB. */ + bx lr /*-----------------------------------------------------------*/ +#if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + +vPortSVCHandler: + tst lr, #4 + ite eq + mrseq r0, msp + mrsne r0, psp + + ldr r1, [r0, #24] + ldrb r2, [r1, #-2] + cmp r2, #portSVC_SYSTEM_CALL_ENTER + beq syscall_enter + cmp r2, #portSVC_SYSTEM_CALL_ENTER_1 + beq syscall_enter_1 + cmp r2, #portSVC_SYSTEM_CALL_EXIT + beq syscall_exit + b vPortSVCHandler_C + + syscall_enter: + mov r1, lr + b vSystemCallEnter + + syscall_enter_1: + mov r1, lr + b vSystemCallEnter_1 + + syscall_exit: + mov r1, lr + b vSystemCallExit + +#else /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + vPortSVCHandler: - #ifndef USE_PROCESS_STACK /* Code should not be required if a main() is using the process stack. */ + #ifndef USE_PROCESS_STACK tst lr, #4 ite eq mrseq r0, msp @@ -151,6 +197,7 @@ vPortSVCHandler: #endif b vPortSVCHandler_C +#endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ /*-----------------------------------------------------------*/ vPortStartFirstTask: @@ -176,60 +223,56 @@ vPortStartFirstTask: /*-----------------------------------------------------------*/ vPortRestoreContextOfFirstTask: - /* Use the NVIC offset register to locate the stack. */ - ldr r0, =0xE000ED08 + ldr r0, =0xE000ED08 /* Use the NVIC offset register to locate the stack. */ ldr r0, [r0] ldr r0, [r0] - /* Set the msp back to the start of the stack. */ - msr msp, r0 - /* Restore the context. */ + msr msp, r0 /* Set the msp back to the start of the stack. */ + + /*------------ Program MPU. ------------ */ ldr r3, =pxCurrentTCB - ldr r1, [r3] - /* The first item in the TCB is the task top of stack. */ - ldr r0, [r1] - /* Move onto the second item in the TCB... */ - add r1, r1, #4 - - dmb /* Complete outstanding transfers before disabling MPU. */ - ldr r2, =0xe000ed94 /* MPU_CTRL register. */ - ldr r3, [r2] /* Read the value of MPU_CTRL. */ - bic r3, r3, #1 /* r3 = r3 & ~1 i.e. Clear the bit 0 in r3. */ - str r3, [r2] /* Disable MPU. */ - - /* Region Base Address register. */ - ldr r2, =0xe000ed9c - /* Read 4 sets of MPU registers [MPU Region # 4 - 7]. */ - ldmia r1!, {r4-r11} - /* Write 4 sets of MPU registers [MPU Region # 4 - 7]. */ - stmia r2, {r4-r11} - - #ifdef configTOTAL_MPU_REGIONS - #if ( configTOTAL_MPU_REGIONS == 16 ) - /* Read 4 sets of MPU registers [MPU Region # 8 - 11]. */ - ldmia r1!, {r4-r11} - /* Write 4 sets of MPU registers. [MPU Region # 8 - 11]. */ - stmia r2, {r4-r11} - /* Read 4 sets of MPU registers [MPU Region # 12 - 15]. */ - ldmia r1!, {r4-r11} - /* Write 4 sets of MPU registers. [MPU Region # 12 - 15]. */ - stmia r2, {r4-r11} - #endif /* configTOTAL_MPU_REGIONS == 16. */ - #endif /* configTOTAL_MPU_REGIONS */ - - ldr r2, =0xe000ed94 /* MPU_CTRL register. */ - ldr r3, [r2] /* Read the value of MPU_CTRL. */ - orr r3, r3, #1 /* r3 = r3 | 1 i.e. Set the bit 0 in r3. */ - str r3, [r2] /* Enable MPU. */ - dsb /* Force memory writes before continuing. */ - - /* Pop the registers that are not automatically saved on exception entry. */ - ldmia r0!, {r3-r11, r14} - msr control, r3 - /* Restore the task stack pointer. */ + ldr r2, [r3] /* r2 = pxCurrentTCB. */ + add r2, r2, #4 /* r2 = Second item in the TCB which is xMPUSettings. */ + + dmb /* Complete outstanding transfers before disabling MPU. */ + ldr r0, =0xe000ed94 /* MPU_CTRL register. */ + ldr r3, [r0] /* Read the value of MPU_CTRL. */ + bic r3, #1 /* r3 = r3 & ~1 i.e. Clear the bit 0 in r3. */ + str r3, [r0] /* Disable MPU. */ + + ldr r0, =0xe000ed9c /* Region Base Address register. */ + ldmia r2!, {r4-r11} /* Read 4 sets of MPU registers [MPU Region # 0 - 3]. */ + stmia r0, {r4-r11} /* Write 4 sets of MPU registers [MPU Region # 0 - 3]. */ + +#ifdef configTOTAL_MPU_REGIONS + #if ( configTOTAL_MPU_REGIONS == 16 ) + ldmia r2!, {r4-r11} /* Read 4 sets of MPU registers [MPU Region # 4 - 7]. */ + stmia r0, {r4-r11} /* Write 4 sets of MPU registers. [MPU Region # 4 - 7]. */ + ldmia r2!, {r4-r11} /* Read 4 sets of MPU registers [MPU Region # 8 - 11]. */ + stmia r0, {r4-r11} /* Write 4 sets of MPU registers. [MPU Region # 8 - 11]. */ + #endif /* configTOTAL_MPU_REGIONS == 16. */ +#endif + + ldr r0, =0xe000ed94 /* MPU_CTRL register. */ + ldr r3, [r0] /* Read the value of MPU_CTRL. */ + orr r3, #1 /* r3 = r3 | 1 i.e. Set the bit 0 in r3. */ + str r3, [r0] /* Enable MPU. */ + dsb /* Force memory writes before continuing. */ + + /*---------- Restore Context. ---------- */ + ldr r3, =pxCurrentTCB + ldr r2, [r3] /* r2 = pxCurrentTCB. */ + ldr r1, [r2] /* r1 = Location of saved context in TCB. */ + + ldmdb r1!, {r0, r4-r11} /* r0 contains PSP after the hardware had saved context. r4-r11 contain hardware saved context. */ msr psp, r0 + stmia r0, {r4-r11} /* Copy the hardware saved context on the task stack. */ + ldmdb r1!, {r3-r11, lr} /* r3 contains CONTROL register. r4-r11 and LR restored. */ + msr control, r3 + str r1, [r2] /* Save the location where the context should be saved next as the first member of TCB. */ + mov r0, #0 msr basepri, r0 - bx r14 + bx lr /*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM4F_MPU/portmacro.h b/portable/IAR/ARM_CM4F_MPU/portmacro.h index 96787e7c31f..4bb8abcdecb 100644 --- a/portable/IAR/ARM_CM4F_MPU/portmacro.h +++ b/portable/IAR/ARM_CM4F_MPU/portmacro.h @@ -195,9 +195,45 @@ typedef struct MPU_REGION_REGISTERS uint32_t ulRegionAttribute; } xMPU_REGION_REGISTERS; +typedef struct MPU_REGION_SETTINGS +{ + uint32_t ulRegionStartAddress; + uint32_t ulRegionEndAddress; + uint32_t ulRegionPermissions; +} xMPU_REGION_SETTINGS; + +#if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + + #ifndef configSYSTEM_CALL_STACK_SIZE + #error configSYSTEM_CALL_STACK_SIZE must be defined to the desired size of the system call stack in words for using MPU wrappers v2. + #endif + + typedef struct SYSTEM_CALL_STACK_INFO + { + uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ]; + uint32_t * pulSystemCallStack; + uint32_t * pulTaskStack; + uint32_t ulLinkRegisterAtSystemCallEntry; + } xSYSTEM_CALL_STACK_INFO; + +#endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + +#define MAX_CONTEXT_SIZE 52 + +/* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ +#define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) +#define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) + typedef struct MPU_SETTINGS { xMPU_REGION_REGISTERS xRegion[ portTOTAL_NUM_REGIONS_IN_TCB ]; + xMPU_REGION_SETTINGS xRegionSettings[ portTOTAL_NUM_REGIONS_IN_TCB ]; + uint32_t ulContext[ MAX_CONTEXT_SIZE ]; + uint32_t ulTaskFlags; + + #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo; + #endif } xMPU_SETTINGS; /* Architecture specifics. */ @@ -207,9 +243,12 @@ typedef struct MPU_SETTINGS /*-----------------------------------------------------------*/ /* SVC numbers for various services. */ -#define portSVC_START_SCHEDULER 0 -#define portSVC_YIELD 1 -#define portSVC_RAISE_PRIVILEGE 2 +#define portSVC_START_SCHEDULER 0 +#define portSVC_YIELD 1 +#define portSVC_RAISE_PRIVILEGE 2 +#define portSVC_SYSTEM_CALL_ENTER 3 /* System calls with upto 4 parameters. */ +#define portSVC_SYSTEM_CALL_ENTER_1 4 /* System calls with 5 parameters. */ +#define portSVC_SYSTEM_CALL_EXIT 5 /* Scheduler utilities. */ @@ -348,6 +387,16 @@ extern void vResetPrivilege( void ); #define portRESET_PRIVILEGE() vResetPrivilege() /*-----------------------------------------------------------*/ +extern BaseType_t xPortIsTaskPrivileged( void ); + +/** + * @brief Checks whether or not the calling task is privileged. + * + * @return pdTRUE if the calling task is privileged, pdFALSE otherwise. + */ +#define portIS_TASK_PRIVILEGED() xPortIsTaskPrivileged() +/*-----------------------------------------------------------*/ + #ifndef configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY #warning "configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY is not defined. We recommend defining it to 1 in FreeRTOSConfig.h for better security. https://www.FreeRTOS.org/FreeRTOS-V10.3.x.html" #define configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY 0 diff --git a/portable/IAR/ARM_CM55/non_secure/mpu_wrappers_v2_asm.S b/portable/IAR/ARM_CM55/non_secure/mpu_wrappers_v2_asm.S new file mode 100644 index 00000000000..f051a6073dd --- /dev/null +++ b/portable/IAR/ARM_CM55/non_secure/mpu_wrappers_v2_asm.S @@ -0,0 +1,1552 @@ +/* + * FreeRTOS Kernel + * Copyright (C) 2021 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 + * + */ + + + SECTION freertos_system_calls:CODE:NOROOT(2) + THUMB +/*-----------------------------------------------------------*/ + +#include "FreeRTOSConfig.h" + +#ifndef configUSE_MPU_WRAPPERS_V1 + #define configUSE_MPU_WRAPPERS_V1 0 +#endif + +/* These must be in sync with portmacro.h. */ +#define portSVC_SYSTEM_CALL_ENTER 4 /* System calls with upto 4 parameters. */ +#define portSVC_SYSTEM_CALL_ENTER_1 5 /* System calls with 5 parameters. */ +#define portSVC_SYSTEM_CALL_EXIT 6 +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + + PUBLIC MPU_xTaskDelayUntil +MPU_xTaskDelayUntil: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskDelayUntil_Unpriv + MPU_xTaskDelayUntil_Priv: + pop {r0} + b MPU_xTaskDelayUntilImpl + MPU_xTaskDelayUntil_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskDelayUntilImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskAbortDelay +MPU_xTaskAbortDelay: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskAbortDelay_Unpriv + MPU_xTaskAbortDelay_Priv: + pop {r0} + b MPU_xTaskAbortDelayImpl + MPU_xTaskAbortDelay_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskAbortDelayImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTaskDelay +MPU_vTaskDelay: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vTaskDelay_Unpriv + MPU_vTaskDelay_Priv: + pop {r0} + b MPU_vTaskDelayImpl + MPU_vTaskDelay_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskDelayImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxTaskPriorityGet +MPU_uxTaskPriorityGet: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_uxTaskPriorityGet_Unpriv + MPU_uxTaskPriorityGet_Priv: + pop {r0} + b MPU_uxTaskPriorityGetImpl + MPU_uxTaskPriorityGet_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxTaskPriorityGetImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_eTaskGetState +MPU_eTaskGetState: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_eTaskGetState_Unpriv + MPU_eTaskGetState_Priv: + pop {r0} + b MPU_eTaskGetStateImpl + MPU_eTaskGetState_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_eTaskGetStateImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTaskGetInfo +MPU_vTaskGetInfo: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vTaskGetInfo_Unpriv + MPU_vTaskGetInfo_Priv: + pop {r0} + b MPU_vTaskGetInfoImpl + MPU_vTaskGetInfo_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskGetInfoImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGetIdleTaskHandle +MPU_xTaskGetIdleTaskHandle: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskGetIdleTaskHandle_Unpriv + MPU_xTaskGetIdleTaskHandle_Priv: + pop {r0} + b MPU_xTaskGetIdleTaskHandleImpl + MPU_xTaskGetIdleTaskHandle_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskGetIdleTaskHandleImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTaskSuspend +MPU_vTaskSuspend: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vTaskSuspend_Unpriv + MPU_vTaskSuspend_Priv: + pop {r0} + b MPU_vTaskSuspendImpl + MPU_vTaskSuspend_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskSuspendImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTaskResume +MPU_vTaskResume: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vTaskResume_Unpriv + MPU_vTaskResume_Priv: + pop {r0} + b MPU_vTaskResumeImpl + MPU_vTaskResume_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskResumeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGetTickCount +MPU_xTaskGetTickCount: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskGetTickCount_Unpriv + MPU_xTaskGetTickCount_Priv: + pop {r0} + b MPU_xTaskGetTickCountImpl + MPU_xTaskGetTickCount_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskGetTickCountImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxTaskGetNumberOfTasks +MPU_uxTaskGetNumberOfTasks: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_uxTaskGetNumberOfTasks_Unpriv + MPU_uxTaskGetNumberOfTasks_Priv: + pop {r0} + b MPU_uxTaskGetNumberOfTasksImpl + MPU_uxTaskGetNumberOfTasks_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxTaskGetNumberOfTasksImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_pcTaskGetName +MPU_pcTaskGetName: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_pcTaskGetName_Unpriv + MPU_pcTaskGetName_Priv: + pop {r0} + b MPU_pcTaskGetNameImpl + MPU_pcTaskGetName_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_pcTaskGetNameImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_ulTaskGetRunTimeCounter +MPU_ulTaskGetRunTimeCounter: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_ulTaskGetRunTimeCounter_Unpriv + MPU_ulTaskGetRunTimeCounter_Priv: + pop {r0} + b MPU_ulTaskGetRunTimeCounterImpl + MPU_ulTaskGetRunTimeCounter_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_ulTaskGetRunTimeCounterImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_ulTaskGetRunTimePercent +MPU_ulTaskGetRunTimePercent: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_ulTaskGetRunTimePercent_Unpriv + MPU_ulTaskGetRunTimePercent_Priv: + pop {r0} + b MPU_ulTaskGetRunTimePercentImpl + MPU_ulTaskGetRunTimePercent_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_ulTaskGetRunTimePercentImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_ulTaskGetIdleRunTimePercent +MPU_ulTaskGetIdleRunTimePercent: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_ulTaskGetIdleRunTimePercent_Unpriv + MPU_ulTaskGetIdleRunTimePercent_Priv: + pop {r0} + b MPU_ulTaskGetIdleRunTimePercentImpl + MPU_ulTaskGetIdleRunTimePercent_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_ulTaskGetIdleRunTimePercentImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_ulTaskGetIdleRunTimeCounter +MPU_ulTaskGetIdleRunTimeCounter: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_ulTaskGetIdleRunTimeCounter_Unpriv + MPU_ulTaskGetIdleRunTimeCounter_Priv: + pop {r0} + b MPU_ulTaskGetIdleRunTimeCounterImpl + MPU_ulTaskGetIdleRunTimeCounter_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_ulTaskGetIdleRunTimeCounterImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTaskSetApplicationTaskTag +MPU_vTaskSetApplicationTaskTag: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vTaskSetApplicationTaskTag_Unpriv + MPU_vTaskSetApplicationTaskTag_Priv: + pop {r0} + b MPU_vTaskSetApplicationTaskTagImpl + MPU_vTaskSetApplicationTaskTag_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskSetApplicationTaskTagImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGetApplicationTaskTag +MPU_xTaskGetApplicationTaskTag: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskGetApplicationTaskTag_Unpriv + MPU_xTaskGetApplicationTaskTag_Priv: + pop {r0} + b MPU_xTaskGetApplicationTaskTagImpl + MPU_xTaskGetApplicationTaskTag_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskGetApplicationTaskTagImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTaskSetThreadLocalStoragePointer +MPU_vTaskSetThreadLocalStoragePointer: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vTaskSetThreadLocalStoragePointer_Unpriv + MPU_vTaskSetThreadLocalStoragePointer_Priv: + pop {r0} + b MPU_vTaskSetThreadLocalStoragePointerImpl + MPU_vTaskSetThreadLocalStoragePointer_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskSetThreadLocalStoragePointerImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_pvTaskGetThreadLocalStoragePointer +MPU_pvTaskGetThreadLocalStoragePointer: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_pvTaskGetThreadLocalStoragePointer_Unpriv + MPU_pvTaskGetThreadLocalStoragePointer_Priv: + pop {r0} + b MPU_pvTaskGetThreadLocalStoragePointerImpl + MPU_pvTaskGetThreadLocalStoragePointer_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_pvTaskGetThreadLocalStoragePointerImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxTaskGetSystemState +MPU_uxTaskGetSystemState: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_uxTaskGetSystemState_Unpriv + MPU_uxTaskGetSystemState_Priv: + pop {r0} + b MPU_uxTaskGetSystemStateImpl + MPU_uxTaskGetSystemState_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxTaskGetSystemStateImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxTaskGetStackHighWaterMark +MPU_uxTaskGetStackHighWaterMark: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_uxTaskGetStackHighWaterMark_Unpriv + MPU_uxTaskGetStackHighWaterMark_Priv: + pop {r0} + b MPU_uxTaskGetStackHighWaterMarkImpl + MPU_uxTaskGetStackHighWaterMark_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxTaskGetStackHighWaterMarkImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxTaskGetStackHighWaterMark2 +MPU_uxTaskGetStackHighWaterMark2: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_uxTaskGetStackHighWaterMark2_Unpriv + MPU_uxTaskGetStackHighWaterMark2_Priv: + pop {r0} + b MPU_uxTaskGetStackHighWaterMark2Impl + MPU_uxTaskGetStackHighWaterMark2_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxTaskGetStackHighWaterMark2Impl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGetCurrentTaskHandle +MPU_xTaskGetCurrentTaskHandle: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskGetCurrentTaskHandle_Unpriv + MPU_xTaskGetCurrentTaskHandle_Priv: + pop {r0} + b MPU_xTaskGetCurrentTaskHandleImpl + MPU_xTaskGetCurrentTaskHandle_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskGetCurrentTaskHandleImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGetSchedulerState +MPU_xTaskGetSchedulerState: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskGetSchedulerState_Unpriv + MPU_xTaskGetSchedulerState_Priv: + pop {r0} + b MPU_xTaskGetSchedulerStateImpl + MPU_xTaskGetSchedulerState_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskGetSchedulerStateImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTaskSetTimeOutState +MPU_vTaskSetTimeOutState: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vTaskSetTimeOutState_Unpriv + MPU_vTaskSetTimeOutState_Priv: + pop {r0} + b MPU_vTaskSetTimeOutStateImpl + MPU_vTaskSetTimeOutState_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskSetTimeOutStateImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskCheckForTimeOut +MPU_xTaskCheckForTimeOut: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskCheckForTimeOut_Unpriv + MPU_xTaskCheckForTimeOut_Priv: + pop {r0} + b MPU_xTaskCheckForTimeOutImpl + MPU_xTaskCheckForTimeOut_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskCheckForTimeOutImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGenericNotify +MPU_xTaskGenericNotify: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskGenericNotify_Unpriv + MPU_xTaskGenericNotify_Priv: + pop {r0} + b MPU_xTaskGenericNotifyImpl + MPU_xTaskGenericNotify_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER_1 + bl MPU_xTaskGenericNotifyImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGenericNotifyWait +MPU_xTaskGenericNotifyWait: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskGenericNotifyWait_Unpriv + MPU_xTaskGenericNotifyWait_Priv: + pop {r0} + b MPU_xTaskGenericNotifyWaitImpl + MPU_xTaskGenericNotifyWait_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER_1 + bl MPU_xTaskGenericNotifyWaitImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_ulTaskGenericNotifyTake +MPU_ulTaskGenericNotifyTake: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_ulTaskGenericNotifyTake_Unpriv + MPU_ulTaskGenericNotifyTake_Priv: + pop {r0} + b MPU_ulTaskGenericNotifyTakeImpl + MPU_ulTaskGenericNotifyTake_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_ulTaskGenericNotifyTakeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGenericNotifyStateClear +MPU_xTaskGenericNotifyStateClear: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskGenericNotifyStateClear_Unpriv + MPU_xTaskGenericNotifyStateClear_Priv: + pop {r0} + b MPU_xTaskGenericNotifyStateClearImpl + MPU_xTaskGenericNotifyStateClear_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskGenericNotifyStateClearImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_ulTaskGenericNotifyValueClear +MPU_ulTaskGenericNotifyValueClear: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_ulTaskGenericNotifyValueClear_Unpriv + MPU_ulTaskGenericNotifyValueClear_Priv: + pop {r0} + b MPU_ulTaskGenericNotifyValueClearImpl + MPU_ulTaskGenericNotifyValueClear_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_ulTaskGenericNotifyValueClearImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueGenericSend +MPU_xQueueGenericSend: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xQueueGenericSend_Unpriv + MPU_xQueueGenericSend_Priv: + pop {r0} + b MPU_xQueueGenericSendImpl + MPU_xQueueGenericSend_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueGenericSendImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxQueueMessagesWaiting +MPU_uxQueueMessagesWaiting: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_uxQueueMessagesWaiting_Unpriv + MPU_uxQueueMessagesWaiting_Priv: + pop {r0} + b MPU_uxQueueMessagesWaitingImpl + MPU_uxQueueMessagesWaiting_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxQueueMessagesWaitingImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxQueueSpacesAvailable +MPU_uxQueueSpacesAvailable: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_uxQueueSpacesAvailable_Unpriv + MPU_uxQueueSpacesAvailable_Priv: + pop {r0} + b MPU_uxQueueSpacesAvailableImpl + MPU_uxQueueSpacesAvailable_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxQueueSpacesAvailableImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueReceive +MPU_xQueueReceive: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xQueueReceive_Unpriv + MPU_xQueueReceive_Priv: + pop {r0} + b MPU_xQueueReceiveImpl + MPU_xQueueReceive_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueReceiveImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueuePeek +MPU_xQueuePeek: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xQueuePeek_Unpriv + MPU_xQueuePeek_Priv: + pop {r0} + b MPU_xQueuePeekImpl + MPU_xQueuePeek_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueuePeekImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueSemaphoreTake +MPU_xQueueSemaphoreTake: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xQueueSemaphoreTake_Unpriv + MPU_xQueueSemaphoreTake_Priv: + pop {r0} + b MPU_xQueueSemaphoreTakeImpl + MPU_xQueueSemaphoreTake_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueSemaphoreTakeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueGetMutexHolder +MPU_xQueueGetMutexHolder: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xQueueGetMutexHolder_Unpriv + MPU_xQueueGetMutexHolder_Priv: + pop {r0} + b MPU_xQueueGetMutexHolderImpl + MPU_xQueueGetMutexHolder_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueGetMutexHolderImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueTakeMutexRecursive +MPU_xQueueTakeMutexRecursive: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xQueueTakeMutexRecursive_Unpriv + MPU_xQueueTakeMutexRecursive_Priv: + pop {r0} + b MPU_xQueueTakeMutexRecursiveImpl + MPU_xQueueTakeMutexRecursive_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueTakeMutexRecursiveImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueGiveMutexRecursive +MPU_xQueueGiveMutexRecursive: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xQueueGiveMutexRecursive_Unpriv + MPU_xQueueGiveMutexRecursive_Priv: + pop {r0} + b MPU_xQueueGiveMutexRecursiveImpl + MPU_xQueueGiveMutexRecursive_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueGiveMutexRecursiveImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueSelectFromSet +MPU_xQueueSelectFromSet: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xQueueSelectFromSet_Unpriv + MPU_xQueueSelectFromSet_Priv: + pop {r0} + b MPU_xQueueSelectFromSetImpl + MPU_xQueueSelectFromSet_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueSelectFromSetImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueAddToSet +MPU_xQueueAddToSet: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xQueueAddToSet_Unpriv + MPU_xQueueAddToSet_Priv: + pop {r0} + b MPU_xQueueAddToSetImpl + MPU_xQueueAddToSet_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueAddToSetImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vQueueAddToRegistry +MPU_vQueueAddToRegistry: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vQueueAddToRegistry_Unpriv + MPU_vQueueAddToRegistry_Priv: + pop {r0} + b MPU_vQueueAddToRegistryImpl + MPU_vQueueAddToRegistry_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vQueueAddToRegistryImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vQueueUnregisterQueue +MPU_vQueueUnregisterQueue: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vQueueUnregisterQueue_Unpriv + MPU_vQueueUnregisterQueue_Priv: + pop {r0} + b MPU_vQueueUnregisterQueueImpl + MPU_vQueueUnregisterQueue_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vQueueUnregisterQueueImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_pcQueueGetName +MPU_pcQueueGetName: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_pcQueueGetName_Unpriv + MPU_pcQueueGetName_Priv: + pop {r0} + b MPU_pcQueueGetNameImpl + MPU_pcQueueGetName_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_pcQueueGetNameImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_pvTimerGetTimerID +MPU_pvTimerGetTimerID: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_pvTimerGetTimerID_Unpriv + MPU_pvTimerGetTimerID_Priv: + pop {r0} + b MPU_pvTimerGetTimerIDImpl + MPU_pvTimerGetTimerID_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_pvTimerGetTimerIDImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTimerSetTimerID +MPU_vTimerSetTimerID: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vTimerSetTimerID_Unpriv + MPU_vTimerSetTimerID_Priv: + pop {r0} + b MPU_vTimerSetTimerIDImpl + MPU_vTimerSetTimerID_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTimerSetTimerIDImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTimerIsTimerActive +MPU_xTimerIsTimerActive: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTimerIsTimerActive_Unpriv + MPU_xTimerIsTimerActive_Priv: + pop {r0} + b MPU_xTimerIsTimerActiveImpl + MPU_xTimerIsTimerActive_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTimerIsTimerActiveImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTimerGetTimerDaemonTaskHandle +MPU_xTimerGetTimerDaemonTaskHandle: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTimerGetTimerDaemonTaskHandle_Unpriv + MPU_xTimerGetTimerDaemonTaskHandle_Priv: + pop {r0} + b MPU_xTimerGetTimerDaemonTaskHandleImpl + MPU_xTimerGetTimerDaemonTaskHandle_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTimerGetTimerDaemonTaskHandleImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTimerGenericCommand +MPU_xTimerGenericCommand: + push {r0} + /* This function can be called from ISR also and therefore, we need a check + * to take privileged path, if called from ISR. */ + mrs r0, ipsr + cmp r0, #0 + bne MPU_xTimerGenericCommand_Priv + mrs r0, control + tst r0, #1 + beq MPU_xTimerGenericCommand_Priv + MPU_xTimerGenericCommand_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER_1 + bl MPU_xTimerGenericCommandImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr + MPU_xTimerGenericCommand_Priv: + pop {r0} + b MPU_xTimerGenericCommandImpl + +/*-----------------------------------------------------------*/ + + PUBLIC MPU_pcTimerGetName +MPU_pcTimerGetName: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_pcTimerGetName_Unpriv + MPU_pcTimerGetName_Priv: + pop {r0} + b MPU_pcTimerGetNameImpl + MPU_pcTimerGetName_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_pcTimerGetNameImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTimerSetReloadMode +MPU_vTimerSetReloadMode: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vTimerSetReloadMode_Unpriv + MPU_vTimerSetReloadMode_Priv: + pop {r0} + b MPU_vTimerSetReloadModeImpl + MPU_vTimerSetReloadMode_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTimerSetReloadModeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTimerGetReloadMode +MPU_xTimerGetReloadMode: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTimerGetReloadMode_Unpriv + MPU_xTimerGetReloadMode_Priv: + pop {r0} + b MPU_xTimerGetReloadModeImpl + MPU_xTimerGetReloadMode_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTimerGetReloadModeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxTimerGetReloadMode +MPU_uxTimerGetReloadMode: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_uxTimerGetReloadMode_Unpriv + MPU_uxTimerGetReloadMode_Priv: + pop {r0} + b MPU_uxTimerGetReloadModeImpl + MPU_uxTimerGetReloadMode_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxTimerGetReloadModeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTimerGetPeriod +MPU_xTimerGetPeriod: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTimerGetPeriod_Unpriv + MPU_xTimerGetPeriod_Priv: + pop {r0} + b MPU_xTimerGetPeriodImpl + MPU_xTimerGetPeriod_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTimerGetPeriodImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTimerGetExpiryTime +MPU_xTimerGetExpiryTime: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTimerGetExpiryTime_Unpriv + MPU_xTimerGetExpiryTime_Priv: + pop {r0} + b MPU_xTimerGetExpiryTimeImpl + MPU_xTimerGetExpiryTime_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTimerGetExpiryTimeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xEventGroupWaitBits +MPU_xEventGroupWaitBits: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xEventGroupWaitBits_Unpriv + MPU_xEventGroupWaitBits_Priv: + pop {r0} + b MPU_xEventGroupWaitBitsImpl + MPU_xEventGroupWaitBits_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER_1 + bl MPU_xEventGroupWaitBitsImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xEventGroupClearBits +MPU_xEventGroupClearBits: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xEventGroupClearBits_Unpriv + MPU_xEventGroupClearBits_Priv: + pop {r0} + b MPU_xEventGroupClearBitsImpl + MPU_xEventGroupClearBits_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xEventGroupClearBitsImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xEventGroupSetBits +MPU_xEventGroupSetBits: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xEventGroupSetBits_Unpriv + MPU_xEventGroupSetBits_Priv: + pop {r0} + b MPU_xEventGroupSetBitsImpl + MPU_xEventGroupSetBits_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xEventGroupSetBitsImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xEventGroupSync +MPU_xEventGroupSync: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xEventGroupSync_Unpriv + MPU_xEventGroupSync_Priv: + pop {r0} + b MPU_xEventGroupSyncImpl + MPU_xEventGroupSync_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xEventGroupSyncImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxEventGroupGetNumber +MPU_uxEventGroupGetNumber: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_uxEventGroupGetNumber_Unpriv + MPU_uxEventGroupGetNumber_Priv: + pop {r0} + b MPU_uxEventGroupGetNumberImpl + MPU_uxEventGroupGetNumber_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxEventGroupGetNumberImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vEventGroupSetNumber +MPU_vEventGroupSetNumber: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vEventGroupSetNumber_Unpriv + MPU_vEventGroupSetNumber_Priv: + pop {r0} + b MPU_vEventGroupSetNumberImpl + MPU_vEventGroupSetNumber_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vEventGroupSetNumberImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferSend +MPU_xStreamBufferSend: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xStreamBufferSend_Unpriv + MPU_xStreamBufferSend_Priv: + pop {r0} + b MPU_xStreamBufferSendImpl + MPU_xStreamBufferSend_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferSendImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferReceive +MPU_xStreamBufferReceive: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xStreamBufferReceive_Unpriv + MPU_xStreamBufferReceive_Priv: + pop {r0} + b MPU_xStreamBufferReceiveImpl + MPU_xStreamBufferReceive_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferReceiveImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferIsFull +MPU_xStreamBufferIsFull: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xStreamBufferIsFull_Unpriv + MPU_xStreamBufferIsFull_Priv: + pop {r0} + b MPU_xStreamBufferIsFullImpl + MPU_xStreamBufferIsFull_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferIsFullImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferIsEmpty +MPU_xStreamBufferIsEmpty: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xStreamBufferIsEmpty_Unpriv + MPU_xStreamBufferIsEmpty_Priv: + pop {r0} + b MPU_xStreamBufferIsEmptyImpl + MPU_xStreamBufferIsEmpty_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferIsEmptyImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferSpacesAvailable +MPU_xStreamBufferSpacesAvailable: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xStreamBufferSpacesAvailable_Unpriv + MPU_xStreamBufferSpacesAvailable_Priv: + pop {r0} + b MPU_xStreamBufferSpacesAvailableImpl + MPU_xStreamBufferSpacesAvailable_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferSpacesAvailableImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferBytesAvailable +MPU_xStreamBufferBytesAvailable: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xStreamBufferBytesAvailable_Unpriv + MPU_xStreamBufferBytesAvailable_Priv: + pop {r0} + b MPU_xStreamBufferBytesAvailableImpl + MPU_xStreamBufferBytesAvailable_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferBytesAvailableImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferSetTriggerLevel +MPU_xStreamBufferSetTriggerLevel: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xStreamBufferSetTriggerLevel_Unpriv + MPU_xStreamBufferSetTriggerLevel_Priv: + pop {r0} + b MPU_xStreamBufferSetTriggerLevelImpl + MPU_xStreamBufferSetTriggerLevel_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferSetTriggerLevelImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferNextMessageLengthBytes +MPU_xStreamBufferNextMessageLengthBytes: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xStreamBufferNextMessageLengthBytes_Unpriv + MPU_xStreamBufferNextMessageLengthBytes_Priv: + pop {r0} + b MPU_xStreamBufferNextMessageLengthBytesImpl + MPU_xStreamBufferNextMessageLengthBytes_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferNextMessageLengthBytesImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + +/* Default weak implementations in case one is not available from + * mpu_wrappers because of config options. */ + + PUBWEAK MPU_xTaskDelayUntilImpl +MPU_xTaskDelayUntilImpl: + b MPU_xTaskDelayUntilImpl + + PUBWEAK MPU_xTaskAbortDelayImpl +MPU_xTaskAbortDelayImpl: + b MPU_xTaskAbortDelayImpl + + PUBWEAK MPU_vTaskDelayImpl +MPU_vTaskDelayImpl: + b MPU_vTaskDelayImpl + + PUBWEAK MPU_uxTaskPriorityGetImpl +MPU_uxTaskPriorityGetImpl: + b MPU_uxTaskPriorityGetImpl + + PUBWEAK MPU_eTaskGetStateImpl +MPU_eTaskGetStateImpl: + b MPU_eTaskGetStateImpl + + PUBWEAK MPU_vTaskGetInfoImpl +MPU_vTaskGetInfoImpl: + b MPU_vTaskGetInfoImpl + + PUBWEAK MPU_xTaskGetIdleTaskHandleImpl +MPU_xTaskGetIdleTaskHandleImpl: + b MPU_xTaskGetIdleTaskHandleImpl + + PUBWEAK MPU_vTaskSuspendImpl +MPU_vTaskSuspendImpl: + b MPU_vTaskSuspendImpl + + PUBWEAK MPU_vTaskResumeImpl +MPU_vTaskResumeImpl: + b MPU_vTaskResumeImpl + + PUBWEAK MPU_xTaskGetTickCountImpl +MPU_xTaskGetTickCountImpl: + b MPU_xTaskGetTickCountImpl + + PUBWEAK MPU_uxTaskGetNumberOfTasksImpl +MPU_uxTaskGetNumberOfTasksImpl: + b MPU_uxTaskGetNumberOfTasksImpl + + PUBWEAK MPU_pcTaskGetNameImpl +MPU_pcTaskGetNameImpl: + b MPU_pcTaskGetNameImpl + + PUBWEAK MPU_ulTaskGetRunTimeCounterImpl +MPU_ulTaskGetRunTimeCounterImpl: + b MPU_ulTaskGetRunTimeCounterImpl + + PUBWEAK MPU_ulTaskGetRunTimePercentImpl +MPU_ulTaskGetRunTimePercentImpl: + b MPU_ulTaskGetRunTimePercentImpl + + PUBWEAK MPU_ulTaskGetIdleRunTimePercentImpl +MPU_ulTaskGetIdleRunTimePercentImpl: + b MPU_ulTaskGetIdleRunTimePercentImpl + + PUBWEAK MPU_ulTaskGetIdleRunTimeCounterImpl +MPU_ulTaskGetIdleRunTimeCounterImpl: + b MPU_ulTaskGetIdleRunTimeCounterImpl + + PUBWEAK MPU_vTaskSetApplicationTaskTagImpl +MPU_vTaskSetApplicationTaskTagImpl: + b MPU_vTaskSetApplicationTaskTagImpl + + PUBWEAK MPU_xTaskGetApplicationTaskTagImpl +MPU_xTaskGetApplicationTaskTagImpl: + b MPU_xTaskGetApplicationTaskTagImpl + + PUBWEAK MPU_vTaskSetThreadLocalStoragePointerImpl +MPU_vTaskSetThreadLocalStoragePointerImpl: + b MPU_vTaskSetThreadLocalStoragePointerImpl + + PUBWEAK MPU_pvTaskGetThreadLocalStoragePointerImpl +MPU_pvTaskGetThreadLocalStoragePointerImpl: + b MPU_pvTaskGetThreadLocalStoragePointerImpl + + PUBWEAK MPU_uxTaskGetSystemStateImpl +MPU_uxTaskGetSystemStateImpl: + b MPU_uxTaskGetSystemStateImpl + + PUBWEAK MPU_uxTaskGetStackHighWaterMarkImpl +MPU_uxTaskGetStackHighWaterMarkImpl: + b MPU_uxTaskGetStackHighWaterMarkImpl + + PUBWEAK MPU_uxTaskGetStackHighWaterMark2Impl +MPU_uxTaskGetStackHighWaterMark2Impl: + b MPU_uxTaskGetStackHighWaterMark2Impl + + PUBWEAK MPU_xTaskGetCurrentTaskHandleImpl +MPU_xTaskGetCurrentTaskHandleImpl: + b MPU_xTaskGetCurrentTaskHandleImpl + + PUBWEAK MPU_xTaskGetSchedulerStateImpl +MPU_xTaskGetSchedulerStateImpl: + b MPU_xTaskGetSchedulerStateImpl + + PUBWEAK MPU_vTaskSetTimeOutStateImpl +MPU_vTaskSetTimeOutStateImpl: + b MPU_vTaskSetTimeOutStateImpl + + PUBWEAK MPU_xTaskCheckForTimeOutImpl +MPU_xTaskCheckForTimeOutImpl: + b MPU_xTaskCheckForTimeOutImpl + + PUBWEAK MPU_xTaskGenericNotifyImpl +MPU_xTaskGenericNotifyImpl: + b MPU_xTaskGenericNotifyImpl + + PUBWEAK MPU_xTaskGenericNotifyWaitImpl +MPU_xTaskGenericNotifyWaitImpl: + b MPU_xTaskGenericNotifyWaitImpl + + PUBWEAK MPU_ulTaskGenericNotifyTakeImpl +MPU_ulTaskGenericNotifyTakeImpl: + b MPU_ulTaskGenericNotifyTakeImpl + + PUBWEAK MPU_xTaskGenericNotifyStateClearImpl +MPU_xTaskGenericNotifyStateClearImpl: + b MPU_xTaskGenericNotifyStateClearImpl + + PUBWEAK MPU_ulTaskGenericNotifyValueClearImpl +MPU_ulTaskGenericNotifyValueClearImpl: + b MPU_ulTaskGenericNotifyValueClearImpl + + PUBWEAK MPU_xQueueGenericSendImpl +MPU_xQueueGenericSendImpl: + b MPU_xQueueGenericSendImpl + + PUBWEAK MPU_uxQueueMessagesWaitingImpl +MPU_uxQueueMessagesWaitingImpl: + b MPU_uxQueueMessagesWaitingImpl + + PUBWEAK MPU_uxQueueSpacesAvailableImpl +MPU_uxQueueSpacesAvailableImpl: + b MPU_uxQueueSpacesAvailableImpl + + PUBWEAK MPU_xQueueReceiveImpl +MPU_xQueueReceiveImpl: + b MPU_xQueueReceiveImpl + + PUBWEAK MPU_xQueuePeekImpl +MPU_xQueuePeekImpl: + b MPU_xQueuePeekImpl + + PUBWEAK MPU_xQueueSemaphoreTakeImpl +MPU_xQueueSemaphoreTakeImpl: + b MPU_xQueueSemaphoreTakeImpl + + PUBWEAK MPU_xQueueGetMutexHolderImpl +MPU_xQueueGetMutexHolderImpl: + b MPU_xQueueGetMutexHolderImpl + + PUBWEAK MPU_xQueueTakeMutexRecursiveImpl +MPU_xQueueTakeMutexRecursiveImpl: + b MPU_xQueueTakeMutexRecursiveImpl + + PUBWEAK MPU_xQueueGiveMutexRecursiveImpl +MPU_xQueueGiveMutexRecursiveImpl: + b MPU_xQueueGiveMutexRecursiveImpl + + PUBWEAK MPU_xQueueSelectFromSetImpl +MPU_xQueueSelectFromSetImpl: + b MPU_xQueueSelectFromSetImpl + + PUBWEAK MPU_xQueueAddToSetImpl +MPU_xQueueAddToSetImpl: + b MPU_xQueueAddToSetImpl + + PUBWEAK MPU_vQueueAddToRegistryImpl +MPU_vQueueAddToRegistryImpl: + b MPU_vQueueAddToRegistryImpl + + PUBWEAK MPU_vQueueUnregisterQueueImpl +MPU_vQueueUnregisterQueueImpl: + b MPU_vQueueUnregisterQueueImpl + + PUBWEAK MPU_pcQueueGetNameImpl +MPU_pcQueueGetNameImpl: + b MPU_pcQueueGetNameImpl + + PUBWEAK MPU_pvTimerGetTimerIDImpl +MPU_pvTimerGetTimerIDImpl: + b MPU_pvTimerGetTimerIDImpl + + PUBWEAK MPU_vTimerSetTimerIDImpl +MPU_vTimerSetTimerIDImpl: + b MPU_vTimerSetTimerIDImpl + + PUBWEAK MPU_xTimerIsTimerActiveImpl +MPU_xTimerIsTimerActiveImpl: + b MPU_xTimerIsTimerActiveImpl + + PUBWEAK MPU_xTimerGetTimerDaemonTaskHandleImpl +MPU_xTimerGetTimerDaemonTaskHandleImpl: + b MPU_xTimerGetTimerDaemonTaskHandleImpl + + PUBWEAK MPU_xTimerGenericCommandImpl +MPU_xTimerGenericCommandImpl: + b MPU_xTimerGenericCommandImpl + + PUBWEAK MPU_pcTimerGetNameImpl +MPU_pcTimerGetNameImpl: + b MPU_pcTimerGetNameImpl + + PUBWEAK MPU_vTimerSetReloadModeImpl +MPU_vTimerSetReloadModeImpl: + b MPU_vTimerSetReloadModeImpl + + PUBWEAK MPU_xTimerGetReloadModeImpl +MPU_xTimerGetReloadModeImpl: + b MPU_xTimerGetReloadModeImpl + + PUBWEAK MPU_uxTimerGetReloadModeImpl +MPU_uxTimerGetReloadModeImpl: + b MPU_uxTimerGetReloadModeImpl + + PUBWEAK MPU_xTimerGetPeriodImpl +MPU_xTimerGetPeriodImpl: + b MPU_xTimerGetPeriodImpl + + PUBWEAK MPU_xTimerGetExpiryTimeImpl +MPU_xTimerGetExpiryTimeImpl: + b MPU_xTimerGetExpiryTimeImpl + + PUBWEAK MPU_xEventGroupWaitBitsImpl +MPU_xEventGroupWaitBitsImpl: + b MPU_xEventGroupWaitBitsImpl + + PUBWEAK MPU_xEventGroupClearBitsImpl +MPU_xEventGroupClearBitsImpl: + b MPU_xEventGroupClearBitsImpl + + PUBWEAK MPU_xEventGroupSetBitsImpl +MPU_xEventGroupSetBitsImpl: + b MPU_xEventGroupSetBitsImpl + + PUBWEAK MPU_xEventGroupSyncImpl +MPU_xEventGroupSyncImpl: + b MPU_xEventGroupSyncImpl + + PUBWEAK MPU_uxEventGroupGetNumberImpl +MPU_uxEventGroupGetNumberImpl: + b MPU_uxEventGroupGetNumberImpl + + PUBWEAK MPU_vEventGroupSetNumberImpl +MPU_vEventGroupSetNumberImpl: + b MPU_vEventGroupSetNumberImpl + + PUBWEAK MPU_xStreamBufferSendImpl +MPU_xStreamBufferSendImpl: + b MPU_xStreamBufferSendImpl + + PUBWEAK MPU_xStreamBufferReceiveImpl +MPU_xStreamBufferReceiveImpl: + b MPU_xStreamBufferReceiveImpl + + PUBWEAK MPU_xStreamBufferIsFullImpl +MPU_xStreamBufferIsFullImpl: + b MPU_xStreamBufferIsFullImpl + + PUBWEAK MPU_xStreamBufferIsEmptyImpl +MPU_xStreamBufferIsEmptyImpl: + b MPU_xStreamBufferIsEmptyImpl + + PUBWEAK MPU_xStreamBufferSpacesAvailableImpl +MPU_xStreamBufferSpacesAvailableImpl: + b MPU_xStreamBufferSpacesAvailableImpl + + PUBWEAK MPU_xStreamBufferBytesAvailableImpl +MPU_xStreamBufferBytesAvailableImpl: + b MPU_xStreamBufferBytesAvailableImpl + + PUBWEAK MPU_xStreamBufferSetTriggerLevelImpl +MPU_xStreamBufferSetTriggerLevelImpl: + b MPU_xStreamBufferSetTriggerLevelImpl + + PUBWEAK MPU_xStreamBufferNextMessageLengthBytesImpl +MPU_xStreamBufferNextMessageLengthBytesImpl: + b MPU_xStreamBufferNextMessageLengthBytesImpl + +/*-----------------------------------------------------------*/ + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + + END diff --git a/portable/IAR/ARM_CM55/non_secure/port.c b/portable/IAR/ARM_CM55/non_secure/port.c index 7bbe1b7bc53..cab1b3668bf 100644 --- a/portable/IAR/ARM_CM55/non_secure/port.c +++ b/portable/IAR/ARM_CM55/non_secure/port.c @@ -107,6 +107,13 @@ #define portPRIGROUP_SHIFT ( 8UL ) /*-----------------------------------------------------------*/ +/** + * @brief Constants used during system call enter and exit. + */ +#define portPSR_STACK_PADDING_MASK ( 1UL << 9UL ) +#define portEXC_RETURN_STACK_FRAME_TYPE_MASK ( 1UL << 4UL ) +/*-----------------------------------------------------------*/ + /** * @brief Constants required to manipulate the FPU. */ @@ -123,6 +130,14 @@ #define portFPCCR_LSPEN_MASK ( 1UL << portFPCCR_LSPEN_POS ) /*-----------------------------------------------------------*/ +/** + * @brief Offsets in the stack to the parameters when inside the SVC handler. + */ +#define portOFFSET_TO_LR ( 5 ) +#define portOFFSET_TO_PC ( 6 ) +#define portOFFSET_TO_PSR ( 7 ) +/*-----------------------------------------------------------*/ + /** * @brief Constants required to manipulate the MPU. */ @@ -148,6 +163,8 @@ #define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ #define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ +#define portMPU_RBAR_ACCESS_PERMISSIONS_MASK ( 3UL << 1UL ) + #define portMPU_MAIR_ATTR0_POS ( 0UL ) #define portMPU_MAIR_ATTR0_MASK ( 0x000000ff ) @@ -191,6 +208,30 @@ /* Expected value of the portMPU_TYPE register. */ #define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) + +/* Extract first address of the MPU region as encoded in the + * RBAR (Region Base Address Register) value. */ +#define portEXTRACT_FIRST_ADDRESS_FROM_RBAR( rbar ) \ + ( ( rbar ) & portMPU_RBAR_ADDRESS_MASK ) + +/* Extract last address of the MPU region as encoded in the + * RLAR (Region Limit Address Register) value. */ +#define portEXTRACT_LAST_ADDRESS_FROM_RLAR( rlar ) \ + ( ( ( rlar ) & portMPU_RLAR_ADDRESS_MASK ) | ~portMPU_RLAR_ADDRESS_MASK ) + +/* Does addr lies within [start, end] address range? */ +#define portIS_ADDRESS_WITHIN_RANGE( addr, start, end ) \ + ( ( ( addr ) >= ( start ) ) && ( ( addr ) <= ( end ) ) ) + +/* Is the access request satisfied by the available permissions? */ +#define portIS_AUTHORIZED( accessRequest, permissions ) \ + ( ( ( permissions ) & ( accessRequest ) ) == accessRequest ) + +/* 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 ) ) ) /*-----------------------------------------------------------*/ /** @@ -311,6 +352,19 @@ static void prvTaskExitError( void ); #if ( configENABLE_MPU == 1 ) +/** + * @brief Extract MPU region's access permissions from the Region Base Address + * Register (RBAR) value. + * + * @param ulRBARValue RBAR value for the MPU region. + * + * @return uint32_t Access permissions. + */ + static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) PRIVILEGED_FUNCTION; +#endif /* configENABLE_MPU */ + +#if ( configENABLE_MPU == 1 ) + /** * @brief Setup the Memory Protection Unit (MPU). */ @@ -365,6 +419,60 @@ void SysTick_Handler( void ) PRIVILEGED_FUNCTION; * @brief C part of SVC handler. */ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIVILEGED_FUNCTION; + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + + /** + * @brief Sets up the system call stack so that upon returning from + * SVC, the system call stack is used. + * + * It is used for the system calls with up to 4 parameters. + * + * @param pulTaskStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + */ + void vSystemCallEnter( uint32_t * pulTaskStack, uint32_t ulLR ) PRIVILEGED_FUNCTION; + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + + /** + * @brief Sets up the system call stack so that upon returning from + * SVC, the system call stack is used. + * + * It is used for the system calls with 5 parameters. + * + * @param pulTaskStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + */ + void vSystemCallEnter_1( uint32_t * pulTaskStack, uint32_t ulLR ) PRIVILEGED_FUNCTION; + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + + /** + * @brief Sets up the task stack so that upon returning from + * SVC, the task stack is used again. + * + * @param pulSystemCallStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + */ + void vSystemCallExit( uint32_t * pulSystemCallStack, uint32_t ulLR ) PRIVILEGED_FUNCTION; + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + +#if ( configENABLE_MPU == 1 ) + + /** + * @brief Checks whether or not the calling task is privileged. + * + * @return pdTRUE if the calling task is privileged, pdFALSE otherwise. + */ + BaseType_t xPortIsTaskPrivileged( void ) PRIVILEGED_FUNCTION; + +#endif /* configENABLE_MPU == 1 */ /*-----------------------------------------------------------*/ /** @@ -681,6 +789,26 @@ static void prvTaskExitError( void ) } /*-----------------------------------------------------------*/ +#if ( configENABLE_MPU == 1 ) + static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) /* PRIVILEGED_FUNCTION */ + { + uint32_t ulAccessPermissions = 0; + + if( ( ulRBARValue & portMPU_RBAR_ACCESS_PERMISSIONS_MASK ) == portMPU_REGION_READ_ONLY ) + { + ulAccessPermissions = tskMPU_READ_PERMISSION; + } + + if( ( ulRBARValue & portMPU_RBAR_ACCESS_PERMISSIONS_MASK ) == portMPU_REGION_READ_WRITE ) + { + ulAccessPermissions = ( tskMPU_READ_PERMISSION | tskMPU_WRITE_PERMISSION ); + } + + return ulAccessPermissions; + } +#endif /* configENABLE_MPU */ +/*-----------------------------------------------------------*/ + #if ( configENABLE_MPU == 1 ) static void prvSetupMPU( void ) /* PRIVILEGED_FUNCTION */ { @@ -853,7 +981,7 @@ void SysTick_Handler( void ) /* PRIVILEGED_FUNCTION */ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTION portDONT_DISCARD */ { - #if ( configENABLE_MPU == 1 ) + #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) ) #if defined( __ARMCC_VERSION ) /* Declaration when these variable are defined in code instead of being @@ -865,7 +993,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO extern uint32_t __syscalls_flash_start__[]; extern uint32_t __syscalls_flash_end__[]; #endif /* defined( __ARMCC_VERSION ) */ - #endif /* configENABLE_MPU */ + #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */ uint32_t ulPC; @@ -880,7 +1008,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO /* Register are stored on the stack in the following order - R0, R1, R2, R3, * R12, LR, PC, xPSR. */ - ulPC = pulCallerStackAddress[ 6 ]; + ulPC = pulCallerStackAddress[ portOFFSET_TO_PC ]; ucSVCNumber = ( ( uint8_t * ) ulPC )[ -2 ]; switch( ucSVCNumber ) @@ -951,18 +1079,18 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO vRestoreContextOfFirstTask(); break; - #if ( configENABLE_MPU == 1 ) - case portSVC_RAISE_PRIVILEGE: + #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) ) + case portSVC_RAISE_PRIVILEGE: - /* Only raise the privilege, if the svc was raised from any of - * the system calls. */ - if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) && - ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ) - { - vRaisePrivilege(); - } - break; - #endif /* configENABLE_MPU */ + /* Only raise the privilege, if the svc was raised from any of + * the system calls. */ + if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ) + { + vRaisePrivilege(); + } + break; + #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */ default: /* Incorrect SVC call. */ @@ -971,51 +1099,455 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } /*-----------------------------------------------------------*/ -/* *INDENT-OFF* */ -#if ( configENABLE_MPU == 1 ) - StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, - StackType_t * pxEndOfStack, - TaskFunction_t pxCode, - void * pvParameters, - BaseType_t xRunPrivileged ) /* PRIVILEGED_FUNCTION */ -#else - StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, - StackType_t * pxEndOfStack, - TaskFunction_t pxCode, - void * pvParameters ) /* PRIVILEGED_FUNCTION */ -#endif /* configENABLE_MPU */ -/* *INDENT-ON* */ +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + +void vSystemCallEnter( uint32_t * pulTaskStack, uint32_t ulLR ) /* PRIVILEGED_FUNCTION */ { - /* Simulate the stack frame as it would be created by a context switch - * interrupt. */ - #if ( portPRELOAD_REGISTERS == 0 ) + extern TaskHandle_t pxCurrentTCB; + xMPU_SETTINGS * pxMpuSettings; + uint32_t * pulSystemCallStack; + uint32_t ulStackFrameSize, ulSystemCallLocation, i; + #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being + * exported from linker scripts. */ + extern uint32_t * __syscalls_flash_start__; + extern uint32_t * __syscalls_flash_end__; + #else + /* Declaration when these variable are exported from linker scripts. */ + extern uint32_t __syscalls_flash_start__[]; + extern uint32_t __syscalls_flash_end__[]; + #endif /* #if defined( __ARMCC_VERSION ) */ + + ulSystemCallLocation = pulTaskStack[ portOFFSET_TO_PC ]; + + /* If the request did not come from the system call section, do nothing. */ + if( ( ulSystemCallLocation >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulSystemCallLocation <= ( uint32_t ) __syscalls_flash_end__ ) ) { - pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ - *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ - pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pxCode; /* PC */ - pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR */ - pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ - *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ - pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */ - *pxTopOfStack = portINITIAL_EXC_RETURN; + pxMpuSettings = xTaskGetMPUSettings( pxCurrentTCB ); + pulSystemCallStack = pxMpuSettings->xSystemCallStackInfo.pulSystemCallStack; - #if ( configENABLE_MPU == 1 ) + /* This is not NULL only for the duration of the system call. */ + configASSERT( pxMpuSettings->xSystemCallStackInfo.pulTaskStack == NULL ); + + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) { - pxTopOfStack--; + if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) + { + /* Extended frame i.e. FPU in use. */ + ulStackFrameSize = 26; + __asm volatile ( + " vpush {s0} \n" /* Trigger lazy stacking. */ + " vpop {s0} \n" /* Nullify the affect of the above instruction. */ + ::: "memory" + ); + } + else + { + /* Standard frame i.e. FPU not in use. */ + ulStackFrameSize = 8; + } + } + #else + { + ulStackFrameSize = 8; + } + #endif /* configENABLE_FPU || configENABLE_MVE */ + + /* Make space on the system call stack for the stack frame. */ + pulSystemCallStack = pulSystemCallStack - ulStackFrameSize; + + /* Copy the stack frame. */ + for( i = 0; i < ulStackFrameSize; i++ ) + { + pulSystemCallStack[ i ] = pulTaskStack[ i ]; + } + + /* Store the value of the LR and PSPLIM registers before the SVC was raised. We need to + * restore it when we exit from the system call. */ + pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; + __asm volatile ( "mrs %0, psplim" : "=r" ( pxMpuSettings->xSystemCallStackInfo.ulStackLimitRegisterAtSystemCallEntry ) ); + + /* Use the pulSystemCallStack in thread mode. */ + __asm volatile ( "msr psp, %0" : : "r" ( pulSystemCallStack ) ); + __asm volatile ( "msr psplim, %0" : : "r" ( pxMpuSettings->xSystemCallStackInfo.pulSystemCallStackLimit ) ); + + /* Remember the location where we should copy the stack frame when we exit from + * the system call. */ + pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulStackFrameSize; + + /* Record if the hardware used padding to force the stack pointer + * to be double word aligned. */ + if( ( pulTaskStack[ portOFFSET_TO_PSR ] & portPSR_STACK_PADDING_MASK ) == portPSR_STACK_PADDING_MASK ) + { + pxMpuSettings->ulTaskFlags |= portSTACK_FRAME_HAS_PADDING_FLAG; + } + else + { + pxMpuSettings->ulTaskFlags &= ( ~portSTACK_FRAME_HAS_PADDING_FLAG ); + } + + /* We ensure in pxPortInitialiseStack that the system call stack is + * double word aligned and therefore, there is no need of padding. + * Clear the bit[9] of stacked xPSR. */ + pulSystemCallStack[ portOFFSET_TO_PSR ] &= ( ~portPSR_STACK_PADDING_MASK ); + + /* Raise the privilege for the duration of the system call. */ + __asm volatile ( + " mrs r0, control \n" /* Obtain current control value. */ + " movs r1, #1 \n" /* r1 = 1. */ + " bics r0, r1 \n" /* Clear nPRIV bit. */ + " msr control, r0 \n" /* Write back new control value. */ + ::: "r0", "r1", "memory" + ); + } +} - if( xRunPrivileged == pdTRUE ) +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + +void vSystemCallEnter_1( uint32_t * pulTaskStack, uint32_t ulLR ) /* PRIVILEGED_FUNCTION */ +{ + extern TaskHandle_t pxCurrentTCB; + xMPU_SETTINGS * pxMpuSettings; + uint32_t * pulSystemCallStack; + uint32_t ulStackFrameSize, ulSystemCallLocation, i; + #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being + * exported from linker scripts. */ + extern uint32_t * __syscalls_flash_start__; + extern uint32_t * __syscalls_flash_end__; + #else + /* Declaration when these variable are exported from linker scripts. */ + extern uint32_t __syscalls_flash_start__[]; + extern uint32_t __syscalls_flash_end__[]; + #endif /* #if defined( __ARMCC_VERSION ) */ + + ulSystemCallLocation = pulTaskStack[ portOFFSET_TO_PC ]; + + /* If the request did not come from the system call section, do nothing. */ + if( ( ulSystemCallLocation >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulSystemCallLocation <= ( uint32_t ) __syscalls_flash_end__ ) ) + { + pxMpuSettings = xTaskGetMPUSettings( pxCurrentTCB ); + pulSystemCallStack = pxMpuSettings->xSystemCallStackInfo.pulSystemCallStack; + + /* This is not NULL only for the duration of the system call. */ + configASSERT( pxMpuSettings->xSystemCallStackInfo.pulTaskStack == NULL ); + + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + { + if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) { - *pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */ + /* Extended frame i.e. FPU in use. */ + ulStackFrameSize = 26; + __asm volatile ( + " vpush {s0} \n" /* Trigger lazy stacking. */ + " vpop {s0} \n" /* Nullify the affect of the above instruction. */ + ::: "memory" + ); } else { - *pxTopOfStack = portINITIAL_CONTROL_UNPRIVILEGED; /* Slot used to hold this task's CONTROL value. */ + /* Standard frame i.e. FPU not in use. */ + ulStackFrameSize = 8; } } - #endif /* configENABLE_MPU */ + #else + { + ulStackFrameSize = 8; + } + #endif /* configENABLE_FPU || configENABLE_MVE */ + + /* Make space on the system call stack for the stack frame and + * the parameter passed on the stack. We only need to copy one + * parameter but we still reserve 2 spaces to keep the stack + * double word aligned. */ + pulSystemCallStack = pulSystemCallStack - ulStackFrameSize - 2UL; + + /* Copy the stack frame. */ + for( i = 0; i < ulStackFrameSize; i++ ) + { + pulSystemCallStack[ i ] = pulTaskStack[ i ]; + } + + /* Copy the parameter which is passed the stack. */ + if( ( pulTaskStack[ portOFFSET_TO_PSR ] & portPSR_STACK_PADDING_MASK ) == portPSR_STACK_PADDING_MASK ) + { + pulSystemCallStack[ ulStackFrameSize ] = pulTaskStack[ ulStackFrameSize + 1 ]; + /* Record if the hardware used padding to force the stack pointer + * to be double word aligned. */ + pxMpuSettings->ulTaskFlags |= portSTACK_FRAME_HAS_PADDING_FLAG; + } + else + { + pulSystemCallStack[ ulStackFrameSize ] = pulTaskStack[ ulStackFrameSize ]; + /* Record if the hardware used padding to force the stack pointer + * to be double word aligned. */ + pxMpuSettings->ulTaskFlags &= ( ~portSTACK_FRAME_HAS_PADDING_FLAG ); + } + + /* Store the value of the LR and PSPLIM registers before the SVC was raised. + * We need to restore it when we exit from the system call. */ + pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; + __asm volatile ( "mrs %0, psplim" : "=r" ( pxMpuSettings->xSystemCallStackInfo.ulStackLimitRegisterAtSystemCallEntry ) ); + + /* Use the pulSystemCallStack in thread mode. */ + __asm volatile ( "msr psp, %0" : : "r" ( pulSystemCallStack ) ); + __asm volatile ( "msr psplim, %0" : : "r" ( pxMpuSettings->xSystemCallStackInfo.pulSystemCallStackLimit ) ); + + /* Remember the location where we should copy the stack frame when we exit from + * the system call. */ + pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulStackFrameSize; + + /* We ensure in pxPortInitialiseStack that the system call stack is + * double word aligned and therefore, there is no need of padding. + * Clear the bit[9] of stacked xPSR. */ + pulSystemCallStack[ portOFFSET_TO_PSR ] &= ( ~portPSR_STACK_PADDING_MASK ); + + /* Raise the privilege for the duration of the system call. */ + __asm volatile ( + " mrs r0, control \n" /* Obtain current control value. */ + " movs r1, #1 \n" /* r1 = 1. */ + " bics r0, r1 \n" /* Clear nPRIV bit. */ + " msr control, r0 \n" /* Write back new control value. */ + ::: "r0", "r1", "memory" + ); + } +} + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) +void vSystemCallExit( uint32_t * pulSystemCallStack, uint32_t ulLR ) /* PRIVILEGED_FUNCTION */ +{ + extern TaskHandle_t pxCurrentTCB; + xMPU_SETTINGS * pxMpuSettings; + uint32_t * pulTaskStack; + uint32_t ulStackFrameSize, ulSystemCallLocation, i; + #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being + * exported from linker scripts. */ + extern uint32_t * __syscalls_flash_start__; + extern uint32_t * __syscalls_flash_end__; + #else + /* Declaration when these variable are exported from linker scripts. */ + extern uint32_t __syscalls_flash_start__[]; + extern uint32_t __syscalls_flash_end__[]; + #endif /* #if defined( __ARMCC_VERSION ) */ + + ulSystemCallLocation = pulSystemCallStack[ portOFFSET_TO_PC ]; + + /* If the request did not come from the system call section, do nothing. */ + if( ( ulSystemCallLocation >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulSystemCallLocation <= ( uint32_t ) __syscalls_flash_end__ ) ) + { + pxMpuSettings = xTaskGetMPUSettings( pxCurrentTCB ); + pulTaskStack = pxMpuSettings->xSystemCallStackInfo.pulTaskStack; + + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + { + if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) + { + /* Extended frame i.e. FPU in use. */ + ulStackFrameSize = 26; + __asm volatile ( + " vpush {s0} \n" /* Trigger lazy stacking. */ + " vpop {s0} \n" /* Nullify the affect of the above instruction. */ + ::: "memory" + ); + } + else + { + /* Standard frame i.e. FPU not in use. */ + ulStackFrameSize = 8; + } + } + #else + { + ulStackFrameSize = 8; + } + #endif /* configENABLE_FPU || configENABLE_MVE */ + + /* Make space on the task stack for the stack frame. */ + pulTaskStack = pulTaskStack - ulStackFrameSize; + + /* Copy the stack frame. */ + for( i = 0; i < ulStackFrameSize; i++ ) + { + pulTaskStack[ i ] = pulSystemCallStack[ i ]; + } + + /* Use the pulTaskStack in thread mode. */ + __asm volatile ( "msr psp, %0" : : "r" ( pulTaskStack ) ); + + /* Restore the LR and PSPLIM to what they were at the time of + * system call entry. */ + pulTaskStack[ portOFFSET_TO_LR ] = pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry; + __asm volatile ( "msr psplim, %0" : : "r" ( pxMpuSettings->xSystemCallStackInfo.ulStackLimitRegisterAtSystemCallEntry ) ); + + /* If the hardware used padding to force the stack pointer + * to be double word aligned, set the stacked xPSR bit[9], + * otherwise clear it. */ + if( ( pxMpuSettings->ulTaskFlags & portSTACK_FRAME_HAS_PADDING_FLAG ) == portSTACK_FRAME_HAS_PADDING_FLAG ) + { + pulTaskStack[ portOFFSET_TO_PSR ] |= portPSR_STACK_PADDING_MASK; + } + else + { + pulTaskStack[ portOFFSET_TO_PSR ] &= ( ~portPSR_STACK_PADDING_MASK ); + } + + /* This is not NULL only for the duration of the system call. */ + pxMpuSettings->xSystemCallStackInfo.pulTaskStack = NULL; + + /* Drop the privilege before returning to the thread mode. */ + __asm volatile ( + " mrs r0, control \n" /* Obtain current control value. */ + " movs r1, #1 \n" /* r1 = 1. */ + " orrs r0, r1 \n" /* Set nPRIV bit. */ + " msr control, r0 \n" /* Write back new control value. */ + ::: "r0", "r1", "memory" + ); + } +} + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configENABLE_MPU == 1 ) + +BaseType_t xPortIsTaskPrivileged( void ) /* PRIVILEGED_FUNCTION */ +{ + BaseType_t xTaskIsPrivileged = pdFALSE; + const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */ + + if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) + { + xTaskIsPrivileged = pdTRUE; + } + + return xTaskIsPrivileged; +} + +#endif /* configENABLE_MPU == 1 */ +/*-----------------------------------------------------------*/ + +#if( configENABLE_MPU == 1 ) + +StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, + StackType_t * pxEndOfStack, + TaskFunction_t pxCode, + void * pvParameters, + BaseType_t xRunPrivileged, + xMPU_SETTINGS * xMPUSettings ) /* PRIVILEGED_FUNCTION */ +{ + uint32_t ulIndex = 0; + + xMPUSettings->ulContext[ ulIndex ] = 0x04040404; /* r4. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x05050505; /* r5. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x06060606; /* r6. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x07070707; /* r7. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x08080808; /* r8. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x09090909; /* r9. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x10101010; /* r10. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x11111111; /* r11. */ + ulIndex++; + + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pvParameters; /* r0. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x01010101; /* r1. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x02020202; /* r2. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x03030303; /* r3. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x12121212; /* r12. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portTASK_RETURN_ADDRESS; /* LR. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxCode; /* PC. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = portINITIAL_XPSR; /* xPSR. */ + ulIndex++; + + #if ( configENABLE_TRUSTZONE == 1 ) + { + xMPUSettings->ulContext[ ulIndex ] = portNO_SECURE_CONTEXT; /* xSecureContext. */ + ulIndex++; + } + #endif /* configENABLE_TRUSTZONE */ + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) ( pxTopOfStack - 8 ); /* PSP with the hardware saved stack. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */ + ulIndex++; + if( xRunPrivileged == pdTRUE ) + { + xMPUSettings->ulTaskFlags |= portTASK_IS_PRIVILEGED_FLAG; + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_PRIVILEGED; /* CONTROL. */ + ulIndex++; + } + else + { + xMPUSettings->ulTaskFlags &= ( ~portTASK_IS_PRIVILEGED_FLAG ); + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_UNPRIVILEGED; /* CONTROL. */ + ulIndex++; + } + xMPUSettings->ulContext[ ulIndex ] = portINITIAL_EXC_RETURN; /* LR (EXC_RETURN). */ + ulIndex++; + + #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + { + /* Ensure that the system call stack is double word aligned. */ + xMPUSettings->xSystemCallStackInfo.pulSystemCallStack = &( xMPUSettings->xSystemCallStackInfo.ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE - 1 ] ); + xMPUSettings->xSystemCallStackInfo.pulSystemCallStack = ( uint32_t * ) ( ( uint32_t ) ( xMPUSettings->xSystemCallStackInfo.pulSystemCallStack ) & + ( uint32_t ) ( ~( portBYTE_ALIGNMENT_MASK ) ) ); + + xMPUSettings->xSystemCallStackInfo.pulSystemCallStackLimit = &( xMPUSettings->xSystemCallStackInfo.ulSystemCallStackBuffer[ 0 ] ); + xMPUSettings->xSystemCallStackInfo.pulSystemCallStackLimit = ( uint32_t * ) ( ( ( uint32_t ) ( xMPUSettings->xSystemCallStackInfo.pulSystemCallStackLimit ) + + ( uint32_t ) ( portBYTE_ALIGNMENT - 1 ) ) & + ( uint32_t ) ( ~( portBYTE_ALIGNMENT_MASK ) ) ); + + /* This is not NULL only for the duration of a system call. */ + xMPUSettings->xSystemCallStackInfo.pulTaskStack = NULL; + } + #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + + return &( xMPUSettings->ulContext[ ulIndex ] ); +} + +#else /* configENABLE_MPU */ + +StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, + StackType_t * pxEndOfStack, + TaskFunction_t pxCode, + void * pvParameters ) /* PRIVILEGED_FUNCTION */ +{ + /* Simulate the stack frame as it would be created by a context switch + * interrupt. */ + #if ( portPRELOAD_REGISTERS == 0 ) + { + pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ + *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR. */ + pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ + pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */ + *pxTopOfStack = portINITIAL_EXC_RETURN; pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ @@ -1029,55 +1561,39 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO #else /* portPRELOAD_REGISTERS */ { pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ - *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ + *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pxCode; /* PC */ + *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR */ + *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x12121212UL; /* R12 */ + *pxTopOfStack = ( StackType_t ) 0x12121212UL; /* R12. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x03030303UL; /* R3 */ + *pxTopOfStack = ( StackType_t ) 0x03030303UL; /* R3. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x02020202UL; /* R2 */ + *pxTopOfStack = ( StackType_t ) 0x02020202UL; /* R2. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x01010101UL; /* R1 */ + *pxTopOfStack = ( StackType_t ) 0x01010101UL; /* R1. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x11111111UL; /* R11 */ + *pxTopOfStack = ( StackType_t ) 0x11111111UL; /* R11. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x10101010UL; /* R10 */ + *pxTopOfStack = ( StackType_t ) 0x10101010UL; /* R10. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x09090909UL; /* R09 */ + *pxTopOfStack = ( StackType_t ) 0x09090909UL; /* R09. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x08080808UL; /* R08 */ + *pxTopOfStack = ( StackType_t ) 0x08080808UL; /* R08. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x07070707UL; /* R07 */ + *pxTopOfStack = ( StackType_t ) 0x07070707UL; /* R07. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x06060606UL; /* R06 */ + *pxTopOfStack = ( StackType_t ) 0x06060606UL; /* R06. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x05050505UL; /* R05 */ + *pxTopOfStack = ( StackType_t ) 0x05050505UL; /* R05. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x04040404UL; /* R04 */ + *pxTopOfStack = ( StackType_t ) 0x04040404UL; /* R04. */ pxTopOfStack--; - *pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN */ - - #if ( configENABLE_MPU == 1 ) - { - pxTopOfStack--; - - if( xRunPrivileged == pdTRUE ) - { - *pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */ - } - else - { - *pxTopOfStack = portINITIAL_CONTROL_UNPRIVILEGED; /* Slot used to hold this task's CONTROL value. */ - } - } - #endif /* configENABLE_MPU */ - + *pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN. */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ @@ -1092,6 +1608,8 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO return pxTopOfStack; } + +#endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ @@ -1128,6 +1646,10 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ configASSERT( ucMaxSysCallPriority ); + /* Check that the bits not implemented in hardware are zero in + * configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & ( ~ucMaxPriorityValue ) ) == 0U ); + /* Calculate the maximum acceptable priority group value for the number * of bits read back. */ @@ -1164,35 +1686,6 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulImplementedPrioBits; } - /* The interrupt priority bits are not modelled in QEMU and the assert that - * checks the number of implemented bits and __NVIC_PRIO_BITS will always fail. - * Therefore, this assert is not adding any value for QEMU targets. The config - * option `configDISABLE_INTERRUPT_PRIO_BITS_CHECK` should be defined in the - * `FreeRTOSConfig.h` for QEMU targets. */ - #ifndef configDISABLE_INTERRUPT_PRIO_BITS_CHECK - { - #ifdef __NVIC_PRIO_BITS - { - /* - * Check that the number of implemented priority bits queried from - * hardware is equal to the CMSIS __NVIC_PRIO_BITS configuration macro. - */ - configASSERT( ulImplementedPrioBits == __NVIC_PRIO_BITS ); - } - #endif /* __NVIC_PRIO_BITS */ - - #ifdef configPRIO_BITS - { - /* - * Check that the number of implemented priority bits queried from - * hardware is equal to the FreeRTOS configPRIO_BITS configuration macro. - */ - configASSERT( ulImplementedPrioBits == configPRIO_BITS ); - } - #endif /* configPRIO_BITS */ - } - #endif /* #ifndef configDISABLE_INTERRUPT_PRIO_BITS_CHECK */ - /* Shift the priority group value back to its position within the AIRCR * register. */ ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT; @@ -1372,6 +1865,54 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ +#if ( configENABLE_MPU == 1 ) + BaseType_t xPortIsAuthorizedToAccessBuffer( const void * pvBuffer, + uint32_t ulBufferLength, + uint32_t ulAccessRequested ) /* PRIVILEGED_FUNCTION */ + + { + uint32_t i, ulBufferStartAddress, ulBufferEndAddress; + BaseType_t xAccessGranted = pdFALSE; + const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */ + + if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) + { + xAccessGranted = pdTRUE; + } + else + { + if( portADD_UINT32_WILL_OVERFLOW( ( ( uint32_t ) pvBuffer ), ( ulBufferLength - 1UL ) ) == pdFALSE ) + { + ulBufferStartAddress = ( uint32_t ) pvBuffer; + ulBufferEndAddress = ( ( ( uint32_t ) pvBuffer ) + ulBufferLength - 1UL ); + + for( i = 0; i < portTOTAL_NUM_REGIONS; i++ ) + { + /* Is the MPU region enabled? */ + if( ( xTaskMpuSettings->xRegionsSettings[ i ].ulRLAR & portMPU_RLAR_REGION_ENABLE ) == portMPU_RLAR_REGION_ENABLE ) + { + if( portIS_ADDRESS_WITHIN_RANGE( ulBufferStartAddress, + portEXTRACT_FIRST_ADDRESS_FROM_RBAR( xTaskMpuSettings->xRegionsSettings[ i ].ulRBAR ), + portEXTRACT_LAST_ADDRESS_FROM_RLAR( xTaskMpuSettings->xRegionsSettings[ i ].ulRLAR ) ) && + portIS_ADDRESS_WITHIN_RANGE( ulBufferEndAddress, + portEXTRACT_FIRST_ADDRESS_FROM_RBAR( xTaskMpuSettings->xRegionsSettings[ i ].ulRBAR ), + portEXTRACT_LAST_ADDRESS_FROM_RLAR( xTaskMpuSettings->xRegionsSettings[ i ].ulRLAR ) ) && + portIS_AUTHORIZED( ulAccessRequested, + prvGetRegionAccessPermissions( xTaskMpuSettings->xRegionsSettings[ i ].ulRBAR ) ) ) + { + xAccessGranted = pdTRUE; + break; + } + } + } + } + } + + return xAccessGranted; + } +#endif /* configENABLE_MPU */ +/*-----------------------------------------------------------*/ + BaseType_t xPortIsInsideInterrupt( void ) { uint32_t ulCurrentInterrupt; diff --git a/portable/IAR/ARM_CM55/non_secure/portasm.s b/portable/IAR/ARM_CM55/non_secure/portasm.s index a193cd7b80e..15e74ffc16b 100644 --- a/portable/IAR/ARM_CM55/non_secure/portasm.s +++ b/portable/IAR/ARM_CM55/non_secure/portasm.s @@ -32,12 +32,21 @@ the code is included in C files but excluded by the preprocessor in assembly files (__ICCARM__ is defined by the IAR C compiler but not by the IAR assembler. */ #include "FreeRTOSConfig.h" +#ifndef configUSE_MPU_WRAPPERS_V1 + #define configUSE_MPU_WRAPPERS_V1 0 +#endif + EXTERN pxCurrentTCB EXTERN xSecureContext EXTERN vTaskSwitchContext EXTERN vPortSVCHandler_C EXTERN SecureContext_SaveContext EXTERN SecureContext_LoadContext +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + EXTERN vSystemCallEnter + EXTERN vSystemCallEnter_1 + EXTERN vSystemCallExit +#endif PUBLIC xIsPrivileged PUBLIC vResetPrivilege @@ -89,50 +98,81 @@ vPortAllocateSecureContext: THUMB /*-----------------------------------------------------------*/ +#if ( configENABLE_MPU == 1 ) + +vRestoreContextOfFirstTask: + program_mpu_first_task: + ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + ldr r0, [r3] /* r0 = pxCurrentTCB. */ + + dmb /* Complete outstanding transfers before disabling MPU. */ + ldr r1, =0xe000ed94 /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + ldr r2, [r1] /* Read the value of MPU_CTRL. */ + bic r2, #1 /* r2 = r2 & ~1 i.e. Clear the bit 0 in r2. */ + str r2, [r1] /* Disable MPU. */ + + adds r0, #4 /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */ + ldr r1, [r0] /* r1 = *r0 i.e. r1 = MAIR0. */ + ldr r2, =0xe000edc0 /* r2 = 0xe000edc0 [Location of MAIR0]. */ + str r1, [r2] /* Program MAIR0. */ + + adds r0, #4 /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */ + ldr r1, =0xe000ed98 /* r1 = 0xe000ed98 [Location of RNR]. */ + ldr r2, =0xe000ed9c /* r2 = 0xe000ed9c [Location of RBAR]. */ + + movs r3, #4 /* r3 = 4. */ + str r3, [r1] /* Program RNR = 4. */ + ldmia r0!, {r4-r11} /* Read 4 set of RBAR/RLAR registers from TCB. */ + stmia r2, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ + + #if ( configTOTAL_MPU_REGIONS == 16 ) + movs r3, #8 /* r3 = 8. */ + str r3, [r1] /* Program RNR = 8. */ + ldmia r0!, {r4-r11} /* Read 4 set of RBAR/RLAR registers from TCB. */ + stmia r2, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ + movs r3, #12 /* r3 = 12. */ + str r3, [r1] /* Program RNR = 12. */ + ldmia r0!, {r4-r11} /* Read 4 set of RBAR/RLAR registers from TCB. */ + stmia r2, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ + #endif /* configTOTAL_MPU_REGIONS == 16 */ + + ldr r1, =0xe000ed94 /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + ldr r2, [r1] /* Read the value of MPU_CTRL. */ + orr r2, #1 /* r2 = r1 | 1 i.e. Set the bit 0 in r2. */ + str r2, [r1] /* Enable MPU. */ + dsb /* Force memory writes before continuing. */ + + restore_context_first_task: + ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + ldr r1, [r3] /* r1 = pxCurrentTCB.*/ + ldr r2, [r1] /* r2 = Location of saved context in TCB. */ + + restore_special_regs_first_task: + ldmdb r2!, {r0, r3-r5, lr} /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */ + msr psp, r3 + msr psplim, r4 + msr control, r5 + ldr r4, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */ + str r0, [r4] /* Restore xSecureContext. */ + + restore_general_regs_first_task: + ldmdb r2!, {r4-r11} /* r4-r11 contain hardware saved context. */ + stmia r3!, {r4-r11} /* Copy the hardware saved context on the task stack. */ + ldmdb r2!, {r4-r11} /* r4-r11 restored. */ + + restore_context_done_first_task: + str r2, [r1] /* Save the location where the context should be saved next as the first member of TCB. */ + mov r0, #0 + msr basepri, r0 /* Ensure that interrupts are enabled when the first task starts. */ + bx lr + +#else /* configENABLE_MPU */ + vRestoreContextOfFirstTask: ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r3, [r2] /* Read pxCurrentTCB. */ ldr r0, [r3] /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ -#if ( configENABLE_MPU == 1 ) - dmb /* Complete outstanding transfers before disabling MPU. */ - ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ - ldr r4, [r2] /* Read the value of MPU_CTRL. */ - bic r4, r4, #1 /* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */ - str r4, [r2] /* Disable MPU. */ - - adds r3, #4 /* r3 = r3 + 4. r3 now points to MAIR0 in TCB. */ - ldr r4, [r3] /* r4 = *r3 i.e. r4 = MAIR0. */ - ldr r2, =0xe000edc0 /* r2 = 0xe000edc0 [Location of MAIR0]. */ - str r4, [r2] /* Program MAIR0. */ - ldr r2, =0xe000ed98 /* r2 = 0xe000ed98 [Location of RNR]. */ - movs r4, #4 /* r4 = 4. */ - str r4, [r2] /* Program RNR = 4. */ - adds r3, #4 /* r3 = r3 + 4. r3 now points to first RBAR in TCB. */ - ldr r2, =0xe000ed9c /* r2 = 0xe000ed9c [Location of RBAR]. */ - ldmia r3!, {r4-r11} /* Read 4 set of RBAR/RLAR registers from TCB. */ - stmia r2!, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ - - ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ - ldr r4, [r2] /* Read the value of MPU_CTRL. */ - orr r4, r4, #1 /* r4 = r4 | 1 i.e. Set the bit 0 in r4. */ - str r4, [r2] /* Enable MPU. */ - dsb /* Force memory writes before continuing. */ -#endif /* configENABLE_MPU */ - -#if ( configENABLE_MPU == 1 ) - ldm r0!, {r1-r4} /* Read from stack - r1 = xSecureContext, r2 = PSPLIM, r3 = CONTROL and r4 = EXC_RETURN. */ - ldr r5, =xSecureContext - str r1, [r5] /* Set xSecureContext to this task's value for the same. */ - msr psplim, r2 /* Set this task's PSPLIM value. */ - msr control, r3 /* Set this task's CONTROL value. */ - adds r0, #32 /* Discard everything up to r0. */ - msr psp, r0 /* This is now the new top of stack to use in the task. */ - isb - mov r0, #0 - msr basepri, r0 /* Ensure that interrupts are enabled when the first task starts. */ - bx r4 /* Finally, branch to EXC_RETURN. */ -#else /* configENABLE_MPU */ ldm r0!, {r1-r3} /* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */ ldr r4, =xSecureContext str r1, [r4] /* Set xSecureContext to this task's value for the same. */ @@ -145,6 +185,7 @@ vRestoreContextOfFirstTask: mov r0, #0 msr basepri, r0 /* Ensure that interrupts are enabled when the first task starts. */ bx r3 /* Finally, branch to EXC_RETURN. */ + #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ @@ -183,6 +224,143 @@ vClearInterruptMask: bx lr /* Return. */ /*-----------------------------------------------------------*/ +#if ( configENABLE_MPU == 1 ) + +PendSV_Handler: + ldr r3, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */ + ldr r0, [r3] /* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */ + ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + ldr r1, [r3] /* Read pxCurrentTCB - Value of pxCurrentTCB must be in r1 as it is used as a parameter later. */ + ldr r2, [r1] /* r2 = Location in TCB where the context should be saved. */ + + cbz r0, save_ns_context /* No secure context to save. */ + save_s_context: + push {r0-r2, lr} + bl SecureContext_SaveContext /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ + pop {r0-r2, lr} + + save_ns_context: + mov r3, lr /* r3 = LR (EXC_RETURN). */ + lsls r3, r3, #25 /* r3 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ + bmi save_special_regs /* r3 < 0 ==> Bit[6] in EXC_RETURN is 1 ==> secure stack was used to store the stack frame. */ + + save_general_regs: + mrs r3, psp + + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + add r3, r3, #0x20 /* Move r3 to location where s0 is saved. */ + tst lr, #0x10 + ittt eq + vstmiaeq r2!, {s16-s31} /* Store s16-s31. */ + vldmiaeq r3, {s0-s16} /* Copy hardware saved FP context into s0-s16. */ + vstmiaeq r2!, {s0-s16} /* Store hardware saved FP context. */ + sub r3, r3, #0x20 /* Set r3 back to the location of hardware saved context. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ + + stmia r2!, {r4-r11} /* Store r4-r11. */ + ldmia r3, {r4-r11} /* Copy the hardware saved context into r4-r11. */ + stmia r2!, {r4-r11} /* Store the hardware saved context. */ + + save_special_regs: + mrs r3, psp /* r3 = PSP. */ + mrs r4, psplim /* r4 = PSPLIM. */ + mrs r5, control /* r5 = CONTROL. */ + stmia r2!, {r0, r3-r5, lr} /* Store xSecureContext, original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */ + str r2, [r1] /* Save the location from where the context should be restored as the first member of TCB. */ + + select_next_task: + mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY + msr basepri, r0 /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + dsb + isb + bl vTaskSwitchContext + mov r0, #0 /* r0 = 0. */ + msr basepri, r0 /* Enable interrupts. */ + + program_mpu: + ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + ldr r0, [r3] /* r0 = pxCurrentTCB.*/ + + dmb /* Complete outstanding transfers before disabling MPU. */ + ldr r1, =0xe000ed94 /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + ldr r2, [r1] /* Read the value of MPU_CTRL. */ + bic r2, #1 /* r2 = r2 & ~1 i.e. Clear the bit 0 in r2. */ + str r2, [r1] /* Disable MPU. */ + + adds r0, #4 /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */ + ldr r1, [r0] /* r1 = *r0 i.e. r1 = MAIR0. */ + ldr r2, =0xe000edc0 /* r2 = 0xe000edc0 [Location of MAIR0]. */ + str r1, [r2] /* Program MAIR0. */ + + adds r0, #4 /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */ + ldr r1, =0xe000ed98 /* r1 = 0xe000ed98 [Location of RNR]. */ + ldr r2, =0xe000ed9c /* r2 = 0xe000ed9c [Location of RBAR]. */ + + movs r3, #4 /* r3 = 4. */ + str r3, [r1] /* Program RNR = 4. */ + ldmia r0!, {r4-r11} /* Read 4 sets of RBAR/RLAR registers from TCB. */ + stmia r2, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ + + #if ( configTOTAL_MPU_REGIONS == 16 ) + movs r3, #8 /* r3 = 8. */ + str r3, [r1] /* Program RNR = 8. */ + ldmia r0!, {r4-r11} /* Read 4 sets of RBAR/RLAR registers from TCB. */ + stmia r2, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ + movs r3, #12 /* r3 = 12. */ + str r3, [r1] /* Program RNR = 12. */ + ldmia r0!, {r4-r11} /* Read 4 sets of RBAR/RLAR registers from TCB. */ + stmia r2, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ + #endif /* configTOTAL_MPU_REGIONS == 16 */ + + ldr r1, =0xe000ed94 /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + ldr r2, [r1] /* Read the value of MPU_CTRL. */ + orr r2, #1 /* r2 = r2 | 1 i.e. Set the bit 0 in r2. */ + str r2, [r1] /* Enable MPU. */ + dsb /* Force memory writes before continuing. */ + + restore_context: + ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + ldr r1, [r3] /* r1 = pxCurrentTCB.*/ + ldr r2, [r1] /* r2 = Location of saved context in TCB. */ + + restore_special_regs: + ldmdb r2!, {r0, r3-r5, lr} /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */ + msr psp, r3 + msr psplim, r4 + msr control, r5 + ldr r4, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */ + str r0, [r4] /* Restore xSecureContext. */ + cbz r0, restore_ns_context /* No secure context to restore. */ + + restore_s_context: + push {r1-r3, lr} + bl SecureContext_LoadContext /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ + pop {r1-r3, lr} + + restore_ns_context: + mov r0, lr /* r0 = LR (EXC_RETURN). */ + lsls r0, r0, #25 /* r0 = r0 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ + bmi restore_context_done /* r0 < 0 ==> Bit[6] in EXC_RETURN is 1 ==> secure stack was used to store the stack frame. */ + + restore_general_regs: + ldmdb r2!, {r4-r11} /* r4-r11 contain hardware saved context. */ + stmia r3!, {r4-r11} /* Copy the hardware saved context on the task stack. */ + ldmdb r2!, {r4-r11} /* r4-r11 restored. */ + + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + tst lr, #0x10 + ittt eq + vldmdbeq r2!, {s0-s16} /* s0-s16 contain hardware saved FP context. */ + vstmiaeq r3!, {s0-s16} /* Copy hardware saved FP context on the task stack. */ + vldmdbeq r2!, {s16-s31} /* Restore s16-s31. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ + + restore_context_done: + str r2, [r1] /* Save the location where the context should be saved next as the first member of TCB. */ + bx lr + +#else /* configENABLE_MPU */ + PendSV_Handler: ldr r3, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */ ldr r0, [r3] /* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */ @@ -200,20 +378,11 @@ PendSV_Handler: ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r3] /* Read pxCurrentTCB. */ -#if ( configENABLE_MPU == 1 ) - subs r2, r2, #16 /* Make space for xSecureContext, PSPLIM, CONTROL and LR on the stack. */ - str r2, [r1] /* Save the new top of stack in TCB. */ - mrs r1, psplim /* r1 = PSPLIM. */ - mrs r3, control /* r3 = CONTROL. */ - mov r4, lr /* r4 = LR/EXC_RETURN. */ - stmia r2!, {r0, r1, r3, r4} /* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */ -#else /* configENABLE_MPU */ subs r2, r2, #12 /* Make space for xSecureContext, PSPLIM and LR on the stack. */ str r2, [r1] /* Save the new top of stack in TCB. */ mrs r1, psplim /* r1 = PSPLIM. */ mov r3, lr /* r3 = LR/EXC_RETURN. */ stmia r2!, {r0, r1, r3} /* Store xSecureContext, PSPLIM and LR on the stack. */ -#endif /* configENABLE_MPU */ b select_next_task save_ns_context: @@ -224,17 +393,6 @@ PendSV_Handler: it eq vstmdbeq r2!, {s16-s31} /* Store the additional FP context registers which are not saved automatically. */ #endif /* configENABLE_FPU || configENABLE_MVE */ - #if ( configENABLE_MPU == 1 ) - subs r2, r2, #48 /* Make space for xSecureContext, PSPLIM, CONTROL, LR and the remaining registers on the stack. */ - str r2, [r1] /* Save the new top of stack in TCB. */ - adds r2, r2, #16 /* r2 = r2 + 16. */ - stm r2, {r4-r11} /* Store the registers that are not saved automatically. */ - mrs r1, psplim /* r1 = PSPLIM. */ - mrs r3, control /* r3 = CONTROL. */ - mov r4, lr /* r4 = LR/EXC_RETURN. */ - subs r2, r2, #16 /* r2 = r2 - 16. */ - stmia r2!, {r0, r1, r3, r4} /* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */ - #else /* configENABLE_MPU */ subs r2, r2, #44 /* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */ str r2, [r1] /* Save the new top of stack in TCB. */ adds r2, r2, #12 /* r2 = r2 + 12. */ @@ -243,7 +401,6 @@ PendSV_Handler: mov r3, lr /* r3 = LR/EXC_RETURN. */ subs r2, r2, #12 /* r2 = r2 - 12. */ stmia r2!, {r0, r1, r3} /* Store xSecureContext, PSPLIM and LR on the stack. */ - #endif /* configENABLE_MPU */ select_next_task: mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY @@ -258,51 +415,6 @@ PendSV_Handler: ldr r1, [r3] /* Read pxCurrentTCB. */ ldr r2, [r1] /* The first item in pxCurrentTCB is the task top of stack. r2 now points to the top of stack. */ - #if ( configENABLE_MPU == 1 ) - dmb /* Complete outstanding transfers before disabling MPU. */ - ldr r3, =0xe000ed94 /* r3 = 0xe000ed94 [Location of MPU_CTRL]. */ - ldr r4, [r3] /* Read the value of MPU_CTRL. */ - bic r4, r4, #1 /* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */ - str r4, [r3] /* Disable MPU. */ - - adds r1, #4 /* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */ - ldr r4, [r1] /* r4 = *r1 i.e. r4 = MAIR0. */ - ldr r3, =0xe000edc0 /* r3 = 0xe000edc0 [Location of MAIR0]. */ - str r4, [r3] /* Program MAIR0. */ - ldr r3, =0xe000ed98 /* r3 = 0xe000ed98 [Location of RNR]. */ - movs r4, #4 /* r4 = 4. */ - str r4, [r3] /* Program RNR = 4. */ - adds r1, #4 /* r1 = r1 + 4. r1 now points to first RBAR in TCB. */ - ldr r3, =0xe000ed9c /* r3 = 0xe000ed9c [Location of RBAR]. */ - ldmia r1!, {r4-r11} /* Read 4 sets of RBAR/RLAR registers from TCB. */ - stmia r3!, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ - - ldr r3, =0xe000ed94 /* r3 = 0xe000ed94 [Location of MPU_CTRL]. */ - ldr r4, [r3] /* Read the value of MPU_CTRL. */ - orr r4, r4, #1 /* r4 = r4 | 1 i.e. Set the bit 0 in r4. */ - str r4, [r3] /* Enable MPU. */ - dsb /* Force memory writes before continuing. */ - #endif /* configENABLE_MPU */ - - #if ( configENABLE_MPU == 1 ) - ldmia r2!, {r0, r1, r3, r4} /* Read from stack - r0 = xSecureContext, r1 = PSPLIM, r3 = CONTROL and r4 = LR. */ - msr psplim, r1 /* Restore the PSPLIM register value for the task. */ - msr control, r3 /* Restore the CONTROL register value for the task. */ - mov lr, r4 /* LR = r4. */ - ldr r3, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */ - str r0, [r3] /* Restore the task's xSecureContext. */ - cbz r0, restore_ns_context /* If there is no secure context for the task, restore the non-secure context. */ - ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - ldr r1, [r3] /* Read pxCurrentTCB. */ - push {r2, r4} - bl SecureContext_LoadContext /* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ - pop {r2, r4} - mov lr, r4 /* LR = r4. */ - lsls r1, r4, #25 /* r1 = r4 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ - bpl restore_ns_context /* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ - msr psp, r2 /* Remember the new top of stack for the task. */ - bx lr - #else /* configENABLE_MPU */ ldmia r2!, {r0, r1, r4} /* Read from stack - r0 = xSecureContext, r1 = PSPLIM and r4 = LR. */ msr psplim, r1 /* Restore the PSPLIM register value for the task. */ mov lr, r4 /* LR = r4. */ @@ -319,7 +431,6 @@ PendSV_Handler: bpl restore_ns_context /* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ msr psp, r2 /* Remember the new top of stack for the task. */ bx lr - #endif /* configENABLE_MPU */ restore_ns_context: ldmia r2!, {r4-r11} /* Restore the registers that are not automatically restored. */ @@ -330,14 +441,50 @@ PendSV_Handler: #endif /* configENABLE_FPU || configENABLE_MVE */ msr psp, r2 /* Remember the new top of stack for the task. */ bx lr + +#endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + SVC_Handler: tst lr, #4 ite eq mrseq r0, msp mrsne r0, psp + + ldr r1, [r0, #24] + ldrb r2, [r1, #-2] + cmp r2, #4 /* portSVC_SYSTEM_CALL_ENTER. */ + beq syscall_enter + cmp r2, #5 /* portSVC_SYSTEM_CALL_ENTER_1. */ + beq syscall_enter_1 + cmp r2, #6 /* portSVC_SYSTEM_CALL_EXIT. */ + beq syscall_exit b vPortSVCHandler_C + + syscall_enter: + mov r1, lr + b vSystemCallEnter + + syscall_enter_1: + mov r1, lr + b vSystemCallEnter_1 + + syscall_exit: + mov r1, lr + b vSystemCallExit + +#else /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + +SVC_Handler: + tst lr, #4 + ite eq + mrseq r0, msp + mrsne r0, psp + b vPortSVCHandler_C + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ /*-----------------------------------------------------------*/ vPortFreeSecureContext: diff --git a/portable/IAR/ARM_CM55/non_secure/portmacrocommon.h b/portable/IAR/ARM_CM55/non_secure/portmacrocommon.h index c2ca5fa7730..65ac109c802 100644 --- a/portable/IAR/ARM_CM55/non_secure/portmacrocommon.h +++ b/portable/IAR/ARM_CM55/non_secure/portmacrocommon.h @@ -186,23 +186,120 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #define portMPU_REGION_EXECUTE_NEVER ( 1UL ) /*-----------------------------------------------------------*/ -/** - * @brief Settings to define an MPU region. - */ -typedef struct MPURegionSettings -{ - uint32_t ulRBAR; /**< RBAR for the region. */ - uint32_t ulRLAR; /**< RLAR for the region. */ -} MPURegionSettings_t; +#if ( configENABLE_MPU == 1 ) -/** - * @brief MPU settings as stored in the TCB. - */ -typedef struct MPU_SETTINGS -{ - uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ - MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */ -} xMPU_SETTINGS; + /** + * @brief Settings to define an MPU region. + */ + typedef struct MPURegionSettings + { + uint32_t ulRBAR; /**< RBAR for the region. */ + uint32_t ulRLAR; /**< RLAR for the region. */ + } MPURegionSettings_t; + + #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + + #ifndef configSYSTEM_CALL_STACK_SIZE + #error configSYSTEM_CALL_STACK_SIZE must be defined to the desired size of the system call stack in words for using MPU wrappers v2. + #endif + + /** + * @brief System call stack. + */ + typedef struct SYSTEM_CALL_STACK_INFO + { + uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ]; + uint32_t * pulSystemCallStack; + uint32_t * pulSystemCallStackLimit; + uint32_t * pulTaskStack; + uint32_t ulLinkRegisterAtSystemCallEntry; + uint32_t ulStackLimitRegisterAtSystemCallEntry; + } xSYSTEM_CALL_STACK_INFO; + + #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + + /** + * @brief MPU settings as stored in the TCB. + */ + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + + #if( configENABLE_TRUSTZONE == 1 ) + + /* + * +-----------+---------------+----------+-----------------+------------------------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | + * | | | | PC, xPSR | CONTROL, EXC_RETURN | | + * +-----------+---------------+----------+-----------------+------------------------------+-----+ + * + * <-----------><--------------><---------><----------------><-----------------------------><----> + * 16 16 8 8 5 1 + */ + #define MAX_CONTEXT_SIZE 54 + + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ + + /* + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | + * | | | | PC, xPSR | EXC_RETURN | | + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * + * <-----------><--------------><---------><----------------><---------------------><----> + * 16 16 8 8 4 1 + */ + #define MAX_CONTEXT_SIZE 53 + + #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + + #else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ + + #if( configENABLE_TRUSTZONE == 1 ) + + /* + * +----------+-----------------+------------------------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | + * | | PC, xPSR | CONTROL, EXC_RETURN | | + * +----------+-----------------+------------------------------+-----+ + * + * <---------><----------------><------------------------------><----> + * 8 8 5 1 + */ + #define MAX_CONTEXT_SIZE 22 + + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ + + /* + * +----------+-----------------+----------------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | + * | | PC, xPSR | EXC_RETURN | | + * +----------+-----------------+----------------------+-----+ + * + * <---------><----------------><----------------------><----> + * 8 8 4 1 + */ + #define MAX_CONTEXT_SIZE 21 + + #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + + #endif /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ + + /* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ + #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) + #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) + + typedef struct MPU_SETTINGS + { + uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ + MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */ + uint32_t ulContext[ MAX_CONTEXT_SIZE ]; + uint32_t ulTaskFlags; + + #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo; + #endif + } xMPU_SETTINGS; + +#endif /* configENABLE_MPU == 1 */ /*-----------------------------------------------------------*/ /** @@ -223,6 +320,9 @@ typedef struct MPU_SETTINGS #define portSVC_FREE_SECURE_CONTEXT 1 #define portSVC_START_SCHEDULER 2 #define portSVC_RAISE_PRIVILEGE 3 +#define portSVC_SYSTEM_CALL_ENTER 4 /* System calls with upto 4 parameters. */ +#define portSVC_SYSTEM_CALL_ENTER_1 5 /* System calls with 5 parameters. */ +#define portSVC_SYSTEM_CALL_EXIT 6 /*-----------------------------------------------------------*/ /** @@ -315,6 +415,20 @@ typedef struct MPU_SETTINGS #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ +#if ( configENABLE_MPU == 1 ) + + extern BaseType_t xPortIsTaskPrivileged( void ); + + /** + * @brief Checks whether or not the calling task is privileged. + * + * @return pdTRUE if the calling task is privileged, pdFALSE otherwise. + */ + #define portIS_TASK_PRIVILEGED() xPortIsTaskPrivileged() + +#endif /* configENABLE_MPU == 1 */ +/*-----------------------------------------------------------*/ + /** * @brief Barriers. */ diff --git a/portable/IAR/ARM_CM55_NTZ/non_secure/mpu_wrappers_v2_asm.S b/portable/IAR/ARM_CM55_NTZ/non_secure/mpu_wrappers_v2_asm.S new file mode 100644 index 00000000000..f051a6073dd --- /dev/null +++ b/portable/IAR/ARM_CM55_NTZ/non_secure/mpu_wrappers_v2_asm.S @@ -0,0 +1,1552 @@ +/* + * FreeRTOS Kernel + * Copyright (C) 2021 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 + * + */ + + + SECTION freertos_system_calls:CODE:NOROOT(2) + THUMB +/*-----------------------------------------------------------*/ + +#include "FreeRTOSConfig.h" + +#ifndef configUSE_MPU_WRAPPERS_V1 + #define configUSE_MPU_WRAPPERS_V1 0 +#endif + +/* These must be in sync with portmacro.h. */ +#define portSVC_SYSTEM_CALL_ENTER 4 /* System calls with upto 4 parameters. */ +#define portSVC_SYSTEM_CALL_ENTER_1 5 /* System calls with 5 parameters. */ +#define portSVC_SYSTEM_CALL_EXIT 6 +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + + PUBLIC MPU_xTaskDelayUntil +MPU_xTaskDelayUntil: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskDelayUntil_Unpriv + MPU_xTaskDelayUntil_Priv: + pop {r0} + b MPU_xTaskDelayUntilImpl + MPU_xTaskDelayUntil_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskDelayUntilImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskAbortDelay +MPU_xTaskAbortDelay: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskAbortDelay_Unpriv + MPU_xTaskAbortDelay_Priv: + pop {r0} + b MPU_xTaskAbortDelayImpl + MPU_xTaskAbortDelay_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskAbortDelayImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTaskDelay +MPU_vTaskDelay: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vTaskDelay_Unpriv + MPU_vTaskDelay_Priv: + pop {r0} + b MPU_vTaskDelayImpl + MPU_vTaskDelay_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskDelayImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxTaskPriorityGet +MPU_uxTaskPriorityGet: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_uxTaskPriorityGet_Unpriv + MPU_uxTaskPriorityGet_Priv: + pop {r0} + b MPU_uxTaskPriorityGetImpl + MPU_uxTaskPriorityGet_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxTaskPriorityGetImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_eTaskGetState +MPU_eTaskGetState: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_eTaskGetState_Unpriv + MPU_eTaskGetState_Priv: + pop {r0} + b MPU_eTaskGetStateImpl + MPU_eTaskGetState_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_eTaskGetStateImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTaskGetInfo +MPU_vTaskGetInfo: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vTaskGetInfo_Unpriv + MPU_vTaskGetInfo_Priv: + pop {r0} + b MPU_vTaskGetInfoImpl + MPU_vTaskGetInfo_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskGetInfoImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGetIdleTaskHandle +MPU_xTaskGetIdleTaskHandle: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskGetIdleTaskHandle_Unpriv + MPU_xTaskGetIdleTaskHandle_Priv: + pop {r0} + b MPU_xTaskGetIdleTaskHandleImpl + MPU_xTaskGetIdleTaskHandle_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskGetIdleTaskHandleImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTaskSuspend +MPU_vTaskSuspend: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vTaskSuspend_Unpriv + MPU_vTaskSuspend_Priv: + pop {r0} + b MPU_vTaskSuspendImpl + MPU_vTaskSuspend_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskSuspendImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTaskResume +MPU_vTaskResume: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vTaskResume_Unpriv + MPU_vTaskResume_Priv: + pop {r0} + b MPU_vTaskResumeImpl + MPU_vTaskResume_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskResumeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGetTickCount +MPU_xTaskGetTickCount: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskGetTickCount_Unpriv + MPU_xTaskGetTickCount_Priv: + pop {r0} + b MPU_xTaskGetTickCountImpl + MPU_xTaskGetTickCount_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskGetTickCountImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxTaskGetNumberOfTasks +MPU_uxTaskGetNumberOfTasks: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_uxTaskGetNumberOfTasks_Unpriv + MPU_uxTaskGetNumberOfTasks_Priv: + pop {r0} + b MPU_uxTaskGetNumberOfTasksImpl + MPU_uxTaskGetNumberOfTasks_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxTaskGetNumberOfTasksImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_pcTaskGetName +MPU_pcTaskGetName: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_pcTaskGetName_Unpriv + MPU_pcTaskGetName_Priv: + pop {r0} + b MPU_pcTaskGetNameImpl + MPU_pcTaskGetName_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_pcTaskGetNameImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_ulTaskGetRunTimeCounter +MPU_ulTaskGetRunTimeCounter: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_ulTaskGetRunTimeCounter_Unpriv + MPU_ulTaskGetRunTimeCounter_Priv: + pop {r0} + b MPU_ulTaskGetRunTimeCounterImpl + MPU_ulTaskGetRunTimeCounter_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_ulTaskGetRunTimeCounterImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_ulTaskGetRunTimePercent +MPU_ulTaskGetRunTimePercent: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_ulTaskGetRunTimePercent_Unpriv + MPU_ulTaskGetRunTimePercent_Priv: + pop {r0} + b MPU_ulTaskGetRunTimePercentImpl + MPU_ulTaskGetRunTimePercent_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_ulTaskGetRunTimePercentImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_ulTaskGetIdleRunTimePercent +MPU_ulTaskGetIdleRunTimePercent: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_ulTaskGetIdleRunTimePercent_Unpriv + MPU_ulTaskGetIdleRunTimePercent_Priv: + pop {r0} + b MPU_ulTaskGetIdleRunTimePercentImpl + MPU_ulTaskGetIdleRunTimePercent_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_ulTaskGetIdleRunTimePercentImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_ulTaskGetIdleRunTimeCounter +MPU_ulTaskGetIdleRunTimeCounter: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_ulTaskGetIdleRunTimeCounter_Unpriv + MPU_ulTaskGetIdleRunTimeCounter_Priv: + pop {r0} + b MPU_ulTaskGetIdleRunTimeCounterImpl + MPU_ulTaskGetIdleRunTimeCounter_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_ulTaskGetIdleRunTimeCounterImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTaskSetApplicationTaskTag +MPU_vTaskSetApplicationTaskTag: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vTaskSetApplicationTaskTag_Unpriv + MPU_vTaskSetApplicationTaskTag_Priv: + pop {r0} + b MPU_vTaskSetApplicationTaskTagImpl + MPU_vTaskSetApplicationTaskTag_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskSetApplicationTaskTagImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGetApplicationTaskTag +MPU_xTaskGetApplicationTaskTag: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskGetApplicationTaskTag_Unpriv + MPU_xTaskGetApplicationTaskTag_Priv: + pop {r0} + b MPU_xTaskGetApplicationTaskTagImpl + MPU_xTaskGetApplicationTaskTag_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskGetApplicationTaskTagImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTaskSetThreadLocalStoragePointer +MPU_vTaskSetThreadLocalStoragePointer: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vTaskSetThreadLocalStoragePointer_Unpriv + MPU_vTaskSetThreadLocalStoragePointer_Priv: + pop {r0} + b MPU_vTaskSetThreadLocalStoragePointerImpl + MPU_vTaskSetThreadLocalStoragePointer_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskSetThreadLocalStoragePointerImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_pvTaskGetThreadLocalStoragePointer +MPU_pvTaskGetThreadLocalStoragePointer: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_pvTaskGetThreadLocalStoragePointer_Unpriv + MPU_pvTaskGetThreadLocalStoragePointer_Priv: + pop {r0} + b MPU_pvTaskGetThreadLocalStoragePointerImpl + MPU_pvTaskGetThreadLocalStoragePointer_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_pvTaskGetThreadLocalStoragePointerImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxTaskGetSystemState +MPU_uxTaskGetSystemState: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_uxTaskGetSystemState_Unpriv + MPU_uxTaskGetSystemState_Priv: + pop {r0} + b MPU_uxTaskGetSystemStateImpl + MPU_uxTaskGetSystemState_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxTaskGetSystemStateImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxTaskGetStackHighWaterMark +MPU_uxTaskGetStackHighWaterMark: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_uxTaskGetStackHighWaterMark_Unpriv + MPU_uxTaskGetStackHighWaterMark_Priv: + pop {r0} + b MPU_uxTaskGetStackHighWaterMarkImpl + MPU_uxTaskGetStackHighWaterMark_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxTaskGetStackHighWaterMarkImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxTaskGetStackHighWaterMark2 +MPU_uxTaskGetStackHighWaterMark2: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_uxTaskGetStackHighWaterMark2_Unpriv + MPU_uxTaskGetStackHighWaterMark2_Priv: + pop {r0} + b MPU_uxTaskGetStackHighWaterMark2Impl + MPU_uxTaskGetStackHighWaterMark2_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxTaskGetStackHighWaterMark2Impl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGetCurrentTaskHandle +MPU_xTaskGetCurrentTaskHandle: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskGetCurrentTaskHandle_Unpriv + MPU_xTaskGetCurrentTaskHandle_Priv: + pop {r0} + b MPU_xTaskGetCurrentTaskHandleImpl + MPU_xTaskGetCurrentTaskHandle_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskGetCurrentTaskHandleImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGetSchedulerState +MPU_xTaskGetSchedulerState: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskGetSchedulerState_Unpriv + MPU_xTaskGetSchedulerState_Priv: + pop {r0} + b MPU_xTaskGetSchedulerStateImpl + MPU_xTaskGetSchedulerState_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskGetSchedulerStateImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTaskSetTimeOutState +MPU_vTaskSetTimeOutState: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vTaskSetTimeOutState_Unpriv + MPU_vTaskSetTimeOutState_Priv: + pop {r0} + b MPU_vTaskSetTimeOutStateImpl + MPU_vTaskSetTimeOutState_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskSetTimeOutStateImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskCheckForTimeOut +MPU_xTaskCheckForTimeOut: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskCheckForTimeOut_Unpriv + MPU_xTaskCheckForTimeOut_Priv: + pop {r0} + b MPU_xTaskCheckForTimeOutImpl + MPU_xTaskCheckForTimeOut_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskCheckForTimeOutImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGenericNotify +MPU_xTaskGenericNotify: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskGenericNotify_Unpriv + MPU_xTaskGenericNotify_Priv: + pop {r0} + b MPU_xTaskGenericNotifyImpl + MPU_xTaskGenericNotify_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER_1 + bl MPU_xTaskGenericNotifyImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGenericNotifyWait +MPU_xTaskGenericNotifyWait: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskGenericNotifyWait_Unpriv + MPU_xTaskGenericNotifyWait_Priv: + pop {r0} + b MPU_xTaskGenericNotifyWaitImpl + MPU_xTaskGenericNotifyWait_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER_1 + bl MPU_xTaskGenericNotifyWaitImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_ulTaskGenericNotifyTake +MPU_ulTaskGenericNotifyTake: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_ulTaskGenericNotifyTake_Unpriv + MPU_ulTaskGenericNotifyTake_Priv: + pop {r0} + b MPU_ulTaskGenericNotifyTakeImpl + MPU_ulTaskGenericNotifyTake_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_ulTaskGenericNotifyTakeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGenericNotifyStateClear +MPU_xTaskGenericNotifyStateClear: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskGenericNotifyStateClear_Unpriv + MPU_xTaskGenericNotifyStateClear_Priv: + pop {r0} + b MPU_xTaskGenericNotifyStateClearImpl + MPU_xTaskGenericNotifyStateClear_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskGenericNotifyStateClearImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_ulTaskGenericNotifyValueClear +MPU_ulTaskGenericNotifyValueClear: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_ulTaskGenericNotifyValueClear_Unpriv + MPU_ulTaskGenericNotifyValueClear_Priv: + pop {r0} + b MPU_ulTaskGenericNotifyValueClearImpl + MPU_ulTaskGenericNotifyValueClear_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_ulTaskGenericNotifyValueClearImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueGenericSend +MPU_xQueueGenericSend: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xQueueGenericSend_Unpriv + MPU_xQueueGenericSend_Priv: + pop {r0} + b MPU_xQueueGenericSendImpl + MPU_xQueueGenericSend_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueGenericSendImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxQueueMessagesWaiting +MPU_uxQueueMessagesWaiting: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_uxQueueMessagesWaiting_Unpriv + MPU_uxQueueMessagesWaiting_Priv: + pop {r0} + b MPU_uxQueueMessagesWaitingImpl + MPU_uxQueueMessagesWaiting_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxQueueMessagesWaitingImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxQueueSpacesAvailable +MPU_uxQueueSpacesAvailable: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_uxQueueSpacesAvailable_Unpriv + MPU_uxQueueSpacesAvailable_Priv: + pop {r0} + b MPU_uxQueueSpacesAvailableImpl + MPU_uxQueueSpacesAvailable_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxQueueSpacesAvailableImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueReceive +MPU_xQueueReceive: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xQueueReceive_Unpriv + MPU_xQueueReceive_Priv: + pop {r0} + b MPU_xQueueReceiveImpl + MPU_xQueueReceive_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueReceiveImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueuePeek +MPU_xQueuePeek: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xQueuePeek_Unpriv + MPU_xQueuePeek_Priv: + pop {r0} + b MPU_xQueuePeekImpl + MPU_xQueuePeek_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueuePeekImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueSemaphoreTake +MPU_xQueueSemaphoreTake: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xQueueSemaphoreTake_Unpriv + MPU_xQueueSemaphoreTake_Priv: + pop {r0} + b MPU_xQueueSemaphoreTakeImpl + MPU_xQueueSemaphoreTake_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueSemaphoreTakeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueGetMutexHolder +MPU_xQueueGetMutexHolder: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xQueueGetMutexHolder_Unpriv + MPU_xQueueGetMutexHolder_Priv: + pop {r0} + b MPU_xQueueGetMutexHolderImpl + MPU_xQueueGetMutexHolder_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueGetMutexHolderImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueTakeMutexRecursive +MPU_xQueueTakeMutexRecursive: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xQueueTakeMutexRecursive_Unpriv + MPU_xQueueTakeMutexRecursive_Priv: + pop {r0} + b MPU_xQueueTakeMutexRecursiveImpl + MPU_xQueueTakeMutexRecursive_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueTakeMutexRecursiveImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueGiveMutexRecursive +MPU_xQueueGiveMutexRecursive: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xQueueGiveMutexRecursive_Unpriv + MPU_xQueueGiveMutexRecursive_Priv: + pop {r0} + b MPU_xQueueGiveMutexRecursiveImpl + MPU_xQueueGiveMutexRecursive_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueGiveMutexRecursiveImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueSelectFromSet +MPU_xQueueSelectFromSet: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xQueueSelectFromSet_Unpriv + MPU_xQueueSelectFromSet_Priv: + pop {r0} + b MPU_xQueueSelectFromSetImpl + MPU_xQueueSelectFromSet_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueSelectFromSetImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueAddToSet +MPU_xQueueAddToSet: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xQueueAddToSet_Unpriv + MPU_xQueueAddToSet_Priv: + pop {r0} + b MPU_xQueueAddToSetImpl + MPU_xQueueAddToSet_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueAddToSetImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vQueueAddToRegistry +MPU_vQueueAddToRegistry: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vQueueAddToRegistry_Unpriv + MPU_vQueueAddToRegistry_Priv: + pop {r0} + b MPU_vQueueAddToRegistryImpl + MPU_vQueueAddToRegistry_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vQueueAddToRegistryImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vQueueUnregisterQueue +MPU_vQueueUnregisterQueue: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vQueueUnregisterQueue_Unpriv + MPU_vQueueUnregisterQueue_Priv: + pop {r0} + b MPU_vQueueUnregisterQueueImpl + MPU_vQueueUnregisterQueue_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vQueueUnregisterQueueImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_pcQueueGetName +MPU_pcQueueGetName: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_pcQueueGetName_Unpriv + MPU_pcQueueGetName_Priv: + pop {r0} + b MPU_pcQueueGetNameImpl + MPU_pcQueueGetName_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_pcQueueGetNameImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_pvTimerGetTimerID +MPU_pvTimerGetTimerID: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_pvTimerGetTimerID_Unpriv + MPU_pvTimerGetTimerID_Priv: + pop {r0} + b MPU_pvTimerGetTimerIDImpl + MPU_pvTimerGetTimerID_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_pvTimerGetTimerIDImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTimerSetTimerID +MPU_vTimerSetTimerID: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vTimerSetTimerID_Unpriv + MPU_vTimerSetTimerID_Priv: + pop {r0} + b MPU_vTimerSetTimerIDImpl + MPU_vTimerSetTimerID_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTimerSetTimerIDImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTimerIsTimerActive +MPU_xTimerIsTimerActive: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTimerIsTimerActive_Unpriv + MPU_xTimerIsTimerActive_Priv: + pop {r0} + b MPU_xTimerIsTimerActiveImpl + MPU_xTimerIsTimerActive_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTimerIsTimerActiveImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTimerGetTimerDaemonTaskHandle +MPU_xTimerGetTimerDaemonTaskHandle: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTimerGetTimerDaemonTaskHandle_Unpriv + MPU_xTimerGetTimerDaemonTaskHandle_Priv: + pop {r0} + b MPU_xTimerGetTimerDaemonTaskHandleImpl + MPU_xTimerGetTimerDaemonTaskHandle_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTimerGetTimerDaemonTaskHandleImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTimerGenericCommand +MPU_xTimerGenericCommand: + push {r0} + /* This function can be called from ISR also and therefore, we need a check + * to take privileged path, if called from ISR. */ + mrs r0, ipsr + cmp r0, #0 + bne MPU_xTimerGenericCommand_Priv + mrs r0, control + tst r0, #1 + beq MPU_xTimerGenericCommand_Priv + MPU_xTimerGenericCommand_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER_1 + bl MPU_xTimerGenericCommandImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr + MPU_xTimerGenericCommand_Priv: + pop {r0} + b MPU_xTimerGenericCommandImpl + +/*-----------------------------------------------------------*/ + + PUBLIC MPU_pcTimerGetName +MPU_pcTimerGetName: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_pcTimerGetName_Unpriv + MPU_pcTimerGetName_Priv: + pop {r0} + b MPU_pcTimerGetNameImpl + MPU_pcTimerGetName_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_pcTimerGetNameImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTimerSetReloadMode +MPU_vTimerSetReloadMode: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vTimerSetReloadMode_Unpriv + MPU_vTimerSetReloadMode_Priv: + pop {r0} + b MPU_vTimerSetReloadModeImpl + MPU_vTimerSetReloadMode_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTimerSetReloadModeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTimerGetReloadMode +MPU_xTimerGetReloadMode: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTimerGetReloadMode_Unpriv + MPU_xTimerGetReloadMode_Priv: + pop {r0} + b MPU_xTimerGetReloadModeImpl + MPU_xTimerGetReloadMode_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTimerGetReloadModeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxTimerGetReloadMode +MPU_uxTimerGetReloadMode: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_uxTimerGetReloadMode_Unpriv + MPU_uxTimerGetReloadMode_Priv: + pop {r0} + b MPU_uxTimerGetReloadModeImpl + MPU_uxTimerGetReloadMode_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxTimerGetReloadModeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTimerGetPeriod +MPU_xTimerGetPeriod: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTimerGetPeriod_Unpriv + MPU_xTimerGetPeriod_Priv: + pop {r0} + b MPU_xTimerGetPeriodImpl + MPU_xTimerGetPeriod_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTimerGetPeriodImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTimerGetExpiryTime +MPU_xTimerGetExpiryTime: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTimerGetExpiryTime_Unpriv + MPU_xTimerGetExpiryTime_Priv: + pop {r0} + b MPU_xTimerGetExpiryTimeImpl + MPU_xTimerGetExpiryTime_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTimerGetExpiryTimeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xEventGroupWaitBits +MPU_xEventGroupWaitBits: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xEventGroupWaitBits_Unpriv + MPU_xEventGroupWaitBits_Priv: + pop {r0} + b MPU_xEventGroupWaitBitsImpl + MPU_xEventGroupWaitBits_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER_1 + bl MPU_xEventGroupWaitBitsImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xEventGroupClearBits +MPU_xEventGroupClearBits: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xEventGroupClearBits_Unpriv + MPU_xEventGroupClearBits_Priv: + pop {r0} + b MPU_xEventGroupClearBitsImpl + MPU_xEventGroupClearBits_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xEventGroupClearBitsImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xEventGroupSetBits +MPU_xEventGroupSetBits: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xEventGroupSetBits_Unpriv + MPU_xEventGroupSetBits_Priv: + pop {r0} + b MPU_xEventGroupSetBitsImpl + MPU_xEventGroupSetBits_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xEventGroupSetBitsImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xEventGroupSync +MPU_xEventGroupSync: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xEventGroupSync_Unpriv + MPU_xEventGroupSync_Priv: + pop {r0} + b MPU_xEventGroupSyncImpl + MPU_xEventGroupSync_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xEventGroupSyncImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxEventGroupGetNumber +MPU_uxEventGroupGetNumber: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_uxEventGroupGetNumber_Unpriv + MPU_uxEventGroupGetNumber_Priv: + pop {r0} + b MPU_uxEventGroupGetNumberImpl + MPU_uxEventGroupGetNumber_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxEventGroupGetNumberImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vEventGroupSetNumber +MPU_vEventGroupSetNumber: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vEventGroupSetNumber_Unpriv + MPU_vEventGroupSetNumber_Priv: + pop {r0} + b MPU_vEventGroupSetNumberImpl + MPU_vEventGroupSetNumber_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vEventGroupSetNumberImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferSend +MPU_xStreamBufferSend: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xStreamBufferSend_Unpriv + MPU_xStreamBufferSend_Priv: + pop {r0} + b MPU_xStreamBufferSendImpl + MPU_xStreamBufferSend_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferSendImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferReceive +MPU_xStreamBufferReceive: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xStreamBufferReceive_Unpriv + MPU_xStreamBufferReceive_Priv: + pop {r0} + b MPU_xStreamBufferReceiveImpl + MPU_xStreamBufferReceive_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferReceiveImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferIsFull +MPU_xStreamBufferIsFull: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xStreamBufferIsFull_Unpriv + MPU_xStreamBufferIsFull_Priv: + pop {r0} + b MPU_xStreamBufferIsFullImpl + MPU_xStreamBufferIsFull_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferIsFullImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferIsEmpty +MPU_xStreamBufferIsEmpty: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xStreamBufferIsEmpty_Unpriv + MPU_xStreamBufferIsEmpty_Priv: + pop {r0} + b MPU_xStreamBufferIsEmptyImpl + MPU_xStreamBufferIsEmpty_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferIsEmptyImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferSpacesAvailable +MPU_xStreamBufferSpacesAvailable: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xStreamBufferSpacesAvailable_Unpriv + MPU_xStreamBufferSpacesAvailable_Priv: + pop {r0} + b MPU_xStreamBufferSpacesAvailableImpl + MPU_xStreamBufferSpacesAvailable_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferSpacesAvailableImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferBytesAvailable +MPU_xStreamBufferBytesAvailable: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xStreamBufferBytesAvailable_Unpriv + MPU_xStreamBufferBytesAvailable_Priv: + pop {r0} + b MPU_xStreamBufferBytesAvailableImpl + MPU_xStreamBufferBytesAvailable_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferBytesAvailableImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferSetTriggerLevel +MPU_xStreamBufferSetTriggerLevel: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xStreamBufferSetTriggerLevel_Unpriv + MPU_xStreamBufferSetTriggerLevel_Priv: + pop {r0} + b MPU_xStreamBufferSetTriggerLevelImpl + MPU_xStreamBufferSetTriggerLevel_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferSetTriggerLevelImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferNextMessageLengthBytes +MPU_xStreamBufferNextMessageLengthBytes: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xStreamBufferNextMessageLengthBytes_Unpriv + MPU_xStreamBufferNextMessageLengthBytes_Priv: + pop {r0} + b MPU_xStreamBufferNextMessageLengthBytesImpl + MPU_xStreamBufferNextMessageLengthBytes_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferNextMessageLengthBytesImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + +/* Default weak implementations in case one is not available from + * mpu_wrappers because of config options. */ + + PUBWEAK MPU_xTaskDelayUntilImpl +MPU_xTaskDelayUntilImpl: + b MPU_xTaskDelayUntilImpl + + PUBWEAK MPU_xTaskAbortDelayImpl +MPU_xTaskAbortDelayImpl: + b MPU_xTaskAbortDelayImpl + + PUBWEAK MPU_vTaskDelayImpl +MPU_vTaskDelayImpl: + b MPU_vTaskDelayImpl + + PUBWEAK MPU_uxTaskPriorityGetImpl +MPU_uxTaskPriorityGetImpl: + b MPU_uxTaskPriorityGetImpl + + PUBWEAK MPU_eTaskGetStateImpl +MPU_eTaskGetStateImpl: + b MPU_eTaskGetStateImpl + + PUBWEAK MPU_vTaskGetInfoImpl +MPU_vTaskGetInfoImpl: + b MPU_vTaskGetInfoImpl + + PUBWEAK MPU_xTaskGetIdleTaskHandleImpl +MPU_xTaskGetIdleTaskHandleImpl: + b MPU_xTaskGetIdleTaskHandleImpl + + PUBWEAK MPU_vTaskSuspendImpl +MPU_vTaskSuspendImpl: + b MPU_vTaskSuspendImpl + + PUBWEAK MPU_vTaskResumeImpl +MPU_vTaskResumeImpl: + b MPU_vTaskResumeImpl + + PUBWEAK MPU_xTaskGetTickCountImpl +MPU_xTaskGetTickCountImpl: + b MPU_xTaskGetTickCountImpl + + PUBWEAK MPU_uxTaskGetNumberOfTasksImpl +MPU_uxTaskGetNumberOfTasksImpl: + b MPU_uxTaskGetNumberOfTasksImpl + + PUBWEAK MPU_pcTaskGetNameImpl +MPU_pcTaskGetNameImpl: + b MPU_pcTaskGetNameImpl + + PUBWEAK MPU_ulTaskGetRunTimeCounterImpl +MPU_ulTaskGetRunTimeCounterImpl: + b MPU_ulTaskGetRunTimeCounterImpl + + PUBWEAK MPU_ulTaskGetRunTimePercentImpl +MPU_ulTaskGetRunTimePercentImpl: + b MPU_ulTaskGetRunTimePercentImpl + + PUBWEAK MPU_ulTaskGetIdleRunTimePercentImpl +MPU_ulTaskGetIdleRunTimePercentImpl: + b MPU_ulTaskGetIdleRunTimePercentImpl + + PUBWEAK MPU_ulTaskGetIdleRunTimeCounterImpl +MPU_ulTaskGetIdleRunTimeCounterImpl: + b MPU_ulTaskGetIdleRunTimeCounterImpl + + PUBWEAK MPU_vTaskSetApplicationTaskTagImpl +MPU_vTaskSetApplicationTaskTagImpl: + b MPU_vTaskSetApplicationTaskTagImpl + + PUBWEAK MPU_xTaskGetApplicationTaskTagImpl +MPU_xTaskGetApplicationTaskTagImpl: + b MPU_xTaskGetApplicationTaskTagImpl + + PUBWEAK MPU_vTaskSetThreadLocalStoragePointerImpl +MPU_vTaskSetThreadLocalStoragePointerImpl: + b MPU_vTaskSetThreadLocalStoragePointerImpl + + PUBWEAK MPU_pvTaskGetThreadLocalStoragePointerImpl +MPU_pvTaskGetThreadLocalStoragePointerImpl: + b MPU_pvTaskGetThreadLocalStoragePointerImpl + + PUBWEAK MPU_uxTaskGetSystemStateImpl +MPU_uxTaskGetSystemStateImpl: + b MPU_uxTaskGetSystemStateImpl + + PUBWEAK MPU_uxTaskGetStackHighWaterMarkImpl +MPU_uxTaskGetStackHighWaterMarkImpl: + b MPU_uxTaskGetStackHighWaterMarkImpl + + PUBWEAK MPU_uxTaskGetStackHighWaterMark2Impl +MPU_uxTaskGetStackHighWaterMark2Impl: + b MPU_uxTaskGetStackHighWaterMark2Impl + + PUBWEAK MPU_xTaskGetCurrentTaskHandleImpl +MPU_xTaskGetCurrentTaskHandleImpl: + b MPU_xTaskGetCurrentTaskHandleImpl + + PUBWEAK MPU_xTaskGetSchedulerStateImpl +MPU_xTaskGetSchedulerStateImpl: + b MPU_xTaskGetSchedulerStateImpl + + PUBWEAK MPU_vTaskSetTimeOutStateImpl +MPU_vTaskSetTimeOutStateImpl: + b MPU_vTaskSetTimeOutStateImpl + + PUBWEAK MPU_xTaskCheckForTimeOutImpl +MPU_xTaskCheckForTimeOutImpl: + b MPU_xTaskCheckForTimeOutImpl + + PUBWEAK MPU_xTaskGenericNotifyImpl +MPU_xTaskGenericNotifyImpl: + b MPU_xTaskGenericNotifyImpl + + PUBWEAK MPU_xTaskGenericNotifyWaitImpl +MPU_xTaskGenericNotifyWaitImpl: + b MPU_xTaskGenericNotifyWaitImpl + + PUBWEAK MPU_ulTaskGenericNotifyTakeImpl +MPU_ulTaskGenericNotifyTakeImpl: + b MPU_ulTaskGenericNotifyTakeImpl + + PUBWEAK MPU_xTaskGenericNotifyStateClearImpl +MPU_xTaskGenericNotifyStateClearImpl: + b MPU_xTaskGenericNotifyStateClearImpl + + PUBWEAK MPU_ulTaskGenericNotifyValueClearImpl +MPU_ulTaskGenericNotifyValueClearImpl: + b MPU_ulTaskGenericNotifyValueClearImpl + + PUBWEAK MPU_xQueueGenericSendImpl +MPU_xQueueGenericSendImpl: + b MPU_xQueueGenericSendImpl + + PUBWEAK MPU_uxQueueMessagesWaitingImpl +MPU_uxQueueMessagesWaitingImpl: + b MPU_uxQueueMessagesWaitingImpl + + PUBWEAK MPU_uxQueueSpacesAvailableImpl +MPU_uxQueueSpacesAvailableImpl: + b MPU_uxQueueSpacesAvailableImpl + + PUBWEAK MPU_xQueueReceiveImpl +MPU_xQueueReceiveImpl: + b MPU_xQueueReceiveImpl + + PUBWEAK MPU_xQueuePeekImpl +MPU_xQueuePeekImpl: + b MPU_xQueuePeekImpl + + PUBWEAK MPU_xQueueSemaphoreTakeImpl +MPU_xQueueSemaphoreTakeImpl: + b MPU_xQueueSemaphoreTakeImpl + + PUBWEAK MPU_xQueueGetMutexHolderImpl +MPU_xQueueGetMutexHolderImpl: + b MPU_xQueueGetMutexHolderImpl + + PUBWEAK MPU_xQueueTakeMutexRecursiveImpl +MPU_xQueueTakeMutexRecursiveImpl: + b MPU_xQueueTakeMutexRecursiveImpl + + PUBWEAK MPU_xQueueGiveMutexRecursiveImpl +MPU_xQueueGiveMutexRecursiveImpl: + b MPU_xQueueGiveMutexRecursiveImpl + + PUBWEAK MPU_xQueueSelectFromSetImpl +MPU_xQueueSelectFromSetImpl: + b MPU_xQueueSelectFromSetImpl + + PUBWEAK MPU_xQueueAddToSetImpl +MPU_xQueueAddToSetImpl: + b MPU_xQueueAddToSetImpl + + PUBWEAK MPU_vQueueAddToRegistryImpl +MPU_vQueueAddToRegistryImpl: + b MPU_vQueueAddToRegistryImpl + + PUBWEAK MPU_vQueueUnregisterQueueImpl +MPU_vQueueUnregisterQueueImpl: + b MPU_vQueueUnregisterQueueImpl + + PUBWEAK MPU_pcQueueGetNameImpl +MPU_pcQueueGetNameImpl: + b MPU_pcQueueGetNameImpl + + PUBWEAK MPU_pvTimerGetTimerIDImpl +MPU_pvTimerGetTimerIDImpl: + b MPU_pvTimerGetTimerIDImpl + + PUBWEAK MPU_vTimerSetTimerIDImpl +MPU_vTimerSetTimerIDImpl: + b MPU_vTimerSetTimerIDImpl + + PUBWEAK MPU_xTimerIsTimerActiveImpl +MPU_xTimerIsTimerActiveImpl: + b MPU_xTimerIsTimerActiveImpl + + PUBWEAK MPU_xTimerGetTimerDaemonTaskHandleImpl +MPU_xTimerGetTimerDaemonTaskHandleImpl: + b MPU_xTimerGetTimerDaemonTaskHandleImpl + + PUBWEAK MPU_xTimerGenericCommandImpl +MPU_xTimerGenericCommandImpl: + b MPU_xTimerGenericCommandImpl + + PUBWEAK MPU_pcTimerGetNameImpl +MPU_pcTimerGetNameImpl: + b MPU_pcTimerGetNameImpl + + PUBWEAK MPU_vTimerSetReloadModeImpl +MPU_vTimerSetReloadModeImpl: + b MPU_vTimerSetReloadModeImpl + + PUBWEAK MPU_xTimerGetReloadModeImpl +MPU_xTimerGetReloadModeImpl: + b MPU_xTimerGetReloadModeImpl + + PUBWEAK MPU_uxTimerGetReloadModeImpl +MPU_uxTimerGetReloadModeImpl: + b MPU_uxTimerGetReloadModeImpl + + PUBWEAK MPU_xTimerGetPeriodImpl +MPU_xTimerGetPeriodImpl: + b MPU_xTimerGetPeriodImpl + + PUBWEAK MPU_xTimerGetExpiryTimeImpl +MPU_xTimerGetExpiryTimeImpl: + b MPU_xTimerGetExpiryTimeImpl + + PUBWEAK MPU_xEventGroupWaitBitsImpl +MPU_xEventGroupWaitBitsImpl: + b MPU_xEventGroupWaitBitsImpl + + PUBWEAK MPU_xEventGroupClearBitsImpl +MPU_xEventGroupClearBitsImpl: + b MPU_xEventGroupClearBitsImpl + + PUBWEAK MPU_xEventGroupSetBitsImpl +MPU_xEventGroupSetBitsImpl: + b MPU_xEventGroupSetBitsImpl + + PUBWEAK MPU_xEventGroupSyncImpl +MPU_xEventGroupSyncImpl: + b MPU_xEventGroupSyncImpl + + PUBWEAK MPU_uxEventGroupGetNumberImpl +MPU_uxEventGroupGetNumberImpl: + b MPU_uxEventGroupGetNumberImpl + + PUBWEAK MPU_vEventGroupSetNumberImpl +MPU_vEventGroupSetNumberImpl: + b MPU_vEventGroupSetNumberImpl + + PUBWEAK MPU_xStreamBufferSendImpl +MPU_xStreamBufferSendImpl: + b MPU_xStreamBufferSendImpl + + PUBWEAK MPU_xStreamBufferReceiveImpl +MPU_xStreamBufferReceiveImpl: + b MPU_xStreamBufferReceiveImpl + + PUBWEAK MPU_xStreamBufferIsFullImpl +MPU_xStreamBufferIsFullImpl: + b MPU_xStreamBufferIsFullImpl + + PUBWEAK MPU_xStreamBufferIsEmptyImpl +MPU_xStreamBufferIsEmptyImpl: + b MPU_xStreamBufferIsEmptyImpl + + PUBWEAK MPU_xStreamBufferSpacesAvailableImpl +MPU_xStreamBufferSpacesAvailableImpl: + b MPU_xStreamBufferSpacesAvailableImpl + + PUBWEAK MPU_xStreamBufferBytesAvailableImpl +MPU_xStreamBufferBytesAvailableImpl: + b MPU_xStreamBufferBytesAvailableImpl + + PUBWEAK MPU_xStreamBufferSetTriggerLevelImpl +MPU_xStreamBufferSetTriggerLevelImpl: + b MPU_xStreamBufferSetTriggerLevelImpl + + PUBWEAK MPU_xStreamBufferNextMessageLengthBytesImpl +MPU_xStreamBufferNextMessageLengthBytesImpl: + b MPU_xStreamBufferNextMessageLengthBytesImpl + +/*-----------------------------------------------------------*/ + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + + END diff --git a/portable/IAR/ARM_CM55_NTZ/non_secure/port.c b/portable/IAR/ARM_CM55_NTZ/non_secure/port.c index 7bbe1b7bc53..cab1b3668bf 100644 --- a/portable/IAR/ARM_CM55_NTZ/non_secure/port.c +++ b/portable/IAR/ARM_CM55_NTZ/non_secure/port.c @@ -107,6 +107,13 @@ #define portPRIGROUP_SHIFT ( 8UL ) /*-----------------------------------------------------------*/ +/** + * @brief Constants used during system call enter and exit. + */ +#define portPSR_STACK_PADDING_MASK ( 1UL << 9UL ) +#define portEXC_RETURN_STACK_FRAME_TYPE_MASK ( 1UL << 4UL ) +/*-----------------------------------------------------------*/ + /** * @brief Constants required to manipulate the FPU. */ @@ -123,6 +130,14 @@ #define portFPCCR_LSPEN_MASK ( 1UL << portFPCCR_LSPEN_POS ) /*-----------------------------------------------------------*/ +/** + * @brief Offsets in the stack to the parameters when inside the SVC handler. + */ +#define portOFFSET_TO_LR ( 5 ) +#define portOFFSET_TO_PC ( 6 ) +#define portOFFSET_TO_PSR ( 7 ) +/*-----------------------------------------------------------*/ + /** * @brief Constants required to manipulate the MPU. */ @@ -148,6 +163,8 @@ #define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ #define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ +#define portMPU_RBAR_ACCESS_PERMISSIONS_MASK ( 3UL << 1UL ) + #define portMPU_MAIR_ATTR0_POS ( 0UL ) #define portMPU_MAIR_ATTR0_MASK ( 0x000000ff ) @@ -191,6 +208,30 @@ /* Expected value of the portMPU_TYPE register. */ #define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) + +/* Extract first address of the MPU region as encoded in the + * RBAR (Region Base Address Register) value. */ +#define portEXTRACT_FIRST_ADDRESS_FROM_RBAR( rbar ) \ + ( ( rbar ) & portMPU_RBAR_ADDRESS_MASK ) + +/* Extract last address of the MPU region as encoded in the + * RLAR (Region Limit Address Register) value. */ +#define portEXTRACT_LAST_ADDRESS_FROM_RLAR( rlar ) \ + ( ( ( rlar ) & portMPU_RLAR_ADDRESS_MASK ) | ~portMPU_RLAR_ADDRESS_MASK ) + +/* Does addr lies within [start, end] address range? */ +#define portIS_ADDRESS_WITHIN_RANGE( addr, start, end ) \ + ( ( ( addr ) >= ( start ) ) && ( ( addr ) <= ( end ) ) ) + +/* Is the access request satisfied by the available permissions? */ +#define portIS_AUTHORIZED( accessRequest, permissions ) \ + ( ( ( permissions ) & ( accessRequest ) ) == accessRequest ) + +/* 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 ) ) ) /*-----------------------------------------------------------*/ /** @@ -311,6 +352,19 @@ static void prvTaskExitError( void ); #if ( configENABLE_MPU == 1 ) +/** + * @brief Extract MPU region's access permissions from the Region Base Address + * Register (RBAR) value. + * + * @param ulRBARValue RBAR value for the MPU region. + * + * @return uint32_t Access permissions. + */ + static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) PRIVILEGED_FUNCTION; +#endif /* configENABLE_MPU */ + +#if ( configENABLE_MPU == 1 ) + /** * @brief Setup the Memory Protection Unit (MPU). */ @@ -365,6 +419,60 @@ void SysTick_Handler( void ) PRIVILEGED_FUNCTION; * @brief C part of SVC handler. */ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIVILEGED_FUNCTION; + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + + /** + * @brief Sets up the system call stack so that upon returning from + * SVC, the system call stack is used. + * + * It is used for the system calls with up to 4 parameters. + * + * @param pulTaskStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + */ + void vSystemCallEnter( uint32_t * pulTaskStack, uint32_t ulLR ) PRIVILEGED_FUNCTION; + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + + /** + * @brief Sets up the system call stack so that upon returning from + * SVC, the system call stack is used. + * + * It is used for the system calls with 5 parameters. + * + * @param pulTaskStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + */ + void vSystemCallEnter_1( uint32_t * pulTaskStack, uint32_t ulLR ) PRIVILEGED_FUNCTION; + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + + /** + * @brief Sets up the task stack so that upon returning from + * SVC, the task stack is used again. + * + * @param pulSystemCallStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + */ + void vSystemCallExit( uint32_t * pulSystemCallStack, uint32_t ulLR ) PRIVILEGED_FUNCTION; + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + +#if ( configENABLE_MPU == 1 ) + + /** + * @brief Checks whether or not the calling task is privileged. + * + * @return pdTRUE if the calling task is privileged, pdFALSE otherwise. + */ + BaseType_t xPortIsTaskPrivileged( void ) PRIVILEGED_FUNCTION; + +#endif /* configENABLE_MPU == 1 */ /*-----------------------------------------------------------*/ /** @@ -681,6 +789,26 @@ static void prvTaskExitError( void ) } /*-----------------------------------------------------------*/ +#if ( configENABLE_MPU == 1 ) + static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) /* PRIVILEGED_FUNCTION */ + { + uint32_t ulAccessPermissions = 0; + + if( ( ulRBARValue & portMPU_RBAR_ACCESS_PERMISSIONS_MASK ) == portMPU_REGION_READ_ONLY ) + { + ulAccessPermissions = tskMPU_READ_PERMISSION; + } + + if( ( ulRBARValue & portMPU_RBAR_ACCESS_PERMISSIONS_MASK ) == portMPU_REGION_READ_WRITE ) + { + ulAccessPermissions = ( tskMPU_READ_PERMISSION | tskMPU_WRITE_PERMISSION ); + } + + return ulAccessPermissions; + } +#endif /* configENABLE_MPU */ +/*-----------------------------------------------------------*/ + #if ( configENABLE_MPU == 1 ) static void prvSetupMPU( void ) /* PRIVILEGED_FUNCTION */ { @@ -853,7 +981,7 @@ void SysTick_Handler( void ) /* PRIVILEGED_FUNCTION */ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTION portDONT_DISCARD */ { - #if ( configENABLE_MPU == 1 ) + #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) ) #if defined( __ARMCC_VERSION ) /* Declaration when these variable are defined in code instead of being @@ -865,7 +993,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO extern uint32_t __syscalls_flash_start__[]; extern uint32_t __syscalls_flash_end__[]; #endif /* defined( __ARMCC_VERSION ) */ - #endif /* configENABLE_MPU */ + #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */ uint32_t ulPC; @@ -880,7 +1008,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO /* Register are stored on the stack in the following order - R0, R1, R2, R3, * R12, LR, PC, xPSR. */ - ulPC = pulCallerStackAddress[ 6 ]; + ulPC = pulCallerStackAddress[ portOFFSET_TO_PC ]; ucSVCNumber = ( ( uint8_t * ) ulPC )[ -2 ]; switch( ucSVCNumber ) @@ -951,18 +1079,18 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO vRestoreContextOfFirstTask(); break; - #if ( configENABLE_MPU == 1 ) - case portSVC_RAISE_PRIVILEGE: + #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) ) + case portSVC_RAISE_PRIVILEGE: - /* Only raise the privilege, if the svc was raised from any of - * the system calls. */ - if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) && - ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ) - { - vRaisePrivilege(); - } - break; - #endif /* configENABLE_MPU */ + /* Only raise the privilege, if the svc was raised from any of + * the system calls. */ + if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ) + { + vRaisePrivilege(); + } + break; + #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */ default: /* Incorrect SVC call. */ @@ -971,51 +1099,455 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } /*-----------------------------------------------------------*/ -/* *INDENT-OFF* */ -#if ( configENABLE_MPU == 1 ) - StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, - StackType_t * pxEndOfStack, - TaskFunction_t pxCode, - void * pvParameters, - BaseType_t xRunPrivileged ) /* PRIVILEGED_FUNCTION */ -#else - StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, - StackType_t * pxEndOfStack, - TaskFunction_t pxCode, - void * pvParameters ) /* PRIVILEGED_FUNCTION */ -#endif /* configENABLE_MPU */ -/* *INDENT-ON* */ +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + +void vSystemCallEnter( uint32_t * pulTaskStack, uint32_t ulLR ) /* PRIVILEGED_FUNCTION */ { - /* Simulate the stack frame as it would be created by a context switch - * interrupt. */ - #if ( portPRELOAD_REGISTERS == 0 ) + extern TaskHandle_t pxCurrentTCB; + xMPU_SETTINGS * pxMpuSettings; + uint32_t * pulSystemCallStack; + uint32_t ulStackFrameSize, ulSystemCallLocation, i; + #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being + * exported from linker scripts. */ + extern uint32_t * __syscalls_flash_start__; + extern uint32_t * __syscalls_flash_end__; + #else + /* Declaration when these variable are exported from linker scripts. */ + extern uint32_t __syscalls_flash_start__[]; + extern uint32_t __syscalls_flash_end__[]; + #endif /* #if defined( __ARMCC_VERSION ) */ + + ulSystemCallLocation = pulTaskStack[ portOFFSET_TO_PC ]; + + /* If the request did not come from the system call section, do nothing. */ + if( ( ulSystemCallLocation >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulSystemCallLocation <= ( uint32_t ) __syscalls_flash_end__ ) ) { - pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ - *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ - pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pxCode; /* PC */ - pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR */ - pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ - *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ - pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */ - *pxTopOfStack = portINITIAL_EXC_RETURN; + pxMpuSettings = xTaskGetMPUSettings( pxCurrentTCB ); + pulSystemCallStack = pxMpuSettings->xSystemCallStackInfo.pulSystemCallStack; - #if ( configENABLE_MPU == 1 ) + /* This is not NULL only for the duration of the system call. */ + configASSERT( pxMpuSettings->xSystemCallStackInfo.pulTaskStack == NULL ); + + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) { - pxTopOfStack--; + if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) + { + /* Extended frame i.e. FPU in use. */ + ulStackFrameSize = 26; + __asm volatile ( + " vpush {s0} \n" /* Trigger lazy stacking. */ + " vpop {s0} \n" /* Nullify the affect of the above instruction. */ + ::: "memory" + ); + } + else + { + /* Standard frame i.e. FPU not in use. */ + ulStackFrameSize = 8; + } + } + #else + { + ulStackFrameSize = 8; + } + #endif /* configENABLE_FPU || configENABLE_MVE */ + + /* Make space on the system call stack for the stack frame. */ + pulSystemCallStack = pulSystemCallStack - ulStackFrameSize; + + /* Copy the stack frame. */ + for( i = 0; i < ulStackFrameSize; i++ ) + { + pulSystemCallStack[ i ] = pulTaskStack[ i ]; + } + + /* Store the value of the LR and PSPLIM registers before the SVC was raised. We need to + * restore it when we exit from the system call. */ + pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; + __asm volatile ( "mrs %0, psplim" : "=r" ( pxMpuSettings->xSystemCallStackInfo.ulStackLimitRegisterAtSystemCallEntry ) ); + + /* Use the pulSystemCallStack in thread mode. */ + __asm volatile ( "msr psp, %0" : : "r" ( pulSystemCallStack ) ); + __asm volatile ( "msr psplim, %0" : : "r" ( pxMpuSettings->xSystemCallStackInfo.pulSystemCallStackLimit ) ); + + /* Remember the location where we should copy the stack frame when we exit from + * the system call. */ + pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulStackFrameSize; + + /* Record if the hardware used padding to force the stack pointer + * to be double word aligned. */ + if( ( pulTaskStack[ portOFFSET_TO_PSR ] & portPSR_STACK_PADDING_MASK ) == portPSR_STACK_PADDING_MASK ) + { + pxMpuSettings->ulTaskFlags |= portSTACK_FRAME_HAS_PADDING_FLAG; + } + else + { + pxMpuSettings->ulTaskFlags &= ( ~portSTACK_FRAME_HAS_PADDING_FLAG ); + } + + /* We ensure in pxPortInitialiseStack that the system call stack is + * double word aligned and therefore, there is no need of padding. + * Clear the bit[9] of stacked xPSR. */ + pulSystemCallStack[ portOFFSET_TO_PSR ] &= ( ~portPSR_STACK_PADDING_MASK ); + + /* Raise the privilege for the duration of the system call. */ + __asm volatile ( + " mrs r0, control \n" /* Obtain current control value. */ + " movs r1, #1 \n" /* r1 = 1. */ + " bics r0, r1 \n" /* Clear nPRIV bit. */ + " msr control, r0 \n" /* Write back new control value. */ + ::: "r0", "r1", "memory" + ); + } +} - if( xRunPrivileged == pdTRUE ) +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + +void vSystemCallEnter_1( uint32_t * pulTaskStack, uint32_t ulLR ) /* PRIVILEGED_FUNCTION */ +{ + extern TaskHandle_t pxCurrentTCB; + xMPU_SETTINGS * pxMpuSettings; + uint32_t * pulSystemCallStack; + uint32_t ulStackFrameSize, ulSystemCallLocation, i; + #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being + * exported from linker scripts. */ + extern uint32_t * __syscalls_flash_start__; + extern uint32_t * __syscalls_flash_end__; + #else + /* Declaration when these variable are exported from linker scripts. */ + extern uint32_t __syscalls_flash_start__[]; + extern uint32_t __syscalls_flash_end__[]; + #endif /* #if defined( __ARMCC_VERSION ) */ + + ulSystemCallLocation = pulTaskStack[ portOFFSET_TO_PC ]; + + /* If the request did not come from the system call section, do nothing. */ + if( ( ulSystemCallLocation >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulSystemCallLocation <= ( uint32_t ) __syscalls_flash_end__ ) ) + { + pxMpuSettings = xTaskGetMPUSettings( pxCurrentTCB ); + pulSystemCallStack = pxMpuSettings->xSystemCallStackInfo.pulSystemCallStack; + + /* This is not NULL only for the duration of the system call. */ + configASSERT( pxMpuSettings->xSystemCallStackInfo.pulTaskStack == NULL ); + + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + { + if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) { - *pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */ + /* Extended frame i.e. FPU in use. */ + ulStackFrameSize = 26; + __asm volatile ( + " vpush {s0} \n" /* Trigger lazy stacking. */ + " vpop {s0} \n" /* Nullify the affect of the above instruction. */ + ::: "memory" + ); } else { - *pxTopOfStack = portINITIAL_CONTROL_UNPRIVILEGED; /* Slot used to hold this task's CONTROL value. */ + /* Standard frame i.e. FPU not in use. */ + ulStackFrameSize = 8; } } - #endif /* configENABLE_MPU */ + #else + { + ulStackFrameSize = 8; + } + #endif /* configENABLE_FPU || configENABLE_MVE */ + + /* Make space on the system call stack for the stack frame and + * the parameter passed on the stack. We only need to copy one + * parameter but we still reserve 2 spaces to keep the stack + * double word aligned. */ + pulSystemCallStack = pulSystemCallStack - ulStackFrameSize - 2UL; + + /* Copy the stack frame. */ + for( i = 0; i < ulStackFrameSize; i++ ) + { + pulSystemCallStack[ i ] = pulTaskStack[ i ]; + } + + /* Copy the parameter which is passed the stack. */ + if( ( pulTaskStack[ portOFFSET_TO_PSR ] & portPSR_STACK_PADDING_MASK ) == portPSR_STACK_PADDING_MASK ) + { + pulSystemCallStack[ ulStackFrameSize ] = pulTaskStack[ ulStackFrameSize + 1 ]; + /* Record if the hardware used padding to force the stack pointer + * to be double word aligned. */ + pxMpuSettings->ulTaskFlags |= portSTACK_FRAME_HAS_PADDING_FLAG; + } + else + { + pulSystemCallStack[ ulStackFrameSize ] = pulTaskStack[ ulStackFrameSize ]; + /* Record if the hardware used padding to force the stack pointer + * to be double word aligned. */ + pxMpuSettings->ulTaskFlags &= ( ~portSTACK_FRAME_HAS_PADDING_FLAG ); + } + + /* Store the value of the LR and PSPLIM registers before the SVC was raised. + * We need to restore it when we exit from the system call. */ + pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; + __asm volatile ( "mrs %0, psplim" : "=r" ( pxMpuSettings->xSystemCallStackInfo.ulStackLimitRegisterAtSystemCallEntry ) ); + + /* Use the pulSystemCallStack in thread mode. */ + __asm volatile ( "msr psp, %0" : : "r" ( pulSystemCallStack ) ); + __asm volatile ( "msr psplim, %0" : : "r" ( pxMpuSettings->xSystemCallStackInfo.pulSystemCallStackLimit ) ); + + /* Remember the location where we should copy the stack frame when we exit from + * the system call. */ + pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulStackFrameSize; + + /* We ensure in pxPortInitialiseStack that the system call stack is + * double word aligned and therefore, there is no need of padding. + * Clear the bit[9] of stacked xPSR. */ + pulSystemCallStack[ portOFFSET_TO_PSR ] &= ( ~portPSR_STACK_PADDING_MASK ); + + /* Raise the privilege for the duration of the system call. */ + __asm volatile ( + " mrs r0, control \n" /* Obtain current control value. */ + " movs r1, #1 \n" /* r1 = 1. */ + " bics r0, r1 \n" /* Clear nPRIV bit. */ + " msr control, r0 \n" /* Write back new control value. */ + ::: "r0", "r1", "memory" + ); + } +} + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) +void vSystemCallExit( uint32_t * pulSystemCallStack, uint32_t ulLR ) /* PRIVILEGED_FUNCTION */ +{ + extern TaskHandle_t pxCurrentTCB; + xMPU_SETTINGS * pxMpuSettings; + uint32_t * pulTaskStack; + uint32_t ulStackFrameSize, ulSystemCallLocation, i; + #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being + * exported from linker scripts. */ + extern uint32_t * __syscalls_flash_start__; + extern uint32_t * __syscalls_flash_end__; + #else + /* Declaration when these variable are exported from linker scripts. */ + extern uint32_t __syscalls_flash_start__[]; + extern uint32_t __syscalls_flash_end__[]; + #endif /* #if defined( __ARMCC_VERSION ) */ + + ulSystemCallLocation = pulSystemCallStack[ portOFFSET_TO_PC ]; + + /* If the request did not come from the system call section, do nothing. */ + if( ( ulSystemCallLocation >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulSystemCallLocation <= ( uint32_t ) __syscalls_flash_end__ ) ) + { + pxMpuSettings = xTaskGetMPUSettings( pxCurrentTCB ); + pulTaskStack = pxMpuSettings->xSystemCallStackInfo.pulTaskStack; + + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + { + if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) + { + /* Extended frame i.e. FPU in use. */ + ulStackFrameSize = 26; + __asm volatile ( + " vpush {s0} \n" /* Trigger lazy stacking. */ + " vpop {s0} \n" /* Nullify the affect of the above instruction. */ + ::: "memory" + ); + } + else + { + /* Standard frame i.e. FPU not in use. */ + ulStackFrameSize = 8; + } + } + #else + { + ulStackFrameSize = 8; + } + #endif /* configENABLE_FPU || configENABLE_MVE */ + + /* Make space on the task stack for the stack frame. */ + pulTaskStack = pulTaskStack - ulStackFrameSize; + + /* Copy the stack frame. */ + for( i = 0; i < ulStackFrameSize; i++ ) + { + pulTaskStack[ i ] = pulSystemCallStack[ i ]; + } + + /* Use the pulTaskStack in thread mode. */ + __asm volatile ( "msr psp, %0" : : "r" ( pulTaskStack ) ); + + /* Restore the LR and PSPLIM to what they were at the time of + * system call entry. */ + pulTaskStack[ portOFFSET_TO_LR ] = pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry; + __asm volatile ( "msr psplim, %0" : : "r" ( pxMpuSettings->xSystemCallStackInfo.ulStackLimitRegisterAtSystemCallEntry ) ); + + /* If the hardware used padding to force the stack pointer + * to be double word aligned, set the stacked xPSR bit[9], + * otherwise clear it. */ + if( ( pxMpuSettings->ulTaskFlags & portSTACK_FRAME_HAS_PADDING_FLAG ) == portSTACK_FRAME_HAS_PADDING_FLAG ) + { + pulTaskStack[ portOFFSET_TO_PSR ] |= portPSR_STACK_PADDING_MASK; + } + else + { + pulTaskStack[ portOFFSET_TO_PSR ] &= ( ~portPSR_STACK_PADDING_MASK ); + } + + /* This is not NULL only for the duration of the system call. */ + pxMpuSettings->xSystemCallStackInfo.pulTaskStack = NULL; + + /* Drop the privilege before returning to the thread mode. */ + __asm volatile ( + " mrs r0, control \n" /* Obtain current control value. */ + " movs r1, #1 \n" /* r1 = 1. */ + " orrs r0, r1 \n" /* Set nPRIV bit. */ + " msr control, r0 \n" /* Write back new control value. */ + ::: "r0", "r1", "memory" + ); + } +} + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configENABLE_MPU == 1 ) + +BaseType_t xPortIsTaskPrivileged( void ) /* PRIVILEGED_FUNCTION */ +{ + BaseType_t xTaskIsPrivileged = pdFALSE; + const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */ + + if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) + { + xTaskIsPrivileged = pdTRUE; + } + + return xTaskIsPrivileged; +} + +#endif /* configENABLE_MPU == 1 */ +/*-----------------------------------------------------------*/ + +#if( configENABLE_MPU == 1 ) + +StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, + StackType_t * pxEndOfStack, + TaskFunction_t pxCode, + void * pvParameters, + BaseType_t xRunPrivileged, + xMPU_SETTINGS * xMPUSettings ) /* PRIVILEGED_FUNCTION */ +{ + uint32_t ulIndex = 0; + + xMPUSettings->ulContext[ ulIndex ] = 0x04040404; /* r4. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x05050505; /* r5. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x06060606; /* r6. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x07070707; /* r7. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x08080808; /* r8. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x09090909; /* r9. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x10101010; /* r10. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x11111111; /* r11. */ + ulIndex++; + + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pvParameters; /* r0. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x01010101; /* r1. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x02020202; /* r2. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x03030303; /* r3. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x12121212; /* r12. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portTASK_RETURN_ADDRESS; /* LR. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxCode; /* PC. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = portINITIAL_XPSR; /* xPSR. */ + ulIndex++; + + #if ( configENABLE_TRUSTZONE == 1 ) + { + xMPUSettings->ulContext[ ulIndex ] = portNO_SECURE_CONTEXT; /* xSecureContext. */ + ulIndex++; + } + #endif /* configENABLE_TRUSTZONE */ + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) ( pxTopOfStack - 8 ); /* PSP with the hardware saved stack. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */ + ulIndex++; + if( xRunPrivileged == pdTRUE ) + { + xMPUSettings->ulTaskFlags |= portTASK_IS_PRIVILEGED_FLAG; + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_PRIVILEGED; /* CONTROL. */ + ulIndex++; + } + else + { + xMPUSettings->ulTaskFlags &= ( ~portTASK_IS_PRIVILEGED_FLAG ); + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_UNPRIVILEGED; /* CONTROL. */ + ulIndex++; + } + xMPUSettings->ulContext[ ulIndex ] = portINITIAL_EXC_RETURN; /* LR (EXC_RETURN). */ + ulIndex++; + + #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + { + /* Ensure that the system call stack is double word aligned. */ + xMPUSettings->xSystemCallStackInfo.pulSystemCallStack = &( xMPUSettings->xSystemCallStackInfo.ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE - 1 ] ); + xMPUSettings->xSystemCallStackInfo.pulSystemCallStack = ( uint32_t * ) ( ( uint32_t ) ( xMPUSettings->xSystemCallStackInfo.pulSystemCallStack ) & + ( uint32_t ) ( ~( portBYTE_ALIGNMENT_MASK ) ) ); + + xMPUSettings->xSystemCallStackInfo.pulSystemCallStackLimit = &( xMPUSettings->xSystemCallStackInfo.ulSystemCallStackBuffer[ 0 ] ); + xMPUSettings->xSystemCallStackInfo.pulSystemCallStackLimit = ( uint32_t * ) ( ( ( uint32_t ) ( xMPUSettings->xSystemCallStackInfo.pulSystemCallStackLimit ) + + ( uint32_t ) ( portBYTE_ALIGNMENT - 1 ) ) & + ( uint32_t ) ( ~( portBYTE_ALIGNMENT_MASK ) ) ); + + /* This is not NULL only for the duration of a system call. */ + xMPUSettings->xSystemCallStackInfo.pulTaskStack = NULL; + } + #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + + return &( xMPUSettings->ulContext[ ulIndex ] ); +} + +#else /* configENABLE_MPU */ + +StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, + StackType_t * pxEndOfStack, + TaskFunction_t pxCode, + void * pvParameters ) /* PRIVILEGED_FUNCTION */ +{ + /* Simulate the stack frame as it would be created by a context switch + * interrupt. */ + #if ( portPRELOAD_REGISTERS == 0 ) + { + pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ + *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR. */ + pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ + pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */ + *pxTopOfStack = portINITIAL_EXC_RETURN; pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ @@ -1029,55 +1561,39 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO #else /* portPRELOAD_REGISTERS */ { pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ - *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ + *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pxCode; /* PC */ + *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR */ + *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x12121212UL; /* R12 */ + *pxTopOfStack = ( StackType_t ) 0x12121212UL; /* R12. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x03030303UL; /* R3 */ + *pxTopOfStack = ( StackType_t ) 0x03030303UL; /* R3. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x02020202UL; /* R2 */ + *pxTopOfStack = ( StackType_t ) 0x02020202UL; /* R2. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x01010101UL; /* R1 */ + *pxTopOfStack = ( StackType_t ) 0x01010101UL; /* R1. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x11111111UL; /* R11 */ + *pxTopOfStack = ( StackType_t ) 0x11111111UL; /* R11. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x10101010UL; /* R10 */ + *pxTopOfStack = ( StackType_t ) 0x10101010UL; /* R10. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x09090909UL; /* R09 */ + *pxTopOfStack = ( StackType_t ) 0x09090909UL; /* R09. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x08080808UL; /* R08 */ + *pxTopOfStack = ( StackType_t ) 0x08080808UL; /* R08. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x07070707UL; /* R07 */ + *pxTopOfStack = ( StackType_t ) 0x07070707UL; /* R07. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x06060606UL; /* R06 */ + *pxTopOfStack = ( StackType_t ) 0x06060606UL; /* R06. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x05050505UL; /* R05 */ + *pxTopOfStack = ( StackType_t ) 0x05050505UL; /* R05. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x04040404UL; /* R04 */ + *pxTopOfStack = ( StackType_t ) 0x04040404UL; /* R04. */ pxTopOfStack--; - *pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN */ - - #if ( configENABLE_MPU == 1 ) - { - pxTopOfStack--; - - if( xRunPrivileged == pdTRUE ) - { - *pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */ - } - else - { - *pxTopOfStack = portINITIAL_CONTROL_UNPRIVILEGED; /* Slot used to hold this task's CONTROL value. */ - } - } - #endif /* configENABLE_MPU */ - + *pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN. */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ @@ -1092,6 +1608,8 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO return pxTopOfStack; } + +#endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ @@ -1128,6 +1646,10 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ configASSERT( ucMaxSysCallPriority ); + /* Check that the bits not implemented in hardware are zero in + * configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & ( ~ucMaxPriorityValue ) ) == 0U ); + /* Calculate the maximum acceptable priority group value for the number * of bits read back. */ @@ -1164,35 +1686,6 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulImplementedPrioBits; } - /* The interrupt priority bits are not modelled in QEMU and the assert that - * checks the number of implemented bits and __NVIC_PRIO_BITS will always fail. - * Therefore, this assert is not adding any value for QEMU targets. The config - * option `configDISABLE_INTERRUPT_PRIO_BITS_CHECK` should be defined in the - * `FreeRTOSConfig.h` for QEMU targets. */ - #ifndef configDISABLE_INTERRUPT_PRIO_BITS_CHECK - { - #ifdef __NVIC_PRIO_BITS - { - /* - * Check that the number of implemented priority bits queried from - * hardware is equal to the CMSIS __NVIC_PRIO_BITS configuration macro. - */ - configASSERT( ulImplementedPrioBits == __NVIC_PRIO_BITS ); - } - #endif /* __NVIC_PRIO_BITS */ - - #ifdef configPRIO_BITS - { - /* - * Check that the number of implemented priority bits queried from - * hardware is equal to the FreeRTOS configPRIO_BITS configuration macro. - */ - configASSERT( ulImplementedPrioBits == configPRIO_BITS ); - } - #endif /* configPRIO_BITS */ - } - #endif /* #ifndef configDISABLE_INTERRUPT_PRIO_BITS_CHECK */ - /* Shift the priority group value back to its position within the AIRCR * register. */ ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT; @@ -1372,6 +1865,54 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ +#if ( configENABLE_MPU == 1 ) + BaseType_t xPortIsAuthorizedToAccessBuffer( const void * pvBuffer, + uint32_t ulBufferLength, + uint32_t ulAccessRequested ) /* PRIVILEGED_FUNCTION */ + + { + uint32_t i, ulBufferStartAddress, ulBufferEndAddress; + BaseType_t xAccessGranted = pdFALSE; + const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */ + + if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) + { + xAccessGranted = pdTRUE; + } + else + { + if( portADD_UINT32_WILL_OVERFLOW( ( ( uint32_t ) pvBuffer ), ( ulBufferLength - 1UL ) ) == pdFALSE ) + { + ulBufferStartAddress = ( uint32_t ) pvBuffer; + ulBufferEndAddress = ( ( ( uint32_t ) pvBuffer ) + ulBufferLength - 1UL ); + + for( i = 0; i < portTOTAL_NUM_REGIONS; i++ ) + { + /* Is the MPU region enabled? */ + if( ( xTaskMpuSettings->xRegionsSettings[ i ].ulRLAR & portMPU_RLAR_REGION_ENABLE ) == portMPU_RLAR_REGION_ENABLE ) + { + if( portIS_ADDRESS_WITHIN_RANGE( ulBufferStartAddress, + portEXTRACT_FIRST_ADDRESS_FROM_RBAR( xTaskMpuSettings->xRegionsSettings[ i ].ulRBAR ), + portEXTRACT_LAST_ADDRESS_FROM_RLAR( xTaskMpuSettings->xRegionsSettings[ i ].ulRLAR ) ) && + portIS_ADDRESS_WITHIN_RANGE( ulBufferEndAddress, + portEXTRACT_FIRST_ADDRESS_FROM_RBAR( xTaskMpuSettings->xRegionsSettings[ i ].ulRBAR ), + portEXTRACT_LAST_ADDRESS_FROM_RLAR( xTaskMpuSettings->xRegionsSettings[ i ].ulRLAR ) ) && + portIS_AUTHORIZED( ulAccessRequested, + prvGetRegionAccessPermissions( xTaskMpuSettings->xRegionsSettings[ i ].ulRBAR ) ) ) + { + xAccessGranted = pdTRUE; + break; + } + } + } + } + } + + return xAccessGranted; + } +#endif /* configENABLE_MPU */ +/*-----------------------------------------------------------*/ + BaseType_t xPortIsInsideInterrupt( void ) { uint32_t ulCurrentInterrupt; diff --git a/portable/IAR/ARM_CM55_NTZ/non_secure/portasm.s b/portable/IAR/ARM_CM55_NTZ/non_secure/portasm.s index 581b84d4951..ec52025270b 100644 --- a/portable/IAR/ARM_CM55_NTZ/non_secure/portasm.s +++ b/portable/IAR/ARM_CM55_NTZ/non_secure/portasm.s @@ -32,9 +32,18 @@ the code is included in C files but excluded by the preprocessor in assembly files (__ICCARM__ is defined by the IAR C compiler but not by the IAR assembler. */ #include "FreeRTOSConfig.h" +#ifndef configUSE_MPU_WRAPPERS_V1 + #define configUSE_MPU_WRAPPERS_V1 0 +#endif + EXTERN pxCurrentTCB EXTERN vTaskSwitchContext EXTERN vPortSVCHandler_C +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + EXTERN vSystemCallEnter + EXTERN vSystemCallEnter_1 + EXTERN vSystemCallExit +#endif PUBLIC xIsPrivileged PUBLIC vResetPrivilege @@ -79,48 +88,79 @@ vResetPrivilege: THUMB /*-----------------------------------------------------------*/ +#if ( configENABLE_MPU == 1 ) + +vRestoreContextOfFirstTask: + program_mpu_first_task: + ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + ldr r0, [r2] /* r0 = pxCurrentTCB. */ + + dmb /* Complete outstanding transfers before disabling MPU. */ + ldr r1, =0xe000ed94 /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + ldr r2, [r1] /* Read the value of MPU_CTRL. */ + bic r2, #1 /* r2 = r2 & ~1 i.e. Clear the bit 0 in r2. */ + str r2, [r1] /* Disable MPU. */ + + adds r0, #4 /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */ + ldr r1, [r0] /* r1 = *r0 i.e. r1 = MAIR0. */ + ldr r2, =0xe000edc0 /* r2 = 0xe000edc0 [Location of MAIR0]. */ + str r1, [r2] /* Program MAIR0. */ + + adds r0, #4 /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */ + ldr r1, =0xe000ed98 /* r1 = 0xe000ed98 [Location of RNR]. */ + ldr r2, =0xe000ed9c /* r2 = 0xe000ed9c [Location of RBAR]. */ + + movs r3, #4 /* r3 = 4. */ + str r3, [r1] /* Program RNR = 4. */ + ldmia r0!, {r4-r11} /* Read 4 sets of RBAR/RLAR registers from TCB. */ + stmia r2, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ + + #if ( configTOTAL_MPU_REGIONS == 16 ) + movs r3, #8 /* r3 = 8. */ + str r3, [r1] /* Program RNR = 8. */ + ldmia r0!, {r4-r11} /* Read 4 sets of RBAR/RLAR registers from TCB. */ + stmia r2, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ + movs r3, #12 /* r3 = 12. */ + str r3, [r1] /* Program RNR = 12. */ + ldmia r0!, {r4-r11} /* Read 4 sets of RBAR/RLAR registers from TCB. */ + stmia r2, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ + #endif /* configTOTAL_MPU_REGIONS == 16 */ + + ldr r1, =0xe000ed94 /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + ldr r2, [r1] /* Read the value of MPU_CTRL. */ + orr r2, #1 /* r2 = r2 | 1 i.e. Set the bit 0 in r2. */ + str r2, [r1] /* Enable MPU. */ + dsb /* Force memory writes before continuing. */ + + restore_context_first_task: + ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + ldr r0, [r2] /* r0 = pxCurrentTCB.*/ + ldr r1, [r0] /* r1 = Location of saved context in TCB. */ + + restore_special_regs_first_task: + ldmdb r1!, {r2-r4, lr} /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */ + msr psp, r2 + msr psplim, r3 + msr control, r4 + + restore_general_regs_first_task: + ldmdb r1!, {r4-r11} /* r4-r11 contain hardware saved context. */ + stmia r2!, {r4-r11} /* Copy the hardware saved context on the task stack. */ + ldmdb r1!, {r4-r11} /* r4-r11 restored. */ + + restore_context_done_first_task: + str r1, [r0] /* Save the location where the context should be saved next as the first member of TCB. */ + mov r0, #0 + msr basepri, r0 /* Ensure that interrupts are enabled when the first task starts. */ + bx lr + +#else /* configENABLE_MPU */ + vRestoreContextOfFirstTask: ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r2] /* Read pxCurrentTCB. */ ldr r0, [r1] /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ -#if ( configENABLE_MPU == 1 ) - dmb /* Complete outstanding transfers before disabling MPU. */ - ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ - ldr r4, [r2] /* Read the value of MPU_CTRL. */ - bic r4, r4, #1 /* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */ - str r4, [r2] /* Disable MPU. */ - - adds r1, #4 /* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */ - ldr r3, [r1] /* r3 = *r1 i.e. r3 = MAIR0. */ - ldr r2, =0xe000edc0 /* r2 = 0xe000edc0 [Location of MAIR0]. */ - str r3, [r2] /* Program MAIR0. */ - ldr r2, =0xe000ed98 /* r2 = 0xe000ed98 [Location of RNR]. */ - movs r3, #4 /* r3 = 4. */ - str r3, [r2] /* Program RNR = 4. */ - adds r1, #4 /* r1 = r1 + 4. r1 now points to first RBAR in TCB. */ - ldr r2, =0xe000ed9c /* r2 = 0xe000ed9c [Location of RBAR]. */ - ldmia r1!, {r4-r11} /* Read 4 sets of RBAR/RLAR registers from TCB. */ - stmia r2!, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ - - ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ - ldr r4, [r2] /* Read the value of MPU_CTRL. */ - orr r4, r4, #1 /* r4 = r4 | 1 i.e. Set the bit 0 in r4. */ - str r4, [r2] /* Enable MPU. */ - dsb /* Force memory writes before continuing. */ -#endif /* configENABLE_MPU */ - -#if ( configENABLE_MPU == 1 ) - ldm r0!, {r1-r3} /* Read from stack - r1 = PSPLIM, r2 = CONTROL and r3 = EXC_RETURN. */ - msr psplim, r1 /* Set this task's PSPLIM value. */ - msr control, r2 /* Set this task's CONTROL value. */ - adds r0, #32 /* Discard everything up to r0. */ - msr psp, r0 /* This is now the new top of stack to use in the task. */ - isb - mov r0, #0 - msr basepri, r0 /* Ensure that interrupts are enabled when the first task starts. */ - bx r3 /* Finally, branch to EXC_RETURN. */ -#else /* configENABLE_MPU */ ldm r0!, {r1-r2} /* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */ msr psplim, r1 /* Set this task's PSPLIM value. */ movs r1, #2 /* r1 = 2. */ @@ -131,6 +171,7 @@ vRestoreContextOfFirstTask: mov r0, #0 msr basepri, r0 /* Ensure that interrupts are enabled when the first task starts. */ bx r2 /* Finally, branch to EXC_RETURN. */ + #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ @@ -169,6 +210,114 @@ vClearInterruptMask: bx lr /* Return. */ /*-----------------------------------------------------------*/ +#if ( configENABLE_MPU == 1 ) + +PendSV_Handler: + ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + ldr r0, [r2] /* r0 = pxCurrentTCB. */ + ldr r1, [r0] /* r1 = Location in TCB where the context should be saved. */ + mrs r2, psp /* r2 = PSP. */ + + save_general_regs: + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + add r2, r2, #0x20 /* Move r2 to location where s0 is saved. */ + tst lr, #0x10 + ittt eq + vstmiaeq r1!, {s16-s31} /* Store s16-s31. */ + vldmiaeq r2, {s0-s16} /* Copy hardware saved FP context into s0-s16. */ + vstmiaeq r1!, {s0-s16} /* Store hardware saved FP context. */ + sub r2, r2, #0x20 /* Set r2 back to the location of hardware saved context. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ + + stmia r1!, {r4-r11} /* Store r4-r11. */ + ldmia r2, {r4-r11} /* Copy the hardware saved context into r4-r11. */ + stmia r1!, {r4-r11} /* Store the hardware saved context. */ + + save_special_regs: + mrs r3, psplim /* r3 = PSPLIM. */ + mrs r4, control /* r4 = CONTROL. */ + stmia r1!, {r2-r4, lr} /* Store original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */ + str r1, [r0] /* Save the location from where the context should be restored as the first member of TCB. */ + + select_next_task: + mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY + msr basepri, r0 /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + dsb + isb + bl vTaskSwitchContext + mov r0, #0 /* r0 = 0. */ + msr basepri, r0 /* Enable interrupts. */ + + program_mpu: + ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + ldr r0, [r2] /* r0 = pxCurrentTCB. */ + + dmb /* Complete outstanding transfers before disabling MPU. */ + ldr r1, =0xe000ed94 /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + ldr r2, [r1] /* Read the value of MPU_CTRL. */ + bic r2, #1 /* r2 = r2 & ~1 i.e. Clear the bit 0 in r2. */ + str r2, [r1] /* Disable MPU. */ + + adds r0, #4 /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */ + ldr r1, [r0] /* r1 = *r0 i.e. r1 = MAIR0. */ + ldr r2, =0xe000edc0 /* r2 = 0xe000edc0 [Location of MAIR0]. */ + str r1, [r2] /* Program MAIR0. */ + + adds r0, #4 /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */ + ldr r1, =0xe000ed98 /* r1 = 0xe000ed98 [Location of RNR]. */ + ldr r2, =0xe000ed9c /* r2 = 0xe000ed9c [Location of RBAR]. */ + + movs r3, #4 /* r3 = 4. */ + str r3, [r1] /* Program RNR = 4. */ + ldmia r0!, {r4-r11} /* Read 4 sets of RBAR/RLAR registers from TCB. */ + stmia r2, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ + + #if ( configTOTAL_MPU_REGIONS == 16 ) + movs r3, #8 /* r3 = 8. */ + str r3, [r1] /* Program RNR = 8. */ + ldmia r0!, {r4-r11} /* Read 4 sets of RBAR/RLAR registers from TCB. */ + stmia r2, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ + movs r3, #12 /* r3 = 12. */ + str r3, [r1] /* Program RNR = 12. */ + ldmia r0!, {r4-r11} /* Read 4 sets of RBAR/RLAR registers from TCB. */ + stmia r2, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ + #endif /* configTOTAL_MPU_REGIONS == 16 */ + + ldr r1, =0xe000ed94 /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + ldr r2, [r1] /* Read the value of MPU_CTRL. */ + orr r2, #1 /* r2 = r2 | 1 i.e. Set the bit 0 in r2. */ + str r2, [r1] /* Enable MPU. */ + dsb /* Force memory writes before continuing. */ + + restore_context: + ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + ldr r0, [r2] /* r0 = pxCurrentTCB.*/ + ldr r1, [r0] /* r1 = Location of saved context in TCB. */ + + restore_special_regs: + ldmdb r1!, {r2-r4, lr} /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */ + msr psp, r2 + msr psplim, r3 + msr control, r4 + + restore_general_regs: + ldmdb r1!, {r4-r11} /* r4-r11 contain hardware saved context. */ + stmia r2!, {r4-r11} /* Copy the hardware saved context on the task stack. */ + ldmdb r1!, {r4-r11} /* r4-r11 restored. */ + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + tst lr, #0x10 + ittt eq + vldmdbeq r1!, {s0-s16} /* s0-s16 contain hardware saved FP context. */ + vstmiaeq r2!, {s0-s16} /* Copy hardware saved FP context on the task stack. */ + vldmdbeq r1!, {s16-s31} /* Restore s16-s31. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ + + restore_context_done: + str r1, [r0] /* Save the location where the context should be saved next as the first member of TCB. */ + bx lr + +#else /* configENABLE_MPU */ + PendSV_Handler: mrs r0, psp /* Read PSP in r0. */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) @@ -176,16 +325,10 @@ PendSV_Handler: it eq vstmdbeq r0!, {s16-s31} /* Store the additional FP context registers which are not saved automatically. */ #endif /* configENABLE_FPU || configENABLE_MVE */ -#if ( configENABLE_MPU == 1 ) - mrs r1, psplim /* r1 = PSPLIM. */ - mrs r2, control /* r2 = CONTROL. */ - mov r3, lr /* r3 = LR/EXC_RETURN. */ - stmdb r0!, {r1-r11} /* Store on the stack - PSPLIM, CONTROL, LR and registers that are not automatically saved. */ -#else /* configENABLE_MPU */ + mrs r2, psplim /* r2 = PSPLIM. */ mov r3, lr /* r3 = LR/EXC_RETURN. */ stmdb r0!, {r2-r11} /* Store on the stack - PSPLIM, LR and registers that are not automatically. */ -#endif /* configENABLE_MPU */ ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r2] /* Read pxCurrentTCB. */ @@ -203,37 +346,7 @@ PendSV_Handler: ldr r1, [r2] /* Read pxCurrentTCB. */ ldr r0, [r1] /* The first item in pxCurrentTCB is the task top of stack. r0 now points to the top of stack. */ -#if ( configENABLE_MPU == 1 ) - dmb /* Complete outstanding transfers before disabling MPU. */ - ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ - ldr r4, [r2] /* Read the value of MPU_CTRL. */ - bic r4, r4, #1 /* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */ - str r4, [r2] /* Disable MPU. */ - - adds r1, #4 /* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */ - ldr r3, [r1] /* r3 = *r1 i.e. r3 = MAIR0. */ - ldr r2, =0xe000edc0 /* r2 = 0xe000edc0 [Location of MAIR0]. */ - str r3, [r2] /* Program MAIR0. */ - ldr r2, =0xe000ed98 /* r2 = 0xe000ed98 [Location of RNR]. */ - movs r3, #4 /* r3 = 4. */ - str r3, [r2] /* Program RNR = 4. */ - adds r1, #4 /* r1 = r1 + 4. r1 now points to first RBAR in TCB. */ - ldr r2, =0xe000ed9c /* r2 = 0xe000ed9c [Location of RBAR]. */ - ldmia r1!, {r4-r11} /* Read 4 sets of RBAR/RLAR registers from TCB. */ - stmia r2!, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ - - ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ - ldr r4, [r2] /* Read the value of MPU_CTRL. */ - orr r4, r4, #1 /* r4 = r4 | 1 i.e. Set the bit 0 in r4. */ - str r4, [r2] /* Enable MPU. */ - dsb /* Force memory writes before continuing. */ -#endif /* configENABLE_MPU */ - -#if ( configENABLE_MPU == 1 ) - ldmia r0!, {r1-r11} /* Read from stack - r1 = PSPLIM, r2 = CONTROL, r3 = LR and r4-r11 restored. */ -#else /* configENABLE_MPU */ ldmia r0!, {r2-r11} /* Read from stack - r2 = PSPLIM, r3 = LR and r4-r11 restored. */ -#endif /* configENABLE_MPU */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) tst r3, #0x10 /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ @@ -241,22 +354,53 @@ PendSV_Handler: vldmiaeq r0!, {s16-s31} /* Restore the additional FP context registers which are not restored automatically. */ #endif /* configENABLE_FPU || configENABLE_MVE */ - #if ( configENABLE_MPU == 1 ) - msr psplim, r1 /* Restore the PSPLIM register value for the task. */ - msr control, r2 /* Restore the CONTROL register value for the task. */ -#else /* configENABLE_MPU */ msr psplim, r2 /* Restore the PSPLIM register value for the task. */ -#endif /* configENABLE_MPU */ msr psp, r0 /* Remember the new top of stack for the task. */ bx r3 + +#endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + +SVC_Handler: + tst lr, #4 + ite eq + mrseq r0, msp + mrsne r0, psp + + ldr r1, [r0, #24] + ldrb r2, [r1, #-2] + cmp r2, #4 /* portSVC_SYSTEM_CALL_ENTER. */ + beq syscall_enter + cmp r2, #5 /* portSVC_SYSTEM_CALL_ENTER_1. */ + beq syscall_enter_1 + cmp r2, #6 /* portSVC_SYSTEM_CALL_EXIT. */ + beq syscall_exit + b vPortSVCHandler_C + + syscall_enter: + mov r1, lr + b vSystemCallEnter + + syscall_enter_1: + mov r1, lr + b vSystemCallEnter_1 + + syscall_exit: + mov r1, lr + b vSystemCallExit + +#else /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + SVC_Handler: tst lr, #4 ite eq mrseq r0, msp mrsne r0, psp b vPortSVCHandler_C + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ /*-----------------------------------------------------------*/ END diff --git a/portable/IAR/ARM_CM55_NTZ/non_secure/portmacrocommon.h b/portable/IAR/ARM_CM55_NTZ/non_secure/portmacrocommon.h index c2ca5fa7730..65ac109c802 100644 --- a/portable/IAR/ARM_CM55_NTZ/non_secure/portmacrocommon.h +++ b/portable/IAR/ARM_CM55_NTZ/non_secure/portmacrocommon.h @@ -186,23 +186,120 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #define portMPU_REGION_EXECUTE_NEVER ( 1UL ) /*-----------------------------------------------------------*/ -/** - * @brief Settings to define an MPU region. - */ -typedef struct MPURegionSettings -{ - uint32_t ulRBAR; /**< RBAR for the region. */ - uint32_t ulRLAR; /**< RLAR for the region. */ -} MPURegionSettings_t; +#if ( configENABLE_MPU == 1 ) -/** - * @brief MPU settings as stored in the TCB. - */ -typedef struct MPU_SETTINGS -{ - uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ - MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */ -} xMPU_SETTINGS; + /** + * @brief Settings to define an MPU region. + */ + typedef struct MPURegionSettings + { + uint32_t ulRBAR; /**< RBAR for the region. */ + uint32_t ulRLAR; /**< RLAR for the region. */ + } MPURegionSettings_t; + + #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + + #ifndef configSYSTEM_CALL_STACK_SIZE + #error configSYSTEM_CALL_STACK_SIZE must be defined to the desired size of the system call stack in words for using MPU wrappers v2. + #endif + + /** + * @brief System call stack. + */ + typedef struct SYSTEM_CALL_STACK_INFO + { + uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ]; + uint32_t * pulSystemCallStack; + uint32_t * pulSystemCallStackLimit; + uint32_t * pulTaskStack; + uint32_t ulLinkRegisterAtSystemCallEntry; + uint32_t ulStackLimitRegisterAtSystemCallEntry; + } xSYSTEM_CALL_STACK_INFO; + + #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + + /** + * @brief MPU settings as stored in the TCB. + */ + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + + #if( configENABLE_TRUSTZONE == 1 ) + + /* + * +-----------+---------------+----------+-----------------+------------------------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | + * | | | | PC, xPSR | CONTROL, EXC_RETURN | | + * +-----------+---------------+----------+-----------------+------------------------------+-----+ + * + * <-----------><--------------><---------><----------------><-----------------------------><----> + * 16 16 8 8 5 1 + */ + #define MAX_CONTEXT_SIZE 54 + + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ + + /* + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | + * | | | | PC, xPSR | EXC_RETURN | | + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * + * <-----------><--------------><---------><----------------><---------------------><----> + * 16 16 8 8 4 1 + */ + #define MAX_CONTEXT_SIZE 53 + + #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + + #else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ + + #if( configENABLE_TRUSTZONE == 1 ) + + /* + * +----------+-----------------+------------------------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | + * | | PC, xPSR | CONTROL, EXC_RETURN | | + * +----------+-----------------+------------------------------+-----+ + * + * <---------><----------------><------------------------------><----> + * 8 8 5 1 + */ + #define MAX_CONTEXT_SIZE 22 + + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ + + /* + * +----------+-----------------+----------------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | + * | | PC, xPSR | EXC_RETURN | | + * +----------+-----------------+----------------------+-----+ + * + * <---------><----------------><----------------------><----> + * 8 8 4 1 + */ + #define MAX_CONTEXT_SIZE 21 + + #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + + #endif /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ + + /* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ + #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) + #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) + + typedef struct MPU_SETTINGS + { + uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ + MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */ + uint32_t ulContext[ MAX_CONTEXT_SIZE ]; + uint32_t ulTaskFlags; + + #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo; + #endif + } xMPU_SETTINGS; + +#endif /* configENABLE_MPU == 1 */ /*-----------------------------------------------------------*/ /** @@ -223,6 +320,9 @@ typedef struct MPU_SETTINGS #define portSVC_FREE_SECURE_CONTEXT 1 #define portSVC_START_SCHEDULER 2 #define portSVC_RAISE_PRIVILEGE 3 +#define portSVC_SYSTEM_CALL_ENTER 4 /* System calls with upto 4 parameters. */ +#define portSVC_SYSTEM_CALL_ENTER_1 5 /* System calls with 5 parameters. */ +#define portSVC_SYSTEM_CALL_EXIT 6 /*-----------------------------------------------------------*/ /** @@ -315,6 +415,20 @@ typedef struct MPU_SETTINGS #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ +#if ( configENABLE_MPU == 1 ) + + extern BaseType_t xPortIsTaskPrivileged( void ); + + /** + * @brief Checks whether or not the calling task is privileged. + * + * @return pdTRUE if the calling task is privileged, pdFALSE otherwise. + */ + #define portIS_TASK_PRIVILEGED() xPortIsTaskPrivileged() + +#endif /* configENABLE_MPU == 1 */ +/*-----------------------------------------------------------*/ + /** * @brief Barriers. */ diff --git a/portable/IAR/ARM_CM7/r0p1/port.c b/portable/IAR/ARM_CM7/r0p1/port.c index 63f83993db9..c1a1cc5aa5a 100755 --- a/portable/IAR/ARM_CM7/r0p1/port.c +++ b/portable/IAR/ARM_CM7/r0p1/port.c @@ -267,6 +267,10 @@ BaseType_t xPortStartScheduler( void ) * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ configASSERT( ucMaxSysCallPriority ); + /* Check that the bits not implemented in hardware are zero in + * configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & ( ~ucMaxPriorityValue ) ) == 0U ); + /* Calculate the maximum acceptable priority group value for the number * of bits read back. */ @@ -303,28 +307,6 @@ BaseType_t xPortStartScheduler( void ) ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulImplementedPrioBits; } - #ifdef __NVIC_PRIO_BITS - { - /* - * Check that the number of implemented priority bits queried from - * hardware is at least as many as specified in the CMSIS - * __NVIC_PRIO_BITS configuration macro. - */ - configASSERT( ulImplementedPrioBits >= __NVIC_PRIO_BITS ); - } - #endif - - #ifdef configPRIO_BITS - { - /* - * Check that the number of implemented priority bits queried from - * hardware is at least as many as specified in the FreeRTOS - * configPRIO_BITS configuration macro. - */ - configASSERT( ulImplementedPrioBits >= configPRIO_BITS ); - } - #endif - /* Shift the priority group value back to its position within the AIRCR * register. */ ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT; diff --git a/portable/IAR/ARM_CM85/non_secure/mpu_wrappers_v2_asm.S b/portable/IAR/ARM_CM85/non_secure/mpu_wrappers_v2_asm.S new file mode 100644 index 00000000000..f051a6073dd --- /dev/null +++ b/portable/IAR/ARM_CM85/non_secure/mpu_wrappers_v2_asm.S @@ -0,0 +1,1552 @@ +/* + * FreeRTOS Kernel + * Copyright (C) 2021 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 + * + */ + + + SECTION freertos_system_calls:CODE:NOROOT(2) + THUMB +/*-----------------------------------------------------------*/ + +#include "FreeRTOSConfig.h" + +#ifndef configUSE_MPU_WRAPPERS_V1 + #define configUSE_MPU_WRAPPERS_V1 0 +#endif + +/* These must be in sync with portmacro.h. */ +#define portSVC_SYSTEM_CALL_ENTER 4 /* System calls with upto 4 parameters. */ +#define portSVC_SYSTEM_CALL_ENTER_1 5 /* System calls with 5 parameters. */ +#define portSVC_SYSTEM_CALL_EXIT 6 +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + + PUBLIC MPU_xTaskDelayUntil +MPU_xTaskDelayUntil: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskDelayUntil_Unpriv + MPU_xTaskDelayUntil_Priv: + pop {r0} + b MPU_xTaskDelayUntilImpl + MPU_xTaskDelayUntil_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskDelayUntilImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskAbortDelay +MPU_xTaskAbortDelay: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskAbortDelay_Unpriv + MPU_xTaskAbortDelay_Priv: + pop {r0} + b MPU_xTaskAbortDelayImpl + MPU_xTaskAbortDelay_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskAbortDelayImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTaskDelay +MPU_vTaskDelay: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vTaskDelay_Unpriv + MPU_vTaskDelay_Priv: + pop {r0} + b MPU_vTaskDelayImpl + MPU_vTaskDelay_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskDelayImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxTaskPriorityGet +MPU_uxTaskPriorityGet: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_uxTaskPriorityGet_Unpriv + MPU_uxTaskPriorityGet_Priv: + pop {r0} + b MPU_uxTaskPriorityGetImpl + MPU_uxTaskPriorityGet_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxTaskPriorityGetImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_eTaskGetState +MPU_eTaskGetState: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_eTaskGetState_Unpriv + MPU_eTaskGetState_Priv: + pop {r0} + b MPU_eTaskGetStateImpl + MPU_eTaskGetState_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_eTaskGetStateImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTaskGetInfo +MPU_vTaskGetInfo: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vTaskGetInfo_Unpriv + MPU_vTaskGetInfo_Priv: + pop {r0} + b MPU_vTaskGetInfoImpl + MPU_vTaskGetInfo_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskGetInfoImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGetIdleTaskHandle +MPU_xTaskGetIdleTaskHandle: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskGetIdleTaskHandle_Unpriv + MPU_xTaskGetIdleTaskHandle_Priv: + pop {r0} + b MPU_xTaskGetIdleTaskHandleImpl + MPU_xTaskGetIdleTaskHandle_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskGetIdleTaskHandleImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTaskSuspend +MPU_vTaskSuspend: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vTaskSuspend_Unpriv + MPU_vTaskSuspend_Priv: + pop {r0} + b MPU_vTaskSuspendImpl + MPU_vTaskSuspend_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskSuspendImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTaskResume +MPU_vTaskResume: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vTaskResume_Unpriv + MPU_vTaskResume_Priv: + pop {r0} + b MPU_vTaskResumeImpl + MPU_vTaskResume_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskResumeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGetTickCount +MPU_xTaskGetTickCount: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskGetTickCount_Unpriv + MPU_xTaskGetTickCount_Priv: + pop {r0} + b MPU_xTaskGetTickCountImpl + MPU_xTaskGetTickCount_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskGetTickCountImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxTaskGetNumberOfTasks +MPU_uxTaskGetNumberOfTasks: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_uxTaskGetNumberOfTasks_Unpriv + MPU_uxTaskGetNumberOfTasks_Priv: + pop {r0} + b MPU_uxTaskGetNumberOfTasksImpl + MPU_uxTaskGetNumberOfTasks_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxTaskGetNumberOfTasksImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_pcTaskGetName +MPU_pcTaskGetName: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_pcTaskGetName_Unpriv + MPU_pcTaskGetName_Priv: + pop {r0} + b MPU_pcTaskGetNameImpl + MPU_pcTaskGetName_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_pcTaskGetNameImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_ulTaskGetRunTimeCounter +MPU_ulTaskGetRunTimeCounter: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_ulTaskGetRunTimeCounter_Unpriv + MPU_ulTaskGetRunTimeCounter_Priv: + pop {r0} + b MPU_ulTaskGetRunTimeCounterImpl + MPU_ulTaskGetRunTimeCounter_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_ulTaskGetRunTimeCounterImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_ulTaskGetRunTimePercent +MPU_ulTaskGetRunTimePercent: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_ulTaskGetRunTimePercent_Unpriv + MPU_ulTaskGetRunTimePercent_Priv: + pop {r0} + b MPU_ulTaskGetRunTimePercentImpl + MPU_ulTaskGetRunTimePercent_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_ulTaskGetRunTimePercentImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_ulTaskGetIdleRunTimePercent +MPU_ulTaskGetIdleRunTimePercent: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_ulTaskGetIdleRunTimePercent_Unpriv + MPU_ulTaskGetIdleRunTimePercent_Priv: + pop {r0} + b MPU_ulTaskGetIdleRunTimePercentImpl + MPU_ulTaskGetIdleRunTimePercent_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_ulTaskGetIdleRunTimePercentImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_ulTaskGetIdleRunTimeCounter +MPU_ulTaskGetIdleRunTimeCounter: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_ulTaskGetIdleRunTimeCounter_Unpriv + MPU_ulTaskGetIdleRunTimeCounter_Priv: + pop {r0} + b MPU_ulTaskGetIdleRunTimeCounterImpl + MPU_ulTaskGetIdleRunTimeCounter_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_ulTaskGetIdleRunTimeCounterImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTaskSetApplicationTaskTag +MPU_vTaskSetApplicationTaskTag: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vTaskSetApplicationTaskTag_Unpriv + MPU_vTaskSetApplicationTaskTag_Priv: + pop {r0} + b MPU_vTaskSetApplicationTaskTagImpl + MPU_vTaskSetApplicationTaskTag_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskSetApplicationTaskTagImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGetApplicationTaskTag +MPU_xTaskGetApplicationTaskTag: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskGetApplicationTaskTag_Unpriv + MPU_xTaskGetApplicationTaskTag_Priv: + pop {r0} + b MPU_xTaskGetApplicationTaskTagImpl + MPU_xTaskGetApplicationTaskTag_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskGetApplicationTaskTagImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTaskSetThreadLocalStoragePointer +MPU_vTaskSetThreadLocalStoragePointer: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vTaskSetThreadLocalStoragePointer_Unpriv + MPU_vTaskSetThreadLocalStoragePointer_Priv: + pop {r0} + b MPU_vTaskSetThreadLocalStoragePointerImpl + MPU_vTaskSetThreadLocalStoragePointer_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskSetThreadLocalStoragePointerImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_pvTaskGetThreadLocalStoragePointer +MPU_pvTaskGetThreadLocalStoragePointer: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_pvTaskGetThreadLocalStoragePointer_Unpriv + MPU_pvTaskGetThreadLocalStoragePointer_Priv: + pop {r0} + b MPU_pvTaskGetThreadLocalStoragePointerImpl + MPU_pvTaskGetThreadLocalStoragePointer_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_pvTaskGetThreadLocalStoragePointerImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxTaskGetSystemState +MPU_uxTaskGetSystemState: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_uxTaskGetSystemState_Unpriv + MPU_uxTaskGetSystemState_Priv: + pop {r0} + b MPU_uxTaskGetSystemStateImpl + MPU_uxTaskGetSystemState_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxTaskGetSystemStateImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxTaskGetStackHighWaterMark +MPU_uxTaskGetStackHighWaterMark: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_uxTaskGetStackHighWaterMark_Unpriv + MPU_uxTaskGetStackHighWaterMark_Priv: + pop {r0} + b MPU_uxTaskGetStackHighWaterMarkImpl + MPU_uxTaskGetStackHighWaterMark_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxTaskGetStackHighWaterMarkImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxTaskGetStackHighWaterMark2 +MPU_uxTaskGetStackHighWaterMark2: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_uxTaskGetStackHighWaterMark2_Unpriv + MPU_uxTaskGetStackHighWaterMark2_Priv: + pop {r0} + b MPU_uxTaskGetStackHighWaterMark2Impl + MPU_uxTaskGetStackHighWaterMark2_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxTaskGetStackHighWaterMark2Impl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGetCurrentTaskHandle +MPU_xTaskGetCurrentTaskHandle: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskGetCurrentTaskHandle_Unpriv + MPU_xTaskGetCurrentTaskHandle_Priv: + pop {r0} + b MPU_xTaskGetCurrentTaskHandleImpl + MPU_xTaskGetCurrentTaskHandle_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskGetCurrentTaskHandleImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGetSchedulerState +MPU_xTaskGetSchedulerState: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskGetSchedulerState_Unpriv + MPU_xTaskGetSchedulerState_Priv: + pop {r0} + b MPU_xTaskGetSchedulerStateImpl + MPU_xTaskGetSchedulerState_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskGetSchedulerStateImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTaskSetTimeOutState +MPU_vTaskSetTimeOutState: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vTaskSetTimeOutState_Unpriv + MPU_vTaskSetTimeOutState_Priv: + pop {r0} + b MPU_vTaskSetTimeOutStateImpl + MPU_vTaskSetTimeOutState_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskSetTimeOutStateImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskCheckForTimeOut +MPU_xTaskCheckForTimeOut: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskCheckForTimeOut_Unpriv + MPU_xTaskCheckForTimeOut_Priv: + pop {r0} + b MPU_xTaskCheckForTimeOutImpl + MPU_xTaskCheckForTimeOut_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskCheckForTimeOutImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGenericNotify +MPU_xTaskGenericNotify: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskGenericNotify_Unpriv + MPU_xTaskGenericNotify_Priv: + pop {r0} + b MPU_xTaskGenericNotifyImpl + MPU_xTaskGenericNotify_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER_1 + bl MPU_xTaskGenericNotifyImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGenericNotifyWait +MPU_xTaskGenericNotifyWait: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskGenericNotifyWait_Unpriv + MPU_xTaskGenericNotifyWait_Priv: + pop {r0} + b MPU_xTaskGenericNotifyWaitImpl + MPU_xTaskGenericNotifyWait_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER_1 + bl MPU_xTaskGenericNotifyWaitImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_ulTaskGenericNotifyTake +MPU_ulTaskGenericNotifyTake: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_ulTaskGenericNotifyTake_Unpriv + MPU_ulTaskGenericNotifyTake_Priv: + pop {r0} + b MPU_ulTaskGenericNotifyTakeImpl + MPU_ulTaskGenericNotifyTake_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_ulTaskGenericNotifyTakeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGenericNotifyStateClear +MPU_xTaskGenericNotifyStateClear: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskGenericNotifyStateClear_Unpriv + MPU_xTaskGenericNotifyStateClear_Priv: + pop {r0} + b MPU_xTaskGenericNotifyStateClearImpl + MPU_xTaskGenericNotifyStateClear_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskGenericNotifyStateClearImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_ulTaskGenericNotifyValueClear +MPU_ulTaskGenericNotifyValueClear: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_ulTaskGenericNotifyValueClear_Unpriv + MPU_ulTaskGenericNotifyValueClear_Priv: + pop {r0} + b MPU_ulTaskGenericNotifyValueClearImpl + MPU_ulTaskGenericNotifyValueClear_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_ulTaskGenericNotifyValueClearImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueGenericSend +MPU_xQueueGenericSend: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xQueueGenericSend_Unpriv + MPU_xQueueGenericSend_Priv: + pop {r0} + b MPU_xQueueGenericSendImpl + MPU_xQueueGenericSend_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueGenericSendImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxQueueMessagesWaiting +MPU_uxQueueMessagesWaiting: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_uxQueueMessagesWaiting_Unpriv + MPU_uxQueueMessagesWaiting_Priv: + pop {r0} + b MPU_uxQueueMessagesWaitingImpl + MPU_uxQueueMessagesWaiting_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxQueueMessagesWaitingImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxQueueSpacesAvailable +MPU_uxQueueSpacesAvailable: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_uxQueueSpacesAvailable_Unpriv + MPU_uxQueueSpacesAvailable_Priv: + pop {r0} + b MPU_uxQueueSpacesAvailableImpl + MPU_uxQueueSpacesAvailable_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxQueueSpacesAvailableImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueReceive +MPU_xQueueReceive: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xQueueReceive_Unpriv + MPU_xQueueReceive_Priv: + pop {r0} + b MPU_xQueueReceiveImpl + MPU_xQueueReceive_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueReceiveImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueuePeek +MPU_xQueuePeek: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xQueuePeek_Unpriv + MPU_xQueuePeek_Priv: + pop {r0} + b MPU_xQueuePeekImpl + MPU_xQueuePeek_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueuePeekImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueSemaphoreTake +MPU_xQueueSemaphoreTake: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xQueueSemaphoreTake_Unpriv + MPU_xQueueSemaphoreTake_Priv: + pop {r0} + b MPU_xQueueSemaphoreTakeImpl + MPU_xQueueSemaphoreTake_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueSemaphoreTakeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueGetMutexHolder +MPU_xQueueGetMutexHolder: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xQueueGetMutexHolder_Unpriv + MPU_xQueueGetMutexHolder_Priv: + pop {r0} + b MPU_xQueueGetMutexHolderImpl + MPU_xQueueGetMutexHolder_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueGetMutexHolderImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueTakeMutexRecursive +MPU_xQueueTakeMutexRecursive: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xQueueTakeMutexRecursive_Unpriv + MPU_xQueueTakeMutexRecursive_Priv: + pop {r0} + b MPU_xQueueTakeMutexRecursiveImpl + MPU_xQueueTakeMutexRecursive_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueTakeMutexRecursiveImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueGiveMutexRecursive +MPU_xQueueGiveMutexRecursive: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xQueueGiveMutexRecursive_Unpriv + MPU_xQueueGiveMutexRecursive_Priv: + pop {r0} + b MPU_xQueueGiveMutexRecursiveImpl + MPU_xQueueGiveMutexRecursive_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueGiveMutexRecursiveImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueSelectFromSet +MPU_xQueueSelectFromSet: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xQueueSelectFromSet_Unpriv + MPU_xQueueSelectFromSet_Priv: + pop {r0} + b MPU_xQueueSelectFromSetImpl + MPU_xQueueSelectFromSet_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueSelectFromSetImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueAddToSet +MPU_xQueueAddToSet: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xQueueAddToSet_Unpriv + MPU_xQueueAddToSet_Priv: + pop {r0} + b MPU_xQueueAddToSetImpl + MPU_xQueueAddToSet_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueAddToSetImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vQueueAddToRegistry +MPU_vQueueAddToRegistry: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vQueueAddToRegistry_Unpriv + MPU_vQueueAddToRegistry_Priv: + pop {r0} + b MPU_vQueueAddToRegistryImpl + MPU_vQueueAddToRegistry_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vQueueAddToRegistryImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vQueueUnregisterQueue +MPU_vQueueUnregisterQueue: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vQueueUnregisterQueue_Unpriv + MPU_vQueueUnregisterQueue_Priv: + pop {r0} + b MPU_vQueueUnregisterQueueImpl + MPU_vQueueUnregisterQueue_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vQueueUnregisterQueueImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_pcQueueGetName +MPU_pcQueueGetName: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_pcQueueGetName_Unpriv + MPU_pcQueueGetName_Priv: + pop {r0} + b MPU_pcQueueGetNameImpl + MPU_pcQueueGetName_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_pcQueueGetNameImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_pvTimerGetTimerID +MPU_pvTimerGetTimerID: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_pvTimerGetTimerID_Unpriv + MPU_pvTimerGetTimerID_Priv: + pop {r0} + b MPU_pvTimerGetTimerIDImpl + MPU_pvTimerGetTimerID_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_pvTimerGetTimerIDImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTimerSetTimerID +MPU_vTimerSetTimerID: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vTimerSetTimerID_Unpriv + MPU_vTimerSetTimerID_Priv: + pop {r0} + b MPU_vTimerSetTimerIDImpl + MPU_vTimerSetTimerID_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTimerSetTimerIDImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTimerIsTimerActive +MPU_xTimerIsTimerActive: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTimerIsTimerActive_Unpriv + MPU_xTimerIsTimerActive_Priv: + pop {r0} + b MPU_xTimerIsTimerActiveImpl + MPU_xTimerIsTimerActive_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTimerIsTimerActiveImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTimerGetTimerDaemonTaskHandle +MPU_xTimerGetTimerDaemonTaskHandle: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTimerGetTimerDaemonTaskHandle_Unpriv + MPU_xTimerGetTimerDaemonTaskHandle_Priv: + pop {r0} + b MPU_xTimerGetTimerDaemonTaskHandleImpl + MPU_xTimerGetTimerDaemonTaskHandle_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTimerGetTimerDaemonTaskHandleImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTimerGenericCommand +MPU_xTimerGenericCommand: + push {r0} + /* This function can be called from ISR also and therefore, we need a check + * to take privileged path, if called from ISR. */ + mrs r0, ipsr + cmp r0, #0 + bne MPU_xTimerGenericCommand_Priv + mrs r0, control + tst r0, #1 + beq MPU_xTimerGenericCommand_Priv + MPU_xTimerGenericCommand_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER_1 + bl MPU_xTimerGenericCommandImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr + MPU_xTimerGenericCommand_Priv: + pop {r0} + b MPU_xTimerGenericCommandImpl + +/*-----------------------------------------------------------*/ + + PUBLIC MPU_pcTimerGetName +MPU_pcTimerGetName: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_pcTimerGetName_Unpriv + MPU_pcTimerGetName_Priv: + pop {r0} + b MPU_pcTimerGetNameImpl + MPU_pcTimerGetName_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_pcTimerGetNameImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTimerSetReloadMode +MPU_vTimerSetReloadMode: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vTimerSetReloadMode_Unpriv + MPU_vTimerSetReloadMode_Priv: + pop {r0} + b MPU_vTimerSetReloadModeImpl + MPU_vTimerSetReloadMode_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTimerSetReloadModeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTimerGetReloadMode +MPU_xTimerGetReloadMode: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTimerGetReloadMode_Unpriv + MPU_xTimerGetReloadMode_Priv: + pop {r0} + b MPU_xTimerGetReloadModeImpl + MPU_xTimerGetReloadMode_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTimerGetReloadModeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxTimerGetReloadMode +MPU_uxTimerGetReloadMode: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_uxTimerGetReloadMode_Unpriv + MPU_uxTimerGetReloadMode_Priv: + pop {r0} + b MPU_uxTimerGetReloadModeImpl + MPU_uxTimerGetReloadMode_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxTimerGetReloadModeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTimerGetPeriod +MPU_xTimerGetPeriod: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTimerGetPeriod_Unpriv + MPU_xTimerGetPeriod_Priv: + pop {r0} + b MPU_xTimerGetPeriodImpl + MPU_xTimerGetPeriod_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTimerGetPeriodImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTimerGetExpiryTime +MPU_xTimerGetExpiryTime: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTimerGetExpiryTime_Unpriv + MPU_xTimerGetExpiryTime_Priv: + pop {r0} + b MPU_xTimerGetExpiryTimeImpl + MPU_xTimerGetExpiryTime_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTimerGetExpiryTimeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xEventGroupWaitBits +MPU_xEventGroupWaitBits: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xEventGroupWaitBits_Unpriv + MPU_xEventGroupWaitBits_Priv: + pop {r0} + b MPU_xEventGroupWaitBitsImpl + MPU_xEventGroupWaitBits_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER_1 + bl MPU_xEventGroupWaitBitsImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xEventGroupClearBits +MPU_xEventGroupClearBits: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xEventGroupClearBits_Unpriv + MPU_xEventGroupClearBits_Priv: + pop {r0} + b MPU_xEventGroupClearBitsImpl + MPU_xEventGroupClearBits_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xEventGroupClearBitsImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xEventGroupSetBits +MPU_xEventGroupSetBits: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xEventGroupSetBits_Unpriv + MPU_xEventGroupSetBits_Priv: + pop {r0} + b MPU_xEventGroupSetBitsImpl + MPU_xEventGroupSetBits_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xEventGroupSetBitsImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xEventGroupSync +MPU_xEventGroupSync: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xEventGroupSync_Unpriv + MPU_xEventGroupSync_Priv: + pop {r0} + b MPU_xEventGroupSyncImpl + MPU_xEventGroupSync_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xEventGroupSyncImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxEventGroupGetNumber +MPU_uxEventGroupGetNumber: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_uxEventGroupGetNumber_Unpriv + MPU_uxEventGroupGetNumber_Priv: + pop {r0} + b MPU_uxEventGroupGetNumberImpl + MPU_uxEventGroupGetNumber_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxEventGroupGetNumberImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vEventGroupSetNumber +MPU_vEventGroupSetNumber: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vEventGroupSetNumber_Unpriv + MPU_vEventGroupSetNumber_Priv: + pop {r0} + b MPU_vEventGroupSetNumberImpl + MPU_vEventGroupSetNumber_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vEventGroupSetNumberImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferSend +MPU_xStreamBufferSend: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xStreamBufferSend_Unpriv + MPU_xStreamBufferSend_Priv: + pop {r0} + b MPU_xStreamBufferSendImpl + MPU_xStreamBufferSend_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferSendImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferReceive +MPU_xStreamBufferReceive: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xStreamBufferReceive_Unpriv + MPU_xStreamBufferReceive_Priv: + pop {r0} + b MPU_xStreamBufferReceiveImpl + MPU_xStreamBufferReceive_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferReceiveImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferIsFull +MPU_xStreamBufferIsFull: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xStreamBufferIsFull_Unpriv + MPU_xStreamBufferIsFull_Priv: + pop {r0} + b MPU_xStreamBufferIsFullImpl + MPU_xStreamBufferIsFull_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferIsFullImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferIsEmpty +MPU_xStreamBufferIsEmpty: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xStreamBufferIsEmpty_Unpriv + MPU_xStreamBufferIsEmpty_Priv: + pop {r0} + b MPU_xStreamBufferIsEmptyImpl + MPU_xStreamBufferIsEmpty_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferIsEmptyImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferSpacesAvailable +MPU_xStreamBufferSpacesAvailable: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xStreamBufferSpacesAvailable_Unpriv + MPU_xStreamBufferSpacesAvailable_Priv: + pop {r0} + b MPU_xStreamBufferSpacesAvailableImpl + MPU_xStreamBufferSpacesAvailable_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferSpacesAvailableImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferBytesAvailable +MPU_xStreamBufferBytesAvailable: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xStreamBufferBytesAvailable_Unpriv + MPU_xStreamBufferBytesAvailable_Priv: + pop {r0} + b MPU_xStreamBufferBytesAvailableImpl + MPU_xStreamBufferBytesAvailable_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferBytesAvailableImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferSetTriggerLevel +MPU_xStreamBufferSetTriggerLevel: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xStreamBufferSetTriggerLevel_Unpriv + MPU_xStreamBufferSetTriggerLevel_Priv: + pop {r0} + b MPU_xStreamBufferSetTriggerLevelImpl + MPU_xStreamBufferSetTriggerLevel_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferSetTriggerLevelImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferNextMessageLengthBytes +MPU_xStreamBufferNextMessageLengthBytes: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xStreamBufferNextMessageLengthBytes_Unpriv + MPU_xStreamBufferNextMessageLengthBytes_Priv: + pop {r0} + b MPU_xStreamBufferNextMessageLengthBytesImpl + MPU_xStreamBufferNextMessageLengthBytes_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferNextMessageLengthBytesImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + +/* Default weak implementations in case one is not available from + * mpu_wrappers because of config options. */ + + PUBWEAK MPU_xTaskDelayUntilImpl +MPU_xTaskDelayUntilImpl: + b MPU_xTaskDelayUntilImpl + + PUBWEAK MPU_xTaskAbortDelayImpl +MPU_xTaskAbortDelayImpl: + b MPU_xTaskAbortDelayImpl + + PUBWEAK MPU_vTaskDelayImpl +MPU_vTaskDelayImpl: + b MPU_vTaskDelayImpl + + PUBWEAK MPU_uxTaskPriorityGetImpl +MPU_uxTaskPriorityGetImpl: + b MPU_uxTaskPriorityGetImpl + + PUBWEAK MPU_eTaskGetStateImpl +MPU_eTaskGetStateImpl: + b MPU_eTaskGetStateImpl + + PUBWEAK MPU_vTaskGetInfoImpl +MPU_vTaskGetInfoImpl: + b MPU_vTaskGetInfoImpl + + PUBWEAK MPU_xTaskGetIdleTaskHandleImpl +MPU_xTaskGetIdleTaskHandleImpl: + b MPU_xTaskGetIdleTaskHandleImpl + + PUBWEAK MPU_vTaskSuspendImpl +MPU_vTaskSuspendImpl: + b MPU_vTaskSuspendImpl + + PUBWEAK MPU_vTaskResumeImpl +MPU_vTaskResumeImpl: + b MPU_vTaskResumeImpl + + PUBWEAK MPU_xTaskGetTickCountImpl +MPU_xTaskGetTickCountImpl: + b MPU_xTaskGetTickCountImpl + + PUBWEAK MPU_uxTaskGetNumberOfTasksImpl +MPU_uxTaskGetNumberOfTasksImpl: + b MPU_uxTaskGetNumberOfTasksImpl + + PUBWEAK MPU_pcTaskGetNameImpl +MPU_pcTaskGetNameImpl: + b MPU_pcTaskGetNameImpl + + PUBWEAK MPU_ulTaskGetRunTimeCounterImpl +MPU_ulTaskGetRunTimeCounterImpl: + b MPU_ulTaskGetRunTimeCounterImpl + + PUBWEAK MPU_ulTaskGetRunTimePercentImpl +MPU_ulTaskGetRunTimePercentImpl: + b MPU_ulTaskGetRunTimePercentImpl + + PUBWEAK MPU_ulTaskGetIdleRunTimePercentImpl +MPU_ulTaskGetIdleRunTimePercentImpl: + b MPU_ulTaskGetIdleRunTimePercentImpl + + PUBWEAK MPU_ulTaskGetIdleRunTimeCounterImpl +MPU_ulTaskGetIdleRunTimeCounterImpl: + b MPU_ulTaskGetIdleRunTimeCounterImpl + + PUBWEAK MPU_vTaskSetApplicationTaskTagImpl +MPU_vTaskSetApplicationTaskTagImpl: + b MPU_vTaskSetApplicationTaskTagImpl + + PUBWEAK MPU_xTaskGetApplicationTaskTagImpl +MPU_xTaskGetApplicationTaskTagImpl: + b MPU_xTaskGetApplicationTaskTagImpl + + PUBWEAK MPU_vTaskSetThreadLocalStoragePointerImpl +MPU_vTaskSetThreadLocalStoragePointerImpl: + b MPU_vTaskSetThreadLocalStoragePointerImpl + + PUBWEAK MPU_pvTaskGetThreadLocalStoragePointerImpl +MPU_pvTaskGetThreadLocalStoragePointerImpl: + b MPU_pvTaskGetThreadLocalStoragePointerImpl + + PUBWEAK MPU_uxTaskGetSystemStateImpl +MPU_uxTaskGetSystemStateImpl: + b MPU_uxTaskGetSystemStateImpl + + PUBWEAK MPU_uxTaskGetStackHighWaterMarkImpl +MPU_uxTaskGetStackHighWaterMarkImpl: + b MPU_uxTaskGetStackHighWaterMarkImpl + + PUBWEAK MPU_uxTaskGetStackHighWaterMark2Impl +MPU_uxTaskGetStackHighWaterMark2Impl: + b MPU_uxTaskGetStackHighWaterMark2Impl + + PUBWEAK MPU_xTaskGetCurrentTaskHandleImpl +MPU_xTaskGetCurrentTaskHandleImpl: + b MPU_xTaskGetCurrentTaskHandleImpl + + PUBWEAK MPU_xTaskGetSchedulerStateImpl +MPU_xTaskGetSchedulerStateImpl: + b MPU_xTaskGetSchedulerStateImpl + + PUBWEAK MPU_vTaskSetTimeOutStateImpl +MPU_vTaskSetTimeOutStateImpl: + b MPU_vTaskSetTimeOutStateImpl + + PUBWEAK MPU_xTaskCheckForTimeOutImpl +MPU_xTaskCheckForTimeOutImpl: + b MPU_xTaskCheckForTimeOutImpl + + PUBWEAK MPU_xTaskGenericNotifyImpl +MPU_xTaskGenericNotifyImpl: + b MPU_xTaskGenericNotifyImpl + + PUBWEAK MPU_xTaskGenericNotifyWaitImpl +MPU_xTaskGenericNotifyWaitImpl: + b MPU_xTaskGenericNotifyWaitImpl + + PUBWEAK MPU_ulTaskGenericNotifyTakeImpl +MPU_ulTaskGenericNotifyTakeImpl: + b MPU_ulTaskGenericNotifyTakeImpl + + PUBWEAK MPU_xTaskGenericNotifyStateClearImpl +MPU_xTaskGenericNotifyStateClearImpl: + b MPU_xTaskGenericNotifyStateClearImpl + + PUBWEAK MPU_ulTaskGenericNotifyValueClearImpl +MPU_ulTaskGenericNotifyValueClearImpl: + b MPU_ulTaskGenericNotifyValueClearImpl + + PUBWEAK MPU_xQueueGenericSendImpl +MPU_xQueueGenericSendImpl: + b MPU_xQueueGenericSendImpl + + PUBWEAK MPU_uxQueueMessagesWaitingImpl +MPU_uxQueueMessagesWaitingImpl: + b MPU_uxQueueMessagesWaitingImpl + + PUBWEAK MPU_uxQueueSpacesAvailableImpl +MPU_uxQueueSpacesAvailableImpl: + b MPU_uxQueueSpacesAvailableImpl + + PUBWEAK MPU_xQueueReceiveImpl +MPU_xQueueReceiveImpl: + b MPU_xQueueReceiveImpl + + PUBWEAK MPU_xQueuePeekImpl +MPU_xQueuePeekImpl: + b MPU_xQueuePeekImpl + + PUBWEAK MPU_xQueueSemaphoreTakeImpl +MPU_xQueueSemaphoreTakeImpl: + b MPU_xQueueSemaphoreTakeImpl + + PUBWEAK MPU_xQueueGetMutexHolderImpl +MPU_xQueueGetMutexHolderImpl: + b MPU_xQueueGetMutexHolderImpl + + PUBWEAK MPU_xQueueTakeMutexRecursiveImpl +MPU_xQueueTakeMutexRecursiveImpl: + b MPU_xQueueTakeMutexRecursiveImpl + + PUBWEAK MPU_xQueueGiveMutexRecursiveImpl +MPU_xQueueGiveMutexRecursiveImpl: + b MPU_xQueueGiveMutexRecursiveImpl + + PUBWEAK MPU_xQueueSelectFromSetImpl +MPU_xQueueSelectFromSetImpl: + b MPU_xQueueSelectFromSetImpl + + PUBWEAK MPU_xQueueAddToSetImpl +MPU_xQueueAddToSetImpl: + b MPU_xQueueAddToSetImpl + + PUBWEAK MPU_vQueueAddToRegistryImpl +MPU_vQueueAddToRegistryImpl: + b MPU_vQueueAddToRegistryImpl + + PUBWEAK MPU_vQueueUnregisterQueueImpl +MPU_vQueueUnregisterQueueImpl: + b MPU_vQueueUnregisterQueueImpl + + PUBWEAK MPU_pcQueueGetNameImpl +MPU_pcQueueGetNameImpl: + b MPU_pcQueueGetNameImpl + + PUBWEAK MPU_pvTimerGetTimerIDImpl +MPU_pvTimerGetTimerIDImpl: + b MPU_pvTimerGetTimerIDImpl + + PUBWEAK MPU_vTimerSetTimerIDImpl +MPU_vTimerSetTimerIDImpl: + b MPU_vTimerSetTimerIDImpl + + PUBWEAK MPU_xTimerIsTimerActiveImpl +MPU_xTimerIsTimerActiveImpl: + b MPU_xTimerIsTimerActiveImpl + + PUBWEAK MPU_xTimerGetTimerDaemonTaskHandleImpl +MPU_xTimerGetTimerDaemonTaskHandleImpl: + b MPU_xTimerGetTimerDaemonTaskHandleImpl + + PUBWEAK MPU_xTimerGenericCommandImpl +MPU_xTimerGenericCommandImpl: + b MPU_xTimerGenericCommandImpl + + PUBWEAK MPU_pcTimerGetNameImpl +MPU_pcTimerGetNameImpl: + b MPU_pcTimerGetNameImpl + + PUBWEAK MPU_vTimerSetReloadModeImpl +MPU_vTimerSetReloadModeImpl: + b MPU_vTimerSetReloadModeImpl + + PUBWEAK MPU_xTimerGetReloadModeImpl +MPU_xTimerGetReloadModeImpl: + b MPU_xTimerGetReloadModeImpl + + PUBWEAK MPU_uxTimerGetReloadModeImpl +MPU_uxTimerGetReloadModeImpl: + b MPU_uxTimerGetReloadModeImpl + + PUBWEAK MPU_xTimerGetPeriodImpl +MPU_xTimerGetPeriodImpl: + b MPU_xTimerGetPeriodImpl + + PUBWEAK MPU_xTimerGetExpiryTimeImpl +MPU_xTimerGetExpiryTimeImpl: + b MPU_xTimerGetExpiryTimeImpl + + PUBWEAK MPU_xEventGroupWaitBitsImpl +MPU_xEventGroupWaitBitsImpl: + b MPU_xEventGroupWaitBitsImpl + + PUBWEAK MPU_xEventGroupClearBitsImpl +MPU_xEventGroupClearBitsImpl: + b MPU_xEventGroupClearBitsImpl + + PUBWEAK MPU_xEventGroupSetBitsImpl +MPU_xEventGroupSetBitsImpl: + b MPU_xEventGroupSetBitsImpl + + PUBWEAK MPU_xEventGroupSyncImpl +MPU_xEventGroupSyncImpl: + b MPU_xEventGroupSyncImpl + + PUBWEAK MPU_uxEventGroupGetNumberImpl +MPU_uxEventGroupGetNumberImpl: + b MPU_uxEventGroupGetNumberImpl + + PUBWEAK MPU_vEventGroupSetNumberImpl +MPU_vEventGroupSetNumberImpl: + b MPU_vEventGroupSetNumberImpl + + PUBWEAK MPU_xStreamBufferSendImpl +MPU_xStreamBufferSendImpl: + b MPU_xStreamBufferSendImpl + + PUBWEAK MPU_xStreamBufferReceiveImpl +MPU_xStreamBufferReceiveImpl: + b MPU_xStreamBufferReceiveImpl + + PUBWEAK MPU_xStreamBufferIsFullImpl +MPU_xStreamBufferIsFullImpl: + b MPU_xStreamBufferIsFullImpl + + PUBWEAK MPU_xStreamBufferIsEmptyImpl +MPU_xStreamBufferIsEmptyImpl: + b MPU_xStreamBufferIsEmptyImpl + + PUBWEAK MPU_xStreamBufferSpacesAvailableImpl +MPU_xStreamBufferSpacesAvailableImpl: + b MPU_xStreamBufferSpacesAvailableImpl + + PUBWEAK MPU_xStreamBufferBytesAvailableImpl +MPU_xStreamBufferBytesAvailableImpl: + b MPU_xStreamBufferBytesAvailableImpl + + PUBWEAK MPU_xStreamBufferSetTriggerLevelImpl +MPU_xStreamBufferSetTriggerLevelImpl: + b MPU_xStreamBufferSetTriggerLevelImpl + + PUBWEAK MPU_xStreamBufferNextMessageLengthBytesImpl +MPU_xStreamBufferNextMessageLengthBytesImpl: + b MPU_xStreamBufferNextMessageLengthBytesImpl + +/*-----------------------------------------------------------*/ + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + + END diff --git a/portable/IAR/ARM_CM85/non_secure/port.c b/portable/IAR/ARM_CM85/non_secure/port.c index 7bbe1b7bc53..cab1b3668bf 100644 --- a/portable/IAR/ARM_CM85/non_secure/port.c +++ b/portable/IAR/ARM_CM85/non_secure/port.c @@ -107,6 +107,13 @@ #define portPRIGROUP_SHIFT ( 8UL ) /*-----------------------------------------------------------*/ +/** + * @brief Constants used during system call enter and exit. + */ +#define portPSR_STACK_PADDING_MASK ( 1UL << 9UL ) +#define portEXC_RETURN_STACK_FRAME_TYPE_MASK ( 1UL << 4UL ) +/*-----------------------------------------------------------*/ + /** * @brief Constants required to manipulate the FPU. */ @@ -123,6 +130,14 @@ #define portFPCCR_LSPEN_MASK ( 1UL << portFPCCR_LSPEN_POS ) /*-----------------------------------------------------------*/ +/** + * @brief Offsets in the stack to the parameters when inside the SVC handler. + */ +#define portOFFSET_TO_LR ( 5 ) +#define portOFFSET_TO_PC ( 6 ) +#define portOFFSET_TO_PSR ( 7 ) +/*-----------------------------------------------------------*/ + /** * @brief Constants required to manipulate the MPU. */ @@ -148,6 +163,8 @@ #define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ #define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ +#define portMPU_RBAR_ACCESS_PERMISSIONS_MASK ( 3UL << 1UL ) + #define portMPU_MAIR_ATTR0_POS ( 0UL ) #define portMPU_MAIR_ATTR0_MASK ( 0x000000ff ) @@ -191,6 +208,30 @@ /* Expected value of the portMPU_TYPE register. */ #define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) + +/* Extract first address of the MPU region as encoded in the + * RBAR (Region Base Address Register) value. */ +#define portEXTRACT_FIRST_ADDRESS_FROM_RBAR( rbar ) \ + ( ( rbar ) & portMPU_RBAR_ADDRESS_MASK ) + +/* Extract last address of the MPU region as encoded in the + * RLAR (Region Limit Address Register) value. */ +#define portEXTRACT_LAST_ADDRESS_FROM_RLAR( rlar ) \ + ( ( ( rlar ) & portMPU_RLAR_ADDRESS_MASK ) | ~portMPU_RLAR_ADDRESS_MASK ) + +/* Does addr lies within [start, end] address range? */ +#define portIS_ADDRESS_WITHIN_RANGE( addr, start, end ) \ + ( ( ( addr ) >= ( start ) ) && ( ( addr ) <= ( end ) ) ) + +/* Is the access request satisfied by the available permissions? */ +#define portIS_AUTHORIZED( accessRequest, permissions ) \ + ( ( ( permissions ) & ( accessRequest ) ) == accessRequest ) + +/* 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 ) ) ) /*-----------------------------------------------------------*/ /** @@ -311,6 +352,19 @@ static void prvTaskExitError( void ); #if ( configENABLE_MPU == 1 ) +/** + * @brief Extract MPU region's access permissions from the Region Base Address + * Register (RBAR) value. + * + * @param ulRBARValue RBAR value for the MPU region. + * + * @return uint32_t Access permissions. + */ + static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) PRIVILEGED_FUNCTION; +#endif /* configENABLE_MPU */ + +#if ( configENABLE_MPU == 1 ) + /** * @brief Setup the Memory Protection Unit (MPU). */ @@ -365,6 +419,60 @@ void SysTick_Handler( void ) PRIVILEGED_FUNCTION; * @brief C part of SVC handler. */ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIVILEGED_FUNCTION; + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + + /** + * @brief Sets up the system call stack so that upon returning from + * SVC, the system call stack is used. + * + * It is used for the system calls with up to 4 parameters. + * + * @param pulTaskStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + */ + void vSystemCallEnter( uint32_t * pulTaskStack, uint32_t ulLR ) PRIVILEGED_FUNCTION; + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + + /** + * @brief Sets up the system call stack so that upon returning from + * SVC, the system call stack is used. + * + * It is used for the system calls with 5 parameters. + * + * @param pulTaskStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + */ + void vSystemCallEnter_1( uint32_t * pulTaskStack, uint32_t ulLR ) PRIVILEGED_FUNCTION; + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + + /** + * @brief Sets up the task stack so that upon returning from + * SVC, the task stack is used again. + * + * @param pulSystemCallStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + */ + void vSystemCallExit( uint32_t * pulSystemCallStack, uint32_t ulLR ) PRIVILEGED_FUNCTION; + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + +#if ( configENABLE_MPU == 1 ) + + /** + * @brief Checks whether or not the calling task is privileged. + * + * @return pdTRUE if the calling task is privileged, pdFALSE otherwise. + */ + BaseType_t xPortIsTaskPrivileged( void ) PRIVILEGED_FUNCTION; + +#endif /* configENABLE_MPU == 1 */ /*-----------------------------------------------------------*/ /** @@ -681,6 +789,26 @@ static void prvTaskExitError( void ) } /*-----------------------------------------------------------*/ +#if ( configENABLE_MPU == 1 ) + static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) /* PRIVILEGED_FUNCTION */ + { + uint32_t ulAccessPermissions = 0; + + if( ( ulRBARValue & portMPU_RBAR_ACCESS_PERMISSIONS_MASK ) == portMPU_REGION_READ_ONLY ) + { + ulAccessPermissions = tskMPU_READ_PERMISSION; + } + + if( ( ulRBARValue & portMPU_RBAR_ACCESS_PERMISSIONS_MASK ) == portMPU_REGION_READ_WRITE ) + { + ulAccessPermissions = ( tskMPU_READ_PERMISSION | tskMPU_WRITE_PERMISSION ); + } + + return ulAccessPermissions; + } +#endif /* configENABLE_MPU */ +/*-----------------------------------------------------------*/ + #if ( configENABLE_MPU == 1 ) static void prvSetupMPU( void ) /* PRIVILEGED_FUNCTION */ { @@ -853,7 +981,7 @@ void SysTick_Handler( void ) /* PRIVILEGED_FUNCTION */ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTION portDONT_DISCARD */ { - #if ( configENABLE_MPU == 1 ) + #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) ) #if defined( __ARMCC_VERSION ) /* Declaration when these variable are defined in code instead of being @@ -865,7 +993,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO extern uint32_t __syscalls_flash_start__[]; extern uint32_t __syscalls_flash_end__[]; #endif /* defined( __ARMCC_VERSION ) */ - #endif /* configENABLE_MPU */ + #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */ uint32_t ulPC; @@ -880,7 +1008,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO /* Register are stored on the stack in the following order - R0, R1, R2, R3, * R12, LR, PC, xPSR. */ - ulPC = pulCallerStackAddress[ 6 ]; + ulPC = pulCallerStackAddress[ portOFFSET_TO_PC ]; ucSVCNumber = ( ( uint8_t * ) ulPC )[ -2 ]; switch( ucSVCNumber ) @@ -951,18 +1079,18 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO vRestoreContextOfFirstTask(); break; - #if ( configENABLE_MPU == 1 ) - case portSVC_RAISE_PRIVILEGE: + #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) ) + case portSVC_RAISE_PRIVILEGE: - /* Only raise the privilege, if the svc was raised from any of - * the system calls. */ - if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) && - ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ) - { - vRaisePrivilege(); - } - break; - #endif /* configENABLE_MPU */ + /* Only raise the privilege, if the svc was raised from any of + * the system calls. */ + if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ) + { + vRaisePrivilege(); + } + break; + #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */ default: /* Incorrect SVC call. */ @@ -971,51 +1099,455 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } /*-----------------------------------------------------------*/ -/* *INDENT-OFF* */ -#if ( configENABLE_MPU == 1 ) - StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, - StackType_t * pxEndOfStack, - TaskFunction_t pxCode, - void * pvParameters, - BaseType_t xRunPrivileged ) /* PRIVILEGED_FUNCTION */ -#else - StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, - StackType_t * pxEndOfStack, - TaskFunction_t pxCode, - void * pvParameters ) /* PRIVILEGED_FUNCTION */ -#endif /* configENABLE_MPU */ -/* *INDENT-ON* */ +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + +void vSystemCallEnter( uint32_t * pulTaskStack, uint32_t ulLR ) /* PRIVILEGED_FUNCTION */ { - /* Simulate the stack frame as it would be created by a context switch - * interrupt. */ - #if ( portPRELOAD_REGISTERS == 0 ) + extern TaskHandle_t pxCurrentTCB; + xMPU_SETTINGS * pxMpuSettings; + uint32_t * pulSystemCallStack; + uint32_t ulStackFrameSize, ulSystemCallLocation, i; + #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being + * exported from linker scripts. */ + extern uint32_t * __syscalls_flash_start__; + extern uint32_t * __syscalls_flash_end__; + #else + /* Declaration when these variable are exported from linker scripts. */ + extern uint32_t __syscalls_flash_start__[]; + extern uint32_t __syscalls_flash_end__[]; + #endif /* #if defined( __ARMCC_VERSION ) */ + + ulSystemCallLocation = pulTaskStack[ portOFFSET_TO_PC ]; + + /* If the request did not come from the system call section, do nothing. */ + if( ( ulSystemCallLocation >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulSystemCallLocation <= ( uint32_t ) __syscalls_flash_end__ ) ) { - pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ - *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ - pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pxCode; /* PC */ - pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR */ - pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ - *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ - pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */ - *pxTopOfStack = portINITIAL_EXC_RETURN; + pxMpuSettings = xTaskGetMPUSettings( pxCurrentTCB ); + pulSystemCallStack = pxMpuSettings->xSystemCallStackInfo.pulSystemCallStack; - #if ( configENABLE_MPU == 1 ) + /* This is not NULL only for the duration of the system call. */ + configASSERT( pxMpuSettings->xSystemCallStackInfo.pulTaskStack == NULL ); + + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) { - pxTopOfStack--; + if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) + { + /* Extended frame i.e. FPU in use. */ + ulStackFrameSize = 26; + __asm volatile ( + " vpush {s0} \n" /* Trigger lazy stacking. */ + " vpop {s0} \n" /* Nullify the affect of the above instruction. */ + ::: "memory" + ); + } + else + { + /* Standard frame i.e. FPU not in use. */ + ulStackFrameSize = 8; + } + } + #else + { + ulStackFrameSize = 8; + } + #endif /* configENABLE_FPU || configENABLE_MVE */ + + /* Make space on the system call stack for the stack frame. */ + pulSystemCallStack = pulSystemCallStack - ulStackFrameSize; + + /* Copy the stack frame. */ + for( i = 0; i < ulStackFrameSize; i++ ) + { + pulSystemCallStack[ i ] = pulTaskStack[ i ]; + } + + /* Store the value of the LR and PSPLIM registers before the SVC was raised. We need to + * restore it when we exit from the system call. */ + pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; + __asm volatile ( "mrs %0, psplim" : "=r" ( pxMpuSettings->xSystemCallStackInfo.ulStackLimitRegisterAtSystemCallEntry ) ); + + /* Use the pulSystemCallStack in thread mode. */ + __asm volatile ( "msr psp, %0" : : "r" ( pulSystemCallStack ) ); + __asm volatile ( "msr psplim, %0" : : "r" ( pxMpuSettings->xSystemCallStackInfo.pulSystemCallStackLimit ) ); + + /* Remember the location where we should copy the stack frame when we exit from + * the system call. */ + pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulStackFrameSize; + + /* Record if the hardware used padding to force the stack pointer + * to be double word aligned. */ + if( ( pulTaskStack[ portOFFSET_TO_PSR ] & portPSR_STACK_PADDING_MASK ) == portPSR_STACK_PADDING_MASK ) + { + pxMpuSettings->ulTaskFlags |= portSTACK_FRAME_HAS_PADDING_FLAG; + } + else + { + pxMpuSettings->ulTaskFlags &= ( ~portSTACK_FRAME_HAS_PADDING_FLAG ); + } + + /* We ensure in pxPortInitialiseStack that the system call stack is + * double word aligned and therefore, there is no need of padding. + * Clear the bit[9] of stacked xPSR. */ + pulSystemCallStack[ portOFFSET_TO_PSR ] &= ( ~portPSR_STACK_PADDING_MASK ); + + /* Raise the privilege for the duration of the system call. */ + __asm volatile ( + " mrs r0, control \n" /* Obtain current control value. */ + " movs r1, #1 \n" /* r1 = 1. */ + " bics r0, r1 \n" /* Clear nPRIV bit. */ + " msr control, r0 \n" /* Write back new control value. */ + ::: "r0", "r1", "memory" + ); + } +} - if( xRunPrivileged == pdTRUE ) +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + +void vSystemCallEnter_1( uint32_t * pulTaskStack, uint32_t ulLR ) /* PRIVILEGED_FUNCTION */ +{ + extern TaskHandle_t pxCurrentTCB; + xMPU_SETTINGS * pxMpuSettings; + uint32_t * pulSystemCallStack; + uint32_t ulStackFrameSize, ulSystemCallLocation, i; + #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being + * exported from linker scripts. */ + extern uint32_t * __syscalls_flash_start__; + extern uint32_t * __syscalls_flash_end__; + #else + /* Declaration when these variable are exported from linker scripts. */ + extern uint32_t __syscalls_flash_start__[]; + extern uint32_t __syscalls_flash_end__[]; + #endif /* #if defined( __ARMCC_VERSION ) */ + + ulSystemCallLocation = pulTaskStack[ portOFFSET_TO_PC ]; + + /* If the request did not come from the system call section, do nothing. */ + if( ( ulSystemCallLocation >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulSystemCallLocation <= ( uint32_t ) __syscalls_flash_end__ ) ) + { + pxMpuSettings = xTaskGetMPUSettings( pxCurrentTCB ); + pulSystemCallStack = pxMpuSettings->xSystemCallStackInfo.pulSystemCallStack; + + /* This is not NULL only for the duration of the system call. */ + configASSERT( pxMpuSettings->xSystemCallStackInfo.pulTaskStack == NULL ); + + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + { + if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) { - *pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */ + /* Extended frame i.e. FPU in use. */ + ulStackFrameSize = 26; + __asm volatile ( + " vpush {s0} \n" /* Trigger lazy stacking. */ + " vpop {s0} \n" /* Nullify the affect of the above instruction. */ + ::: "memory" + ); } else { - *pxTopOfStack = portINITIAL_CONTROL_UNPRIVILEGED; /* Slot used to hold this task's CONTROL value. */ + /* Standard frame i.e. FPU not in use. */ + ulStackFrameSize = 8; } } - #endif /* configENABLE_MPU */ + #else + { + ulStackFrameSize = 8; + } + #endif /* configENABLE_FPU || configENABLE_MVE */ + + /* Make space on the system call stack for the stack frame and + * the parameter passed on the stack. We only need to copy one + * parameter but we still reserve 2 spaces to keep the stack + * double word aligned. */ + pulSystemCallStack = pulSystemCallStack - ulStackFrameSize - 2UL; + + /* Copy the stack frame. */ + for( i = 0; i < ulStackFrameSize; i++ ) + { + pulSystemCallStack[ i ] = pulTaskStack[ i ]; + } + + /* Copy the parameter which is passed the stack. */ + if( ( pulTaskStack[ portOFFSET_TO_PSR ] & portPSR_STACK_PADDING_MASK ) == portPSR_STACK_PADDING_MASK ) + { + pulSystemCallStack[ ulStackFrameSize ] = pulTaskStack[ ulStackFrameSize + 1 ]; + /* Record if the hardware used padding to force the stack pointer + * to be double word aligned. */ + pxMpuSettings->ulTaskFlags |= portSTACK_FRAME_HAS_PADDING_FLAG; + } + else + { + pulSystemCallStack[ ulStackFrameSize ] = pulTaskStack[ ulStackFrameSize ]; + /* Record if the hardware used padding to force the stack pointer + * to be double word aligned. */ + pxMpuSettings->ulTaskFlags &= ( ~portSTACK_FRAME_HAS_PADDING_FLAG ); + } + + /* Store the value of the LR and PSPLIM registers before the SVC was raised. + * We need to restore it when we exit from the system call. */ + pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; + __asm volatile ( "mrs %0, psplim" : "=r" ( pxMpuSettings->xSystemCallStackInfo.ulStackLimitRegisterAtSystemCallEntry ) ); + + /* Use the pulSystemCallStack in thread mode. */ + __asm volatile ( "msr psp, %0" : : "r" ( pulSystemCallStack ) ); + __asm volatile ( "msr psplim, %0" : : "r" ( pxMpuSettings->xSystemCallStackInfo.pulSystemCallStackLimit ) ); + + /* Remember the location where we should copy the stack frame when we exit from + * the system call. */ + pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulStackFrameSize; + + /* We ensure in pxPortInitialiseStack that the system call stack is + * double word aligned and therefore, there is no need of padding. + * Clear the bit[9] of stacked xPSR. */ + pulSystemCallStack[ portOFFSET_TO_PSR ] &= ( ~portPSR_STACK_PADDING_MASK ); + + /* Raise the privilege for the duration of the system call. */ + __asm volatile ( + " mrs r0, control \n" /* Obtain current control value. */ + " movs r1, #1 \n" /* r1 = 1. */ + " bics r0, r1 \n" /* Clear nPRIV bit. */ + " msr control, r0 \n" /* Write back new control value. */ + ::: "r0", "r1", "memory" + ); + } +} + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) +void vSystemCallExit( uint32_t * pulSystemCallStack, uint32_t ulLR ) /* PRIVILEGED_FUNCTION */ +{ + extern TaskHandle_t pxCurrentTCB; + xMPU_SETTINGS * pxMpuSettings; + uint32_t * pulTaskStack; + uint32_t ulStackFrameSize, ulSystemCallLocation, i; + #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being + * exported from linker scripts. */ + extern uint32_t * __syscalls_flash_start__; + extern uint32_t * __syscalls_flash_end__; + #else + /* Declaration when these variable are exported from linker scripts. */ + extern uint32_t __syscalls_flash_start__[]; + extern uint32_t __syscalls_flash_end__[]; + #endif /* #if defined( __ARMCC_VERSION ) */ + + ulSystemCallLocation = pulSystemCallStack[ portOFFSET_TO_PC ]; + + /* If the request did not come from the system call section, do nothing. */ + if( ( ulSystemCallLocation >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulSystemCallLocation <= ( uint32_t ) __syscalls_flash_end__ ) ) + { + pxMpuSettings = xTaskGetMPUSettings( pxCurrentTCB ); + pulTaskStack = pxMpuSettings->xSystemCallStackInfo.pulTaskStack; + + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + { + if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) + { + /* Extended frame i.e. FPU in use. */ + ulStackFrameSize = 26; + __asm volatile ( + " vpush {s0} \n" /* Trigger lazy stacking. */ + " vpop {s0} \n" /* Nullify the affect of the above instruction. */ + ::: "memory" + ); + } + else + { + /* Standard frame i.e. FPU not in use. */ + ulStackFrameSize = 8; + } + } + #else + { + ulStackFrameSize = 8; + } + #endif /* configENABLE_FPU || configENABLE_MVE */ + + /* Make space on the task stack for the stack frame. */ + pulTaskStack = pulTaskStack - ulStackFrameSize; + + /* Copy the stack frame. */ + for( i = 0; i < ulStackFrameSize; i++ ) + { + pulTaskStack[ i ] = pulSystemCallStack[ i ]; + } + + /* Use the pulTaskStack in thread mode. */ + __asm volatile ( "msr psp, %0" : : "r" ( pulTaskStack ) ); + + /* Restore the LR and PSPLIM to what they were at the time of + * system call entry. */ + pulTaskStack[ portOFFSET_TO_LR ] = pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry; + __asm volatile ( "msr psplim, %0" : : "r" ( pxMpuSettings->xSystemCallStackInfo.ulStackLimitRegisterAtSystemCallEntry ) ); + + /* If the hardware used padding to force the stack pointer + * to be double word aligned, set the stacked xPSR bit[9], + * otherwise clear it. */ + if( ( pxMpuSettings->ulTaskFlags & portSTACK_FRAME_HAS_PADDING_FLAG ) == portSTACK_FRAME_HAS_PADDING_FLAG ) + { + pulTaskStack[ portOFFSET_TO_PSR ] |= portPSR_STACK_PADDING_MASK; + } + else + { + pulTaskStack[ portOFFSET_TO_PSR ] &= ( ~portPSR_STACK_PADDING_MASK ); + } + + /* This is not NULL only for the duration of the system call. */ + pxMpuSettings->xSystemCallStackInfo.pulTaskStack = NULL; + + /* Drop the privilege before returning to the thread mode. */ + __asm volatile ( + " mrs r0, control \n" /* Obtain current control value. */ + " movs r1, #1 \n" /* r1 = 1. */ + " orrs r0, r1 \n" /* Set nPRIV bit. */ + " msr control, r0 \n" /* Write back new control value. */ + ::: "r0", "r1", "memory" + ); + } +} + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configENABLE_MPU == 1 ) + +BaseType_t xPortIsTaskPrivileged( void ) /* PRIVILEGED_FUNCTION */ +{ + BaseType_t xTaskIsPrivileged = pdFALSE; + const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */ + + if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) + { + xTaskIsPrivileged = pdTRUE; + } + + return xTaskIsPrivileged; +} + +#endif /* configENABLE_MPU == 1 */ +/*-----------------------------------------------------------*/ + +#if( configENABLE_MPU == 1 ) + +StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, + StackType_t * pxEndOfStack, + TaskFunction_t pxCode, + void * pvParameters, + BaseType_t xRunPrivileged, + xMPU_SETTINGS * xMPUSettings ) /* PRIVILEGED_FUNCTION */ +{ + uint32_t ulIndex = 0; + + xMPUSettings->ulContext[ ulIndex ] = 0x04040404; /* r4. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x05050505; /* r5. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x06060606; /* r6. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x07070707; /* r7. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x08080808; /* r8. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x09090909; /* r9. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x10101010; /* r10. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x11111111; /* r11. */ + ulIndex++; + + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pvParameters; /* r0. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x01010101; /* r1. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x02020202; /* r2. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x03030303; /* r3. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x12121212; /* r12. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portTASK_RETURN_ADDRESS; /* LR. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxCode; /* PC. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = portINITIAL_XPSR; /* xPSR. */ + ulIndex++; + + #if ( configENABLE_TRUSTZONE == 1 ) + { + xMPUSettings->ulContext[ ulIndex ] = portNO_SECURE_CONTEXT; /* xSecureContext. */ + ulIndex++; + } + #endif /* configENABLE_TRUSTZONE */ + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) ( pxTopOfStack - 8 ); /* PSP with the hardware saved stack. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */ + ulIndex++; + if( xRunPrivileged == pdTRUE ) + { + xMPUSettings->ulTaskFlags |= portTASK_IS_PRIVILEGED_FLAG; + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_PRIVILEGED; /* CONTROL. */ + ulIndex++; + } + else + { + xMPUSettings->ulTaskFlags &= ( ~portTASK_IS_PRIVILEGED_FLAG ); + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_UNPRIVILEGED; /* CONTROL. */ + ulIndex++; + } + xMPUSettings->ulContext[ ulIndex ] = portINITIAL_EXC_RETURN; /* LR (EXC_RETURN). */ + ulIndex++; + + #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + { + /* Ensure that the system call stack is double word aligned. */ + xMPUSettings->xSystemCallStackInfo.pulSystemCallStack = &( xMPUSettings->xSystemCallStackInfo.ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE - 1 ] ); + xMPUSettings->xSystemCallStackInfo.pulSystemCallStack = ( uint32_t * ) ( ( uint32_t ) ( xMPUSettings->xSystemCallStackInfo.pulSystemCallStack ) & + ( uint32_t ) ( ~( portBYTE_ALIGNMENT_MASK ) ) ); + + xMPUSettings->xSystemCallStackInfo.pulSystemCallStackLimit = &( xMPUSettings->xSystemCallStackInfo.ulSystemCallStackBuffer[ 0 ] ); + xMPUSettings->xSystemCallStackInfo.pulSystemCallStackLimit = ( uint32_t * ) ( ( ( uint32_t ) ( xMPUSettings->xSystemCallStackInfo.pulSystemCallStackLimit ) + + ( uint32_t ) ( portBYTE_ALIGNMENT - 1 ) ) & + ( uint32_t ) ( ~( portBYTE_ALIGNMENT_MASK ) ) ); + + /* This is not NULL only for the duration of a system call. */ + xMPUSettings->xSystemCallStackInfo.pulTaskStack = NULL; + } + #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + + return &( xMPUSettings->ulContext[ ulIndex ] ); +} + +#else /* configENABLE_MPU */ + +StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, + StackType_t * pxEndOfStack, + TaskFunction_t pxCode, + void * pvParameters ) /* PRIVILEGED_FUNCTION */ +{ + /* Simulate the stack frame as it would be created by a context switch + * interrupt. */ + #if ( portPRELOAD_REGISTERS == 0 ) + { + pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ + *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR. */ + pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ + pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */ + *pxTopOfStack = portINITIAL_EXC_RETURN; pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ @@ -1029,55 +1561,39 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO #else /* portPRELOAD_REGISTERS */ { pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ - *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ + *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pxCode; /* PC */ + *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR */ + *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x12121212UL; /* R12 */ + *pxTopOfStack = ( StackType_t ) 0x12121212UL; /* R12. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x03030303UL; /* R3 */ + *pxTopOfStack = ( StackType_t ) 0x03030303UL; /* R3. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x02020202UL; /* R2 */ + *pxTopOfStack = ( StackType_t ) 0x02020202UL; /* R2. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x01010101UL; /* R1 */ + *pxTopOfStack = ( StackType_t ) 0x01010101UL; /* R1. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x11111111UL; /* R11 */ + *pxTopOfStack = ( StackType_t ) 0x11111111UL; /* R11. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x10101010UL; /* R10 */ + *pxTopOfStack = ( StackType_t ) 0x10101010UL; /* R10. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x09090909UL; /* R09 */ + *pxTopOfStack = ( StackType_t ) 0x09090909UL; /* R09. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x08080808UL; /* R08 */ + *pxTopOfStack = ( StackType_t ) 0x08080808UL; /* R08. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x07070707UL; /* R07 */ + *pxTopOfStack = ( StackType_t ) 0x07070707UL; /* R07. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x06060606UL; /* R06 */ + *pxTopOfStack = ( StackType_t ) 0x06060606UL; /* R06. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x05050505UL; /* R05 */ + *pxTopOfStack = ( StackType_t ) 0x05050505UL; /* R05. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x04040404UL; /* R04 */ + *pxTopOfStack = ( StackType_t ) 0x04040404UL; /* R04. */ pxTopOfStack--; - *pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN */ - - #if ( configENABLE_MPU == 1 ) - { - pxTopOfStack--; - - if( xRunPrivileged == pdTRUE ) - { - *pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */ - } - else - { - *pxTopOfStack = portINITIAL_CONTROL_UNPRIVILEGED; /* Slot used to hold this task's CONTROL value. */ - } - } - #endif /* configENABLE_MPU */ - + *pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN. */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ @@ -1092,6 +1608,8 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO return pxTopOfStack; } + +#endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ @@ -1128,6 +1646,10 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ configASSERT( ucMaxSysCallPriority ); + /* Check that the bits not implemented in hardware are zero in + * configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & ( ~ucMaxPriorityValue ) ) == 0U ); + /* Calculate the maximum acceptable priority group value for the number * of bits read back. */ @@ -1164,35 +1686,6 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulImplementedPrioBits; } - /* The interrupt priority bits are not modelled in QEMU and the assert that - * checks the number of implemented bits and __NVIC_PRIO_BITS will always fail. - * Therefore, this assert is not adding any value for QEMU targets. The config - * option `configDISABLE_INTERRUPT_PRIO_BITS_CHECK` should be defined in the - * `FreeRTOSConfig.h` for QEMU targets. */ - #ifndef configDISABLE_INTERRUPT_PRIO_BITS_CHECK - { - #ifdef __NVIC_PRIO_BITS - { - /* - * Check that the number of implemented priority bits queried from - * hardware is equal to the CMSIS __NVIC_PRIO_BITS configuration macro. - */ - configASSERT( ulImplementedPrioBits == __NVIC_PRIO_BITS ); - } - #endif /* __NVIC_PRIO_BITS */ - - #ifdef configPRIO_BITS - { - /* - * Check that the number of implemented priority bits queried from - * hardware is equal to the FreeRTOS configPRIO_BITS configuration macro. - */ - configASSERT( ulImplementedPrioBits == configPRIO_BITS ); - } - #endif /* configPRIO_BITS */ - } - #endif /* #ifndef configDISABLE_INTERRUPT_PRIO_BITS_CHECK */ - /* Shift the priority group value back to its position within the AIRCR * register. */ ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT; @@ -1372,6 +1865,54 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ +#if ( configENABLE_MPU == 1 ) + BaseType_t xPortIsAuthorizedToAccessBuffer( const void * pvBuffer, + uint32_t ulBufferLength, + uint32_t ulAccessRequested ) /* PRIVILEGED_FUNCTION */ + + { + uint32_t i, ulBufferStartAddress, ulBufferEndAddress; + BaseType_t xAccessGranted = pdFALSE; + const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */ + + if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) + { + xAccessGranted = pdTRUE; + } + else + { + if( portADD_UINT32_WILL_OVERFLOW( ( ( uint32_t ) pvBuffer ), ( ulBufferLength - 1UL ) ) == pdFALSE ) + { + ulBufferStartAddress = ( uint32_t ) pvBuffer; + ulBufferEndAddress = ( ( ( uint32_t ) pvBuffer ) + ulBufferLength - 1UL ); + + for( i = 0; i < portTOTAL_NUM_REGIONS; i++ ) + { + /* Is the MPU region enabled? */ + if( ( xTaskMpuSettings->xRegionsSettings[ i ].ulRLAR & portMPU_RLAR_REGION_ENABLE ) == portMPU_RLAR_REGION_ENABLE ) + { + if( portIS_ADDRESS_WITHIN_RANGE( ulBufferStartAddress, + portEXTRACT_FIRST_ADDRESS_FROM_RBAR( xTaskMpuSettings->xRegionsSettings[ i ].ulRBAR ), + portEXTRACT_LAST_ADDRESS_FROM_RLAR( xTaskMpuSettings->xRegionsSettings[ i ].ulRLAR ) ) && + portIS_ADDRESS_WITHIN_RANGE( ulBufferEndAddress, + portEXTRACT_FIRST_ADDRESS_FROM_RBAR( xTaskMpuSettings->xRegionsSettings[ i ].ulRBAR ), + portEXTRACT_LAST_ADDRESS_FROM_RLAR( xTaskMpuSettings->xRegionsSettings[ i ].ulRLAR ) ) && + portIS_AUTHORIZED( ulAccessRequested, + prvGetRegionAccessPermissions( xTaskMpuSettings->xRegionsSettings[ i ].ulRBAR ) ) ) + { + xAccessGranted = pdTRUE; + break; + } + } + } + } + } + + return xAccessGranted; + } +#endif /* configENABLE_MPU */ +/*-----------------------------------------------------------*/ + BaseType_t xPortIsInsideInterrupt( void ) { uint32_t ulCurrentInterrupt; diff --git a/portable/IAR/ARM_CM85/non_secure/portasm.s b/portable/IAR/ARM_CM85/non_secure/portasm.s index a193cd7b80e..15e74ffc16b 100644 --- a/portable/IAR/ARM_CM85/non_secure/portasm.s +++ b/portable/IAR/ARM_CM85/non_secure/portasm.s @@ -32,12 +32,21 @@ the code is included in C files but excluded by the preprocessor in assembly files (__ICCARM__ is defined by the IAR C compiler but not by the IAR assembler. */ #include "FreeRTOSConfig.h" +#ifndef configUSE_MPU_WRAPPERS_V1 + #define configUSE_MPU_WRAPPERS_V1 0 +#endif + EXTERN pxCurrentTCB EXTERN xSecureContext EXTERN vTaskSwitchContext EXTERN vPortSVCHandler_C EXTERN SecureContext_SaveContext EXTERN SecureContext_LoadContext +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + EXTERN vSystemCallEnter + EXTERN vSystemCallEnter_1 + EXTERN vSystemCallExit +#endif PUBLIC xIsPrivileged PUBLIC vResetPrivilege @@ -89,50 +98,81 @@ vPortAllocateSecureContext: THUMB /*-----------------------------------------------------------*/ +#if ( configENABLE_MPU == 1 ) + +vRestoreContextOfFirstTask: + program_mpu_first_task: + ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + ldr r0, [r3] /* r0 = pxCurrentTCB. */ + + dmb /* Complete outstanding transfers before disabling MPU. */ + ldr r1, =0xe000ed94 /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + ldr r2, [r1] /* Read the value of MPU_CTRL. */ + bic r2, #1 /* r2 = r2 & ~1 i.e. Clear the bit 0 in r2. */ + str r2, [r1] /* Disable MPU. */ + + adds r0, #4 /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */ + ldr r1, [r0] /* r1 = *r0 i.e. r1 = MAIR0. */ + ldr r2, =0xe000edc0 /* r2 = 0xe000edc0 [Location of MAIR0]. */ + str r1, [r2] /* Program MAIR0. */ + + adds r0, #4 /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */ + ldr r1, =0xe000ed98 /* r1 = 0xe000ed98 [Location of RNR]. */ + ldr r2, =0xe000ed9c /* r2 = 0xe000ed9c [Location of RBAR]. */ + + movs r3, #4 /* r3 = 4. */ + str r3, [r1] /* Program RNR = 4. */ + ldmia r0!, {r4-r11} /* Read 4 set of RBAR/RLAR registers from TCB. */ + stmia r2, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ + + #if ( configTOTAL_MPU_REGIONS == 16 ) + movs r3, #8 /* r3 = 8. */ + str r3, [r1] /* Program RNR = 8. */ + ldmia r0!, {r4-r11} /* Read 4 set of RBAR/RLAR registers from TCB. */ + stmia r2, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ + movs r3, #12 /* r3 = 12. */ + str r3, [r1] /* Program RNR = 12. */ + ldmia r0!, {r4-r11} /* Read 4 set of RBAR/RLAR registers from TCB. */ + stmia r2, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ + #endif /* configTOTAL_MPU_REGIONS == 16 */ + + ldr r1, =0xe000ed94 /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + ldr r2, [r1] /* Read the value of MPU_CTRL. */ + orr r2, #1 /* r2 = r1 | 1 i.e. Set the bit 0 in r2. */ + str r2, [r1] /* Enable MPU. */ + dsb /* Force memory writes before continuing. */ + + restore_context_first_task: + ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + ldr r1, [r3] /* r1 = pxCurrentTCB.*/ + ldr r2, [r1] /* r2 = Location of saved context in TCB. */ + + restore_special_regs_first_task: + ldmdb r2!, {r0, r3-r5, lr} /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */ + msr psp, r3 + msr psplim, r4 + msr control, r5 + ldr r4, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */ + str r0, [r4] /* Restore xSecureContext. */ + + restore_general_regs_first_task: + ldmdb r2!, {r4-r11} /* r4-r11 contain hardware saved context. */ + stmia r3!, {r4-r11} /* Copy the hardware saved context on the task stack. */ + ldmdb r2!, {r4-r11} /* r4-r11 restored. */ + + restore_context_done_first_task: + str r2, [r1] /* Save the location where the context should be saved next as the first member of TCB. */ + mov r0, #0 + msr basepri, r0 /* Ensure that interrupts are enabled when the first task starts. */ + bx lr + +#else /* configENABLE_MPU */ + vRestoreContextOfFirstTask: ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r3, [r2] /* Read pxCurrentTCB. */ ldr r0, [r3] /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ -#if ( configENABLE_MPU == 1 ) - dmb /* Complete outstanding transfers before disabling MPU. */ - ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ - ldr r4, [r2] /* Read the value of MPU_CTRL. */ - bic r4, r4, #1 /* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */ - str r4, [r2] /* Disable MPU. */ - - adds r3, #4 /* r3 = r3 + 4. r3 now points to MAIR0 in TCB. */ - ldr r4, [r3] /* r4 = *r3 i.e. r4 = MAIR0. */ - ldr r2, =0xe000edc0 /* r2 = 0xe000edc0 [Location of MAIR0]. */ - str r4, [r2] /* Program MAIR0. */ - ldr r2, =0xe000ed98 /* r2 = 0xe000ed98 [Location of RNR]. */ - movs r4, #4 /* r4 = 4. */ - str r4, [r2] /* Program RNR = 4. */ - adds r3, #4 /* r3 = r3 + 4. r3 now points to first RBAR in TCB. */ - ldr r2, =0xe000ed9c /* r2 = 0xe000ed9c [Location of RBAR]. */ - ldmia r3!, {r4-r11} /* Read 4 set of RBAR/RLAR registers from TCB. */ - stmia r2!, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ - - ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ - ldr r4, [r2] /* Read the value of MPU_CTRL. */ - orr r4, r4, #1 /* r4 = r4 | 1 i.e. Set the bit 0 in r4. */ - str r4, [r2] /* Enable MPU. */ - dsb /* Force memory writes before continuing. */ -#endif /* configENABLE_MPU */ - -#if ( configENABLE_MPU == 1 ) - ldm r0!, {r1-r4} /* Read from stack - r1 = xSecureContext, r2 = PSPLIM, r3 = CONTROL and r4 = EXC_RETURN. */ - ldr r5, =xSecureContext - str r1, [r5] /* Set xSecureContext to this task's value for the same. */ - msr psplim, r2 /* Set this task's PSPLIM value. */ - msr control, r3 /* Set this task's CONTROL value. */ - adds r0, #32 /* Discard everything up to r0. */ - msr psp, r0 /* This is now the new top of stack to use in the task. */ - isb - mov r0, #0 - msr basepri, r0 /* Ensure that interrupts are enabled when the first task starts. */ - bx r4 /* Finally, branch to EXC_RETURN. */ -#else /* configENABLE_MPU */ ldm r0!, {r1-r3} /* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */ ldr r4, =xSecureContext str r1, [r4] /* Set xSecureContext to this task's value for the same. */ @@ -145,6 +185,7 @@ vRestoreContextOfFirstTask: mov r0, #0 msr basepri, r0 /* Ensure that interrupts are enabled when the first task starts. */ bx r3 /* Finally, branch to EXC_RETURN. */ + #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ @@ -183,6 +224,143 @@ vClearInterruptMask: bx lr /* Return. */ /*-----------------------------------------------------------*/ +#if ( configENABLE_MPU == 1 ) + +PendSV_Handler: + ldr r3, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */ + ldr r0, [r3] /* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */ + ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + ldr r1, [r3] /* Read pxCurrentTCB - Value of pxCurrentTCB must be in r1 as it is used as a parameter later. */ + ldr r2, [r1] /* r2 = Location in TCB where the context should be saved. */ + + cbz r0, save_ns_context /* No secure context to save. */ + save_s_context: + push {r0-r2, lr} + bl SecureContext_SaveContext /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ + pop {r0-r2, lr} + + save_ns_context: + mov r3, lr /* r3 = LR (EXC_RETURN). */ + lsls r3, r3, #25 /* r3 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ + bmi save_special_regs /* r3 < 0 ==> Bit[6] in EXC_RETURN is 1 ==> secure stack was used to store the stack frame. */ + + save_general_regs: + mrs r3, psp + + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + add r3, r3, #0x20 /* Move r3 to location where s0 is saved. */ + tst lr, #0x10 + ittt eq + vstmiaeq r2!, {s16-s31} /* Store s16-s31. */ + vldmiaeq r3, {s0-s16} /* Copy hardware saved FP context into s0-s16. */ + vstmiaeq r2!, {s0-s16} /* Store hardware saved FP context. */ + sub r3, r3, #0x20 /* Set r3 back to the location of hardware saved context. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ + + stmia r2!, {r4-r11} /* Store r4-r11. */ + ldmia r3, {r4-r11} /* Copy the hardware saved context into r4-r11. */ + stmia r2!, {r4-r11} /* Store the hardware saved context. */ + + save_special_regs: + mrs r3, psp /* r3 = PSP. */ + mrs r4, psplim /* r4 = PSPLIM. */ + mrs r5, control /* r5 = CONTROL. */ + stmia r2!, {r0, r3-r5, lr} /* Store xSecureContext, original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */ + str r2, [r1] /* Save the location from where the context should be restored as the first member of TCB. */ + + select_next_task: + mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY + msr basepri, r0 /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + dsb + isb + bl vTaskSwitchContext + mov r0, #0 /* r0 = 0. */ + msr basepri, r0 /* Enable interrupts. */ + + program_mpu: + ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + ldr r0, [r3] /* r0 = pxCurrentTCB.*/ + + dmb /* Complete outstanding transfers before disabling MPU. */ + ldr r1, =0xe000ed94 /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + ldr r2, [r1] /* Read the value of MPU_CTRL. */ + bic r2, #1 /* r2 = r2 & ~1 i.e. Clear the bit 0 in r2. */ + str r2, [r1] /* Disable MPU. */ + + adds r0, #4 /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */ + ldr r1, [r0] /* r1 = *r0 i.e. r1 = MAIR0. */ + ldr r2, =0xe000edc0 /* r2 = 0xe000edc0 [Location of MAIR0]. */ + str r1, [r2] /* Program MAIR0. */ + + adds r0, #4 /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */ + ldr r1, =0xe000ed98 /* r1 = 0xe000ed98 [Location of RNR]. */ + ldr r2, =0xe000ed9c /* r2 = 0xe000ed9c [Location of RBAR]. */ + + movs r3, #4 /* r3 = 4. */ + str r3, [r1] /* Program RNR = 4. */ + ldmia r0!, {r4-r11} /* Read 4 sets of RBAR/RLAR registers from TCB. */ + stmia r2, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ + + #if ( configTOTAL_MPU_REGIONS == 16 ) + movs r3, #8 /* r3 = 8. */ + str r3, [r1] /* Program RNR = 8. */ + ldmia r0!, {r4-r11} /* Read 4 sets of RBAR/RLAR registers from TCB. */ + stmia r2, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ + movs r3, #12 /* r3 = 12. */ + str r3, [r1] /* Program RNR = 12. */ + ldmia r0!, {r4-r11} /* Read 4 sets of RBAR/RLAR registers from TCB. */ + stmia r2, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ + #endif /* configTOTAL_MPU_REGIONS == 16 */ + + ldr r1, =0xe000ed94 /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + ldr r2, [r1] /* Read the value of MPU_CTRL. */ + orr r2, #1 /* r2 = r2 | 1 i.e. Set the bit 0 in r2. */ + str r2, [r1] /* Enable MPU. */ + dsb /* Force memory writes before continuing. */ + + restore_context: + ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + ldr r1, [r3] /* r1 = pxCurrentTCB.*/ + ldr r2, [r1] /* r2 = Location of saved context in TCB. */ + + restore_special_regs: + ldmdb r2!, {r0, r3-r5, lr} /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */ + msr psp, r3 + msr psplim, r4 + msr control, r5 + ldr r4, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */ + str r0, [r4] /* Restore xSecureContext. */ + cbz r0, restore_ns_context /* No secure context to restore. */ + + restore_s_context: + push {r1-r3, lr} + bl SecureContext_LoadContext /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ + pop {r1-r3, lr} + + restore_ns_context: + mov r0, lr /* r0 = LR (EXC_RETURN). */ + lsls r0, r0, #25 /* r0 = r0 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ + bmi restore_context_done /* r0 < 0 ==> Bit[6] in EXC_RETURN is 1 ==> secure stack was used to store the stack frame. */ + + restore_general_regs: + ldmdb r2!, {r4-r11} /* r4-r11 contain hardware saved context. */ + stmia r3!, {r4-r11} /* Copy the hardware saved context on the task stack. */ + ldmdb r2!, {r4-r11} /* r4-r11 restored. */ + + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + tst lr, #0x10 + ittt eq + vldmdbeq r2!, {s0-s16} /* s0-s16 contain hardware saved FP context. */ + vstmiaeq r3!, {s0-s16} /* Copy hardware saved FP context on the task stack. */ + vldmdbeq r2!, {s16-s31} /* Restore s16-s31. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ + + restore_context_done: + str r2, [r1] /* Save the location where the context should be saved next as the first member of TCB. */ + bx lr + +#else /* configENABLE_MPU */ + PendSV_Handler: ldr r3, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */ ldr r0, [r3] /* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */ @@ -200,20 +378,11 @@ PendSV_Handler: ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r3] /* Read pxCurrentTCB. */ -#if ( configENABLE_MPU == 1 ) - subs r2, r2, #16 /* Make space for xSecureContext, PSPLIM, CONTROL and LR on the stack. */ - str r2, [r1] /* Save the new top of stack in TCB. */ - mrs r1, psplim /* r1 = PSPLIM. */ - mrs r3, control /* r3 = CONTROL. */ - mov r4, lr /* r4 = LR/EXC_RETURN. */ - stmia r2!, {r0, r1, r3, r4} /* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */ -#else /* configENABLE_MPU */ subs r2, r2, #12 /* Make space for xSecureContext, PSPLIM and LR on the stack. */ str r2, [r1] /* Save the new top of stack in TCB. */ mrs r1, psplim /* r1 = PSPLIM. */ mov r3, lr /* r3 = LR/EXC_RETURN. */ stmia r2!, {r0, r1, r3} /* Store xSecureContext, PSPLIM and LR on the stack. */ -#endif /* configENABLE_MPU */ b select_next_task save_ns_context: @@ -224,17 +393,6 @@ PendSV_Handler: it eq vstmdbeq r2!, {s16-s31} /* Store the additional FP context registers which are not saved automatically. */ #endif /* configENABLE_FPU || configENABLE_MVE */ - #if ( configENABLE_MPU == 1 ) - subs r2, r2, #48 /* Make space for xSecureContext, PSPLIM, CONTROL, LR and the remaining registers on the stack. */ - str r2, [r1] /* Save the new top of stack in TCB. */ - adds r2, r2, #16 /* r2 = r2 + 16. */ - stm r2, {r4-r11} /* Store the registers that are not saved automatically. */ - mrs r1, psplim /* r1 = PSPLIM. */ - mrs r3, control /* r3 = CONTROL. */ - mov r4, lr /* r4 = LR/EXC_RETURN. */ - subs r2, r2, #16 /* r2 = r2 - 16. */ - stmia r2!, {r0, r1, r3, r4} /* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */ - #else /* configENABLE_MPU */ subs r2, r2, #44 /* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */ str r2, [r1] /* Save the new top of stack in TCB. */ adds r2, r2, #12 /* r2 = r2 + 12. */ @@ -243,7 +401,6 @@ PendSV_Handler: mov r3, lr /* r3 = LR/EXC_RETURN. */ subs r2, r2, #12 /* r2 = r2 - 12. */ stmia r2!, {r0, r1, r3} /* Store xSecureContext, PSPLIM and LR on the stack. */ - #endif /* configENABLE_MPU */ select_next_task: mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY @@ -258,51 +415,6 @@ PendSV_Handler: ldr r1, [r3] /* Read pxCurrentTCB. */ ldr r2, [r1] /* The first item in pxCurrentTCB is the task top of stack. r2 now points to the top of stack. */ - #if ( configENABLE_MPU == 1 ) - dmb /* Complete outstanding transfers before disabling MPU. */ - ldr r3, =0xe000ed94 /* r3 = 0xe000ed94 [Location of MPU_CTRL]. */ - ldr r4, [r3] /* Read the value of MPU_CTRL. */ - bic r4, r4, #1 /* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */ - str r4, [r3] /* Disable MPU. */ - - adds r1, #4 /* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */ - ldr r4, [r1] /* r4 = *r1 i.e. r4 = MAIR0. */ - ldr r3, =0xe000edc0 /* r3 = 0xe000edc0 [Location of MAIR0]. */ - str r4, [r3] /* Program MAIR0. */ - ldr r3, =0xe000ed98 /* r3 = 0xe000ed98 [Location of RNR]. */ - movs r4, #4 /* r4 = 4. */ - str r4, [r3] /* Program RNR = 4. */ - adds r1, #4 /* r1 = r1 + 4. r1 now points to first RBAR in TCB. */ - ldr r3, =0xe000ed9c /* r3 = 0xe000ed9c [Location of RBAR]. */ - ldmia r1!, {r4-r11} /* Read 4 sets of RBAR/RLAR registers from TCB. */ - stmia r3!, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ - - ldr r3, =0xe000ed94 /* r3 = 0xe000ed94 [Location of MPU_CTRL]. */ - ldr r4, [r3] /* Read the value of MPU_CTRL. */ - orr r4, r4, #1 /* r4 = r4 | 1 i.e. Set the bit 0 in r4. */ - str r4, [r3] /* Enable MPU. */ - dsb /* Force memory writes before continuing. */ - #endif /* configENABLE_MPU */ - - #if ( configENABLE_MPU == 1 ) - ldmia r2!, {r0, r1, r3, r4} /* Read from stack - r0 = xSecureContext, r1 = PSPLIM, r3 = CONTROL and r4 = LR. */ - msr psplim, r1 /* Restore the PSPLIM register value for the task. */ - msr control, r3 /* Restore the CONTROL register value for the task. */ - mov lr, r4 /* LR = r4. */ - ldr r3, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */ - str r0, [r3] /* Restore the task's xSecureContext. */ - cbz r0, restore_ns_context /* If there is no secure context for the task, restore the non-secure context. */ - ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - ldr r1, [r3] /* Read pxCurrentTCB. */ - push {r2, r4} - bl SecureContext_LoadContext /* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ - pop {r2, r4} - mov lr, r4 /* LR = r4. */ - lsls r1, r4, #25 /* r1 = r4 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ - bpl restore_ns_context /* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ - msr psp, r2 /* Remember the new top of stack for the task. */ - bx lr - #else /* configENABLE_MPU */ ldmia r2!, {r0, r1, r4} /* Read from stack - r0 = xSecureContext, r1 = PSPLIM and r4 = LR. */ msr psplim, r1 /* Restore the PSPLIM register value for the task. */ mov lr, r4 /* LR = r4. */ @@ -319,7 +431,6 @@ PendSV_Handler: bpl restore_ns_context /* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ msr psp, r2 /* Remember the new top of stack for the task. */ bx lr - #endif /* configENABLE_MPU */ restore_ns_context: ldmia r2!, {r4-r11} /* Restore the registers that are not automatically restored. */ @@ -330,14 +441,50 @@ PendSV_Handler: #endif /* configENABLE_FPU || configENABLE_MVE */ msr psp, r2 /* Remember the new top of stack for the task. */ bx lr + +#endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + SVC_Handler: tst lr, #4 ite eq mrseq r0, msp mrsne r0, psp + + ldr r1, [r0, #24] + ldrb r2, [r1, #-2] + cmp r2, #4 /* portSVC_SYSTEM_CALL_ENTER. */ + beq syscall_enter + cmp r2, #5 /* portSVC_SYSTEM_CALL_ENTER_1. */ + beq syscall_enter_1 + cmp r2, #6 /* portSVC_SYSTEM_CALL_EXIT. */ + beq syscall_exit b vPortSVCHandler_C + + syscall_enter: + mov r1, lr + b vSystemCallEnter + + syscall_enter_1: + mov r1, lr + b vSystemCallEnter_1 + + syscall_exit: + mov r1, lr + b vSystemCallExit + +#else /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + +SVC_Handler: + tst lr, #4 + ite eq + mrseq r0, msp + mrsne r0, psp + b vPortSVCHandler_C + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ /*-----------------------------------------------------------*/ vPortFreeSecureContext: diff --git a/portable/IAR/ARM_CM85/non_secure/portmacrocommon.h b/portable/IAR/ARM_CM85/non_secure/portmacrocommon.h index c2ca5fa7730..65ac109c802 100644 --- a/portable/IAR/ARM_CM85/non_secure/portmacrocommon.h +++ b/portable/IAR/ARM_CM85/non_secure/portmacrocommon.h @@ -186,23 +186,120 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #define portMPU_REGION_EXECUTE_NEVER ( 1UL ) /*-----------------------------------------------------------*/ -/** - * @brief Settings to define an MPU region. - */ -typedef struct MPURegionSettings -{ - uint32_t ulRBAR; /**< RBAR for the region. */ - uint32_t ulRLAR; /**< RLAR for the region. */ -} MPURegionSettings_t; +#if ( configENABLE_MPU == 1 ) -/** - * @brief MPU settings as stored in the TCB. - */ -typedef struct MPU_SETTINGS -{ - uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ - MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */ -} xMPU_SETTINGS; + /** + * @brief Settings to define an MPU region. + */ + typedef struct MPURegionSettings + { + uint32_t ulRBAR; /**< RBAR for the region. */ + uint32_t ulRLAR; /**< RLAR for the region. */ + } MPURegionSettings_t; + + #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + + #ifndef configSYSTEM_CALL_STACK_SIZE + #error configSYSTEM_CALL_STACK_SIZE must be defined to the desired size of the system call stack in words for using MPU wrappers v2. + #endif + + /** + * @brief System call stack. + */ + typedef struct SYSTEM_CALL_STACK_INFO + { + uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ]; + uint32_t * pulSystemCallStack; + uint32_t * pulSystemCallStackLimit; + uint32_t * pulTaskStack; + uint32_t ulLinkRegisterAtSystemCallEntry; + uint32_t ulStackLimitRegisterAtSystemCallEntry; + } xSYSTEM_CALL_STACK_INFO; + + #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + + /** + * @brief MPU settings as stored in the TCB. + */ + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + + #if( configENABLE_TRUSTZONE == 1 ) + + /* + * +-----------+---------------+----------+-----------------+------------------------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | + * | | | | PC, xPSR | CONTROL, EXC_RETURN | | + * +-----------+---------------+----------+-----------------+------------------------------+-----+ + * + * <-----------><--------------><---------><----------------><-----------------------------><----> + * 16 16 8 8 5 1 + */ + #define MAX_CONTEXT_SIZE 54 + + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ + + /* + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | + * | | | | PC, xPSR | EXC_RETURN | | + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * + * <-----------><--------------><---------><----------------><---------------------><----> + * 16 16 8 8 4 1 + */ + #define MAX_CONTEXT_SIZE 53 + + #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + + #else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ + + #if( configENABLE_TRUSTZONE == 1 ) + + /* + * +----------+-----------------+------------------------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | + * | | PC, xPSR | CONTROL, EXC_RETURN | | + * +----------+-----------------+------------------------------+-----+ + * + * <---------><----------------><------------------------------><----> + * 8 8 5 1 + */ + #define MAX_CONTEXT_SIZE 22 + + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ + + /* + * +----------+-----------------+----------------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | + * | | PC, xPSR | EXC_RETURN | | + * +----------+-----------------+----------------------+-----+ + * + * <---------><----------------><----------------------><----> + * 8 8 4 1 + */ + #define MAX_CONTEXT_SIZE 21 + + #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + + #endif /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ + + /* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ + #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) + #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) + + typedef struct MPU_SETTINGS + { + uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ + MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */ + uint32_t ulContext[ MAX_CONTEXT_SIZE ]; + uint32_t ulTaskFlags; + + #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo; + #endif + } xMPU_SETTINGS; + +#endif /* configENABLE_MPU == 1 */ /*-----------------------------------------------------------*/ /** @@ -223,6 +320,9 @@ typedef struct MPU_SETTINGS #define portSVC_FREE_SECURE_CONTEXT 1 #define portSVC_START_SCHEDULER 2 #define portSVC_RAISE_PRIVILEGE 3 +#define portSVC_SYSTEM_CALL_ENTER 4 /* System calls with upto 4 parameters. */ +#define portSVC_SYSTEM_CALL_ENTER_1 5 /* System calls with 5 parameters. */ +#define portSVC_SYSTEM_CALL_EXIT 6 /*-----------------------------------------------------------*/ /** @@ -315,6 +415,20 @@ typedef struct MPU_SETTINGS #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ +#if ( configENABLE_MPU == 1 ) + + extern BaseType_t xPortIsTaskPrivileged( void ); + + /** + * @brief Checks whether or not the calling task is privileged. + * + * @return pdTRUE if the calling task is privileged, pdFALSE otherwise. + */ + #define portIS_TASK_PRIVILEGED() xPortIsTaskPrivileged() + +#endif /* configENABLE_MPU == 1 */ +/*-----------------------------------------------------------*/ + /** * @brief Barriers. */ diff --git a/portable/IAR/ARM_CM85_NTZ/non_secure/mpu_wrappers_v2_asm.S b/portable/IAR/ARM_CM85_NTZ/non_secure/mpu_wrappers_v2_asm.S new file mode 100644 index 00000000000..f051a6073dd --- /dev/null +++ b/portable/IAR/ARM_CM85_NTZ/non_secure/mpu_wrappers_v2_asm.S @@ -0,0 +1,1552 @@ +/* + * FreeRTOS Kernel + * Copyright (C) 2021 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 + * + */ + + + SECTION freertos_system_calls:CODE:NOROOT(2) + THUMB +/*-----------------------------------------------------------*/ + +#include "FreeRTOSConfig.h" + +#ifndef configUSE_MPU_WRAPPERS_V1 + #define configUSE_MPU_WRAPPERS_V1 0 +#endif + +/* These must be in sync with portmacro.h. */ +#define portSVC_SYSTEM_CALL_ENTER 4 /* System calls with upto 4 parameters. */ +#define portSVC_SYSTEM_CALL_ENTER_1 5 /* System calls with 5 parameters. */ +#define portSVC_SYSTEM_CALL_EXIT 6 +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + + PUBLIC MPU_xTaskDelayUntil +MPU_xTaskDelayUntil: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskDelayUntil_Unpriv + MPU_xTaskDelayUntil_Priv: + pop {r0} + b MPU_xTaskDelayUntilImpl + MPU_xTaskDelayUntil_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskDelayUntilImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskAbortDelay +MPU_xTaskAbortDelay: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskAbortDelay_Unpriv + MPU_xTaskAbortDelay_Priv: + pop {r0} + b MPU_xTaskAbortDelayImpl + MPU_xTaskAbortDelay_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskAbortDelayImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTaskDelay +MPU_vTaskDelay: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vTaskDelay_Unpriv + MPU_vTaskDelay_Priv: + pop {r0} + b MPU_vTaskDelayImpl + MPU_vTaskDelay_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskDelayImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxTaskPriorityGet +MPU_uxTaskPriorityGet: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_uxTaskPriorityGet_Unpriv + MPU_uxTaskPriorityGet_Priv: + pop {r0} + b MPU_uxTaskPriorityGetImpl + MPU_uxTaskPriorityGet_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxTaskPriorityGetImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_eTaskGetState +MPU_eTaskGetState: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_eTaskGetState_Unpriv + MPU_eTaskGetState_Priv: + pop {r0} + b MPU_eTaskGetStateImpl + MPU_eTaskGetState_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_eTaskGetStateImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTaskGetInfo +MPU_vTaskGetInfo: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vTaskGetInfo_Unpriv + MPU_vTaskGetInfo_Priv: + pop {r0} + b MPU_vTaskGetInfoImpl + MPU_vTaskGetInfo_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskGetInfoImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGetIdleTaskHandle +MPU_xTaskGetIdleTaskHandle: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskGetIdleTaskHandle_Unpriv + MPU_xTaskGetIdleTaskHandle_Priv: + pop {r0} + b MPU_xTaskGetIdleTaskHandleImpl + MPU_xTaskGetIdleTaskHandle_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskGetIdleTaskHandleImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTaskSuspend +MPU_vTaskSuspend: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vTaskSuspend_Unpriv + MPU_vTaskSuspend_Priv: + pop {r0} + b MPU_vTaskSuspendImpl + MPU_vTaskSuspend_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskSuspendImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTaskResume +MPU_vTaskResume: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vTaskResume_Unpriv + MPU_vTaskResume_Priv: + pop {r0} + b MPU_vTaskResumeImpl + MPU_vTaskResume_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskResumeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGetTickCount +MPU_xTaskGetTickCount: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskGetTickCount_Unpriv + MPU_xTaskGetTickCount_Priv: + pop {r0} + b MPU_xTaskGetTickCountImpl + MPU_xTaskGetTickCount_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskGetTickCountImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxTaskGetNumberOfTasks +MPU_uxTaskGetNumberOfTasks: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_uxTaskGetNumberOfTasks_Unpriv + MPU_uxTaskGetNumberOfTasks_Priv: + pop {r0} + b MPU_uxTaskGetNumberOfTasksImpl + MPU_uxTaskGetNumberOfTasks_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxTaskGetNumberOfTasksImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_pcTaskGetName +MPU_pcTaskGetName: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_pcTaskGetName_Unpriv + MPU_pcTaskGetName_Priv: + pop {r0} + b MPU_pcTaskGetNameImpl + MPU_pcTaskGetName_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_pcTaskGetNameImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_ulTaskGetRunTimeCounter +MPU_ulTaskGetRunTimeCounter: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_ulTaskGetRunTimeCounter_Unpriv + MPU_ulTaskGetRunTimeCounter_Priv: + pop {r0} + b MPU_ulTaskGetRunTimeCounterImpl + MPU_ulTaskGetRunTimeCounter_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_ulTaskGetRunTimeCounterImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_ulTaskGetRunTimePercent +MPU_ulTaskGetRunTimePercent: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_ulTaskGetRunTimePercent_Unpriv + MPU_ulTaskGetRunTimePercent_Priv: + pop {r0} + b MPU_ulTaskGetRunTimePercentImpl + MPU_ulTaskGetRunTimePercent_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_ulTaskGetRunTimePercentImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_ulTaskGetIdleRunTimePercent +MPU_ulTaskGetIdleRunTimePercent: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_ulTaskGetIdleRunTimePercent_Unpriv + MPU_ulTaskGetIdleRunTimePercent_Priv: + pop {r0} + b MPU_ulTaskGetIdleRunTimePercentImpl + MPU_ulTaskGetIdleRunTimePercent_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_ulTaskGetIdleRunTimePercentImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_ulTaskGetIdleRunTimeCounter +MPU_ulTaskGetIdleRunTimeCounter: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_ulTaskGetIdleRunTimeCounter_Unpriv + MPU_ulTaskGetIdleRunTimeCounter_Priv: + pop {r0} + b MPU_ulTaskGetIdleRunTimeCounterImpl + MPU_ulTaskGetIdleRunTimeCounter_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_ulTaskGetIdleRunTimeCounterImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTaskSetApplicationTaskTag +MPU_vTaskSetApplicationTaskTag: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vTaskSetApplicationTaskTag_Unpriv + MPU_vTaskSetApplicationTaskTag_Priv: + pop {r0} + b MPU_vTaskSetApplicationTaskTagImpl + MPU_vTaskSetApplicationTaskTag_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskSetApplicationTaskTagImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGetApplicationTaskTag +MPU_xTaskGetApplicationTaskTag: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskGetApplicationTaskTag_Unpriv + MPU_xTaskGetApplicationTaskTag_Priv: + pop {r0} + b MPU_xTaskGetApplicationTaskTagImpl + MPU_xTaskGetApplicationTaskTag_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskGetApplicationTaskTagImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTaskSetThreadLocalStoragePointer +MPU_vTaskSetThreadLocalStoragePointer: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vTaskSetThreadLocalStoragePointer_Unpriv + MPU_vTaskSetThreadLocalStoragePointer_Priv: + pop {r0} + b MPU_vTaskSetThreadLocalStoragePointerImpl + MPU_vTaskSetThreadLocalStoragePointer_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskSetThreadLocalStoragePointerImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_pvTaskGetThreadLocalStoragePointer +MPU_pvTaskGetThreadLocalStoragePointer: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_pvTaskGetThreadLocalStoragePointer_Unpriv + MPU_pvTaskGetThreadLocalStoragePointer_Priv: + pop {r0} + b MPU_pvTaskGetThreadLocalStoragePointerImpl + MPU_pvTaskGetThreadLocalStoragePointer_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_pvTaskGetThreadLocalStoragePointerImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxTaskGetSystemState +MPU_uxTaskGetSystemState: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_uxTaskGetSystemState_Unpriv + MPU_uxTaskGetSystemState_Priv: + pop {r0} + b MPU_uxTaskGetSystemStateImpl + MPU_uxTaskGetSystemState_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxTaskGetSystemStateImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxTaskGetStackHighWaterMark +MPU_uxTaskGetStackHighWaterMark: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_uxTaskGetStackHighWaterMark_Unpriv + MPU_uxTaskGetStackHighWaterMark_Priv: + pop {r0} + b MPU_uxTaskGetStackHighWaterMarkImpl + MPU_uxTaskGetStackHighWaterMark_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxTaskGetStackHighWaterMarkImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxTaskGetStackHighWaterMark2 +MPU_uxTaskGetStackHighWaterMark2: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_uxTaskGetStackHighWaterMark2_Unpriv + MPU_uxTaskGetStackHighWaterMark2_Priv: + pop {r0} + b MPU_uxTaskGetStackHighWaterMark2Impl + MPU_uxTaskGetStackHighWaterMark2_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxTaskGetStackHighWaterMark2Impl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGetCurrentTaskHandle +MPU_xTaskGetCurrentTaskHandle: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskGetCurrentTaskHandle_Unpriv + MPU_xTaskGetCurrentTaskHandle_Priv: + pop {r0} + b MPU_xTaskGetCurrentTaskHandleImpl + MPU_xTaskGetCurrentTaskHandle_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskGetCurrentTaskHandleImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGetSchedulerState +MPU_xTaskGetSchedulerState: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskGetSchedulerState_Unpriv + MPU_xTaskGetSchedulerState_Priv: + pop {r0} + b MPU_xTaskGetSchedulerStateImpl + MPU_xTaskGetSchedulerState_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskGetSchedulerStateImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTaskSetTimeOutState +MPU_vTaskSetTimeOutState: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vTaskSetTimeOutState_Unpriv + MPU_vTaskSetTimeOutState_Priv: + pop {r0} + b MPU_vTaskSetTimeOutStateImpl + MPU_vTaskSetTimeOutState_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskSetTimeOutStateImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskCheckForTimeOut +MPU_xTaskCheckForTimeOut: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskCheckForTimeOut_Unpriv + MPU_xTaskCheckForTimeOut_Priv: + pop {r0} + b MPU_xTaskCheckForTimeOutImpl + MPU_xTaskCheckForTimeOut_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskCheckForTimeOutImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGenericNotify +MPU_xTaskGenericNotify: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskGenericNotify_Unpriv + MPU_xTaskGenericNotify_Priv: + pop {r0} + b MPU_xTaskGenericNotifyImpl + MPU_xTaskGenericNotify_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER_1 + bl MPU_xTaskGenericNotifyImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGenericNotifyWait +MPU_xTaskGenericNotifyWait: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskGenericNotifyWait_Unpriv + MPU_xTaskGenericNotifyWait_Priv: + pop {r0} + b MPU_xTaskGenericNotifyWaitImpl + MPU_xTaskGenericNotifyWait_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER_1 + bl MPU_xTaskGenericNotifyWaitImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_ulTaskGenericNotifyTake +MPU_ulTaskGenericNotifyTake: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_ulTaskGenericNotifyTake_Unpriv + MPU_ulTaskGenericNotifyTake_Priv: + pop {r0} + b MPU_ulTaskGenericNotifyTakeImpl + MPU_ulTaskGenericNotifyTake_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_ulTaskGenericNotifyTakeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTaskGenericNotifyStateClear +MPU_xTaskGenericNotifyStateClear: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskGenericNotifyStateClear_Unpriv + MPU_xTaskGenericNotifyStateClear_Priv: + pop {r0} + b MPU_xTaskGenericNotifyStateClearImpl + MPU_xTaskGenericNotifyStateClear_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskGenericNotifyStateClearImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_ulTaskGenericNotifyValueClear +MPU_ulTaskGenericNotifyValueClear: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_ulTaskGenericNotifyValueClear_Unpriv + MPU_ulTaskGenericNotifyValueClear_Priv: + pop {r0} + b MPU_ulTaskGenericNotifyValueClearImpl + MPU_ulTaskGenericNotifyValueClear_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_ulTaskGenericNotifyValueClearImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueGenericSend +MPU_xQueueGenericSend: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xQueueGenericSend_Unpriv + MPU_xQueueGenericSend_Priv: + pop {r0} + b MPU_xQueueGenericSendImpl + MPU_xQueueGenericSend_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueGenericSendImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxQueueMessagesWaiting +MPU_uxQueueMessagesWaiting: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_uxQueueMessagesWaiting_Unpriv + MPU_uxQueueMessagesWaiting_Priv: + pop {r0} + b MPU_uxQueueMessagesWaitingImpl + MPU_uxQueueMessagesWaiting_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxQueueMessagesWaitingImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxQueueSpacesAvailable +MPU_uxQueueSpacesAvailable: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_uxQueueSpacesAvailable_Unpriv + MPU_uxQueueSpacesAvailable_Priv: + pop {r0} + b MPU_uxQueueSpacesAvailableImpl + MPU_uxQueueSpacesAvailable_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxQueueSpacesAvailableImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueReceive +MPU_xQueueReceive: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xQueueReceive_Unpriv + MPU_xQueueReceive_Priv: + pop {r0} + b MPU_xQueueReceiveImpl + MPU_xQueueReceive_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueReceiveImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueuePeek +MPU_xQueuePeek: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xQueuePeek_Unpriv + MPU_xQueuePeek_Priv: + pop {r0} + b MPU_xQueuePeekImpl + MPU_xQueuePeek_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueuePeekImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueSemaphoreTake +MPU_xQueueSemaphoreTake: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xQueueSemaphoreTake_Unpriv + MPU_xQueueSemaphoreTake_Priv: + pop {r0} + b MPU_xQueueSemaphoreTakeImpl + MPU_xQueueSemaphoreTake_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueSemaphoreTakeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueGetMutexHolder +MPU_xQueueGetMutexHolder: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xQueueGetMutexHolder_Unpriv + MPU_xQueueGetMutexHolder_Priv: + pop {r0} + b MPU_xQueueGetMutexHolderImpl + MPU_xQueueGetMutexHolder_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueGetMutexHolderImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueTakeMutexRecursive +MPU_xQueueTakeMutexRecursive: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xQueueTakeMutexRecursive_Unpriv + MPU_xQueueTakeMutexRecursive_Priv: + pop {r0} + b MPU_xQueueTakeMutexRecursiveImpl + MPU_xQueueTakeMutexRecursive_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueTakeMutexRecursiveImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueGiveMutexRecursive +MPU_xQueueGiveMutexRecursive: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xQueueGiveMutexRecursive_Unpriv + MPU_xQueueGiveMutexRecursive_Priv: + pop {r0} + b MPU_xQueueGiveMutexRecursiveImpl + MPU_xQueueGiveMutexRecursive_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueGiveMutexRecursiveImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueSelectFromSet +MPU_xQueueSelectFromSet: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xQueueSelectFromSet_Unpriv + MPU_xQueueSelectFromSet_Priv: + pop {r0} + b MPU_xQueueSelectFromSetImpl + MPU_xQueueSelectFromSet_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueSelectFromSetImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xQueueAddToSet +MPU_xQueueAddToSet: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xQueueAddToSet_Unpriv + MPU_xQueueAddToSet_Priv: + pop {r0} + b MPU_xQueueAddToSetImpl + MPU_xQueueAddToSet_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueAddToSetImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vQueueAddToRegistry +MPU_vQueueAddToRegistry: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vQueueAddToRegistry_Unpriv + MPU_vQueueAddToRegistry_Priv: + pop {r0} + b MPU_vQueueAddToRegistryImpl + MPU_vQueueAddToRegistry_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vQueueAddToRegistryImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vQueueUnregisterQueue +MPU_vQueueUnregisterQueue: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vQueueUnregisterQueue_Unpriv + MPU_vQueueUnregisterQueue_Priv: + pop {r0} + b MPU_vQueueUnregisterQueueImpl + MPU_vQueueUnregisterQueue_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vQueueUnregisterQueueImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_pcQueueGetName +MPU_pcQueueGetName: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_pcQueueGetName_Unpriv + MPU_pcQueueGetName_Priv: + pop {r0} + b MPU_pcQueueGetNameImpl + MPU_pcQueueGetName_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_pcQueueGetNameImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_pvTimerGetTimerID +MPU_pvTimerGetTimerID: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_pvTimerGetTimerID_Unpriv + MPU_pvTimerGetTimerID_Priv: + pop {r0} + b MPU_pvTimerGetTimerIDImpl + MPU_pvTimerGetTimerID_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_pvTimerGetTimerIDImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTimerSetTimerID +MPU_vTimerSetTimerID: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vTimerSetTimerID_Unpriv + MPU_vTimerSetTimerID_Priv: + pop {r0} + b MPU_vTimerSetTimerIDImpl + MPU_vTimerSetTimerID_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTimerSetTimerIDImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTimerIsTimerActive +MPU_xTimerIsTimerActive: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTimerIsTimerActive_Unpriv + MPU_xTimerIsTimerActive_Priv: + pop {r0} + b MPU_xTimerIsTimerActiveImpl + MPU_xTimerIsTimerActive_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTimerIsTimerActiveImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTimerGetTimerDaemonTaskHandle +MPU_xTimerGetTimerDaemonTaskHandle: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTimerGetTimerDaemonTaskHandle_Unpriv + MPU_xTimerGetTimerDaemonTaskHandle_Priv: + pop {r0} + b MPU_xTimerGetTimerDaemonTaskHandleImpl + MPU_xTimerGetTimerDaemonTaskHandle_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTimerGetTimerDaemonTaskHandleImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTimerGenericCommand +MPU_xTimerGenericCommand: + push {r0} + /* This function can be called from ISR also and therefore, we need a check + * to take privileged path, if called from ISR. */ + mrs r0, ipsr + cmp r0, #0 + bne MPU_xTimerGenericCommand_Priv + mrs r0, control + tst r0, #1 + beq MPU_xTimerGenericCommand_Priv + MPU_xTimerGenericCommand_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER_1 + bl MPU_xTimerGenericCommandImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr + MPU_xTimerGenericCommand_Priv: + pop {r0} + b MPU_xTimerGenericCommandImpl + +/*-----------------------------------------------------------*/ + + PUBLIC MPU_pcTimerGetName +MPU_pcTimerGetName: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_pcTimerGetName_Unpriv + MPU_pcTimerGetName_Priv: + pop {r0} + b MPU_pcTimerGetNameImpl + MPU_pcTimerGetName_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_pcTimerGetNameImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vTimerSetReloadMode +MPU_vTimerSetReloadMode: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vTimerSetReloadMode_Unpriv + MPU_vTimerSetReloadMode_Priv: + pop {r0} + b MPU_vTimerSetReloadModeImpl + MPU_vTimerSetReloadMode_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTimerSetReloadModeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTimerGetReloadMode +MPU_xTimerGetReloadMode: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTimerGetReloadMode_Unpriv + MPU_xTimerGetReloadMode_Priv: + pop {r0} + b MPU_xTimerGetReloadModeImpl + MPU_xTimerGetReloadMode_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTimerGetReloadModeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxTimerGetReloadMode +MPU_uxTimerGetReloadMode: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_uxTimerGetReloadMode_Unpriv + MPU_uxTimerGetReloadMode_Priv: + pop {r0} + b MPU_uxTimerGetReloadModeImpl + MPU_uxTimerGetReloadMode_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxTimerGetReloadModeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTimerGetPeriod +MPU_xTimerGetPeriod: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTimerGetPeriod_Unpriv + MPU_xTimerGetPeriod_Priv: + pop {r0} + b MPU_xTimerGetPeriodImpl + MPU_xTimerGetPeriod_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTimerGetPeriodImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xTimerGetExpiryTime +MPU_xTimerGetExpiryTime: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTimerGetExpiryTime_Unpriv + MPU_xTimerGetExpiryTime_Priv: + pop {r0} + b MPU_xTimerGetExpiryTimeImpl + MPU_xTimerGetExpiryTime_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTimerGetExpiryTimeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xEventGroupWaitBits +MPU_xEventGroupWaitBits: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xEventGroupWaitBits_Unpriv + MPU_xEventGroupWaitBits_Priv: + pop {r0} + b MPU_xEventGroupWaitBitsImpl + MPU_xEventGroupWaitBits_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER_1 + bl MPU_xEventGroupWaitBitsImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xEventGroupClearBits +MPU_xEventGroupClearBits: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xEventGroupClearBits_Unpriv + MPU_xEventGroupClearBits_Priv: + pop {r0} + b MPU_xEventGroupClearBitsImpl + MPU_xEventGroupClearBits_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xEventGroupClearBitsImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xEventGroupSetBits +MPU_xEventGroupSetBits: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xEventGroupSetBits_Unpriv + MPU_xEventGroupSetBits_Priv: + pop {r0} + b MPU_xEventGroupSetBitsImpl + MPU_xEventGroupSetBits_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xEventGroupSetBitsImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xEventGroupSync +MPU_xEventGroupSync: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xEventGroupSync_Unpriv + MPU_xEventGroupSync_Priv: + pop {r0} + b MPU_xEventGroupSyncImpl + MPU_xEventGroupSync_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xEventGroupSyncImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_uxEventGroupGetNumber +MPU_uxEventGroupGetNumber: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_uxEventGroupGetNumber_Unpriv + MPU_uxEventGroupGetNumber_Priv: + pop {r0} + b MPU_uxEventGroupGetNumberImpl + MPU_uxEventGroupGetNumber_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxEventGroupGetNumberImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_vEventGroupSetNumber +MPU_vEventGroupSetNumber: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vEventGroupSetNumber_Unpriv + MPU_vEventGroupSetNumber_Priv: + pop {r0} + b MPU_vEventGroupSetNumberImpl + MPU_vEventGroupSetNumber_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vEventGroupSetNumberImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferSend +MPU_xStreamBufferSend: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xStreamBufferSend_Unpriv + MPU_xStreamBufferSend_Priv: + pop {r0} + b MPU_xStreamBufferSendImpl + MPU_xStreamBufferSend_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferSendImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferReceive +MPU_xStreamBufferReceive: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xStreamBufferReceive_Unpriv + MPU_xStreamBufferReceive_Priv: + pop {r0} + b MPU_xStreamBufferReceiveImpl + MPU_xStreamBufferReceive_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferReceiveImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferIsFull +MPU_xStreamBufferIsFull: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xStreamBufferIsFull_Unpriv + MPU_xStreamBufferIsFull_Priv: + pop {r0} + b MPU_xStreamBufferIsFullImpl + MPU_xStreamBufferIsFull_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferIsFullImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferIsEmpty +MPU_xStreamBufferIsEmpty: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xStreamBufferIsEmpty_Unpriv + MPU_xStreamBufferIsEmpty_Priv: + pop {r0} + b MPU_xStreamBufferIsEmptyImpl + MPU_xStreamBufferIsEmpty_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferIsEmptyImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferSpacesAvailable +MPU_xStreamBufferSpacesAvailable: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xStreamBufferSpacesAvailable_Unpriv + MPU_xStreamBufferSpacesAvailable_Priv: + pop {r0} + b MPU_xStreamBufferSpacesAvailableImpl + MPU_xStreamBufferSpacesAvailable_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferSpacesAvailableImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferBytesAvailable +MPU_xStreamBufferBytesAvailable: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xStreamBufferBytesAvailable_Unpriv + MPU_xStreamBufferBytesAvailable_Priv: + pop {r0} + b MPU_xStreamBufferBytesAvailableImpl + MPU_xStreamBufferBytesAvailable_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferBytesAvailableImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferSetTriggerLevel +MPU_xStreamBufferSetTriggerLevel: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xStreamBufferSetTriggerLevel_Unpriv + MPU_xStreamBufferSetTriggerLevel_Priv: + pop {r0} + b MPU_xStreamBufferSetTriggerLevelImpl + MPU_xStreamBufferSetTriggerLevel_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferSetTriggerLevelImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + + PUBLIC MPU_xStreamBufferNextMessageLengthBytes +MPU_xStreamBufferNextMessageLengthBytes: + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xStreamBufferNextMessageLengthBytes_Unpriv + MPU_xStreamBufferNextMessageLengthBytes_Priv: + pop {r0} + b MPU_xStreamBufferNextMessageLengthBytesImpl + MPU_xStreamBufferNextMessageLengthBytes_Unpriv: + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferNextMessageLengthBytesImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +/*-----------------------------------------------------------*/ + +/* Default weak implementations in case one is not available from + * mpu_wrappers because of config options. */ + + PUBWEAK MPU_xTaskDelayUntilImpl +MPU_xTaskDelayUntilImpl: + b MPU_xTaskDelayUntilImpl + + PUBWEAK MPU_xTaskAbortDelayImpl +MPU_xTaskAbortDelayImpl: + b MPU_xTaskAbortDelayImpl + + PUBWEAK MPU_vTaskDelayImpl +MPU_vTaskDelayImpl: + b MPU_vTaskDelayImpl + + PUBWEAK MPU_uxTaskPriorityGetImpl +MPU_uxTaskPriorityGetImpl: + b MPU_uxTaskPriorityGetImpl + + PUBWEAK MPU_eTaskGetStateImpl +MPU_eTaskGetStateImpl: + b MPU_eTaskGetStateImpl + + PUBWEAK MPU_vTaskGetInfoImpl +MPU_vTaskGetInfoImpl: + b MPU_vTaskGetInfoImpl + + PUBWEAK MPU_xTaskGetIdleTaskHandleImpl +MPU_xTaskGetIdleTaskHandleImpl: + b MPU_xTaskGetIdleTaskHandleImpl + + PUBWEAK MPU_vTaskSuspendImpl +MPU_vTaskSuspendImpl: + b MPU_vTaskSuspendImpl + + PUBWEAK MPU_vTaskResumeImpl +MPU_vTaskResumeImpl: + b MPU_vTaskResumeImpl + + PUBWEAK MPU_xTaskGetTickCountImpl +MPU_xTaskGetTickCountImpl: + b MPU_xTaskGetTickCountImpl + + PUBWEAK MPU_uxTaskGetNumberOfTasksImpl +MPU_uxTaskGetNumberOfTasksImpl: + b MPU_uxTaskGetNumberOfTasksImpl + + PUBWEAK MPU_pcTaskGetNameImpl +MPU_pcTaskGetNameImpl: + b MPU_pcTaskGetNameImpl + + PUBWEAK MPU_ulTaskGetRunTimeCounterImpl +MPU_ulTaskGetRunTimeCounterImpl: + b MPU_ulTaskGetRunTimeCounterImpl + + PUBWEAK MPU_ulTaskGetRunTimePercentImpl +MPU_ulTaskGetRunTimePercentImpl: + b MPU_ulTaskGetRunTimePercentImpl + + PUBWEAK MPU_ulTaskGetIdleRunTimePercentImpl +MPU_ulTaskGetIdleRunTimePercentImpl: + b MPU_ulTaskGetIdleRunTimePercentImpl + + PUBWEAK MPU_ulTaskGetIdleRunTimeCounterImpl +MPU_ulTaskGetIdleRunTimeCounterImpl: + b MPU_ulTaskGetIdleRunTimeCounterImpl + + PUBWEAK MPU_vTaskSetApplicationTaskTagImpl +MPU_vTaskSetApplicationTaskTagImpl: + b MPU_vTaskSetApplicationTaskTagImpl + + PUBWEAK MPU_xTaskGetApplicationTaskTagImpl +MPU_xTaskGetApplicationTaskTagImpl: + b MPU_xTaskGetApplicationTaskTagImpl + + PUBWEAK MPU_vTaskSetThreadLocalStoragePointerImpl +MPU_vTaskSetThreadLocalStoragePointerImpl: + b MPU_vTaskSetThreadLocalStoragePointerImpl + + PUBWEAK MPU_pvTaskGetThreadLocalStoragePointerImpl +MPU_pvTaskGetThreadLocalStoragePointerImpl: + b MPU_pvTaskGetThreadLocalStoragePointerImpl + + PUBWEAK MPU_uxTaskGetSystemStateImpl +MPU_uxTaskGetSystemStateImpl: + b MPU_uxTaskGetSystemStateImpl + + PUBWEAK MPU_uxTaskGetStackHighWaterMarkImpl +MPU_uxTaskGetStackHighWaterMarkImpl: + b MPU_uxTaskGetStackHighWaterMarkImpl + + PUBWEAK MPU_uxTaskGetStackHighWaterMark2Impl +MPU_uxTaskGetStackHighWaterMark2Impl: + b MPU_uxTaskGetStackHighWaterMark2Impl + + PUBWEAK MPU_xTaskGetCurrentTaskHandleImpl +MPU_xTaskGetCurrentTaskHandleImpl: + b MPU_xTaskGetCurrentTaskHandleImpl + + PUBWEAK MPU_xTaskGetSchedulerStateImpl +MPU_xTaskGetSchedulerStateImpl: + b MPU_xTaskGetSchedulerStateImpl + + PUBWEAK MPU_vTaskSetTimeOutStateImpl +MPU_vTaskSetTimeOutStateImpl: + b MPU_vTaskSetTimeOutStateImpl + + PUBWEAK MPU_xTaskCheckForTimeOutImpl +MPU_xTaskCheckForTimeOutImpl: + b MPU_xTaskCheckForTimeOutImpl + + PUBWEAK MPU_xTaskGenericNotifyImpl +MPU_xTaskGenericNotifyImpl: + b MPU_xTaskGenericNotifyImpl + + PUBWEAK MPU_xTaskGenericNotifyWaitImpl +MPU_xTaskGenericNotifyWaitImpl: + b MPU_xTaskGenericNotifyWaitImpl + + PUBWEAK MPU_ulTaskGenericNotifyTakeImpl +MPU_ulTaskGenericNotifyTakeImpl: + b MPU_ulTaskGenericNotifyTakeImpl + + PUBWEAK MPU_xTaskGenericNotifyStateClearImpl +MPU_xTaskGenericNotifyStateClearImpl: + b MPU_xTaskGenericNotifyStateClearImpl + + PUBWEAK MPU_ulTaskGenericNotifyValueClearImpl +MPU_ulTaskGenericNotifyValueClearImpl: + b MPU_ulTaskGenericNotifyValueClearImpl + + PUBWEAK MPU_xQueueGenericSendImpl +MPU_xQueueGenericSendImpl: + b MPU_xQueueGenericSendImpl + + PUBWEAK MPU_uxQueueMessagesWaitingImpl +MPU_uxQueueMessagesWaitingImpl: + b MPU_uxQueueMessagesWaitingImpl + + PUBWEAK MPU_uxQueueSpacesAvailableImpl +MPU_uxQueueSpacesAvailableImpl: + b MPU_uxQueueSpacesAvailableImpl + + PUBWEAK MPU_xQueueReceiveImpl +MPU_xQueueReceiveImpl: + b MPU_xQueueReceiveImpl + + PUBWEAK MPU_xQueuePeekImpl +MPU_xQueuePeekImpl: + b MPU_xQueuePeekImpl + + PUBWEAK MPU_xQueueSemaphoreTakeImpl +MPU_xQueueSemaphoreTakeImpl: + b MPU_xQueueSemaphoreTakeImpl + + PUBWEAK MPU_xQueueGetMutexHolderImpl +MPU_xQueueGetMutexHolderImpl: + b MPU_xQueueGetMutexHolderImpl + + PUBWEAK MPU_xQueueTakeMutexRecursiveImpl +MPU_xQueueTakeMutexRecursiveImpl: + b MPU_xQueueTakeMutexRecursiveImpl + + PUBWEAK MPU_xQueueGiveMutexRecursiveImpl +MPU_xQueueGiveMutexRecursiveImpl: + b MPU_xQueueGiveMutexRecursiveImpl + + PUBWEAK MPU_xQueueSelectFromSetImpl +MPU_xQueueSelectFromSetImpl: + b MPU_xQueueSelectFromSetImpl + + PUBWEAK MPU_xQueueAddToSetImpl +MPU_xQueueAddToSetImpl: + b MPU_xQueueAddToSetImpl + + PUBWEAK MPU_vQueueAddToRegistryImpl +MPU_vQueueAddToRegistryImpl: + b MPU_vQueueAddToRegistryImpl + + PUBWEAK MPU_vQueueUnregisterQueueImpl +MPU_vQueueUnregisterQueueImpl: + b MPU_vQueueUnregisterQueueImpl + + PUBWEAK MPU_pcQueueGetNameImpl +MPU_pcQueueGetNameImpl: + b MPU_pcQueueGetNameImpl + + PUBWEAK MPU_pvTimerGetTimerIDImpl +MPU_pvTimerGetTimerIDImpl: + b MPU_pvTimerGetTimerIDImpl + + PUBWEAK MPU_vTimerSetTimerIDImpl +MPU_vTimerSetTimerIDImpl: + b MPU_vTimerSetTimerIDImpl + + PUBWEAK MPU_xTimerIsTimerActiveImpl +MPU_xTimerIsTimerActiveImpl: + b MPU_xTimerIsTimerActiveImpl + + PUBWEAK MPU_xTimerGetTimerDaemonTaskHandleImpl +MPU_xTimerGetTimerDaemonTaskHandleImpl: + b MPU_xTimerGetTimerDaemonTaskHandleImpl + + PUBWEAK MPU_xTimerGenericCommandImpl +MPU_xTimerGenericCommandImpl: + b MPU_xTimerGenericCommandImpl + + PUBWEAK MPU_pcTimerGetNameImpl +MPU_pcTimerGetNameImpl: + b MPU_pcTimerGetNameImpl + + PUBWEAK MPU_vTimerSetReloadModeImpl +MPU_vTimerSetReloadModeImpl: + b MPU_vTimerSetReloadModeImpl + + PUBWEAK MPU_xTimerGetReloadModeImpl +MPU_xTimerGetReloadModeImpl: + b MPU_xTimerGetReloadModeImpl + + PUBWEAK MPU_uxTimerGetReloadModeImpl +MPU_uxTimerGetReloadModeImpl: + b MPU_uxTimerGetReloadModeImpl + + PUBWEAK MPU_xTimerGetPeriodImpl +MPU_xTimerGetPeriodImpl: + b MPU_xTimerGetPeriodImpl + + PUBWEAK MPU_xTimerGetExpiryTimeImpl +MPU_xTimerGetExpiryTimeImpl: + b MPU_xTimerGetExpiryTimeImpl + + PUBWEAK MPU_xEventGroupWaitBitsImpl +MPU_xEventGroupWaitBitsImpl: + b MPU_xEventGroupWaitBitsImpl + + PUBWEAK MPU_xEventGroupClearBitsImpl +MPU_xEventGroupClearBitsImpl: + b MPU_xEventGroupClearBitsImpl + + PUBWEAK MPU_xEventGroupSetBitsImpl +MPU_xEventGroupSetBitsImpl: + b MPU_xEventGroupSetBitsImpl + + PUBWEAK MPU_xEventGroupSyncImpl +MPU_xEventGroupSyncImpl: + b MPU_xEventGroupSyncImpl + + PUBWEAK MPU_uxEventGroupGetNumberImpl +MPU_uxEventGroupGetNumberImpl: + b MPU_uxEventGroupGetNumberImpl + + PUBWEAK MPU_vEventGroupSetNumberImpl +MPU_vEventGroupSetNumberImpl: + b MPU_vEventGroupSetNumberImpl + + PUBWEAK MPU_xStreamBufferSendImpl +MPU_xStreamBufferSendImpl: + b MPU_xStreamBufferSendImpl + + PUBWEAK MPU_xStreamBufferReceiveImpl +MPU_xStreamBufferReceiveImpl: + b MPU_xStreamBufferReceiveImpl + + PUBWEAK MPU_xStreamBufferIsFullImpl +MPU_xStreamBufferIsFullImpl: + b MPU_xStreamBufferIsFullImpl + + PUBWEAK MPU_xStreamBufferIsEmptyImpl +MPU_xStreamBufferIsEmptyImpl: + b MPU_xStreamBufferIsEmptyImpl + + PUBWEAK MPU_xStreamBufferSpacesAvailableImpl +MPU_xStreamBufferSpacesAvailableImpl: + b MPU_xStreamBufferSpacesAvailableImpl + + PUBWEAK MPU_xStreamBufferBytesAvailableImpl +MPU_xStreamBufferBytesAvailableImpl: + b MPU_xStreamBufferBytesAvailableImpl + + PUBWEAK MPU_xStreamBufferSetTriggerLevelImpl +MPU_xStreamBufferSetTriggerLevelImpl: + b MPU_xStreamBufferSetTriggerLevelImpl + + PUBWEAK MPU_xStreamBufferNextMessageLengthBytesImpl +MPU_xStreamBufferNextMessageLengthBytesImpl: + b MPU_xStreamBufferNextMessageLengthBytesImpl + +/*-----------------------------------------------------------*/ + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + + END diff --git a/portable/IAR/ARM_CM85_NTZ/non_secure/port.c b/portable/IAR/ARM_CM85_NTZ/non_secure/port.c index 7bbe1b7bc53..cab1b3668bf 100644 --- a/portable/IAR/ARM_CM85_NTZ/non_secure/port.c +++ b/portable/IAR/ARM_CM85_NTZ/non_secure/port.c @@ -107,6 +107,13 @@ #define portPRIGROUP_SHIFT ( 8UL ) /*-----------------------------------------------------------*/ +/** + * @brief Constants used during system call enter and exit. + */ +#define portPSR_STACK_PADDING_MASK ( 1UL << 9UL ) +#define portEXC_RETURN_STACK_FRAME_TYPE_MASK ( 1UL << 4UL ) +/*-----------------------------------------------------------*/ + /** * @brief Constants required to manipulate the FPU. */ @@ -123,6 +130,14 @@ #define portFPCCR_LSPEN_MASK ( 1UL << portFPCCR_LSPEN_POS ) /*-----------------------------------------------------------*/ +/** + * @brief Offsets in the stack to the parameters when inside the SVC handler. + */ +#define portOFFSET_TO_LR ( 5 ) +#define portOFFSET_TO_PC ( 6 ) +#define portOFFSET_TO_PSR ( 7 ) +/*-----------------------------------------------------------*/ + /** * @brief Constants required to manipulate the MPU. */ @@ -148,6 +163,8 @@ #define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ #define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ +#define portMPU_RBAR_ACCESS_PERMISSIONS_MASK ( 3UL << 1UL ) + #define portMPU_MAIR_ATTR0_POS ( 0UL ) #define portMPU_MAIR_ATTR0_MASK ( 0x000000ff ) @@ -191,6 +208,30 @@ /* Expected value of the portMPU_TYPE register. */ #define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) + +/* Extract first address of the MPU region as encoded in the + * RBAR (Region Base Address Register) value. */ +#define portEXTRACT_FIRST_ADDRESS_FROM_RBAR( rbar ) \ + ( ( rbar ) & portMPU_RBAR_ADDRESS_MASK ) + +/* Extract last address of the MPU region as encoded in the + * RLAR (Region Limit Address Register) value. */ +#define portEXTRACT_LAST_ADDRESS_FROM_RLAR( rlar ) \ + ( ( ( rlar ) & portMPU_RLAR_ADDRESS_MASK ) | ~portMPU_RLAR_ADDRESS_MASK ) + +/* Does addr lies within [start, end] address range? */ +#define portIS_ADDRESS_WITHIN_RANGE( addr, start, end ) \ + ( ( ( addr ) >= ( start ) ) && ( ( addr ) <= ( end ) ) ) + +/* Is the access request satisfied by the available permissions? */ +#define portIS_AUTHORIZED( accessRequest, permissions ) \ + ( ( ( permissions ) & ( accessRequest ) ) == accessRequest ) + +/* 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 ) ) ) /*-----------------------------------------------------------*/ /** @@ -311,6 +352,19 @@ static void prvTaskExitError( void ); #if ( configENABLE_MPU == 1 ) +/** + * @brief Extract MPU region's access permissions from the Region Base Address + * Register (RBAR) value. + * + * @param ulRBARValue RBAR value for the MPU region. + * + * @return uint32_t Access permissions. + */ + static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) PRIVILEGED_FUNCTION; +#endif /* configENABLE_MPU */ + +#if ( configENABLE_MPU == 1 ) + /** * @brief Setup the Memory Protection Unit (MPU). */ @@ -365,6 +419,60 @@ void SysTick_Handler( void ) PRIVILEGED_FUNCTION; * @brief C part of SVC handler. */ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIVILEGED_FUNCTION; + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + + /** + * @brief Sets up the system call stack so that upon returning from + * SVC, the system call stack is used. + * + * It is used for the system calls with up to 4 parameters. + * + * @param pulTaskStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + */ + void vSystemCallEnter( uint32_t * pulTaskStack, uint32_t ulLR ) PRIVILEGED_FUNCTION; + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + + /** + * @brief Sets up the system call stack so that upon returning from + * SVC, the system call stack is used. + * + * It is used for the system calls with 5 parameters. + * + * @param pulTaskStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + */ + void vSystemCallEnter_1( uint32_t * pulTaskStack, uint32_t ulLR ) PRIVILEGED_FUNCTION; + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + + /** + * @brief Sets up the task stack so that upon returning from + * SVC, the task stack is used again. + * + * @param pulSystemCallStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + */ + void vSystemCallExit( uint32_t * pulSystemCallStack, uint32_t ulLR ) PRIVILEGED_FUNCTION; + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + +#if ( configENABLE_MPU == 1 ) + + /** + * @brief Checks whether or not the calling task is privileged. + * + * @return pdTRUE if the calling task is privileged, pdFALSE otherwise. + */ + BaseType_t xPortIsTaskPrivileged( void ) PRIVILEGED_FUNCTION; + +#endif /* configENABLE_MPU == 1 */ /*-----------------------------------------------------------*/ /** @@ -681,6 +789,26 @@ static void prvTaskExitError( void ) } /*-----------------------------------------------------------*/ +#if ( configENABLE_MPU == 1 ) + static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) /* PRIVILEGED_FUNCTION */ + { + uint32_t ulAccessPermissions = 0; + + if( ( ulRBARValue & portMPU_RBAR_ACCESS_PERMISSIONS_MASK ) == portMPU_REGION_READ_ONLY ) + { + ulAccessPermissions = tskMPU_READ_PERMISSION; + } + + if( ( ulRBARValue & portMPU_RBAR_ACCESS_PERMISSIONS_MASK ) == portMPU_REGION_READ_WRITE ) + { + ulAccessPermissions = ( tskMPU_READ_PERMISSION | tskMPU_WRITE_PERMISSION ); + } + + return ulAccessPermissions; + } +#endif /* configENABLE_MPU */ +/*-----------------------------------------------------------*/ + #if ( configENABLE_MPU == 1 ) static void prvSetupMPU( void ) /* PRIVILEGED_FUNCTION */ { @@ -853,7 +981,7 @@ void SysTick_Handler( void ) /* PRIVILEGED_FUNCTION */ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTION portDONT_DISCARD */ { - #if ( configENABLE_MPU == 1 ) + #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) ) #if defined( __ARMCC_VERSION ) /* Declaration when these variable are defined in code instead of being @@ -865,7 +993,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO extern uint32_t __syscalls_flash_start__[]; extern uint32_t __syscalls_flash_end__[]; #endif /* defined( __ARMCC_VERSION ) */ - #endif /* configENABLE_MPU */ + #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */ uint32_t ulPC; @@ -880,7 +1008,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO /* Register are stored on the stack in the following order - R0, R1, R2, R3, * R12, LR, PC, xPSR. */ - ulPC = pulCallerStackAddress[ 6 ]; + ulPC = pulCallerStackAddress[ portOFFSET_TO_PC ]; ucSVCNumber = ( ( uint8_t * ) ulPC )[ -2 ]; switch( ucSVCNumber ) @@ -951,18 +1079,18 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO vRestoreContextOfFirstTask(); break; - #if ( configENABLE_MPU == 1 ) - case portSVC_RAISE_PRIVILEGE: + #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) ) + case portSVC_RAISE_PRIVILEGE: - /* Only raise the privilege, if the svc was raised from any of - * the system calls. */ - if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) && - ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ) - { - vRaisePrivilege(); - } - break; - #endif /* configENABLE_MPU */ + /* Only raise the privilege, if the svc was raised from any of + * the system calls. */ + if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ) + { + vRaisePrivilege(); + } + break; + #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */ default: /* Incorrect SVC call. */ @@ -971,51 +1099,455 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } /*-----------------------------------------------------------*/ -/* *INDENT-OFF* */ -#if ( configENABLE_MPU == 1 ) - StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, - StackType_t * pxEndOfStack, - TaskFunction_t pxCode, - void * pvParameters, - BaseType_t xRunPrivileged ) /* PRIVILEGED_FUNCTION */ -#else - StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, - StackType_t * pxEndOfStack, - TaskFunction_t pxCode, - void * pvParameters ) /* PRIVILEGED_FUNCTION */ -#endif /* configENABLE_MPU */ -/* *INDENT-ON* */ +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + +void vSystemCallEnter( uint32_t * pulTaskStack, uint32_t ulLR ) /* PRIVILEGED_FUNCTION */ { - /* Simulate the stack frame as it would be created by a context switch - * interrupt. */ - #if ( portPRELOAD_REGISTERS == 0 ) + extern TaskHandle_t pxCurrentTCB; + xMPU_SETTINGS * pxMpuSettings; + uint32_t * pulSystemCallStack; + uint32_t ulStackFrameSize, ulSystemCallLocation, i; + #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being + * exported from linker scripts. */ + extern uint32_t * __syscalls_flash_start__; + extern uint32_t * __syscalls_flash_end__; + #else + /* Declaration when these variable are exported from linker scripts. */ + extern uint32_t __syscalls_flash_start__[]; + extern uint32_t __syscalls_flash_end__[]; + #endif /* #if defined( __ARMCC_VERSION ) */ + + ulSystemCallLocation = pulTaskStack[ portOFFSET_TO_PC ]; + + /* If the request did not come from the system call section, do nothing. */ + if( ( ulSystemCallLocation >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulSystemCallLocation <= ( uint32_t ) __syscalls_flash_end__ ) ) { - pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ - *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ - pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pxCode; /* PC */ - pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR */ - pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ - *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ - pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */ - *pxTopOfStack = portINITIAL_EXC_RETURN; + pxMpuSettings = xTaskGetMPUSettings( pxCurrentTCB ); + pulSystemCallStack = pxMpuSettings->xSystemCallStackInfo.pulSystemCallStack; - #if ( configENABLE_MPU == 1 ) + /* This is not NULL only for the duration of the system call. */ + configASSERT( pxMpuSettings->xSystemCallStackInfo.pulTaskStack == NULL ); + + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) { - pxTopOfStack--; + if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) + { + /* Extended frame i.e. FPU in use. */ + ulStackFrameSize = 26; + __asm volatile ( + " vpush {s0} \n" /* Trigger lazy stacking. */ + " vpop {s0} \n" /* Nullify the affect of the above instruction. */ + ::: "memory" + ); + } + else + { + /* Standard frame i.e. FPU not in use. */ + ulStackFrameSize = 8; + } + } + #else + { + ulStackFrameSize = 8; + } + #endif /* configENABLE_FPU || configENABLE_MVE */ + + /* Make space on the system call stack for the stack frame. */ + pulSystemCallStack = pulSystemCallStack - ulStackFrameSize; + + /* Copy the stack frame. */ + for( i = 0; i < ulStackFrameSize; i++ ) + { + pulSystemCallStack[ i ] = pulTaskStack[ i ]; + } + + /* Store the value of the LR and PSPLIM registers before the SVC was raised. We need to + * restore it when we exit from the system call. */ + pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; + __asm volatile ( "mrs %0, psplim" : "=r" ( pxMpuSettings->xSystemCallStackInfo.ulStackLimitRegisterAtSystemCallEntry ) ); + + /* Use the pulSystemCallStack in thread mode. */ + __asm volatile ( "msr psp, %0" : : "r" ( pulSystemCallStack ) ); + __asm volatile ( "msr psplim, %0" : : "r" ( pxMpuSettings->xSystemCallStackInfo.pulSystemCallStackLimit ) ); + + /* Remember the location where we should copy the stack frame when we exit from + * the system call. */ + pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulStackFrameSize; + + /* Record if the hardware used padding to force the stack pointer + * to be double word aligned. */ + if( ( pulTaskStack[ portOFFSET_TO_PSR ] & portPSR_STACK_PADDING_MASK ) == portPSR_STACK_PADDING_MASK ) + { + pxMpuSettings->ulTaskFlags |= portSTACK_FRAME_HAS_PADDING_FLAG; + } + else + { + pxMpuSettings->ulTaskFlags &= ( ~portSTACK_FRAME_HAS_PADDING_FLAG ); + } + + /* We ensure in pxPortInitialiseStack that the system call stack is + * double word aligned and therefore, there is no need of padding. + * Clear the bit[9] of stacked xPSR. */ + pulSystemCallStack[ portOFFSET_TO_PSR ] &= ( ~portPSR_STACK_PADDING_MASK ); + + /* Raise the privilege for the duration of the system call. */ + __asm volatile ( + " mrs r0, control \n" /* Obtain current control value. */ + " movs r1, #1 \n" /* r1 = 1. */ + " bics r0, r1 \n" /* Clear nPRIV bit. */ + " msr control, r0 \n" /* Write back new control value. */ + ::: "r0", "r1", "memory" + ); + } +} - if( xRunPrivileged == pdTRUE ) +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + +void vSystemCallEnter_1( uint32_t * pulTaskStack, uint32_t ulLR ) /* PRIVILEGED_FUNCTION */ +{ + extern TaskHandle_t pxCurrentTCB; + xMPU_SETTINGS * pxMpuSettings; + uint32_t * pulSystemCallStack; + uint32_t ulStackFrameSize, ulSystemCallLocation, i; + #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being + * exported from linker scripts. */ + extern uint32_t * __syscalls_flash_start__; + extern uint32_t * __syscalls_flash_end__; + #else + /* Declaration when these variable are exported from linker scripts. */ + extern uint32_t __syscalls_flash_start__[]; + extern uint32_t __syscalls_flash_end__[]; + #endif /* #if defined( __ARMCC_VERSION ) */ + + ulSystemCallLocation = pulTaskStack[ portOFFSET_TO_PC ]; + + /* If the request did not come from the system call section, do nothing. */ + if( ( ulSystemCallLocation >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulSystemCallLocation <= ( uint32_t ) __syscalls_flash_end__ ) ) + { + pxMpuSettings = xTaskGetMPUSettings( pxCurrentTCB ); + pulSystemCallStack = pxMpuSettings->xSystemCallStackInfo.pulSystemCallStack; + + /* This is not NULL only for the duration of the system call. */ + configASSERT( pxMpuSettings->xSystemCallStackInfo.pulTaskStack == NULL ); + + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + { + if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) { - *pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */ + /* Extended frame i.e. FPU in use. */ + ulStackFrameSize = 26; + __asm volatile ( + " vpush {s0} \n" /* Trigger lazy stacking. */ + " vpop {s0} \n" /* Nullify the affect of the above instruction. */ + ::: "memory" + ); } else { - *pxTopOfStack = portINITIAL_CONTROL_UNPRIVILEGED; /* Slot used to hold this task's CONTROL value. */ + /* Standard frame i.e. FPU not in use. */ + ulStackFrameSize = 8; } } - #endif /* configENABLE_MPU */ + #else + { + ulStackFrameSize = 8; + } + #endif /* configENABLE_FPU || configENABLE_MVE */ + + /* Make space on the system call stack for the stack frame and + * the parameter passed on the stack. We only need to copy one + * parameter but we still reserve 2 spaces to keep the stack + * double word aligned. */ + pulSystemCallStack = pulSystemCallStack - ulStackFrameSize - 2UL; + + /* Copy the stack frame. */ + for( i = 0; i < ulStackFrameSize; i++ ) + { + pulSystemCallStack[ i ] = pulTaskStack[ i ]; + } + + /* Copy the parameter which is passed the stack. */ + if( ( pulTaskStack[ portOFFSET_TO_PSR ] & portPSR_STACK_PADDING_MASK ) == portPSR_STACK_PADDING_MASK ) + { + pulSystemCallStack[ ulStackFrameSize ] = pulTaskStack[ ulStackFrameSize + 1 ]; + /* Record if the hardware used padding to force the stack pointer + * to be double word aligned. */ + pxMpuSettings->ulTaskFlags |= portSTACK_FRAME_HAS_PADDING_FLAG; + } + else + { + pulSystemCallStack[ ulStackFrameSize ] = pulTaskStack[ ulStackFrameSize ]; + /* Record if the hardware used padding to force the stack pointer + * to be double word aligned. */ + pxMpuSettings->ulTaskFlags &= ( ~portSTACK_FRAME_HAS_PADDING_FLAG ); + } + + /* Store the value of the LR and PSPLIM registers before the SVC was raised. + * We need to restore it when we exit from the system call. */ + pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; + __asm volatile ( "mrs %0, psplim" : "=r" ( pxMpuSettings->xSystemCallStackInfo.ulStackLimitRegisterAtSystemCallEntry ) ); + + /* Use the pulSystemCallStack in thread mode. */ + __asm volatile ( "msr psp, %0" : : "r" ( pulSystemCallStack ) ); + __asm volatile ( "msr psplim, %0" : : "r" ( pxMpuSettings->xSystemCallStackInfo.pulSystemCallStackLimit ) ); + + /* Remember the location where we should copy the stack frame when we exit from + * the system call. */ + pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulStackFrameSize; + + /* We ensure in pxPortInitialiseStack that the system call stack is + * double word aligned and therefore, there is no need of padding. + * Clear the bit[9] of stacked xPSR. */ + pulSystemCallStack[ portOFFSET_TO_PSR ] &= ( ~portPSR_STACK_PADDING_MASK ); + + /* Raise the privilege for the duration of the system call. */ + __asm volatile ( + " mrs r0, control \n" /* Obtain current control value. */ + " movs r1, #1 \n" /* r1 = 1. */ + " bics r0, r1 \n" /* Clear nPRIV bit. */ + " msr control, r0 \n" /* Write back new control value. */ + ::: "r0", "r1", "memory" + ); + } +} + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) +void vSystemCallExit( uint32_t * pulSystemCallStack, uint32_t ulLR ) /* PRIVILEGED_FUNCTION */ +{ + extern TaskHandle_t pxCurrentTCB; + xMPU_SETTINGS * pxMpuSettings; + uint32_t * pulTaskStack; + uint32_t ulStackFrameSize, ulSystemCallLocation, i; + #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being + * exported from linker scripts. */ + extern uint32_t * __syscalls_flash_start__; + extern uint32_t * __syscalls_flash_end__; + #else + /* Declaration when these variable are exported from linker scripts. */ + extern uint32_t __syscalls_flash_start__[]; + extern uint32_t __syscalls_flash_end__[]; + #endif /* #if defined( __ARMCC_VERSION ) */ + + ulSystemCallLocation = pulSystemCallStack[ portOFFSET_TO_PC ]; + + /* If the request did not come from the system call section, do nothing. */ + if( ( ulSystemCallLocation >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulSystemCallLocation <= ( uint32_t ) __syscalls_flash_end__ ) ) + { + pxMpuSettings = xTaskGetMPUSettings( pxCurrentTCB ); + pulTaskStack = pxMpuSettings->xSystemCallStackInfo.pulTaskStack; + + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + { + if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) + { + /* Extended frame i.e. FPU in use. */ + ulStackFrameSize = 26; + __asm volatile ( + " vpush {s0} \n" /* Trigger lazy stacking. */ + " vpop {s0} \n" /* Nullify the affect of the above instruction. */ + ::: "memory" + ); + } + else + { + /* Standard frame i.e. FPU not in use. */ + ulStackFrameSize = 8; + } + } + #else + { + ulStackFrameSize = 8; + } + #endif /* configENABLE_FPU || configENABLE_MVE */ + + /* Make space on the task stack for the stack frame. */ + pulTaskStack = pulTaskStack - ulStackFrameSize; + + /* Copy the stack frame. */ + for( i = 0; i < ulStackFrameSize; i++ ) + { + pulTaskStack[ i ] = pulSystemCallStack[ i ]; + } + + /* Use the pulTaskStack in thread mode. */ + __asm volatile ( "msr psp, %0" : : "r" ( pulTaskStack ) ); + + /* Restore the LR and PSPLIM to what they were at the time of + * system call entry. */ + pulTaskStack[ portOFFSET_TO_LR ] = pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry; + __asm volatile ( "msr psplim, %0" : : "r" ( pxMpuSettings->xSystemCallStackInfo.ulStackLimitRegisterAtSystemCallEntry ) ); + + /* If the hardware used padding to force the stack pointer + * to be double word aligned, set the stacked xPSR bit[9], + * otherwise clear it. */ + if( ( pxMpuSettings->ulTaskFlags & portSTACK_FRAME_HAS_PADDING_FLAG ) == portSTACK_FRAME_HAS_PADDING_FLAG ) + { + pulTaskStack[ portOFFSET_TO_PSR ] |= portPSR_STACK_PADDING_MASK; + } + else + { + pulTaskStack[ portOFFSET_TO_PSR ] &= ( ~portPSR_STACK_PADDING_MASK ); + } + + /* This is not NULL only for the duration of the system call. */ + pxMpuSettings->xSystemCallStackInfo.pulTaskStack = NULL; + + /* Drop the privilege before returning to the thread mode. */ + __asm volatile ( + " mrs r0, control \n" /* Obtain current control value. */ + " movs r1, #1 \n" /* r1 = 1. */ + " orrs r0, r1 \n" /* Set nPRIV bit. */ + " msr control, r0 \n" /* Write back new control value. */ + ::: "r0", "r1", "memory" + ); + } +} + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configENABLE_MPU == 1 ) + +BaseType_t xPortIsTaskPrivileged( void ) /* PRIVILEGED_FUNCTION */ +{ + BaseType_t xTaskIsPrivileged = pdFALSE; + const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */ + + if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) + { + xTaskIsPrivileged = pdTRUE; + } + + return xTaskIsPrivileged; +} + +#endif /* configENABLE_MPU == 1 */ +/*-----------------------------------------------------------*/ + +#if( configENABLE_MPU == 1 ) + +StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, + StackType_t * pxEndOfStack, + TaskFunction_t pxCode, + void * pvParameters, + BaseType_t xRunPrivileged, + xMPU_SETTINGS * xMPUSettings ) /* PRIVILEGED_FUNCTION */ +{ + uint32_t ulIndex = 0; + + xMPUSettings->ulContext[ ulIndex ] = 0x04040404; /* r4. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x05050505; /* r5. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x06060606; /* r6. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x07070707; /* r7. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x08080808; /* r8. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x09090909; /* r9. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x10101010; /* r10. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x11111111; /* r11. */ + ulIndex++; + + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pvParameters; /* r0. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x01010101; /* r1. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x02020202; /* r2. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x03030303; /* r3. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = 0x12121212; /* r12. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portTASK_RETURN_ADDRESS; /* LR. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxCode; /* PC. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = portINITIAL_XPSR; /* xPSR. */ + ulIndex++; + + #if ( configENABLE_TRUSTZONE == 1 ) + { + xMPUSettings->ulContext[ ulIndex ] = portNO_SECURE_CONTEXT; /* xSecureContext. */ + ulIndex++; + } + #endif /* configENABLE_TRUSTZONE */ + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) ( pxTopOfStack - 8 ); /* PSP with the hardware saved stack. */ + ulIndex++; + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */ + ulIndex++; + if( xRunPrivileged == pdTRUE ) + { + xMPUSettings->ulTaskFlags |= portTASK_IS_PRIVILEGED_FLAG; + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_PRIVILEGED; /* CONTROL. */ + ulIndex++; + } + else + { + xMPUSettings->ulTaskFlags &= ( ~portTASK_IS_PRIVILEGED_FLAG ); + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_UNPRIVILEGED; /* CONTROL. */ + ulIndex++; + } + xMPUSettings->ulContext[ ulIndex ] = portINITIAL_EXC_RETURN; /* LR (EXC_RETURN). */ + ulIndex++; + + #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + { + /* Ensure that the system call stack is double word aligned. */ + xMPUSettings->xSystemCallStackInfo.pulSystemCallStack = &( xMPUSettings->xSystemCallStackInfo.ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE - 1 ] ); + xMPUSettings->xSystemCallStackInfo.pulSystemCallStack = ( uint32_t * ) ( ( uint32_t ) ( xMPUSettings->xSystemCallStackInfo.pulSystemCallStack ) & + ( uint32_t ) ( ~( portBYTE_ALIGNMENT_MASK ) ) ); + + xMPUSettings->xSystemCallStackInfo.pulSystemCallStackLimit = &( xMPUSettings->xSystemCallStackInfo.ulSystemCallStackBuffer[ 0 ] ); + xMPUSettings->xSystemCallStackInfo.pulSystemCallStackLimit = ( uint32_t * ) ( ( ( uint32_t ) ( xMPUSettings->xSystemCallStackInfo.pulSystemCallStackLimit ) + + ( uint32_t ) ( portBYTE_ALIGNMENT - 1 ) ) & + ( uint32_t ) ( ~( portBYTE_ALIGNMENT_MASK ) ) ); + + /* This is not NULL only for the duration of a system call. */ + xMPUSettings->xSystemCallStackInfo.pulTaskStack = NULL; + } + #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + + return &( xMPUSettings->ulContext[ ulIndex ] ); +} + +#else /* configENABLE_MPU */ + +StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, + StackType_t * pxEndOfStack, + TaskFunction_t pxCode, + void * pvParameters ) /* PRIVILEGED_FUNCTION */ +{ + /* Simulate the stack frame as it would be created by a context switch + * interrupt. */ + #if ( portPRELOAD_REGISTERS == 0 ) + { + pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ + *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR. */ + pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ + pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */ + *pxTopOfStack = portINITIAL_EXC_RETURN; pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ @@ -1029,55 +1561,39 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO #else /* portPRELOAD_REGISTERS */ { pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ - *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ + *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pxCode; /* PC */ + *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR */ + *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x12121212UL; /* R12 */ + *pxTopOfStack = ( StackType_t ) 0x12121212UL; /* R12. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x03030303UL; /* R3 */ + *pxTopOfStack = ( StackType_t ) 0x03030303UL; /* R3. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x02020202UL; /* R2 */ + *pxTopOfStack = ( StackType_t ) 0x02020202UL; /* R2. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x01010101UL; /* R1 */ + *pxTopOfStack = ( StackType_t ) 0x01010101UL; /* R1. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x11111111UL; /* R11 */ + *pxTopOfStack = ( StackType_t ) 0x11111111UL; /* R11. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x10101010UL; /* R10 */ + *pxTopOfStack = ( StackType_t ) 0x10101010UL; /* R10. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x09090909UL; /* R09 */ + *pxTopOfStack = ( StackType_t ) 0x09090909UL; /* R09. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x08080808UL; /* R08 */ + *pxTopOfStack = ( StackType_t ) 0x08080808UL; /* R08. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x07070707UL; /* R07 */ + *pxTopOfStack = ( StackType_t ) 0x07070707UL; /* R07. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x06060606UL; /* R06 */ + *pxTopOfStack = ( StackType_t ) 0x06060606UL; /* R06. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x05050505UL; /* R05 */ + *pxTopOfStack = ( StackType_t ) 0x05050505UL; /* R05. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x04040404UL; /* R04 */ + *pxTopOfStack = ( StackType_t ) 0x04040404UL; /* R04. */ pxTopOfStack--; - *pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN */ - - #if ( configENABLE_MPU == 1 ) - { - pxTopOfStack--; - - if( xRunPrivileged == pdTRUE ) - { - *pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */ - } - else - { - *pxTopOfStack = portINITIAL_CONTROL_UNPRIVILEGED; /* Slot used to hold this task's CONTROL value. */ - } - } - #endif /* configENABLE_MPU */ - + *pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN. */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ @@ -1092,6 +1608,8 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO return pxTopOfStack; } + +#endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ @@ -1128,6 +1646,10 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ configASSERT( ucMaxSysCallPriority ); + /* Check that the bits not implemented in hardware are zero in + * configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & ( ~ucMaxPriorityValue ) ) == 0U ); + /* Calculate the maximum acceptable priority group value for the number * of bits read back. */ @@ -1164,35 +1686,6 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulImplementedPrioBits; } - /* The interrupt priority bits are not modelled in QEMU and the assert that - * checks the number of implemented bits and __NVIC_PRIO_BITS will always fail. - * Therefore, this assert is not adding any value for QEMU targets. The config - * option `configDISABLE_INTERRUPT_PRIO_BITS_CHECK` should be defined in the - * `FreeRTOSConfig.h` for QEMU targets. */ - #ifndef configDISABLE_INTERRUPT_PRIO_BITS_CHECK - { - #ifdef __NVIC_PRIO_BITS - { - /* - * Check that the number of implemented priority bits queried from - * hardware is equal to the CMSIS __NVIC_PRIO_BITS configuration macro. - */ - configASSERT( ulImplementedPrioBits == __NVIC_PRIO_BITS ); - } - #endif /* __NVIC_PRIO_BITS */ - - #ifdef configPRIO_BITS - { - /* - * Check that the number of implemented priority bits queried from - * hardware is equal to the FreeRTOS configPRIO_BITS configuration macro. - */ - configASSERT( ulImplementedPrioBits == configPRIO_BITS ); - } - #endif /* configPRIO_BITS */ - } - #endif /* #ifndef configDISABLE_INTERRUPT_PRIO_BITS_CHECK */ - /* Shift the priority group value back to its position within the AIRCR * register. */ ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT; @@ -1372,6 +1865,54 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ +#if ( configENABLE_MPU == 1 ) + BaseType_t xPortIsAuthorizedToAccessBuffer( const void * pvBuffer, + uint32_t ulBufferLength, + uint32_t ulAccessRequested ) /* PRIVILEGED_FUNCTION */ + + { + uint32_t i, ulBufferStartAddress, ulBufferEndAddress; + BaseType_t xAccessGranted = pdFALSE; + const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */ + + if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) + { + xAccessGranted = pdTRUE; + } + else + { + if( portADD_UINT32_WILL_OVERFLOW( ( ( uint32_t ) pvBuffer ), ( ulBufferLength - 1UL ) ) == pdFALSE ) + { + ulBufferStartAddress = ( uint32_t ) pvBuffer; + ulBufferEndAddress = ( ( ( uint32_t ) pvBuffer ) + ulBufferLength - 1UL ); + + for( i = 0; i < portTOTAL_NUM_REGIONS; i++ ) + { + /* Is the MPU region enabled? */ + if( ( xTaskMpuSettings->xRegionsSettings[ i ].ulRLAR & portMPU_RLAR_REGION_ENABLE ) == portMPU_RLAR_REGION_ENABLE ) + { + if( portIS_ADDRESS_WITHIN_RANGE( ulBufferStartAddress, + portEXTRACT_FIRST_ADDRESS_FROM_RBAR( xTaskMpuSettings->xRegionsSettings[ i ].ulRBAR ), + portEXTRACT_LAST_ADDRESS_FROM_RLAR( xTaskMpuSettings->xRegionsSettings[ i ].ulRLAR ) ) && + portIS_ADDRESS_WITHIN_RANGE( ulBufferEndAddress, + portEXTRACT_FIRST_ADDRESS_FROM_RBAR( xTaskMpuSettings->xRegionsSettings[ i ].ulRBAR ), + portEXTRACT_LAST_ADDRESS_FROM_RLAR( xTaskMpuSettings->xRegionsSettings[ i ].ulRLAR ) ) && + portIS_AUTHORIZED( ulAccessRequested, + prvGetRegionAccessPermissions( xTaskMpuSettings->xRegionsSettings[ i ].ulRBAR ) ) ) + { + xAccessGranted = pdTRUE; + break; + } + } + } + } + } + + return xAccessGranted; + } +#endif /* configENABLE_MPU */ +/*-----------------------------------------------------------*/ + BaseType_t xPortIsInsideInterrupt( void ) { uint32_t ulCurrentInterrupt; diff --git a/portable/IAR/ARM_CM85_NTZ/non_secure/portasm.s b/portable/IAR/ARM_CM85_NTZ/non_secure/portasm.s index 581b84d4951..ec52025270b 100644 --- a/portable/IAR/ARM_CM85_NTZ/non_secure/portasm.s +++ b/portable/IAR/ARM_CM85_NTZ/non_secure/portasm.s @@ -32,9 +32,18 @@ the code is included in C files but excluded by the preprocessor in assembly files (__ICCARM__ is defined by the IAR C compiler but not by the IAR assembler. */ #include "FreeRTOSConfig.h" +#ifndef configUSE_MPU_WRAPPERS_V1 + #define configUSE_MPU_WRAPPERS_V1 0 +#endif + EXTERN pxCurrentTCB EXTERN vTaskSwitchContext EXTERN vPortSVCHandler_C +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + EXTERN vSystemCallEnter + EXTERN vSystemCallEnter_1 + EXTERN vSystemCallExit +#endif PUBLIC xIsPrivileged PUBLIC vResetPrivilege @@ -79,48 +88,79 @@ vResetPrivilege: THUMB /*-----------------------------------------------------------*/ +#if ( configENABLE_MPU == 1 ) + +vRestoreContextOfFirstTask: + program_mpu_first_task: + ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + ldr r0, [r2] /* r0 = pxCurrentTCB. */ + + dmb /* Complete outstanding transfers before disabling MPU. */ + ldr r1, =0xe000ed94 /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + ldr r2, [r1] /* Read the value of MPU_CTRL. */ + bic r2, #1 /* r2 = r2 & ~1 i.e. Clear the bit 0 in r2. */ + str r2, [r1] /* Disable MPU. */ + + adds r0, #4 /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */ + ldr r1, [r0] /* r1 = *r0 i.e. r1 = MAIR0. */ + ldr r2, =0xe000edc0 /* r2 = 0xe000edc0 [Location of MAIR0]. */ + str r1, [r2] /* Program MAIR0. */ + + adds r0, #4 /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */ + ldr r1, =0xe000ed98 /* r1 = 0xe000ed98 [Location of RNR]. */ + ldr r2, =0xe000ed9c /* r2 = 0xe000ed9c [Location of RBAR]. */ + + movs r3, #4 /* r3 = 4. */ + str r3, [r1] /* Program RNR = 4. */ + ldmia r0!, {r4-r11} /* Read 4 sets of RBAR/RLAR registers from TCB. */ + stmia r2, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ + + #if ( configTOTAL_MPU_REGIONS == 16 ) + movs r3, #8 /* r3 = 8. */ + str r3, [r1] /* Program RNR = 8. */ + ldmia r0!, {r4-r11} /* Read 4 sets of RBAR/RLAR registers from TCB. */ + stmia r2, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ + movs r3, #12 /* r3 = 12. */ + str r3, [r1] /* Program RNR = 12. */ + ldmia r0!, {r4-r11} /* Read 4 sets of RBAR/RLAR registers from TCB. */ + stmia r2, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ + #endif /* configTOTAL_MPU_REGIONS == 16 */ + + ldr r1, =0xe000ed94 /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + ldr r2, [r1] /* Read the value of MPU_CTRL. */ + orr r2, #1 /* r2 = r2 | 1 i.e. Set the bit 0 in r2. */ + str r2, [r1] /* Enable MPU. */ + dsb /* Force memory writes before continuing. */ + + restore_context_first_task: + ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + ldr r0, [r2] /* r0 = pxCurrentTCB.*/ + ldr r1, [r0] /* r1 = Location of saved context in TCB. */ + + restore_special_regs_first_task: + ldmdb r1!, {r2-r4, lr} /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */ + msr psp, r2 + msr psplim, r3 + msr control, r4 + + restore_general_regs_first_task: + ldmdb r1!, {r4-r11} /* r4-r11 contain hardware saved context. */ + stmia r2!, {r4-r11} /* Copy the hardware saved context on the task stack. */ + ldmdb r1!, {r4-r11} /* r4-r11 restored. */ + + restore_context_done_first_task: + str r1, [r0] /* Save the location where the context should be saved next as the first member of TCB. */ + mov r0, #0 + msr basepri, r0 /* Ensure that interrupts are enabled when the first task starts. */ + bx lr + +#else /* configENABLE_MPU */ + vRestoreContextOfFirstTask: ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r2] /* Read pxCurrentTCB. */ ldr r0, [r1] /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ -#if ( configENABLE_MPU == 1 ) - dmb /* Complete outstanding transfers before disabling MPU. */ - ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ - ldr r4, [r2] /* Read the value of MPU_CTRL. */ - bic r4, r4, #1 /* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */ - str r4, [r2] /* Disable MPU. */ - - adds r1, #4 /* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */ - ldr r3, [r1] /* r3 = *r1 i.e. r3 = MAIR0. */ - ldr r2, =0xe000edc0 /* r2 = 0xe000edc0 [Location of MAIR0]. */ - str r3, [r2] /* Program MAIR0. */ - ldr r2, =0xe000ed98 /* r2 = 0xe000ed98 [Location of RNR]. */ - movs r3, #4 /* r3 = 4. */ - str r3, [r2] /* Program RNR = 4. */ - adds r1, #4 /* r1 = r1 + 4. r1 now points to first RBAR in TCB. */ - ldr r2, =0xe000ed9c /* r2 = 0xe000ed9c [Location of RBAR]. */ - ldmia r1!, {r4-r11} /* Read 4 sets of RBAR/RLAR registers from TCB. */ - stmia r2!, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ - - ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ - ldr r4, [r2] /* Read the value of MPU_CTRL. */ - orr r4, r4, #1 /* r4 = r4 | 1 i.e. Set the bit 0 in r4. */ - str r4, [r2] /* Enable MPU. */ - dsb /* Force memory writes before continuing. */ -#endif /* configENABLE_MPU */ - -#if ( configENABLE_MPU == 1 ) - ldm r0!, {r1-r3} /* Read from stack - r1 = PSPLIM, r2 = CONTROL and r3 = EXC_RETURN. */ - msr psplim, r1 /* Set this task's PSPLIM value. */ - msr control, r2 /* Set this task's CONTROL value. */ - adds r0, #32 /* Discard everything up to r0. */ - msr psp, r0 /* This is now the new top of stack to use in the task. */ - isb - mov r0, #0 - msr basepri, r0 /* Ensure that interrupts are enabled when the first task starts. */ - bx r3 /* Finally, branch to EXC_RETURN. */ -#else /* configENABLE_MPU */ ldm r0!, {r1-r2} /* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */ msr psplim, r1 /* Set this task's PSPLIM value. */ movs r1, #2 /* r1 = 2. */ @@ -131,6 +171,7 @@ vRestoreContextOfFirstTask: mov r0, #0 msr basepri, r0 /* Ensure that interrupts are enabled when the first task starts. */ bx r2 /* Finally, branch to EXC_RETURN. */ + #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ @@ -169,6 +210,114 @@ vClearInterruptMask: bx lr /* Return. */ /*-----------------------------------------------------------*/ +#if ( configENABLE_MPU == 1 ) + +PendSV_Handler: + ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + ldr r0, [r2] /* r0 = pxCurrentTCB. */ + ldr r1, [r0] /* r1 = Location in TCB where the context should be saved. */ + mrs r2, psp /* r2 = PSP. */ + + save_general_regs: + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + add r2, r2, #0x20 /* Move r2 to location where s0 is saved. */ + tst lr, #0x10 + ittt eq + vstmiaeq r1!, {s16-s31} /* Store s16-s31. */ + vldmiaeq r2, {s0-s16} /* Copy hardware saved FP context into s0-s16. */ + vstmiaeq r1!, {s0-s16} /* Store hardware saved FP context. */ + sub r2, r2, #0x20 /* Set r2 back to the location of hardware saved context. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ + + stmia r1!, {r4-r11} /* Store r4-r11. */ + ldmia r2, {r4-r11} /* Copy the hardware saved context into r4-r11. */ + stmia r1!, {r4-r11} /* Store the hardware saved context. */ + + save_special_regs: + mrs r3, psplim /* r3 = PSPLIM. */ + mrs r4, control /* r4 = CONTROL. */ + stmia r1!, {r2-r4, lr} /* Store original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */ + str r1, [r0] /* Save the location from where the context should be restored as the first member of TCB. */ + + select_next_task: + mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY + msr basepri, r0 /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + dsb + isb + bl vTaskSwitchContext + mov r0, #0 /* r0 = 0. */ + msr basepri, r0 /* Enable interrupts. */ + + program_mpu: + ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + ldr r0, [r2] /* r0 = pxCurrentTCB. */ + + dmb /* Complete outstanding transfers before disabling MPU. */ + ldr r1, =0xe000ed94 /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + ldr r2, [r1] /* Read the value of MPU_CTRL. */ + bic r2, #1 /* r2 = r2 & ~1 i.e. Clear the bit 0 in r2. */ + str r2, [r1] /* Disable MPU. */ + + adds r0, #4 /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */ + ldr r1, [r0] /* r1 = *r0 i.e. r1 = MAIR0. */ + ldr r2, =0xe000edc0 /* r2 = 0xe000edc0 [Location of MAIR0]. */ + str r1, [r2] /* Program MAIR0. */ + + adds r0, #4 /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */ + ldr r1, =0xe000ed98 /* r1 = 0xe000ed98 [Location of RNR]. */ + ldr r2, =0xe000ed9c /* r2 = 0xe000ed9c [Location of RBAR]. */ + + movs r3, #4 /* r3 = 4. */ + str r3, [r1] /* Program RNR = 4. */ + ldmia r0!, {r4-r11} /* Read 4 sets of RBAR/RLAR registers from TCB. */ + stmia r2, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ + + #if ( configTOTAL_MPU_REGIONS == 16 ) + movs r3, #8 /* r3 = 8. */ + str r3, [r1] /* Program RNR = 8. */ + ldmia r0!, {r4-r11} /* Read 4 sets of RBAR/RLAR registers from TCB. */ + stmia r2, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ + movs r3, #12 /* r3 = 12. */ + str r3, [r1] /* Program RNR = 12. */ + ldmia r0!, {r4-r11} /* Read 4 sets of RBAR/RLAR registers from TCB. */ + stmia r2, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ + #endif /* configTOTAL_MPU_REGIONS == 16 */ + + ldr r1, =0xe000ed94 /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ + ldr r2, [r1] /* Read the value of MPU_CTRL. */ + orr r2, #1 /* r2 = r2 | 1 i.e. Set the bit 0 in r2. */ + str r2, [r1] /* Enable MPU. */ + dsb /* Force memory writes before continuing. */ + + restore_context: + ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + ldr r0, [r2] /* r0 = pxCurrentTCB.*/ + ldr r1, [r0] /* r1 = Location of saved context in TCB. */ + + restore_special_regs: + ldmdb r1!, {r2-r4, lr} /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */ + msr psp, r2 + msr psplim, r3 + msr control, r4 + + restore_general_regs: + ldmdb r1!, {r4-r11} /* r4-r11 contain hardware saved context. */ + stmia r2!, {r4-r11} /* Copy the hardware saved context on the task stack. */ + ldmdb r1!, {r4-r11} /* r4-r11 restored. */ + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + tst lr, #0x10 + ittt eq + vldmdbeq r1!, {s0-s16} /* s0-s16 contain hardware saved FP context. */ + vstmiaeq r2!, {s0-s16} /* Copy hardware saved FP context on the task stack. */ + vldmdbeq r1!, {s16-s31} /* Restore s16-s31. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ + + restore_context_done: + str r1, [r0] /* Save the location where the context should be saved next as the first member of TCB. */ + bx lr + +#else /* configENABLE_MPU */ + PendSV_Handler: mrs r0, psp /* Read PSP in r0. */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) @@ -176,16 +325,10 @@ PendSV_Handler: it eq vstmdbeq r0!, {s16-s31} /* Store the additional FP context registers which are not saved automatically. */ #endif /* configENABLE_FPU || configENABLE_MVE */ -#if ( configENABLE_MPU == 1 ) - mrs r1, psplim /* r1 = PSPLIM. */ - mrs r2, control /* r2 = CONTROL. */ - mov r3, lr /* r3 = LR/EXC_RETURN. */ - stmdb r0!, {r1-r11} /* Store on the stack - PSPLIM, CONTROL, LR and registers that are not automatically saved. */ -#else /* configENABLE_MPU */ + mrs r2, psplim /* r2 = PSPLIM. */ mov r3, lr /* r3 = LR/EXC_RETURN. */ stmdb r0!, {r2-r11} /* Store on the stack - PSPLIM, LR and registers that are not automatically. */ -#endif /* configENABLE_MPU */ ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r2] /* Read pxCurrentTCB. */ @@ -203,37 +346,7 @@ PendSV_Handler: ldr r1, [r2] /* Read pxCurrentTCB. */ ldr r0, [r1] /* The first item in pxCurrentTCB is the task top of stack. r0 now points to the top of stack. */ -#if ( configENABLE_MPU == 1 ) - dmb /* Complete outstanding transfers before disabling MPU. */ - ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ - ldr r4, [r2] /* Read the value of MPU_CTRL. */ - bic r4, r4, #1 /* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */ - str r4, [r2] /* Disable MPU. */ - - adds r1, #4 /* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */ - ldr r3, [r1] /* r3 = *r1 i.e. r3 = MAIR0. */ - ldr r2, =0xe000edc0 /* r2 = 0xe000edc0 [Location of MAIR0]. */ - str r3, [r2] /* Program MAIR0. */ - ldr r2, =0xe000ed98 /* r2 = 0xe000ed98 [Location of RNR]. */ - movs r3, #4 /* r3 = 4. */ - str r3, [r2] /* Program RNR = 4. */ - adds r1, #4 /* r1 = r1 + 4. r1 now points to first RBAR in TCB. */ - ldr r2, =0xe000ed9c /* r2 = 0xe000ed9c [Location of RBAR]. */ - ldmia r1!, {r4-r11} /* Read 4 sets of RBAR/RLAR registers from TCB. */ - stmia r2!, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ - - ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ - ldr r4, [r2] /* Read the value of MPU_CTRL. */ - orr r4, r4, #1 /* r4 = r4 | 1 i.e. Set the bit 0 in r4. */ - str r4, [r2] /* Enable MPU. */ - dsb /* Force memory writes before continuing. */ -#endif /* configENABLE_MPU */ - -#if ( configENABLE_MPU == 1 ) - ldmia r0!, {r1-r11} /* Read from stack - r1 = PSPLIM, r2 = CONTROL, r3 = LR and r4-r11 restored. */ -#else /* configENABLE_MPU */ ldmia r0!, {r2-r11} /* Read from stack - r2 = PSPLIM, r3 = LR and r4-r11 restored. */ -#endif /* configENABLE_MPU */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) tst r3, #0x10 /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ @@ -241,22 +354,53 @@ PendSV_Handler: vldmiaeq r0!, {s16-s31} /* Restore the additional FP context registers which are not restored automatically. */ #endif /* configENABLE_FPU || configENABLE_MVE */ - #if ( configENABLE_MPU == 1 ) - msr psplim, r1 /* Restore the PSPLIM register value for the task. */ - msr control, r2 /* Restore the CONTROL register value for the task. */ -#else /* configENABLE_MPU */ msr psplim, r2 /* Restore the PSPLIM register value for the task. */ -#endif /* configENABLE_MPU */ msr psp, r0 /* Remember the new top of stack for the task. */ bx r3 + +#endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + +SVC_Handler: + tst lr, #4 + ite eq + mrseq r0, msp + mrsne r0, psp + + ldr r1, [r0, #24] + ldrb r2, [r1, #-2] + cmp r2, #4 /* portSVC_SYSTEM_CALL_ENTER. */ + beq syscall_enter + cmp r2, #5 /* portSVC_SYSTEM_CALL_ENTER_1. */ + beq syscall_enter_1 + cmp r2, #6 /* portSVC_SYSTEM_CALL_EXIT. */ + beq syscall_exit + b vPortSVCHandler_C + + syscall_enter: + mov r1, lr + b vSystemCallEnter + + syscall_enter_1: + mov r1, lr + b vSystemCallEnter_1 + + syscall_exit: + mov r1, lr + b vSystemCallExit + +#else /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + SVC_Handler: tst lr, #4 ite eq mrseq r0, msp mrsne r0, psp b vPortSVCHandler_C + +#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ /*-----------------------------------------------------------*/ END diff --git a/portable/IAR/ARM_CM85_NTZ/non_secure/portmacrocommon.h b/portable/IAR/ARM_CM85_NTZ/non_secure/portmacrocommon.h index c2ca5fa7730..65ac109c802 100644 --- a/portable/IAR/ARM_CM85_NTZ/non_secure/portmacrocommon.h +++ b/portable/IAR/ARM_CM85_NTZ/non_secure/portmacrocommon.h @@ -186,23 +186,120 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #define portMPU_REGION_EXECUTE_NEVER ( 1UL ) /*-----------------------------------------------------------*/ -/** - * @brief Settings to define an MPU region. - */ -typedef struct MPURegionSettings -{ - uint32_t ulRBAR; /**< RBAR for the region. */ - uint32_t ulRLAR; /**< RLAR for the region. */ -} MPURegionSettings_t; +#if ( configENABLE_MPU == 1 ) -/** - * @brief MPU settings as stored in the TCB. - */ -typedef struct MPU_SETTINGS -{ - uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ - MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */ -} xMPU_SETTINGS; + /** + * @brief Settings to define an MPU region. + */ + typedef struct MPURegionSettings + { + uint32_t ulRBAR; /**< RBAR for the region. */ + uint32_t ulRLAR; /**< RLAR for the region. */ + } MPURegionSettings_t; + + #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + + #ifndef configSYSTEM_CALL_STACK_SIZE + #error configSYSTEM_CALL_STACK_SIZE must be defined to the desired size of the system call stack in words for using MPU wrappers v2. + #endif + + /** + * @brief System call stack. + */ + typedef struct SYSTEM_CALL_STACK_INFO + { + uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ]; + uint32_t * pulSystemCallStack; + uint32_t * pulSystemCallStackLimit; + uint32_t * pulTaskStack; + uint32_t ulLinkRegisterAtSystemCallEntry; + uint32_t ulStackLimitRegisterAtSystemCallEntry; + } xSYSTEM_CALL_STACK_INFO; + + #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + + /** + * @brief MPU settings as stored in the TCB. + */ + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + + #if( configENABLE_TRUSTZONE == 1 ) + + /* + * +-----------+---------------+----------+-----------------+------------------------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | + * | | | | PC, xPSR | CONTROL, EXC_RETURN | | + * +-----------+---------------+----------+-----------------+------------------------------+-----+ + * + * <-----------><--------------><---------><----------------><-----------------------------><----> + * 16 16 8 8 5 1 + */ + #define MAX_CONTEXT_SIZE 54 + + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ + + /* + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | + * | | | | PC, xPSR | EXC_RETURN | | + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * + * <-----------><--------------><---------><----------------><---------------------><----> + * 16 16 8 8 4 1 + */ + #define MAX_CONTEXT_SIZE 53 + + #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + + #else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ + + #if( configENABLE_TRUSTZONE == 1 ) + + /* + * +----------+-----------------+------------------------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | + * | | PC, xPSR | CONTROL, EXC_RETURN | | + * +----------+-----------------+------------------------------+-----+ + * + * <---------><----------------><------------------------------><----> + * 8 8 5 1 + */ + #define MAX_CONTEXT_SIZE 22 + + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ + + /* + * +----------+-----------------+----------------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | + * | | PC, xPSR | EXC_RETURN | | + * +----------+-----------------+----------------------+-----+ + * + * <---------><----------------><----------------------><----> + * 8 8 4 1 + */ + #define MAX_CONTEXT_SIZE 21 + + #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + + #endif /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ + + /* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ + #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) + #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) + + typedef struct MPU_SETTINGS + { + uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ + MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */ + uint32_t ulContext[ MAX_CONTEXT_SIZE ]; + uint32_t ulTaskFlags; + + #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo; + #endif + } xMPU_SETTINGS; + +#endif /* configENABLE_MPU == 1 */ /*-----------------------------------------------------------*/ /** @@ -223,6 +320,9 @@ typedef struct MPU_SETTINGS #define portSVC_FREE_SECURE_CONTEXT 1 #define portSVC_START_SCHEDULER 2 #define portSVC_RAISE_PRIVILEGE 3 +#define portSVC_SYSTEM_CALL_ENTER 4 /* System calls with upto 4 parameters. */ +#define portSVC_SYSTEM_CALL_ENTER_1 5 /* System calls with 5 parameters. */ +#define portSVC_SYSTEM_CALL_EXIT 6 /*-----------------------------------------------------------*/ /** @@ -315,6 +415,20 @@ typedef struct MPU_SETTINGS #endif /* configENABLE_MPU */ /*-----------------------------------------------------------*/ +#if ( configENABLE_MPU == 1 ) + + extern BaseType_t xPortIsTaskPrivileged( void ); + + /** + * @brief Checks whether or not the calling task is privileged. + * + * @return pdTRUE if the calling task is privileged, pdFALSE otherwise. + */ + #define portIS_TASK_PRIVILEGED() xPortIsTaskPrivileged() + +#endif /* configENABLE_MPU == 1 */ +/*-----------------------------------------------------------*/ + /** * @brief Barriers. */ diff --git a/portable/IAR/ATMega323/portmacro.h b/portable/IAR/ATMega323/portmacro.h index 69ba2f1d9ac..cbc7b2d156b 100644 --- a/portable/IAR/ATMega323/portmacro.h +++ b/portable/IAR/ATMega323/portmacro.h @@ -71,7 +71,7 @@ typedef unsigned char UBaseType_t; #define portMAX_DELAY ( TickType_t ) 0xffff #elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; - #define portMAX_DELAY ( TickType_t ) ( 0xFFFFFFFF ) + #define portMAX_DELAY ( TickType_t ) ( 0xFFFFFFFFUL ) #else #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif diff --git a/portable/IAR/AVR32_UC3/portmacro.h b/portable/IAR/AVR32_UC3/portmacro.h index 73c206ca5f8..98aa5be0745 100644 --- a/portable/IAR/AVR32_UC3/portmacro.h +++ b/portable/IAR/AVR32_UC3/portmacro.h @@ -119,7 +119,7 @@ typedef unsigned long UBaseType_t; #define portMAX_DELAY ( TickType_t ) 0xffff #elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; - #define portMAX_DELAY ( TickType_t ) ( 0xFFFFFFFF ) + #define portMAX_DELAY ( TickType_t ) ( 0xFFFFFFFFUL ) #else #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif diff --git a/portable/IAR/AVR_AVRDx/portmacro.h b/portable/IAR/AVR_AVRDx/portmacro.h index 5b4b5be8b3c..cb3cb7ec201 100644 --- a/portable/IAR/AVR_AVRDx/portmacro.h +++ b/portable/IAR/AVR_AVRDx/portmacro.h @@ -65,7 +65,7 @@ typedef unsigned char UBaseType_t; #define portMAX_DELAY ( TickType_t ) 0xffff #elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; - #define portMAX_DELAY ( TickType_t ) ( 0xFFFFFFFF ) + #define portMAX_DELAY ( TickType_t ) ( 0xFFFFFFFFUL ) #else #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif diff --git a/portable/IAR/AVR_Mega0/portmacro.h b/portable/IAR/AVR_Mega0/portmacro.h index 5b4b5be8b3c..cb3cb7ec201 100644 --- a/portable/IAR/AVR_Mega0/portmacro.h +++ b/portable/IAR/AVR_Mega0/portmacro.h @@ -65,7 +65,7 @@ typedef unsigned char UBaseType_t; #define portMAX_DELAY ( TickType_t ) 0xffff #elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; - #define portMAX_DELAY ( TickType_t ) ( 0xFFFFFFFF ) + #define portMAX_DELAY ( TickType_t ) ( 0xFFFFFFFFUL ) #else #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif diff --git a/portable/IAR/AtmelSAM7S64/port.c b/portable/IAR/AtmelSAM7S64/port.c index 1e14d2e4aaa..32489702348 100644 --- a/portable/IAR/AtmelSAM7S64/port.c +++ b/portable/IAR/AtmelSAM7S64/port.c @@ -218,7 +218,7 @@ AT91PS_PITC pxPIT = AT91C_BASE_PITC; /* Configure the PIT period. */ pxPIT->PITC_PIMR = portPIT_ENABLE | portPIT_INT_ENABLE | portPIT_COUNTER_VALUE; - /* Enable the interrupt. Global interrupts are disables at this point so + /* Enable the interrupt. Global interrupts are disabled at this point so this is safe. */ AT91F_AIC_EnableIt( AT91C_BASE_AIC, AT91C_ID_SYS ); } diff --git a/portable/IAR/AtmelSAM7S64/portmacro.h b/portable/IAR/AtmelSAM7S64/portmacro.h index 01c6eed6aad..9bcf8a67003 100644 --- a/portable/IAR/AtmelSAM7S64/portmacro.h +++ b/portable/IAR/AtmelSAM7S64/portmacro.h @@ -64,7 +64,7 @@ typedef unsigned long UBaseType_t; #define portMAX_DELAY ( TickType_t ) 0xffff #elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; - #define portMAX_DELAY ( TickType_t ) ( 0xFFFFFFFF ) + #define portMAX_DELAY ( TickType_t ) ( 0xFFFFFFFFUL ) #else #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif diff --git a/portable/IAR/AtmelSAM9XE/portmacro.h b/portable/IAR/AtmelSAM9XE/portmacro.h index db6f10cca85..fdc7c2ba684 100644 --- a/portable/IAR/AtmelSAM9XE/portmacro.h +++ b/portable/IAR/AtmelSAM9XE/portmacro.h @@ -67,7 +67,7 @@ typedef unsigned long UBaseType_t; #define portMAX_DELAY ( TickType_t ) 0xffff #elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; - #define portMAX_DELAY ( TickType_t ) ( 0xFFFFFFFF ) + #define portMAX_DELAY ( TickType_t ) ( 0xFFFFFFFFUL ) #else #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif diff --git a/portable/IAR/LPC2000/portmacro.h b/portable/IAR/LPC2000/portmacro.h index 8fdf1fe75a3..2929ecba54a 100644 --- a/portable/IAR/LPC2000/portmacro.h +++ b/portable/IAR/LPC2000/portmacro.h @@ -67,7 +67,7 @@ typedef unsigned long UBaseType_t; #define portMAX_DELAY ( TickType_t ) 0xffff #elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; - #define portMAX_DELAY ( TickType_t ) ( 0xFFFFFFFF ) + #define portMAX_DELAY ( TickType_t ) ( 0xFFFFFFFFUL ) #else #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif diff --git a/portable/IAR/MSP430/portmacro.h b/portable/IAR/MSP430/portmacro.h index 298307f5519..6dcec2f0314 100644 --- a/portable/IAR/MSP430/portmacro.h +++ b/portable/IAR/MSP430/portmacro.h @@ -58,7 +58,7 @@ typedef unsigned short UBaseType_t; #define portMAX_DELAY ( TickType_t ) 0xffff #elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; - #define portMAX_DELAY ( TickType_t ) ( 0xFFFFFFFF ) + #define portMAX_DELAY ( TickType_t ) ( 0xFFFFFFFFUL ) #else #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif diff --git a/portable/IAR/MSP430X/portmacro.h b/portable/IAR/MSP430X/portmacro.h index 1ab4665b9bf..72456cf11c0 100644 --- a/portable/IAR/MSP430X/portmacro.h +++ b/portable/IAR/MSP430X/portmacro.h @@ -67,7 +67,7 @@ typedef unsigned short UBaseType_t; #define portMAX_DELAY ( TickType_t ) 0xffff #elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; - #define portMAX_DELAY ( TickType_t ) ( 0xFFFFFFFF ) + #define portMAX_DELAY ( TickType_t ) ( 0xFFFFFFFFUL ) #else #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif diff --git a/portable/IAR/RL78/portmacro.h b/portable/IAR/RL78/portmacro.h index 9685b569d5d..1cfe85fa650 100644 --- a/portable/IAR/RL78/portmacro.h +++ b/portable/IAR/RL78/portmacro.h @@ -82,7 +82,7 @@ typedef unsigned short UBaseType_t; #define portMAX_DELAY ( TickType_t ) 0xffff #elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; - #define portMAX_DELAY ( TickType_t ) ( 0xFFFFFFFF ) + #define portMAX_DELAY ( TickType_t ) ( 0xFFFFFFFFUL ) #else #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif diff --git a/portable/MikroC/ARM_CM4F/port.c b/portable/MikroC/ARM_CM4F/port.c index 8ef593f5523..91c924a05c7 100755 --- a/portable/MikroC/ARM_CM4F/port.c +++ b/portable/MikroC/ARM_CM4F/port.c @@ -329,6 +329,10 @@ BaseType_t xPortStartScheduler( void ) * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ configASSERT( ucMaxSysCallPriority ); + /* Check that the bits not implemented in hardware are zero in + * configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & ( ~ucMaxPriorityValue ) ) == 0U ); + /* Calculate the maximum acceptable priority group value for the number * of bits read back. */ @@ -365,28 +369,6 @@ BaseType_t xPortStartScheduler( void ) ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulImplementedPrioBits; } - #ifdef __NVIC_PRIO_BITS - { - /* - * Check that the number of implemented priority bits queried from - * hardware is at least as many as specified in the CMSIS - * __NVIC_PRIO_BITS configuration macro. - */ - configASSERT( ulImplementedPrioBits >= __NVIC_PRIO_BITS ); - } - #endif - - #ifdef configPRIO_BITS - { - /* - * Check that the number of implemented priority bits queried from - * hardware is at least as many as specified in the FreeRTOS - * configPRIO_BITS configuration macro. - */ - configASSERT( ulImplementedPrioBits >= configPRIO_BITS ); - } - #endif - /* Shift the priority group value back to its position within the AIRCR * register. */ ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT; diff --git a/portable/RVDS/ARM_CM3/port.c b/portable/RVDS/ARM_CM3/port.c index ae7ce37f37b..91038fd69b5 100755 --- a/portable/RVDS/ARM_CM3/port.c +++ b/portable/RVDS/ARM_CM3/port.c @@ -294,6 +294,10 @@ BaseType_t xPortStartScheduler( void ) * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ configASSERT( ucMaxSysCallPriority ); + /* Check that the bits not implemented in hardware are zero in + * configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & ( ~ucMaxPriorityValue ) ) == 0U ); + /* Calculate the maximum acceptable priority group value for the number * of bits read back. */ @@ -330,28 +334,6 @@ BaseType_t xPortStartScheduler( void ) ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulImplementedPrioBits; } - #ifdef __NVIC_PRIO_BITS - { - /* - * Check that the number of implemented priority bits queried from - * hardware is at least as many as specified in the CMSIS - * __NVIC_PRIO_BITS configuration macro. - */ - configASSERT( ulImplementedPrioBits >= __NVIC_PRIO_BITS ); - } - #endif - - #ifdef configPRIO_BITS - { - /* - * Check that the number of implemented priority bits queried from - * hardware is at least as many as specified in the FreeRTOS - * configPRIO_BITS configuration macro. - */ - configASSERT( ulImplementedPrioBits >= configPRIO_BITS ); - } - #endif - /* Shift the priority group value back to its position within the AIRCR * register. */ ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT; diff --git a/portable/RVDS/ARM_CM4F/port.c b/portable/RVDS/ARM_CM4F/port.c index cb003aa38f9..3c2040596b0 100755 --- a/portable/RVDS/ARM_CM4F/port.c +++ b/portable/RVDS/ARM_CM4F/port.c @@ -360,6 +360,10 @@ BaseType_t xPortStartScheduler( void ) * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ configASSERT( ucMaxSysCallPriority ); + /* Check that the bits not implemented in hardware are zero in + * configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & ( ~ucMaxPriorityValue ) ) == 0U ); + /* Calculate the maximum acceptable priority group value for the number * of bits read back. */ @@ -396,28 +400,6 @@ BaseType_t xPortStartScheduler( void ) ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulImplementedPrioBits; } - #ifdef __NVIC_PRIO_BITS - { - /* - * Check that the number of implemented priority bits queried from - * hardware is at least as many as specified in the CMSIS - * __NVIC_PRIO_BITS configuration macro. - */ - configASSERT( ulImplementedPrioBits >= __NVIC_PRIO_BITS ); - } - #endif - - #ifdef configPRIO_BITS - { - /* - * Check that the number of implemented priority bits queried from - * hardware is at least as many as specified in the FreeRTOS - * configPRIO_BITS configuration macro. - */ - configASSERT( ulImplementedPrioBits >= configPRIO_BITS ); - } - #endif - /* Shift the priority group value back to its position within the AIRCR * register. */ ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT; diff --git a/portable/RVDS/ARM_CM4_MPU/mpu_wrappers_v2_asm.c b/portable/RVDS/ARM_CM4_MPU/mpu_wrappers_v2_asm.c new file mode 100644 index 00000000000..aa1e825fc1d --- /dev/null +++ b/portable/RVDS/ARM_CM4_MPU/mpu_wrappers_v2_asm.c @@ -0,0 +1,1993 @@ +/* + * FreeRTOS Kernel + * Copyright (C) 2021 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 + * + */ + +/* 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. */ +#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +/* Scheduler includes. */ +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" +#include "timers.h" +#include "event_groups.h" +#include "stream_buffer.h" + +#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE +/*-----------------------------------------------------------*/ + +#if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + +#if ( INCLUDE_xTaskDelayUntil == 1 ) + +BaseType_t MPU_xTaskDelayUntil( TickType_t * const pxPreviousWakeTime, + const TickType_t xTimeIncrement ) FREERTOS_SYSTEM_CALL; + +__asm BaseType_t MPU_xTaskDelayUntil( TickType_t * const pxPreviousWakeTime, + const TickType_t xTimeIncrement ) /* FREERTOS_SYSTEM_CALL */ +{ + PRESERVE8 + extern MPU_xTaskDelayUntilImpl + + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskDelayUntil_Unpriv +MPU_xTaskDelayUntil_Priv + pop {r0} + b MPU_xTaskDelayUntilImpl +MPU_xTaskDelayUntil_Unpriv + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskDelayUntilImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +} + +#endif /* if ( INCLUDE_xTaskDelayUntil == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_xTaskAbortDelay == 1 ) + +BaseType_t MPU_xTaskAbortDelay( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL; + +__asm BaseType_t MPU_xTaskAbortDelay( TaskHandle_t xTask ) /* FREERTOS_SYSTEM_CALL */ +{ + PRESERVE8 + extern MPU_xTaskAbortDelayImpl + + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskAbortDelay_Unpriv +MPU_xTaskAbortDelay_Priv + pop {r0} + b MPU_xTaskAbortDelayImpl +MPU_xTaskAbortDelay_Unpriv + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskAbortDelayImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +} + +#endif /* if ( INCLUDE_xTaskAbortDelay == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskDelay == 1 ) + +void MPU_vTaskDelay( const TickType_t xTicksToDelay ) FREERTOS_SYSTEM_CALL; + +__asm void MPU_vTaskDelay( const TickType_t xTicksToDelay ) /* FREERTOS_SYSTEM_CALL */ +{ + PRESERVE8 + extern MPU_vTaskDelayImpl + + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vTaskDelay_Unpriv +MPU_vTaskDelay_Priv + pop {r0} + b MPU_vTaskDelayImpl +MPU_vTaskDelay_Unpriv + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskDelayImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +} + +#endif /* if ( INCLUDE_vTaskDelay == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_uxTaskPriorityGet == 1 ) + +UBaseType_t MPU_uxTaskPriorityGet( const TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL; + +__asm UBaseType_t MPU_uxTaskPriorityGet( const TaskHandle_t xTask ) /* FREERTOS_SYSTEM_CALL */ +{ + PRESERVE8 + extern MPU_uxTaskPriorityGetImpl + + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_uxTaskPriorityGet_Unpriv +MPU_uxTaskPriorityGet_Priv + pop {r0} + b MPU_uxTaskPriorityGetImpl +MPU_uxTaskPriorityGet_Unpriv + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxTaskPriorityGetImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +} + +#endif /* if ( INCLUDE_uxTaskPriorityGet == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_eTaskGetState == 1 ) + +eTaskState MPU_eTaskGetState( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL; + +__asm eTaskState MPU_eTaskGetState( TaskHandle_t xTask ) /* FREERTOS_SYSTEM_CALL */ +{ + PRESERVE8 + extern MPU_eTaskGetStateImpl + + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_eTaskGetState_Unpriv +MPU_eTaskGetState_Priv + pop {r0} + b MPU_eTaskGetStateImpl +MPU_eTaskGetState_Unpriv + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_eTaskGetStateImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +} + +#endif /* if ( INCLUDE_eTaskGetState == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + +void MPU_vTaskGetInfo( TaskHandle_t xTask, + TaskStatus_t * pxTaskStatus, + BaseType_t xGetFreeStackSpace, + eTaskState eState ) FREERTOS_SYSTEM_CALL; + +__asm void MPU_vTaskGetInfo( TaskHandle_t xTask, + TaskStatus_t * pxTaskStatus, + BaseType_t xGetFreeStackSpace, + eTaskState eState ) /* FREERTOS_SYSTEM_CALL */ +{ + PRESERVE8 + extern MPU_vTaskGetInfoImpl + + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vTaskGetInfo_Unpriv +MPU_vTaskGetInfo_Priv + pop {r0} + b MPU_vTaskGetInfoImpl +MPU_vTaskGetInfo_Unpriv + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskGetInfoImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +} + +#endif /* if ( configUSE_TRACE_FACILITY == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) + +TaskHandle_t MPU_xTaskGetIdleTaskHandle( void ) FREERTOS_SYSTEM_CALL; + +__asm TaskHandle_t MPU_xTaskGetIdleTaskHandle( void ) /* FREERTOS_SYSTEM_CALL */ +{ + PRESERVE8 + extern MPU_xTaskGetIdleTaskHandleImpl + + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskGetIdleTaskHandle_Unpriv +MPU_xTaskGetIdleTaskHandle_Priv + pop {r0} + b MPU_xTaskGetIdleTaskHandleImpl +MPU_xTaskGetIdleTaskHandle_Unpriv + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskGetIdleTaskHandleImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +} + +#endif /* if ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskSuspend == 1 ) + +void MPU_vTaskSuspend( TaskHandle_t xTaskToSuspend ) FREERTOS_SYSTEM_CALL; + +__asm void MPU_vTaskSuspend( TaskHandle_t xTaskToSuspend ) /* FREERTOS_SYSTEM_CALL */ +{ + PRESERVE8 + extern MPU_vTaskSuspendImpl + + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vTaskSuspend_Unpriv +MPU_vTaskSuspend_Priv + pop {r0} + b MPU_vTaskSuspendImpl +MPU_vTaskSuspend_Unpriv + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskSuspendImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +} + +#endif /* if ( INCLUDE_vTaskSuspend == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskSuspend == 1 ) + +void MPU_vTaskResume( TaskHandle_t xTaskToResume ) FREERTOS_SYSTEM_CALL; + +__asm void MPU_vTaskResume( TaskHandle_t xTaskToResume ) /* FREERTOS_SYSTEM_CALL */ +{ + PRESERVE8 + extern MPU_vTaskResumeImpl + + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vTaskResume_Unpriv +MPU_vTaskResume_Priv + pop {r0} + b MPU_vTaskResumeImpl +MPU_vTaskResume_Unpriv + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskResumeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +} + +#endif /* if ( INCLUDE_vTaskSuspend == 1 ) */ +/*-----------------------------------------------------------*/ + +TickType_t MPU_xTaskGetTickCount( void ) FREERTOS_SYSTEM_CALL; + +__asm TickType_t MPU_xTaskGetTickCount( void ) /* FREERTOS_SYSTEM_CALL */ +{ + PRESERVE8 + extern MPU_xTaskGetTickCountImpl + + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskGetTickCount_Unpriv +MPU_xTaskGetTickCount_Priv + pop {r0} + b MPU_xTaskGetTickCountImpl +MPU_xTaskGetTickCount_Unpriv + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskGetTickCountImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +} +/*-----------------------------------------------------------*/ + +UBaseType_t MPU_uxTaskGetNumberOfTasks( void ) FREERTOS_SYSTEM_CALL; + +__asm UBaseType_t MPU_uxTaskGetNumberOfTasks( void ) /* FREERTOS_SYSTEM_CALL */ +{ + PRESERVE8 + extern MPU_uxTaskGetNumberOfTasksImpl + + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_uxTaskGetNumberOfTasks_Unpriv +MPU_uxTaskGetNumberOfTasks_Priv + pop {r0} + b MPU_uxTaskGetNumberOfTasksImpl +MPU_uxTaskGetNumberOfTasks_Unpriv + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxTaskGetNumberOfTasksImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +} +/*-----------------------------------------------------------*/ + +char * MPU_pcTaskGetName( TaskHandle_t xTaskToQuery ) FREERTOS_SYSTEM_CALL; + +__asm char * MPU_pcTaskGetName( TaskHandle_t xTaskToQuery ) /* FREERTOS_SYSTEM_CALL */ +{ + PRESERVE8 + extern MPU_pcTaskGetNameImpl + + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_pcTaskGetName_Unpriv +MPU_pcTaskGetName_Priv + pop {r0} + b MPU_pcTaskGetNameImpl +MPU_pcTaskGetName_Unpriv + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_pcTaskGetNameImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +} +/*-----------------------------------------------------------*/ + +#if ( configGENERATE_RUN_TIME_STATS == 1 ) + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetRunTimeCounter( const TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL; + +__asm configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetRunTimeCounter( const TaskHandle_t xTask ) /* FREERTOS_SYSTEM_CALL */ +{ + PRESERVE8 + extern MPU_ulTaskGetRunTimeCounterImpl + + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_ulTaskGetRunTimeCounter_Unpriv +MPU_ulTaskGetRunTimeCounter_Priv + pop {r0} + b MPU_ulTaskGetRunTimeCounterImpl +MPU_ulTaskGetRunTimeCounter_Unpriv + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_ulTaskGetRunTimeCounterImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +} + +#endif /* if ( ( configGENERATE_RUN_TIME_STATS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configGENERATE_RUN_TIME_STATS == 1 ) + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetRunTimePercent( const TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL; + +__asm configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetRunTimePercent( const TaskHandle_t xTask ) /* FREERTOS_SYSTEM_CALL */ +{ + PRESERVE8 + extern MPU_ulTaskGetRunTimePercentImpl + + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_ulTaskGetRunTimePercent_Unpriv +MPU_ulTaskGetRunTimePercent_Priv + pop {r0} + b MPU_ulTaskGetRunTimePercentImpl +MPU_ulTaskGetRunTimePercent_Unpriv + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_ulTaskGetRunTimePercentImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +} + +#endif /* if ( ( configGENERATE_RUN_TIME_STATS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimePercent( void ) FREERTOS_SYSTEM_CALL; + +__asm configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimePercent( void ) /* FREERTOS_SYSTEM_CALL */ +{ + PRESERVE8 + extern MPU_ulTaskGetIdleRunTimePercentImpl + + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_ulTaskGetIdleRunTimePercent_Unpriv +MPU_ulTaskGetIdleRunTimePercent_Priv + pop {r0} + b MPU_ulTaskGetIdleRunTimePercentImpl +MPU_ulTaskGetIdleRunTimePercent_Unpriv + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_ulTaskGetIdleRunTimePercentImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +} + +#endif /* if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimeCounter( void ) FREERTOS_SYSTEM_CALL; + +__asm configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimeCounter( void ) /* FREERTOS_SYSTEM_CALL */ +{ + PRESERVE8 + extern MPU_ulTaskGetIdleRunTimeCounterImpl + + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_ulTaskGetIdleRunTimeCounter_Unpriv +MPU_ulTaskGetIdleRunTimeCounter_Priv + pop {r0} + b MPU_ulTaskGetIdleRunTimeCounterImpl +MPU_ulTaskGetIdleRunTimeCounter_Unpriv + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_ulTaskGetIdleRunTimeCounterImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +} + +#endif /* if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_APPLICATION_TASK_TAG == 1 ) + +void MPU_vTaskSetApplicationTaskTag( TaskHandle_t xTask, + TaskHookFunction_t pxHookFunction ) FREERTOS_SYSTEM_CALL; + +__asm void MPU_vTaskSetApplicationTaskTag( TaskHandle_t xTask, + TaskHookFunction_t pxHookFunction ) /* FREERTOS_SYSTEM_CALL */ +{ + PRESERVE8 + extern MPU_vTaskSetApplicationTaskTagImpl + + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vTaskSetApplicationTaskTag_Unpriv +MPU_vTaskSetApplicationTaskTag_Priv + pop {r0} + b MPU_vTaskSetApplicationTaskTagImpl +MPU_vTaskSetApplicationTaskTag_Unpriv + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskSetApplicationTaskTagImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +} + +#endif /* if ( configUSE_APPLICATION_TASK_TAG == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_APPLICATION_TASK_TAG == 1 ) + +TaskHookFunction_t MPU_xTaskGetApplicationTaskTag( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL; + +__asm TaskHookFunction_t MPU_xTaskGetApplicationTaskTag( TaskHandle_t xTask ) /* FREERTOS_SYSTEM_CALL */ +{ + PRESERVE8 + extern MPU_xTaskGetApplicationTaskTagImpl + + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskGetApplicationTaskTag_Unpriv +MPU_xTaskGetApplicationTaskTag_Priv + pop {r0} + b MPU_xTaskGetApplicationTaskTagImpl +MPU_xTaskGetApplicationTaskTag_Unpriv + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskGetApplicationTaskTagImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +} + +#endif /* if ( configUSE_APPLICATION_TASK_TAG == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) + +void MPU_vTaskSetThreadLocalStoragePointer( TaskHandle_t xTaskToSet, + BaseType_t xIndex, + void * pvValue ) FREERTOS_SYSTEM_CALL; + +__asm void MPU_vTaskSetThreadLocalStoragePointer( TaskHandle_t xTaskToSet, + BaseType_t xIndex, + void * pvValue ) /* FREERTOS_SYSTEM_CALL */ +{ + PRESERVE8 + extern MPU_vTaskSetThreadLocalStoragePointerImpl + + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vTaskSetThreadLocalStoragePointer_Unpriv +MPU_vTaskSetThreadLocalStoragePointer_Priv + pop {r0} + b MPU_vTaskSetThreadLocalStoragePointerImpl +MPU_vTaskSetThreadLocalStoragePointer_Unpriv + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskSetThreadLocalStoragePointerImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +} + +#endif /* if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) + +void * MPU_pvTaskGetThreadLocalStoragePointer( TaskHandle_t xTaskToQuery, + BaseType_t xIndex ) FREERTOS_SYSTEM_CALL; + +__asm void * MPU_pvTaskGetThreadLocalStoragePointer( TaskHandle_t xTaskToQuery, + BaseType_t xIndex ) /* FREERTOS_SYSTEM_CALL */ +{ + PRESERVE8 + extern MPU_pvTaskGetThreadLocalStoragePointerImpl + + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_pvTaskGetThreadLocalStoragePointer_Unpriv +MPU_pvTaskGetThreadLocalStoragePointer_Priv + pop {r0} + b MPU_pvTaskGetThreadLocalStoragePointerImpl +MPU_pvTaskGetThreadLocalStoragePointer_Unpriv + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_pvTaskGetThreadLocalStoragePointerImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +} + +#endif /* if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + +UBaseType_t MPU_uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray, + const UBaseType_t uxArraySize, + configRUN_TIME_COUNTER_TYPE * const pulTotalRunTime ) FREERTOS_SYSTEM_CALL; + +__asm UBaseType_t MPU_uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray, + const UBaseType_t uxArraySize, + configRUN_TIME_COUNTER_TYPE * const pulTotalRunTime ) /* FREERTOS_SYSTEM_CALL */ +{ + PRESERVE8 + extern MPU_uxTaskGetSystemStateImpl + + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_uxTaskGetSystemState_Unpriv +MPU_uxTaskGetSystemState_Priv + pop {r0} + b MPU_uxTaskGetSystemStateImpl +MPU_uxTaskGetSystemState_Unpriv + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxTaskGetSystemStateImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +} + +#endif /* if ( configUSE_TRACE_FACILITY == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) + +UBaseType_t MPU_uxTaskGetStackHighWaterMark( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL; + +__asm UBaseType_t MPU_uxTaskGetStackHighWaterMark( TaskHandle_t xTask ) /* FREERTOS_SYSTEM_CALL */ +{ + PRESERVE8 + extern MPU_uxTaskGetStackHighWaterMarkImpl + + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_uxTaskGetStackHighWaterMark_Unpriv +MPU_uxTaskGetStackHighWaterMark_Priv + pop {r0} + b MPU_uxTaskGetStackHighWaterMarkImpl +MPU_uxTaskGetStackHighWaterMark_Unpriv + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxTaskGetStackHighWaterMarkImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +} + +#endif /* if ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) + +configSTACK_DEPTH_TYPE MPU_uxTaskGetStackHighWaterMark2( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL; + +__asm configSTACK_DEPTH_TYPE MPU_uxTaskGetStackHighWaterMark2( TaskHandle_t xTask ) /* FREERTOS_SYSTEM_CALL */ +{ + PRESERVE8 + extern MPU_uxTaskGetStackHighWaterMark2Impl + + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_uxTaskGetStackHighWaterMark2_Unpriv +MPU_uxTaskGetStackHighWaterMark2_Priv + pop {r0} + b MPU_uxTaskGetStackHighWaterMark2Impl +MPU_uxTaskGetStackHighWaterMark2_Unpriv + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxTaskGetStackHighWaterMark2Impl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +} + +#endif /* if ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) ) + +TaskHandle_t MPU_xTaskGetCurrentTaskHandle( void ) FREERTOS_SYSTEM_CALL; + +__asm TaskHandle_t MPU_xTaskGetCurrentTaskHandle( void ) /* FREERTOS_SYSTEM_CALL */ +{ + PRESERVE8 + extern MPU_xTaskGetCurrentTaskHandleImpl + + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskGetCurrentTaskHandle_Unpriv +MPU_xTaskGetCurrentTaskHandle_Priv + pop {r0} + b MPU_xTaskGetCurrentTaskHandleImpl +MPU_xTaskGetCurrentTaskHandle_Unpriv + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskGetCurrentTaskHandleImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +} + +#endif /* if ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_xTaskGetSchedulerState == 1 ) + +BaseType_t MPU_xTaskGetSchedulerState( void ) FREERTOS_SYSTEM_CALL; + +__asm BaseType_t MPU_xTaskGetSchedulerState( void ) /* FREERTOS_SYSTEM_CALL */ +{ + PRESERVE8 + extern MPU_xTaskGetSchedulerStateImpl + + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskGetSchedulerState_Unpriv +MPU_xTaskGetSchedulerState_Priv + pop {r0} + b MPU_xTaskGetSchedulerStateImpl +MPU_xTaskGetSchedulerState_Unpriv + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskGetSchedulerStateImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +} + +#endif /* if ( INCLUDE_xTaskGetSchedulerState == 1 ) */ +/*-----------------------------------------------------------*/ + +void MPU_vTaskSetTimeOutState( TimeOut_t * const pxTimeOut ) FREERTOS_SYSTEM_CALL; + +__asm void MPU_vTaskSetTimeOutState( TimeOut_t * const pxTimeOut ) /* FREERTOS_SYSTEM_CALL */ +{ + PRESERVE8 + extern MPU_vTaskSetTimeOutStateImpl + + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vTaskSetTimeOutState_Unpriv +MPU_vTaskSetTimeOutState_Priv + pop {r0} + b MPU_vTaskSetTimeOutStateImpl +MPU_vTaskSetTimeOutState_Unpriv + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTaskSetTimeOutStateImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut, + TickType_t * const pxTicksToWait ) FREERTOS_SYSTEM_CALL; + +__asm BaseType_t MPU_xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut, + TickType_t * const pxTicksToWait ) /* FREERTOS_SYSTEM_CALL */ +{ + PRESERVE8 + extern MPU_xTaskCheckForTimeOutImpl + + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskCheckForTimeOut_Unpriv +MPU_xTaskCheckForTimeOut_Priv + pop {r0} + b MPU_xTaskCheckForTimeOutImpl +MPU_xTaskCheckForTimeOut_Unpriv + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskCheckForTimeOutImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +} +/*-----------------------------------------------------------*/ + +#if ( configUSE_TASK_NOTIFICATIONS == 1 ) + +BaseType_t MPU_xTaskGenericNotify( TaskHandle_t xTaskToNotify, + UBaseType_t uxIndexToNotify, + uint32_t ulValue, + eNotifyAction eAction, + uint32_t * pulPreviousNotificationValue ) FREERTOS_SYSTEM_CALL; + +__asm BaseType_t MPU_xTaskGenericNotify( TaskHandle_t xTaskToNotify, + UBaseType_t uxIndexToNotify, + uint32_t ulValue, + eNotifyAction eAction, + uint32_t * pulPreviousNotificationValue ) /* FREERTOS_SYSTEM_CALL */ +{ + PRESERVE8 + extern MPU_xTaskGenericNotifyImpl + + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskGenericNotify_Unpriv +MPU_xTaskGenericNotify_Priv + pop {r0} + b MPU_xTaskGenericNotifyImpl +MPU_xTaskGenericNotify_Unpriv + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER_1 + bl MPU_xTaskGenericNotifyImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +} + +#endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TASK_NOTIFICATIONS == 1 ) + +BaseType_t MPU_xTaskGenericNotifyWait( UBaseType_t uxIndexToWaitOn, + uint32_t ulBitsToClearOnEntry, + uint32_t ulBitsToClearOnExit, + uint32_t * pulNotificationValue, + TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; + +__asm BaseType_t MPU_xTaskGenericNotifyWait( UBaseType_t uxIndexToWaitOn, + uint32_t ulBitsToClearOnEntry, + uint32_t ulBitsToClearOnExit, + uint32_t * pulNotificationValue, + TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */ +{ + PRESERVE8 + extern MPU_xTaskGenericNotifyWaitImpl + + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskGenericNotifyWait_Unpriv +MPU_xTaskGenericNotifyWait_Priv + pop {r0} + b MPU_xTaskGenericNotifyWaitImpl +MPU_xTaskGenericNotifyWait_Unpriv + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER_1 + bl MPU_xTaskGenericNotifyWaitImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +} + +#endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TASK_NOTIFICATIONS == 1 ) + +uint32_t MPU_ulTaskGenericNotifyTake( UBaseType_t uxIndexToWaitOn, + BaseType_t xClearCountOnExit, + TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; + +__asm uint32_t MPU_ulTaskGenericNotifyTake( UBaseType_t uxIndexToWaitOn, + BaseType_t xClearCountOnExit, + TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */ +{ + PRESERVE8 + extern MPU_ulTaskGenericNotifyTakeImpl + + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_ulTaskGenericNotifyTake_Unpriv +MPU_ulTaskGenericNotifyTake_Priv + pop {r0} + b MPU_ulTaskGenericNotifyTakeImpl +MPU_ulTaskGenericNotifyTake_Unpriv + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_ulTaskGenericNotifyTakeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +} + +#endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TASK_NOTIFICATIONS == 1 ) + +BaseType_t MPU_xTaskGenericNotifyStateClear( TaskHandle_t xTask, + UBaseType_t uxIndexToClear ) FREERTOS_SYSTEM_CALL; + +__asm BaseType_t MPU_xTaskGenericNotifyStateClear( TaskHandle_t xTask, + UBaseType_t uxIndexToClear ) /* FREERTOS_SYSTEM_CALL */ +{ + PRESERVE8 + extern MPU_xTaskGenericNotifyStateClearImpl + + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTaskGenericNotifyStateClear_Unpriv +MPU_xTaskGenericNotifyStateClear_Priv + pop {r0} + b MPU_xTaskGenericNotifyStateClearImpl +MPU_xTaskGenericNotifyStateClear_Unpriv + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTaskGenericNotifyStateClearImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +} + +#endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TASK_NOTIFICATIONS == 1 ) + +uint32_t MPU_ulTaskGenericNotifyValueClear( TaskHandle_t xTask, + UBaseType_t uxIndexToClear, + uint32_t ulBitsToClear ) FREERTOS_SYSTEM_CALL; + +__asm uint32_t MPU_ulTaskGenericNotifyValueClear( TaskHandle_t xTask, + UBaseType_t uxIndexToClear, + uint32_t ulBitsToClear ) /* FREERTOS_SYSTEM_CALL */ +{ + PRESERVE8 + extern MPU_ulTaskGenericNotifyValueClearImpl + + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_ulTaskGenericNotifyValueClear_Unpriv +MPU_ulTaskGenericNotifyValueClear_Priv + pop {r0} + b MPU_ulTaskGenericNotifyValueClearImpl +MPU_ulTaskGenericNotifyValueClear_Unpriv + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_ulTaskGenericNotifyValueClearImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +} + +#endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xQueueGenericSend( QueueHandle_t xQueue, + const void * const pvItemToQueue, + TickType_t xTicksToWait, + const BaseType_t xCopyPosition ) FREERTOS_SYSTEM_CALL; + +__asm BaseType_t MPU_xQueueGenericSend( QueueHandle_t xQueue, + const void * const pvItemToQueue, + TickType_t xTicksToWait, + const BaseType_t xCopyPosition ) /* FREERTOS_SYSTEM_CALL */ +{ + PRESERVE8 + extern MPU_xQueueGenericSendImpl + + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xQueueGenericSend_Unpriv +MPU_xQueueGenericSend_Priv + pop {r0} + b MPU_xQueueGenericSendImpl +MPU_xQueueGenericSend_Unpriv + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueGenericSendImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +} +/*-----------------------------------------------------------*/ + +UBaseType_t MPU_uxQueueMessagesWaiting( const QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL; + +__asm UBaseType_t MPU_uxQueueMessagesWaiting( const QueueHandle_t xQueue ) /* FREERTOS_SYSTEM_CALL */ +{ + PRESERVE8 + extern MPU_uxQueueMessagesWaitingImpl + + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_uxQueueMessagesWaiting_Unpriv +MPU_uxQueueMessagesWaiting_Priv + pop {r0} + b MPU_uxQueueMessagesWaitingImpl +MPU_uxQueueMessagesWaiting_Unpriv + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxQueueMessagesWaitingImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +} +/*-----------------------------------------------------------*/ + +UBaseType_t MPU_uxQueueSpacesAvailable( const QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL; + +__asm UBaseType_t MPU_uxQueueSpacesAvailable( const QueueHandle_t xQueue ) /* FREERTOS_SYSTEM_CALL */ +{ + PRESERVE8 + extern MPU_uxQueueSpacesAvailableImpl + + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_uxQueueSpacesAvailable_Unpriv +MPU_uxQueueSpacesAvailable_Priv + pop {r0} + b MPU_uxQueueSpacesAvailableImpl +MPU_uxQueueSpacesAvailable_Unpriv + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxQueueSpacesAvailableImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xQueueReceive( QueueHandle_t xQueue, + void * const pvBuffer, + TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; + +__asm BaseType_t MPU_xQueueReceive( QueueHandle_t xQueue, + void * const pvBuffer, + TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */ +{ + PRESERVE8 + extern MPU_xQueueReceiveImpl + + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xQueueReceive_Unpriv +MPU_xQueueReceive_Priv + pop {r0} + b MPU_xQueueReceiveImpl +MPU_xQueueReceive_Unpriv + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueReceiveImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xQueuePeek( QueueHandle_t xQueue, + void * const pvBuffer, + TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; + +__asm BaseType_t MPU_xQueuePeek( QueueHandle_t xQueue, + void * const pvBuffer, + TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */ +{ + PRESERVE8 + extern MPU_xQueuePeekImpl + + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xQueuePeek_Unpriv +MPU_xQueuePeek_Priv + pop {r0} + b MPU_xQueuePeekImpl +MPU_xQueuePeek_Unpriv + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueuePeekImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xQueueSemaphoreTake( QueueHandle_t xQueue, + TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; + +__asm BaseType_t MPU_xQueueSemaphoreTake( QueueHandle_t xQueue, + TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */ +{ + PRESERVE8 + extern MPU_xQueueSemaphoreTakeImpl + + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xQueueSemaphoreTake_Unpriv +MPU_xQueueSemaphoreTake_Priv + pop {r0} + b MPU_xQueueSemaphoreTakeImpl +MPU_xQueueSemaphoreTake_Unpriv + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueSemaphoreTakeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +} +/*-----------------------------------------------------------*/ + +#if ( ( configUSE_MUTEXES == 1 ) && ( INCLUDE_xSemaphoreGetMutexHolder == 1 ) ) + +TaskHandle_t MPU_xQueueGetMutexHolder( QueueHandle_t xSemaphore ) FREERTOS_SYSTEM_CALL; + +__asm TaskHandle_t MPU_xQueueGetMutexHolder( QueueHandle_t xSemaphore ) /* FREERTOS_SYSTEM_CALL */ +{ + PRESERVE8 + extern MPU_xQueueGetMutexHolderImpl + + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xQueueGetMutexHolder_Unpriv +MPU_xQueueGetMutexHolder_Priv + pop {r0} + b MPU_xQueueGetMutexHolderImpl +MPU_xQueueGetMutexHolder_Unpriv + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueGetMutexHolderImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +} + +#endif /* if ( ( configUSE_MUTEXES == 1 ) && ( INCLUDE_xSemaphoreGetMutexHolder == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_RECURSIVE_MUTEXES == 1 ) + +BaseType_t MPU_xQueueTakeMutexRecursive( QueueHandle_t xMutex, + TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; + +__asm BaseType_t MPU_xQueueTakeMutexRecursive( QueueHandle_t xMutex, + TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */ +{ + PRESERVE8 + extern MPU_xQueueTakeMutexRecursiveImpl + + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xQueueTakeMutexRecursive_Unpriv +MPU_xQueueTakeMutexRecursive_Priv + pop {r0} + b MPU_xQueueTakeMutexRecursiveImpl +MPU_xQueueTakeMutexRecursive_Unpriv + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueTakeMutexRecursiveImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +} + +#endif /* if ( configUSE_RECURSIVE_MUTEXES == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_RECURSIVE_MUTEXES == 1 ) + +BaseType_t MPU_xQueueGiveMutexRecursive( QueueHandle_t pxMutex ) FREERTOS_SYSTEM_CALL; + +__asm BaseType_t MPU_xQueueGiveMutexRecursive( QueueHandle_t pxMutex ) /* FREERTOS_SYSTEM_CALL */ +{ + PRESERVE8 + extern MPU_xQueueGiveMutexRecursiveImpl + + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xQueueGiveMutexRecursive_Unpriv +MPU_xQueueGiveMutexRecursive_Priv + pop {r0} + b MPU_xQueueGiveMutexRecursiveImpl +MPU_xQueueGiveMutexRecursive_Unpriv + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueGiveMutexRecursiveImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +} + +#endif /* if ( configUSE_RECURSIVE_MUTEXES == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_QUEUE_SETS == 1 ) + +QueueSetMemberHandle_t MPU_xQueueSelectFromSet( QueueSetHandle_t xQueueSet, + const TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; + +__asm QueueSetMemberHandle_t MPU_xQueueSelectFromSet( QueueSetHandle_t xQueueSet, + const TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */ +{ + PRESERVE8 + extern MPU_xQueueSelectFromSetImpl + + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xQueueSelectFromSet_Unpriv +MPU_xQueueSelectFromSet_Priv + pop {r0} + b MPU_xQueueSelectFromSetImpl +MPU_xQueueSelectFromSet_Unpriv + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueSelectFromSetImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +} + +#endif /* if ( configUSE_QUEUE_SETS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_QUEUE_SETS == 1 ) + +BaseType_t MPU_xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore, + QueueSetHandle_t xQueueSet ) FREERTOS_SYSTEM_CALL; + +__asm BaseType_t MPU_xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore, + QueueSetHandle_t xQueueSet ) /* FREERTOS_SYSTEM_CALL */ +{ + PRESERVE8 + extern MPU_xQueueAddToSetImpl + + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xQueueAddToSet_Unpriv +MPU_xQueueAddToSet_Priv + pop {r0} + b MPU_xQueueAddToSetImpl +MPU_xQueueAddToSet_Unpriv + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xQueueAddToSetImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +} + +#endif /* if ( configUSE_QUEUE_SETS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configQUEUE_REGISTRY_SIZE > 0 ) + +void MPU_vQueueAddToRegistry( QueueHandle_t xQueue, + const char * pcName ) FREERTOS_SYSTEM_CALL; + +__asm void MPU_vQueueAddToRegistry( QueueHandle_t xQueue, + const char * pcName ) /* FREERTOS_SYSTEM_CALL */ +{ + PRESERVE8 + extern MPU_vQueueAddToRegistryImpl + + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vQueueAddToRegistry_Unpriv +MPU_vQueueAddToRegistry_Priv + pop {r0} + b MPU_vQueueAddToRegistryImpl +MPU_vQueueAddToRegistry_Unpriv + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vQueueAddToRegistryImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +} + +#endif /* if ( configQUEUE_REGISTRY_SIZE > 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configQUEUE_REGISTRY_SIZE > 0 ) + +void MPU_vQueueUnregisterQueue( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL; + +__asm void MPU_vQueueUnregisterQueue( QueueHandle_t xQueue ) /* FREERTOS_SYSTEM_CALL */ +{ + PRESERVE8 + extern MPU_vQueueUnregisterQueueImpl + + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vQueueUnregisterQueue_Unpriv +MPU_vQueueUnregisterQueue_Priv + pop {r0} + b MPU_vQueueUnregisterQueueImpl +MPU_vQueueUnregisterQueue_Unpriv + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vQueueUnregisterQueueImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +} + +#endif /* if ( configQUEUE_REGISTRY_SIZE > 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configQUEUE_REGISTRY_SIZE > 0 ) + +const char * MPU_pcQueueGetName( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL; + +__asm const char * MPU_pcQueueGetName( QueueHandle_t xQueue ) /* FREERTOS_SYSTEM_CALL */ +{ + PRESERVE8 + extern MPU_pcQueueGetNameImpl + + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_pcQueueGetName_Unpriv +MPU_pcQueueGetName_Priv + pop {r0} + b MPU_pcQueueGetNameImpl +MPU_pcQueueGetName_Unpriv + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_pcQueueGetNameImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +} + +#endif /* if ( configQUEUE_REGISTRY_SIZE > 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +void * MPU_pvTimerGetTimerID( const TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL; + +__asm void * MPU_pvTimerGetTimerID( const TimerHandle_t xTimer ) /* FREERTOS_SYSTEM_CALL */ +{ + PRESERVE8 + extern MPU_pvTimerGetTimerIDImpl + + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_pvTimerGetTimerID_Unpriv +MPU_pvTimerGetTimerID_Priv + pop {r0} + b MPU_pvTimerGetTimerIDImpl +MPU_pvTimerGetTimerID_Unpriv + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_pvTimerGetTimerIDImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +void MPU_vTimerSetTimerID( TimerHandle_t xTimer, + void * pvNewID ) FREERTOS_SYSTEM_CALL; + +__asm void MPU_vTimerSetTimerID( TimerHandle_t xTimer, + void * pvNewID ) /* FREERTOS_SYSTEM_CALL */ +{ + PRESERVE8 + extern MPU_vTimerSetTimerIDImpl + + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vTimerSetTimerID_Unpriv +MPU_vTimerSetTimerID_Priv + pop {r0} + b MPU_vTimerSetTimerIDImpl +MPU_vTimerSetTimerID_Unpriv + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTimerSetTimerIDImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +BaseType_t MPU_xTimerIsTimerActive( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL; + +__asm BaseType_t MPU_xTimerIsTimerActive( TimerHandle_t xTimer ) /* FREERTOS_SYSTEM_CALL */ +{ + PRESERVE8 + extern MPU_xTimerIsTimerActiveImpl + + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTimerIsTimerActive_Unpriv +MPU_xTimerIsTimerActive_Priv + pop {r0} + b MPU_xTimerIsTimerActiveImpl +MPU_xTimerIsTimerActive_Unpriv + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTimerIsTimerActiveImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +TaskHandle_t MPU_xTimerGetTimerDaemonTaskHandle( void ) FREERTOS_SYSTEM_CALL; + +__asm TaskHandle_t MPU_xTimerGetTimerDaemonTaskHandle( void ) /* FREERTOS_SYSTEM_CALL */ +{ + PRESERVE8 + extern MPU_xTimerGetTimerDaemonTaskHandleImpl + + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTimerGetTimerDaemonTaskHandle_Unpriv +MPU_xTimerGetTimerDaemonTaskHandle_Priv + pop {r0} + b MPU_xTimerGetTimerDaemonTaskHandleImpl +MPU_xTimerGetTimerDaemonTaskHandle_Unpriv + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTimerGetTimerDaemonTaskHandleImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +BaseType_t MPU_xTimerGenericCommand( TimerHandle_t xTimer, + const BaseType_t xCommandID, + const TickType_t xOptionalValue, + BaseType_t * const pxHigherPriorityTaskWoken, + const TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; + +__asm BaseType_t MPU_xTimerGenericCommand( TimerHandle_t xTimer, + const BaseType_t xCommandID, + const TickType_t xOptionalValue, + BaseType_t * const pxHigherPriorityTaskWoken, + const TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */ +{ + PRESERVE8 + extern MPU_xTimerGenericCommandImpl + + push {r0} + mrs r0, ipsr + cmp r0, #0 + bne MPU_xTimerGenericCommand_Priv + mrs r0, control + tst r0, #1 + beq MPU_xTimerGenericCommand_Priv +MPU_xTimerGenericCommand_Unpriv + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER_1 + bl MPU_xTimerGenericCommandImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +MPU_xTimerGenericCommand_Priv + pop {r0} + b MPU_xTimerGenericCommandImpl +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +const char * MPU_pcTimerGetName( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL; + +__asm const char * MPU_pcTimerGetName( TimerHandle_t xTimer ) /* FREERTOS_SYSTEM_CALL */ +{ + PRESERVE8 + extern MPU_pcTimerGetNameImpl + + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_pcTimerGetName_Unpriv +MPU_pcTimerGetName_Priv + pop {r0} + b MPU_pcTimerGetNameImpl +MPU_pcTimerGetName_Unpriv + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_pcTimerGetNameImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, + const BaseType_t uxAutoReload ) FREERTOS_SYSTEM_CALL; + +__asm void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, + const BaseType_t uxAutoReload ) /* FREERTOS_SYSTEM_CALL */ +{ + PRESERVE8 + extern MPU_vTimerSetReloadModeImpl + + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vTimerSetReloadMode_Unpriv +MPU_vTimerSetReloadMode_Priv + pop {r0} + b MPU_vTimerSetReloadModeImpl +MPU_vTimerSetReloadMode_Unpriv + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vTimerSetReloadModeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +BaseType_t MPU_xTimerGetReloadMode( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL; + +__asm BaseType_t MPU_xTimerGetReloadMode( TimerHandle_t xTimer ) /* FREERTOS_SYSTEM_CALL */ +{ + PRESERVE8 + extern MPU_xTimerGetReloadModeImpl + + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTimerGetReloadMode_Unpriv +MPU_xTimerGetReloadMode_Priv + pop {r0} + b MPU_xTimerGetReloadModeImpl +MPU_xTimerGetReloadMode_Unpriv + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTimerGetReloadModeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +UBaseType_t MPU_uxTimerGetReloadMode( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL; + +__asm UBaseType_t MPU_uxTimerGetReloadMode( TimerHandle_t xTimer ) /* FREERTOS_SYSTEM_CALL */ +{ + PRESERVE8 + extern MPU_uxTimerGetReloadModeImpl + + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_uxTimerGetReloadMode_Unpriv +MPU_uxTimerGetReloadMode_Priv + pop {r0} + b MPU_uxTimerGetReloadModeImpl +MPU_uxTimerGetReloadMode_Unpriv + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxTimerGetReloadModeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +TickType_t MPU_xTimerGetPeriod( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL; + +__asm TickType_t MPU_xTimerGetPeriod( TimerHandle_t xTimer ) /* FREERTOS_SYSTEM_CALL */ +{ + PRESERVE8 + extern MPU_xTimerGetPeriodImpl + + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTimerGetPeriod_Unpriv +MPU_xTimerGetPeriod_Priv + pop {r0} + b MPU_xTimerGetPeriodImpl +MPU_xTimerGetPeriod_Unpriv + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTimerGetPeriodImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + +TickType_t MPU_xTimerGetExpiryTime( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL; + +__asm TickType_t MPU_xTimerGetExpiryTime( TimerHandle_t xTimer ) /* FREERTOS_SYSTEM_CALL */ +{ + PRESERVE8 + extern MPU_xTimerGetExpiryTimeImpl + + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xTimerGetExpiryTime_Unpriv +MPU_xTimerGetExpiryTime_Priv + pop {r0} + b MPU_xTimerGetExpiryTimeImpl +MPU_xTimerGetExpiryTime_Unpriv + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xTimerGetExpiryTimeImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +} + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +EventBits_t MPU_xEventGroupWaitBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToWaitFor, + const BaseType_t xClearOnExit, + const BaseType_t xWaitForAllBits, + TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; + +__asm EventBits_t MPU_xEventGroupWaitBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToWaitFor, + const BaseType_t xClearOnExit, + const BaseType_t xWaitForAllBits, + TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */ +{ + PRESERVE8 + extern MPU_xEventGroupWaitBitsImpl + + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xEventGroupWaitBits_Unpriv +MPU_xEventGroupWaitBits_Priv + pop {r0} + b MPU_xEventGroupWaitBitsImpl +MPU_xEventGroupWaitBits_Unpriv + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER_1 + bl MPU_xEventGroupWaitBitsImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +} +/*-----------------------------------------------------------*/ + +EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToClear ) FREERTOS_SYSTEM_CALL; + +__asm EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToClear ) /* FREERTOS_SYSTEM_CALL */ +{ + PRESERVE8 + extern MPU_xEventGroupClearBitsImpl + + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xEventGroupClearBits_Unpriv +MPU_xEventGroupClearBits_Priv + pop {r0} + b MPU_xEventGroupClearBitsImpl +MPU_xEventGroupClearBits_Unpriv + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xEventGroupClearBitsImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +} +/*-----------------------------------------------------------*/ + +EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet ) FREERTOS_SYSTEM_CALL; + +__asm EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet ) /* FREERTOS_SYSTEM_CALL */ +{ + PRESERVE8 + extern MPU_xEventGroupSetBitsImpl + + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xEventGroupSetBits_Unpriv +MPU_xEventGroupSetBits_Priv + pop {r0} + b MPU_xEventGroupSetBitsImpl +MPU_xEventGroupSetBits_Unpriv + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xEventGroupSetBitsImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +} +/*-----------------------------------------------------------*/ + +EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet, + const EventBits_t uxBitsToWaitFor, + TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; + +__asm EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet, + const EventBits_t uxBitsToWaitFor, + TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */ +{ + PRESERVE8 + extern MPU_xEventGroupSyncImpl + + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xEventGroupSync_Unpriv +MPU_xEventGroupSync_Priv + pop {r0} + b MPU_xEventGroupSyncImpl +MPU_xEventGroupSync_Unpriv + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xEventGroupSyncImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +} +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + +UBaseType_t MPU_uxEventGroupGetNumber( void * xEventGroup ) FREERTOS_SYSTEM_CALL; + +__asm UBaseType_t MPU_uxEventGroupGetNumber( void * xEventGroup ) /* FREERTOS_SYSTEM_CALL */ +{ + PRESERVE8 + extern MPU_uxEventGroupGetNumberImpl + + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_uxEventGroupGetNumber_Unpriv +MPU_uxEventGroupGetNumber_Priv + pop {r0} + b MPU_uxEventGroupGetNumberImpl +MPU_uxEventGroupGetNumber_Unpriv + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_uxEventGroupGetNumberImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +} + +#endif /*( configUSE_TRACE_FACILITY == 1 )*/ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + +void MPU_vEventGroupSetNumber( void * xEventGroup, + UBaseType_t uxEventGroupNumber ) FREERTOS_SYSTEM_CALL; + +__asm void MPU_vEventGroupSetNumber( void * xEventGroup, + UBaseType_t uxEventGroupNumber ) /* FREERTOS_SYSTEM_CALL */ +{ + PRESERVE8 + extern MPU_vEventGroupSetNumberImpl + + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_vEventGroupSetNumber_Unpriv +MPU_vEventGroupSetNumber_Priv + pop {r0} + b MPU_vEventGroupSetNumberImpl +MPU_vEventGroupSetNumber_Unpriv + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_vEventGroupSetNumberImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +} + +#endif /*( configUSE_TRACE_FACILITY == 1 )*/ +/*-----------------------------------------------------------*/ + +size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, + const void * pvTxData, + size_t xDataLengthBytes, + TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; + +__asm size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, + const void * pvTxData, + size_t xDataLengthBytes, + TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */ +{ + PRESERVE8 + extern MPU_xStreamBufferSendImpl + + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xStreamBufferSend_Unpriv +MPU_xStreamBufferSend_Priv + pop {r0} + b MPU_xStreamBufferSendImpl +MPU_xStreamBufferSend_Unpriv + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferSendImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +} +/*-----------------------------------------------------------*/ + +size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, + void * pvRxData, + size_t xBufferLengthBytes, + TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; + +__asm size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, + void * pvRxData, + size_t xBufferLengthBytes, + TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */ +{ + PRESERVE8 + extern MPU_xStreamBufferReceiveImpl + + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xStreamBufferReceive_Unpriv +MPU_xStreamBufferReceive_Priv + pop {r0} + b MPU_xStreamBufferReceiveImpl +MPU_xStreamBufferReceive_Unpriv + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferReceiveImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL; + +__asm BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) /* FREERTOS_SYSTEM_CALL */ +{ + PRESERVE8 + extern MPU_xStreamBufferIsFullImpl + + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xStreamBufferIsFull_Unpriv +MPU_xStreamBufferIsFull_Priv + pop {r0} + b MPU_xStreamBufferIsFullImpl +MPU_xStreamBufferIsFull_Unpriv + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferIsFullImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL; + +__asm BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) /* FREERTOS_SYSTEM_CALL */ +{ + PRESERVE8 + extern MPU_xStreamBufferIsEmptyImpl + + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xStreamBufferIsEmpty_Unpriv +MPU_xStreamBufferIsEmpty_Priv + pop {r0} + b MPU_xStreamBufferIsEmptyImpl +MPU_xStreamBufferIsEmpty_Unpriv + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferIsEmptyImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +} +/*-----------------------------------------------------------*/ + +size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL; + +__asm size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) /* FREERTOS_SYSTEM_CALL */ +{ + PRESERVE8 + extern MPU_xStreamBufferSpacesAvailableImpl + + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xStreamBufferSpacesAvailable_Unpriv +MPU_xStreamBufferSpacesAvailable_Priv + pop {r0} + b MPU_xStreamBufferSpacesAvailableImpl +MPU_xStreamBufferSpacesAvailable_Unpriv + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferSpacesAvailableImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +} +/*-----------------------------------------------------------*/ + +size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL; + +__asm size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) /* FREERTOS_SYSTEM_CALL */ +{ + PRESERVE8 + extern MPU_xStreamBufferBytesAvailableImpl + + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xStreamBufferBytesAvailable_Unpriv +MPU_xStreamBufferBytesAvailable_Priv + pop {r0} + b MPU_xStreamBufferBytesAvailableImpl +MPU_xStreamBufferBytesAvailable_Unpriv + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferBytesAvailableImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, + size_t xTriggerLevel ) FREERTOS_SYSTEM_CALL; + +__asm BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, + size_t xTriggerLevel ) /* FREERTOS_SYSTEM_CALL */ +{ + PRESERVE8 + extern MPU_xStreamBufferSetTriggerLevelImpl + + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xStreamBufferSetTriggerLevel_Unpriv +MPU_xStreamBufferSetTriggerLevel_Priv + pop {r0} + b MPU_xStreamBufferSetTriggerLevelImpl +MPU_xStreamBufferSetTriggerLevel_Unpriv + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferSetTriggerLevelImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +} +/*-----------------------------------------------------------*/ + +size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL; + +__asm size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) /* FREERTOS_SYSTEM_CALL */ +{ + PRESERVE8 + extern MPU_xStreamBufferNextMessageLengthBytesImpl + + push {r0} + mrs r0, control + tst r0, #1 + bne MPU_xStreamBufferNextMessageLengthBytes_Unpriv +MPU_xStreamBufferNextMessageLengthBytes_Priv + pop {r0} + b MPU_xStreamBufferNextMessageLengthBytesImpl +MPU_xStreamBufferNextMessageLengthBytes_Unpriv + pop {r0} + svc #portSVC_SYSTEM_CALL_ENTER + bl MPU_xStreamBufferNextMessageLengthBytesImpl + svc #portSVC_SYSTEM_CALL_EXIT + bx lr +} +/*-----------------------------------------------------------*/ + +#endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ diff --git a/portable/RVDS/ARM_CM4_MPU/port.c b/portable/RVDS/ARM_CM4_MPU/port.c index 13e2f8a8ed1..7bcf6bc8813 100755 --- a/portable/RVDS/ARM_CM4_MPU/port.c +++ b/portable/RVDS/ARM_CM4_MPU/port.c @@ -108,13 +108,34 @@ #define portPRIORITY_GROUP_MASK ( 0x07UL << 8UL ) #define portPRIGROUP_SHIFT ( 8UL ) +/* Constants used during system call enter and exit. */ +#define portPSR_STACK_PADDING_MASK ( 1UL << 9UL ) +#define portEXC_RETURN_STACK_FRAME_TYPE_MASK ( 1UL << 4UL ) + /* Offsets in the stack to the parameters when inside the SVC handler. */ +#define portOFFSET_TO_LR ( 5 ) #define portOFFSET_TO_PC ( 6 ) +#define portOFFSET_TO_PSR ( 7 ) /* For strict compliance with the Cortex-M spec the task start address should * have bit-0 clear, as it is loaded into the PC on exit from an ISR. */ #define portSTART_ADDRESS_MASK ( ( StackType_t ) 0xfffffffeUL ) +/* Does addr lie within [start, end] address range? */ +#define portIS_ADDRESS_WITHIN_RANGE( addr, start, end ) \ + ( ( ( addr ) >= ( start ) ) && ( ( addr ) <= ( end ) ) ) + +/* Is the access request satisfied by the available permissions? */ +#define portIS_AUTHORIZED( accessRequest, permissions ) \ + ( ( ( permissions ) & ( accessRequest ) ) == accessRequest ) + +/* 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 ) ) ) +/*-----------------------------------------------------------*/ + /* Each task maintains its own interrupt status in the critical nesting * variable. Note this is not saved as part of the task context as context * switches can only occur when uxCriticalNesting is zero. */ @@ -158,7 +179,7 @@ static void prvRestoreContextOfFirstTask( void ) PRIVILEGED_FUNCTION; * C portion of the SVC handler. The SVC handler is split between an asm entry * and a C wrapper for simplicity of coding and maintenance. */ -void prvSVCHandler( uint32_t * pulRegisters ) __attribute__( ( used ) ) PRIVILEGED_FUNCTION; +void vSVCHandler_C( uint32_t * pulRegisters ) __attribute__( ( used ) ) PRIVILEGED_FUNCTION; /* * Function to enable the VFP. @@ -215,6 +236,61 @@ void vResetPrivilege( void ); #else void vPortExitCritical( void ) PRIVILEGED_FUNCTION; #endif + +/** + * @brief Triggers lazy stacking of FPU registers. + */ +static void prvTriggerLazyStacking( void ) PRIVILEGED_FUNCTION; + +#if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + + /** + * @brief Sets up the system call stack so that upon returning from + * SVC, the system call stack is used. + * + * It is used for the system calls with up to 4 parameters. + * + * @param pulTaskStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + */ + void vSystemCallEnter( uint32_t * pulTaskStack, uint32_t ulLR ) PRIVILEGED_FUNCTION; + +#endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + +#if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + + /** + * @brief Sets up the system call stack so that upon returning from + * SVC, the system call stack is used. + * + * It is used for the system calls with 5 parameters. + * + * @param pulTaskStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + */ + void vSystemCallEnter_1( uint32_t * pulTaskStack, uint32_t ulLR ) PRIVILEGED_FUNCTION; + +#endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + +#if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + + /** + * @brief Sets up the task stack so that upon returning from + * SVC, the task stack is used again. + * + * @param pulSystemCallStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + */ + void vSystemCallExit( uint32_t * pulSystemCallStack, uint32_t ulLR ) PRIVILEGED_FUNCTION; + +#endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + +/** + * @brief Checks whether or not the calling task is privileged. + * + * @return pdTRUE if the calling task is privileged, pdFALSE otherwise. + */ +BaseType_t xPortIsTaskPrivileged( void ) PRIVILEGED_FUNCTION; /*-----------------------------------------------------------*/ /* @@ -223,43 +299,59 @@ void vResetPrivilege( void ); StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, TaskFunction_t pxCode, void * pvParameters, - BaseType_t xRunPrivileged ) + BaseType_t xRunPrivileged, + xMPU_SETTINGS * xMPUSettings ) { - /* Simulate the stack frame as it would be created by a context switch - * interrupt. */ - pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ - *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ - pxTopOfStack--; - *pxTopOfStack = ( ( StackType_t ) pxCode ) & portSTART_ADDRESS_MASK; /* PC */ - pxTopOfStack--; - *pxTopOfStack = 0; /* LR */ - pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ - *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ - - /* A save method is being used that requires each task to maintain its - * own exec return value. */ - pxTopOfStack--; - *pxTopOfStack = portINITIAL_EXC_RETURN; - - pxTopOfStack -= 9; /* R11, R10, R9, R8, R7, R6, R5 and R4. */ - if( xRunPrivileged == pdTRUE ) { - *pxTopOfStack = portINITIAL_CONTROL_IF_PRIVILEGED; + xMPUSettings->ulTaskFlags |= portTASK_IS_PRIVILEGED_FLAG; + xMPUSettings->ulContext[ 0 ] = portINITIAL_CONTROL_IF_PRIVILEGED; } else { - *pxTopOfStack = portINITIAL_CONTROL_IF_UNPRIVILEGED; + xMPUSettings->ulTaskFlags &= ( ~portTASK_IS_PRIVILEGED_FLAG ); + xMPUSettings->ulContext[ 0 ] = portINITIAL_CONTROL_IF_UNPRIVILEGED; + } + xMPUSettings->ulContext[ 1 ] = 0x04040404; /* r4. */ + xMPUSettings->ulContext[ 2 ] = 0x05050505; /* r5. */ + xMPUSettings->ulContext[ 3 ] = 0x06060606; /* r6. */ + xMPUSettings->ulContext[ 4 ] = 0x07070707; /* r7. */ + xMPUSettings->ulContext[ 5 ] = 0x08080808; /* r8. */ + xMPUSettings->ulContext[ 6 ] = 0x09090909; /* r9. */ + xMPUSettings->ulContext[ 7 ] = 0x10101010; /* r10. */ + xMPUSettings->ulContext[ 8 ] = 0x11111111; /* r11. */ + xMPUSettings->ulContext[ 9 ] = portINITIAL_EXC_RETURN; /* EXC_RETURN. */ + + xMPUSettings->ulContext[ 10 ] = ( uint32_t ) ( pxTopOfStack - 8 ); /* PSP with the hardware saved stack. */ + xMPUSettings->ulContext[ 11 ] = ( uint32_t ) pvParameters; /* r0. */ + xMPUSettings->ulContext[ 12 ] = 0x01010101; /* r1. */ + xMPUSettings->ulContext[ 13 ] = 0x02020202; /* r2. */ + xMPUSettings->ulContext[ 14 ] = 0x03030303; /* r3. */ + xMPUSettings->ulContext[ 15 ] = 0x12121212; /* r12. */ + xMPUSettings->ulContext[ 16 ] = 0; /* LR. */ + xMPUSettings->ulContext[ 17 ] = ( ( uint32_t ) pxCode ) & portSTART_ADDRESS_MASK; /* PC. */ + xMPUSettings->ulContext[ 18 ] = portINITIAL_XPSR; /* xPSR. */ + + #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + { + /* Ensure that the system call stack is double word aligned. */ + xMPUSettings->xSystemCallStackInfo.pulSystemCallStack = &( xMPUSettings->xSystemCallStackInfo.ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE - 1 ] ); + xMPUSettings->xSystemCallStackInfo.pulSystemCallStack = ( uint32_t * ) ( ( uint32_t ) ( xMPUSettings->xSystemCallStackInfo.pulSystemCallStack ) & + ( uint32_t ) ( ~( portBYTE_ALIGNMENT_MASK ) ) ); + + /* This is not NULL only for the duration of a system call. */ + xMPUSettings->xSystemCallStackInfo.pulTaskStack = NULL; } + #endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ - return pxTopOfStack; + return &( xMPUSettings->ulContext[ 19 ] ); } /*-----------------------------------------------------------*/ -void prvSVCHandler( uint32_t * pulParam ) +void vSVCHandler_C( uint32_t * pulParam ) { uint8_t ucSVCNumber; - uint32_t ulReg, ulPC; + uint32_t ulPC, ulReg; #if ( configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY == 1 ) extern uint32_t __syscalls_flash_start__; @@ -300,11 +392,11 @@ void prvSVCHandler( uint32_t * pulParam ) { __asm { -/* *INDENT-OFF* */ + /* *INDENT-OFF* */ mrs ulReg, control /* Obtain current control value. */ bic ulReg, # 1 /* Set privilege bit. */ msr control, ulReg /* Write back new control value. */ -/* *INDENT-ON* */ + /* *INDENT-ON* */ } } @@ -313,14 +405,14 @@ void prvSVCHandler( uint32_t * pulParam ) case portSVC_RAISE_PRIVILEGE: __asm { -/* *INDENT-OFF* */ + /* *INDENT-OFF* */ mrs ulReg, control /* Obtain current control value. */ bic ulReg, # 1 /* Set privilege bit. */ msr control, ulReg /* Write back new control value. */ -/* *INDENT-ON* */ + /* *INDENT-ON* */ } break; - #endif /* #if( configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY == 1 ) */ + #endif /* #if( configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY == 1 ) */ default: /* Unknown SVC call. */ break; @@ -328,9 +420,339 @@ void prvSVCHandler( uint32_t * pulParam ) } /*-----------------------------------------------------------*/ +__asm void prvTriggerLazyStacking( void ) /* PRIVILEGED_FUNCTION */ +{ +/* *INDENT-OFF* */ + PRESERVE8 + + vpush {s0} /* Trigger lazy stacking. */ + vpop {s0} /* Nullify the affect of the above instruction. */ + +/* *INDENT-ON* */ +} +/*-----------------------------------------------------------*/ + +#if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + +void vSystemCallEnter( uint32_t * pulTaskStack, uint32_t ulLR ) /* PRIVILEGED_FUNCTION */ +{ + extern TaskHandle_t pxCurrentTCB; + xMPU_SETTINGS * pxMpuSettings; + uint32_t * pulSystemCallStack; + uint32_t ulStackFrameSize, ulSystemCallLocation, i, r1; + extern uint32_t __syscalls_flash_start__; + extern uint32_t __syscalls_flash_end__; + + ulSystemCallLocation = pulTaskStack[ portOFFSET_TO_PC ]; + + /* If the request did not come from the system call section, do nothing. */ + if( ( ulSystemCallLocation >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulSystemCallLocation <= ( uint32_t ) __syscalls_flash_end__ ) ) + { + pxMpuSettings = xTaskGetMPUSettings( pxCurrentTCB ); + pulSystemCallStack = pxMpuSettings->xSystemCallStackInfo.pulSystemCallStack; + + /* This is not NULL only for the duration of the system call. */ + configASSERT( pxMpuSettings->xSystemCallStackInfo.pulTaskStack == NULL ); + + if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) + { + /* Extended frame i.e. FPU in use. */ + ulStackFrameSize = 26; + prvTriggerLazyStacking(); + } + else + { + /* Standard frame i.e. FPU not in use. */ + ulStackFrameSize = 8; + } + + /* Make space on the system call stack for the stack frame. */ + pulSystemCallStack = pulSystemCallStack - ulStackFrameSize; + + /* Copy the stack frame. */ + for( i = 0; i < ulStackFrameSize; i++ ) + { + pulSystemCallStack[ i ] = pulTaskStack[ i ]; + } + + /* Use the pulSystemCallStack in thread mode. */ + __asm + { + msr psp, pulSystemCallStack + }; + + /* Raise the privilege for the duration of the system call. */ + __asm + { + mrs r1, control /* Obtain current control value. */ + bic r1, #1 /* Clear nPRIV bit. */ + msr control, r1 /* Write back new control value. */ + }; + + /* Remember the location where we should copy the stack frame when we exit from + * the system call. */ + pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulStackFrameSize; + + /* Store the value of the Link Register before the SVC was raised. We need to + * restore it when we exit from the system call. */ + pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; + + /* Record if the hardware used padding to force the stack pointer + * to be double word aligned. */ + if( ( pulTaskStack[ portOFFSET_TO_PSR ] & portPSR_STACK_PADDING_MASK ) == portPSR_STACK_PADDING_MASK ) + { + pxMpuSettings->ulTaskFlags |= portSTACK_FRAME_HAS_PADDING_FLAG; + } + else + { + pxMpuSettings->ulTaskFlags &= ( ~portSTACK_FRAME_HAS_PADDING_FLAG ); + } + + /* We ensure in pxPortInitialiseStack that the system call stack is + * double word aligned and therefore, there is no need of padding. + * Clear the bit[9] of stacked xPSR. */ + pulSystemCallStack[ portOFFSET_TO_PSR ] &= ( ~portPSR_STACK_PADDING_MASK ); + } +} + +#endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + +void vSystemCallEnter_1( uint32_t * pulTaskStack, uint32_t ulLR ) /* PRIVILEGED_FUNCTION */ +{ + extern TaskHandle_t pxCurrentTCB; + xMPU_SETTINGS * pxMpuSettings; + uint32_t * pulSystemCallStack; + uint32_t ulStackFrameSize, ulSystemCallLocation, i, r1; + extern uint32_t __syscalls_flash_start__; + extern uint32_t __syscalls_flash_end__; + + ulSystemCallLocation = pulTaskStack[ portOFFSET_TO_PC ]; + + /* If the request did not come from the system call section, do nothing. */ + if( ( ulSystemCallLocation >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulSystemCallLocation <= ( uint32_t ) __syscalls_flash_end__ ) ) + { + pxMpuSettings = xTaskGetMPUSettings( pxCurrentTCB ); + pulSystemCallStack = pxMpuSettings->xSystemCallStackInfo.pulSystemCallStack; + + /* This is not NULL only for the duration of the system call. */ + configASSERT( pxMpuSettings->xSystemCallStackInfo.pulTaskStack == NULL ); + + if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) + { + /* Extended frame i.e. FPU in use. */ + ulStackFrameSize = 26; + prvTriggerLazyStacking(); + } + else + { + /* Standard frame i.e. FPU not in use. */ + ulStackFrameSize = 8; + } + + /* Make space on the system call stack for the stack frame and + * the parameter passed on the stack. We only need to copy one + * parameter but we still reserve 2 spaces to keep the stack + * double word aligned. */ + pulSystemCallStack = pulSystemCallStack - ulStackFrameSize - 2UL; + + /* Copy the stack frame. */ + for( i = 0; i < ulStackFrameSize; i++ ) + { + pulSystemCallStack[ i ] = pulTaskStack[ i ]; + } + + /* Copy the parameter which is passed the stack. */ + if( ( pulTaskStack[ portOFFSET_TO_PSR ] & portPSR_STACK_PADDING_MASK ) == portPSR_STACK_PADDING_MASK ) + { + pulSystemCallStack[ ulStackFrameSize ] = pulTaskStack[ ulStackFrameSize + 1 ]; + /* Record if the hardware used padding to force the stack pointer + * to be double word aligned. */ + pxMpuSettings->ulTaskFlags |= portSTACK_FRAME_HAS_PADDING_FLAG; + } + else + { + pulSystemCallStack[ ulStackFrameSize ] = pulTaskStack[ ulStackFrameSize ]; + /* Record if the hardware used padding to force the stack pointer + * to be double word aligned. */ + pxMpuSettings->ulTaskFlags &= ( ~portSTACK_FRAME_HAS_PADDING_FLAG ); + } + + /* Use the pulSystemCallStack in thread mode. */ + __asm + { + msr psp, pulSystemCallStack + }; + + /* Raise the privilege for the duration of the system call. */ + __asm + { + mrs r1, control /* Obtain current control value. */ + bic r1, #1 /* Clear nPRIV bit. */ + msr control, r1 /* Write back new control value. */ + }; + + /* Remember the location where we should copy the stack frame when we exit from + * the system call. */ + pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulStackFrameSize; + + /* Store the value of the Link Register before the SVC was raised. We need to + * restore it when we exit from the system call. */ + pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; + + /* We ensure in pxPortInitialiseStack that the system call stack is + * double word aligned and therefore, there is no need of padding. + * Clear the bit[9] of stacked xPSR. */ + pulSystemCallStack[ portOFFSET_TO_PSR ] &= ( ~portPSR_STACK_PADDING_MASK ); + } +} + +#endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + +void vSystemCallExit( uint32_t * pulSystemCallStack, uint32_t ulLR ) /* PRIVILEGED_FUNCTION */ +{ + extern TaskHandle_t pxCurrentTCB; + xMPU_SETTINGS * pxMpuSettings; + uint32_t * pulTaskStack; + uint32_t ulStackFrameSize, ulSystemCallLocation, i, r1; + extern uint32_t __syscalls_flash_start__; + extern uint32_t __syscalls_flash_end__; + + ulSystemCallLocation = pulSystemCallStack[ portOFFSET_TO_PC ]; + + /* If the request did not come from the system call section, do nothing. */ + if( ( ulSystemCallLocation >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulSystemCallLocation <= ( uint32_t ) __syscalls_flash_end__ ) ) + { + pxMpuSettings = xTaskGetMPUSettings( pxCurrentTCB ); + pulTaskStack = pxMpuSettings->xSystemCallStackInfo.pulTaskStack; + + if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) + { + /* Extended frame i.e. FPU in use. */ + ulStackFrameSize = 26; + prvTriggerLazyStacking(); + } + else + { + /* Standard frame i.e. FPU not in use. */ + ulStackFrameSize = 8; + } + + /* Make space on the task stack for the stack frame. */ + pulTaskStack = pulTaskStack - ulStackFrameSize; + + /* Copy the stack frame. */ + for( i = 0; i < ulStackFrameSize; i++ ) + { + pulTaskStack[ i ] = pulSystemCallStack[ i ]; + } + + /* Use the pulTaskStack in thread mode. */ + __asm + { + msr psp, pulTaskStack + }; + + /* Drop the privilege before returning to the thread mode. */ + __asm + { + mrs r1, control /* Obtain current control value. */ + orr r1, #1 /* Set nPRIV bit. */ + msr control, r1 /* Write back new control value. */ + }; + + /* Restore the stacked link register to what it was at the time of + * system call entry. */ + pulTaskStack[ portOFFSET_TO_LR ] = pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry; + + /* If the hardware used padding to force the stack pointer + * to be double word aligned, set the stacked xPSR bit[9], + * otherwise clear it. */ + if( ( pxMpuSettings->ulTaskFlags & portSTACK_FRAME_HAS_PADDING_FLAG ) == portSTACK_FRAME_HAS_PADDING_FLAG ) + { + pulTaskStack[ portOFFSET_TO_PSR ] |= portPSR_STACK_PADDING_MASK; + } + else + { + pulTaskStack[ portOFFSET_TO_PSR ] &= ( ~portPSR_STACK_PADDING_MASK ); + } + + /* This is not NULL only for the duration of the system call. */ + pxMpuSettings->xSystemCallStackInfo.pulTaskStack = NULL; + } +} + +#endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ +/*-----------------------------------------------------------*/ + +BaseType_t xPortIsTaskPrivileged( void ) /* PRIVILEGED_FUNCTION */ +{ + BaseType_t xTaskIsPrivileged = pdFALSE; + const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */ + + if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) + { + xTaskIsPrivileged = pdTRUE; + } + + return xTaskIsPrivileged; +} +/*-----------------------------------------------------------*/ + +#if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + +__asm void vPortSVCHandler( void ) +{ + extern vSVCHandler_C + extern vSystemCallEnter + extern vSystemCallEnter_1 + extern vSystemCallExit + +/* *INDENT-OFF* */ + PRESERVE8 + + tst lr, #4 + ite eq + mrseq r0, msp + mrsne r0, psp + + ldr r1, [r0, #24] + ldrb r2, [r1, #-2] + cmp r2, #portSVC_SYSTEM_CALL_ENTER + beq syscall_enter + cmp r2, #portSVC_SYSTEM_CALL_ENTER_1 + beq syscall_enter_1 + cmp r2, #portSVC_SYSTEM_CALL_EXIT + beq syscall_exit + b vSVCHandler_C + +syscall_enter + mov r1, lr + b vSystemCallEnter + +syscall_enter_1 + mov r1, lr + b vSystemCallEnter_1 + +syscall_exit + mov r1, lr + b vSystemCallExit +/* *INDENT-ON* */ +} + +#else /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + __asm void vPortSVCHandler( void ) { - extern prvSVCHandler + extern vSVCHandler_C /* *INDENT-OFF* */ PRESERVE8 @@ -345,9 +767,11 @@ __asm void vPortSVCHandler( void ) mrs r0, psp #endif - b prvSVCHandler + b vSVCHandler_C /* *INDENT-ON* */ } + +#endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ /*-----------------------------------------------------------*/ __asm void prvRestoreContextOfFirstTask( void ) @@ -355,45 +779,54 @@ __asm void prvRestoreContextOfFirstTask( void ) /* *INDENT-OFF* */ PRESERVE8 - ldr r0, =0xE000ED08 /* Use the NVIC offset register to locate the stack. */ - ldr r0, [ r0 ] - ldr r0, [ r0 ] - msr msp, r0 /* Set the msp back to the start of the stack. */ - ldr r3, =pxCurrentTCB /* Restore the context. */ - ldr r1, [ r3 ] - ldr r0, [ r1 ] /* The first item in the TCB is the task top of stack. */ - add r1, r1, #4 /* Move onto the second item in the TCB... */ - - dmb /* Complete outstanding transfers before disabling MPU. */ - ldr r2, =0xe000ed94 /* MPU_CTRL register. */ - ldr r3, [ r2 ] /* Read the value of MPU_CTRL. */ - bic r3, r3, # 1 /* r3 = r3 & ~1 i.e. Clear the bit 0 in r3. */ - str r3, [ r2 ] /* Disable MPU. */ - - ldr r2, =0xe000ed9c /* Region Base Address register. */ - ldmia r1 !, { r4 - r11 } /* Read 4 sets of MPU registers [MPU Region # 4 - 7]. */ - stmia r2, { r4 - r11 } /* Write 4 sets of MPU registers [MPU Region # 4 - 7]. */ + ldr r0, =0xE000ED08 /* Use the NVIC offset register to locate the stack. */ + ldr r0, [r0] + ldr r0, [r0] + msr msp, r0 /* Set the msp back to the start of the stack. */ + + /*------------ Program MPU. ------------ */ + ldr r3, =pxCurrentTCB /* r3 = &( pxCurrentTCB ). */ + ldr r2, [r3] /* r2 = pxCurrentTCB. */ + add r2, r2, #4 /* r2 = Second item in the TCB which is xMPUSettings. */ + + dmb /* Complete outstanding transfers before disabling MPU. */ + ldr r0, =0xe000ed94 /* MPU_CTRL register. */ + ldr r3, [r0] /* Read the value of MPU_CTRL. */ + bic r3, r3, # 1 /* r3 = r3 & ~1 i.e. Clear the bit 0 in r3. */ + str r3, [r0] /* Disable MPU. */ + + ldr r0, =0xe000ed9c /* Region Base Address register. */ + ldmia r2!, {r4-r11} /* Read 4 sets of MPU registers [MPU Region # 0 - 3]. */ + stmia r0, {r4-r11} /* Write 4 sets of MPU registers [MPU Region # 0 - 3]. */ #if ( configTOTAL_MPU_REGIONS == 16 ) - ldmia r1 !, { r4 - r11 } /* Read 4 sets of MPU registers [MPU Region # 8 - 11]. */ - stmia r2, { r4 - r11 } /* Write 4 sets of MPU registers. [MPU Region # 8 - 11]. */ - ldmia r1 !, { r4 - r11 } /* Read 4 sets of MPU registers [MPU Region # 12 - 15]. */ - stmia r2, { r4 - r11 } /* Write 4 sets of MPU registers. [MPU Region # 12 - 15]. */ + ldmia r2!, {r4-r11} /* Read 4 sets of MPU registers [MPU Region # 4 - 7]. */ + stmia r0, {r4-r11} /* Write 4 sets of MPU registers. [MPU Region # 4 - 7]. */ + ldmia r2!, {r4-r11} /* Read 4 sets of MPU registers [MPU Region # 8 - 11]. */ + stmia r0, {r4-r11} /* Write 4 sets of MPU registers. [MPU Region # 8 - 11]. */ #endif /* configTOTAL_MPU_REGIONS == 16. */ - ldr r2, =0xe000ed94 /* MPU_CTRL register. */ - ldr r3, [ r2 ] /* Read the value of MPU_CTRL. */ - orr r3, r3, #1 /* r3 = r3 | 1 i.e. Set the bit 0 in r3. */ - str r3, [ r2 ] /* Enable MPU. */ - dsb /* Force memory writes before continuing. */ + ldr r0, =0xe000ed94 /* MPU_CTRL register. */ + ldr r3, [r0] /* Read the value of MPU_CTRL. */ + orr r3, r3, #1 /* r3 = r3 | 1 i.e. Set the bit 0 in r3. */ + str r3, [r0] /* Enable MPU. */ + dsb /* Force memory writes before continuing. */ + + /*---------- Restore Context. ---------- */ + ldr r3, =pxCurrentTCB /* r3 = &( pxCurrentTCB ). */ + ldr r2, [r3] /* r2 = pxCurrentTCB. */ + ldr r1, [r2] /* r1 = Location of saved context in TCB. */ - ldmia r0 !, { r3 - r11, r14 } /* Pop the registers that are not automatically saved on exception entry. */ + ldmdb r1!, {r0, r4-r11} /* r0 contains PSP after the hardware had saved context. r4-r11 contain hardware saved context. */ + msr psp, r0 + stmia r0, {r4-r11} /* Copy the hardware saved context on the task stack. */ + ldmdb r1!, {r3-r11, lr} /* r3 contains CONTROL register. r4-r11 and LR restored. */ msr control, r3 - msr psp, r0 /* Restore the task stack pointer. */ + str r1, [r2] /* Save the location where the context should be saved next as the first member of TCB. */ + mov r0, #0 msr basepri, r0 - bx r14 - nop + bx lr /* *INDENT-ON* */ } /*-----------------------------------------------------------*/ @@ -453,6 +886,10 @@ BaseType_t xPortStartScheduler( void ) * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ configASSERT( ucMaxSysCallPriority ); + /* Check that the bits not implemented in hardware are zero in + * configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & ( ~ucMaxPriorityValue ) ) == 0U ); + /* Calculate the maximum acceptable priority group value for the number * of bits read back. */ @@ -489,28 +926,6 @@ BaseType_t xPortStartScheduler( void ) ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulImplementedPrioBits; } - #ifdef __NVIC_PRIO_BITS - { - /* - * Check that the number of implemented priority bits queried from - * hardware is at least as many as specified in the CMSIS - * __NVIC_PRIO_BITS configuration macro. - */ - configASSERT( ulImplementedPrioBits >= __NVIC_PRIO_BITS ); - } - #endif - - #ifdef configPRIO_BITS - { - /* - * Check that the number of implemented priority bits queried from - * hardware is at least as many as specified in the FreeRTOS - * configPRIO_BITS configuration macro. - */ - configASSERT( ulImplementedPrioBits >= configPRIO_BITS ); - } - #endif - /* Shift the priority group value back to its position within the AIRCR * register. */ ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT; @@ -668,72 +1083,90 @@ __asm void xPortPendSVHandler( void ) /* *INDENT-OFF* */ PRESERVE8 - mrs r0, psp - - ldr r3, =pxCurrentTCB /* Get the location of the current TCB. */ - ldr r2, [ r3 ] - - tst r14, #0x10 /* Is the task using the FPU context? If so, push high vfp registers. */ - it eq - vstmdbeq r0 !, { s16 - s31 } + ldr r3, =pxCurrentTCB /* r3 = &( pxCurrentTCB ). */ + ldr r2, [r3] /* r2 = pxCurrentTCB. */ + ldr r1, [r2] /* r1 = Location where the context should be saved. */ - mrs r1, control - stmdb r0 !, { r1, r4 - r11, r14 } /* Save the remaining registers. */ - str r0, [ r2 ] /* Save the new top of stack into the first member of the TCB. */ + /*------------ Save Context. ----------- */ + mrs r3, control + mrs r0, psp + isb - stmdb sp !, { r0, r3 } - mov r0, # configMAX_SYSCALL_INTERRUPT_PRIORITY - #if ( configENABLE_ERRATA_837070_WORKAROUND == 1 ) - cpsid i /* ARM Cortex-M7 r0p1 Errata 837070 workaround. */ - #endif + add r0, r0, #0x20 /* Move r0 to location where s0 is saved. */ + tst lr, #0x10 + ittt eq + vstmiaeq r1!, {s16-s31} /* Store s16-s31. */ + vldmiaeq r0, {s0-s16} /* Copy hardware saved FP context into s0-s16. */ + vstmiaeq r1!, {s0-s16} /* Store hardware saved FP context. */ + sub r0, r0, #0x20 /* Set r0 back to the location of hardware saved context. */ + + stmia r1!, {r3-r11, lr} /* Store CONTROL register, r4-r11 and LR. */ + ldmia r0, {r4-r11} /* Copy hardware saved context into r4-r11. */ + stmia r1!, {r0, r4-r11} /* Store original PSP (after hardware has saved context) and the hardware saved context. */ + str r1, [r2] /* Save the location from where the context should be restored as the first member of TCB. */ + + /*---------- Select next task. --------- */ + mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY +#if ( configENABLE_ERRATA_837070_WORKAROUND == 1 ) + cpsid i /* ARM Cortex-M7 r0p1 Errata 837070 workaround. */ +#endif msr basepri, r0 dsb isb - #if ( configENABLE_ERRATA_837070_WORKAROUND == 1 ) - cpsie i /* ARM Cortex-M7 r0p1 Errata 837070 workaround. */ - #endif +#if ( configENABLE_ERRATA_837070_WORKAROUND == 1 ) + cpsie i /* ARM Cortex-M7 r0p1 Errata 837070 workaround. */ +#endif bl vTaskSwitchContext mov r0, #0 msr basepri, r0 - ldmia sp !, { r0, r3 } - /* Restore the context. */ - ldr r1, [ r3 ] - ldr r0, [ r1 ] /* The first item in the TCB is the task top of stack. */ - add r1, r1, #4 /* Move onto the second item in the TCB... */ - - dmb /* Complete outstanding transfers before disabling MPU. */ - ldr r2, =0xe000ed94 /* MPU_CTRL register. */ - ldr r3, [ r2 ] /* Read the value of MPU_CTRL. */ - bic r3, r3, #1 /* r3 = r3 & ~1 i.e. Clear the bit 0 in r3. */ - str r3, [ r2 ] /* Disable MPU. */ - - ldr r2, =0xe000ed9c /* Region Base Address register. */ - ldmia r1 !, { r4 - r11 } /* Read 4 sets of MPU registers [MPU Region # 4 - 7]. */ - stmia r2, { r4 - r11 } /* Write 4 sets of MPU registers [MPU Region # 4 - 7]. */ - - #if ( configTOTAL_MPU_REGIONS == 16 ) - ldmia r1 !, { r4 - r11 } /* Read 4 sets of MPU registers [MPU Region # 8 - 11]. */ - stmia r2, { r4 - r11 } /* Write 4 sets of MPU registers. [MPU Region # 8 - 11]. */ - ldmia r1 !, { r4 - r11 } /* Read 4 sets of MPU registers [MPU Region # 12 - 15]. */ - stmia r2, { r4 - r11 } /* Write 4 sets of MPU registers. [MPU Region # 12 - 15]. */ - #endif /* configTOTAL_MPU_REGIONS == 16. */ - - ldr r2, =0xe000ed94 /* MPU_CTRL register. */ - ldr r3, [ r2 ] /* Read the value of MPU_CTRL. */ - orr r3, r3, #1 /* r3 = r3 | 1 i.e. Set the bit 0 in r3. */ - str r3, [ r2 ] /* Enable MPU. */ - dsb /* Force memory writes before continuing. */ - ldmia r0 !, { r3 - r11, r14 } /* Pop the registers that are not automatically saved on exception entry. */ + /*------------ Program MPU. ------------ */ + ldr r3, =pxCurrentTCB /* r3 = &( pxCurrentTCB ). */ + ldr r2, [r3] /* r2 = pxCurrentTCB. */ + add r2, r2, #4 /* r2 = Second item in the TCB which is xMPUSettings. */ + + dmb /* Complete outstanding transfers before disabling MPU. */ + ldr r0, =0xe000ed94 /* MPU_CTRL register. */ + ldr r3, [r0] /* Read the value of MPU_CTRL. */ + bic r3, #1 /* r3 = r3 & ~1 i.e. Clear the bit 0 in r3. */ + str r3, [r0] /* Disable MPU. */ + + ldr r0, =0xe000ed9c /* Region Base Address register. */ + ldmia r2!, {r4-r11} /* Read 4 sets of MPU registers [MPU Region # 0 - 3]. */ + stmia r0, {r4-r11} /* Write 4 sets of MPU registers [MPU Region # 0 - 3]. */ + +#if ( configTOTAL_MPU_REGIONS == 16 ) + ldmia r2!, {r4-r11} /* Read 4 sets of MPU registers [MPU Region # 4 - 7]. */ + stmia r0, {r4-r11} /* Write 4 sets of MPU registers. [MPU Region # 4 - 7]. */ + ldmia r2!, {r4-r11} /* Read 4 sets of MPU registers [MPU Region # 8 - 11]. */ + stmia r0, {r4-r11} /* Write 4 sets of MPU registers. [MPU Region # 8 - 11]. */ +#endif /* configTOTAL_MPU_REGIONS == 16. */ + + ldr r0, =0xe000ed94 /* MPU_CTRL register. */ + ldr r3, [r0] /* Read the value of MPU_CTRL. */ + orr r3, #1 /* r3 = r3 | 1 i.e. Set the bit 0 in r3. */ + str r3, [r0] /* Enable MPU. */ + dsb /* Force memory writes before continuing. */ + + /*---------- Restore Context. ---------- */ + ldr r3, =pxCurrentTCB /* r3 = &( pxCurrentTCB ). */ + ldr r2, [r3] /* r2 = pxCurrentTCB. */ + ldr r1, [r2] /* r1 = Location of saved context in TCB. */ + + ldmdb r1!, {r0, r4-r11} /* r0 contains PSP after the hardware had saved context. r4-r11 contain hardware saved context. */ + msr psp, r0 + stmia r0!, {r4-r11} /* Copy the hardware saved context on the task stack. */ + ldmdb r1!, {r3-r11, lr} /* r3 contains CONTROL register. r4-r11 and LR restored. */ msr control, r3 - tst r14, #0x10 /* Is the task using the FPU context? If so, pop the high vfp registers too. */ - it eq - vldmiaeq r0 !, { s16 - s31 } + tst lr, #0x10 + ittt eq + vldmdbeq r1!, {s0-s16} /* s0-s16 contain hardware saved FP context. */ + vstmiaeq r0!, {s0-s16} /* Copy hardware saved FP context on the task stack. */ + vldmdbeq r1!, {s16-s31} /* Restore s16-s31. */ - msr psp, r0 - bx r14 - nop + str r1, [r2] /* Save the location where the context should be saved next as the first member of TCB. */ + bx lr /* *INDENT-ON* */ } /*-----------------------------------------------------------*/ @@ -952,11 +1385,19 @@ void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings, ( prvGetMPURegionSizeSetting( ( uint32_t ) __SRAM_segment_end__ - ( uint32_t ) __SRAM_segment_start__ ) ) | ( portMPU_REGION_ENABLE ); + xMPUSettings->xRegionSettings[ 0 ].ulRegionStartAddress = ( uint32_t ) __SRAM_segment_start__; + xMPUSettings->xRegionSettings[ 0 ].ulRegionEndAddress = ( uint32_t ) __SRAM_segment_end__; + xMPUSettings->xRegionSettings[ 0 ].ulRegionPermissions = ( tskMPU_READ_PERMISSION | + tskMPU_WRITE_PERMISSION ); + /* Invalidate user configurable regions. */ for( ul = 1UL; ul <= portNUM_CONFIGURABLE_REGIONS; ul++ ) { xMPUSettings->xRegion[ ul ].ulRegionBaseAddress = ( ( ul - 1UL ) | portMPU_REGION_VALID ); xMPUSettings->xRegion[ ul ].ulRegionAttribute = 0UL; + xMPUSettings->xRegionSettings[ ul ].ulRegionStartAddress = 0UL; + xMPUSettings->xRegionSettings[ ul ].ulRegionEndAddress = 0UL; + xMPUSettings->xRegionSettings[ ul ].ulRegionPermissions = 0UL; } } else @@ -979,6 +1420,12 @@ void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings, ( prvGetMPURegionSizeSetting( ulStackDepth * ( uint32_t ) sizeof( StackType_t ) ) ) | ( ( configTEX_S_C_B_SRAM & portMPU_RASR_TEX_S_C_B_MASK ) << portMPU_RASR_TEX_S_C_B_LOCATION ) | ( portMPU_REGION_ENABLE ); + + xMPUSettings->xRegionSettings[ 0 ].ulRegionStartAddress = ( uint32_t ) pxBottomOfStack; + xMPUSettings->xRegionSettings[ 0 ].ulRegionEndAddress = ( uint32_t ) ( ( uint32_t ) ( pxBottomOfStack ) + + ( ulStackDepth * ( uint32_t ) sizeof( StackType_t ) ) - 1UL ); + xMPUSettings->xRegionSettings[ 0 ].ulRegionPermissions = ( tskMPU_READ_PERMISSION | + tskMPU_WRITE_PERMISSION ); } lIndex = 0; @@ -999,12 +1446,28 @@ void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings, ( prvGetMPURegionSizeSetting( xRegions[ lIndex ].ulLengthInBytes ) ) | ( xRegions[ lIndex ].ulParameters ) | ( portMPU_REGION_ENABLE ); + + xMPUSettings->xRegionSettings[ ul ].ulRegionStartAddress = ( uint32_t ) xRegions[ lIndex ].pvBaseAddress; + xMPUSettings->xRegionSettings[ ul ].ulRegionEndAddress = ( uint32_t ) ( ( uint32_t ) xRegions[ lIndex ].pvBaseAddress + xRegions[ lIndex ].ulLengthInBytes - 1UL ); + xMPUSettings->xRegionSettings[ ul ].ulRegionPermissions = 0UL; + if( ( ( xRegions[ lIndex ].ulParameters & portMPU_REGION_READ_ONLY ) == portMPU_REGION_READ_ONLY ) || + ( ( xRegions[lIndex].ulParameters & portMPU_REGION_PRIVILEGED_READ_WRITE_UNPRIV_READ_ONLY ) == portMPU_REGION_PRIVILEGED_READ_WRITE_UNPRIV_READ_ONLY ) ) + { + xMPUSettings->xRegionSettings[ ul ].ulRegionPermissions = tskMPU_READ_PERMISSION; + } + if( ( xRegions[ lIndex ].ulParameters & portMPU_REGION_READ_WRITE ) == portMPU_REGION_READ_WRITE ) + { + xMPUSettings->xRegionSettings[ ul ].ulRegionPermissions = ( tskMPU_READ_PERMISSION | tskMPU_WRITE_PERMISSION ); + } } else { /* Invalidate the region. */ xMPUSettings->xRegion[ ul ].ulRegionBaseAddress = ( ( ul - 1UL ) | portMPU_REGION_VALID ); xMPUSettings->xRegion[ ul ].ulRegionAttribute = 0UL; + xMPUSettings->xRegionSettings[ ul ].ulRegionStartAddress = 0UL; + xMPUSettings->xRegionSettings[ ul ].ulRegionEndAddress = 0UL; + xMPUSettings->xRegionSettings[ ul ].ulRegionPermissions = 0UL; } lIndex++; @@ -1013,6 +1476,47 @@ void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings, } /*-----------------------------------------------------------*/ +BaseType_t xPortIsAuthorizedToAccessBuffer( const void * pvBuffer, + uint32_t ulBufferLength, + uint32_t ulAccessRequested ) /* PRIVILEGED_FUNCTION */ + +{ + uint32_t i, ulBufferStartAddress, ulBufferEndAddress; + BaseType_t xAccessGranted = pdFALSE; + const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */ + + if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) + { + xAccessGranted = pdTRUE; + } + else + { + if( portADD_UINT32_WILL_OVERFLOW( ( ( uint32_t ) pvBuffer ), ( ulBufferLength - 1UL ) ) == pdFALSE ) + { + ulBufferStartAddress = ( uint32_t ) pvBuffer; + ulBufferEndAddress = ( ( ( uint32_t ) pvBuffer ) + ulBufferLength - 1UL ); + + for( i = 0; i < portTOTAL_NUM_REGIONS_IN_TCB; i++ ) + { + if( portIS_ADDRESS_WITHIN_RANGE( ulBufferStartAddress, + xTaskMpuSettings->xRegionSettings[ i ].ulRegionStartAddress, + xTaskMpuSettings->xRegionSettings[ i ].ulRegionEndAddress ) && + portIS_ADDRESS_WITHIN_RANGE( ulBufferEndAddress, + xTaskMpuSettings->xRegionSettings[ i ].ulRegionStartAddress, + xTaskMpuSettings->xRegionSettings[ i ].ulRegionEndAddress ) && + portIS_AUTHORIZED( ulAccessRequested, xTaskMpuSettings->xRegionSettings[ i ].ulRegionPermissions ) ) + { + xAccessGranted = pdTRUE; + break; + } + } + } + } + + return xAccessGranted; +} +/*-----------------------------------------------------------*/ + __asm uint32_t prvPortGetIPSR( void ) { /* *INDENT-OFF* */ diff --git a/portable/RVDS/ARM_CM4_MPU/portmacro.h b/portable/RVDS/ARM_CM4_MPU/portmacro.h index c7cd5628951..cc4e136d67e 100644 --- a/portable/RVDS/ARM_CM4_MPU/portmacro.h +++ b/portable/RVDS/ARM_CM4_MPU/portmacro.h @@ -193,9 +193,45 @@ typedef struct MPU_REGION_REGISTERS uint32_t ulRegionAttribute; } xMPU_REGION_REGISTERS; +typedef struct MPU_REGION_SETTINGS +{ + uint32_t ulRegionStartAddress; + uint32_t ulRegionEndAddress; + uint32_t ulRegionPermissions; +} xMPU_REGION_SETTINGS; + +#if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + + #ifndef configSYSTEM_CALL_STACK_SIZE + #error configSYSTEM_CALL_STACK_SIZE must be defined to the desired size of the system call stack in words for using MPU wrappers v2. + #endif + + typedef struct SYSTEM_CALL_STACK_INFO + { + uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ]; + uint32_t * pulSystemCallStack; + uint32_t * pulTaskStack; + uint32_t ulLinkRegisterAtSystemCallEntry; + } xSYSTEM_CALL_STACK_INFO; + +#endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + +#define MAX_CONTEXT_SIZE 52 + +/* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ +#define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) +#define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) + typedef struct MPU_SETTINGS { xMPU_REGION_REGISTERS xRegion[ portTOTAL_NUM_REGIONS_IN_TCB ]; + xMPU_REGION_SETTINGS xRegionSettings[ portTOTAL_NUM_REGIONS_IN_TCB ]; + uint32_t ulContext[ MAX_CONTEXT_SIZE ]; + uint32_t ulTaskFlags; + + #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo; + #endif } xMPU_SETTINGS; /* Architecture specifics. */ @@ -209,9 +245,12 @@ typedef struct MPU_SETTINGS /*-----------------------------------------------------------*/ /* SVC numbers for various services. */ -#define portSVC_START_SCHEDULER 0 -#define portSVC_YIELD 1 -#define portSVC_RAISE_PRIVILEGE 2 +#define portSVC_START_SCHEDULER 0 +#define portSVC_YIELD 1 +#define portSVC_RAISE_PRIVILEGE 2 +#define portSVC_SYSTEM_CALL_ENTER 3 /* System calls with upto 4 parameters. */ +#define portSVC_SYSTEM_CALL_ENTER_1 4 /* System calls with 5 parameters. */ +#define portSVC_SYSTEM_CALL_EXIT 5 /* Scheduler utilities. */ @@ -314,6 +353,16 @@ extern void vResetPrivilege( void ); #define portRESET_PRIVILEGE() vResetPrivilege() /*-----------------------------------------------------------*/ +extern BaseType_t xPortIsTaskPrivileged( void ); + +/** + * @brief Checks whether or not the calling task is privileged. + * + * @return pdTRUE if the calling task is privileged, pdFALSE otherwise. + */ +#define portIS_TASK_PRIVILEGED() xPortIsTaskPrivileged() +/*-----------------------------------------------------------*/ + static portFORCE_INLINE void vPortSetBASEPRI( uint32_t ulBASEPRI ) { __asm diff --git a/portable/RVDS/ARM_CM7/r0p1/port.c b/portable/RVDS/ARM_CM7/r0p1/port.c index 1df54ab2802..8414acc99e6 100755 --- a/portable/RVDS/ARM_CM7/r0p1/port.c +++ b/portable/RVDS/ARM_CM7/r0p1/port.c @@ -344,6 +344,10 @@ BaseType_t xPortStartScheduler( void ) * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ configASSERT( ucMaxSysCallPriority ); + /* Check that the bits not implemented in hardware are zero in + * configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & ( ~ucMaxPriorityValue ) ) == 0U ); + /* Calculate the maximum acceptable priority group value for the number * of bits read back. */ @@ -380,28 +384,6 @@ BaseType_t xPortStartScheduler( void ) ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulImplementedPrioBits; } - #ifdef __NVIC_PRIO_BITS - { - /* - * Check that the number of implemented priority bits queried from - * hardware is at least as many as specified in the CMSIS - * __NVIC_PRIO_BITS configuration macro. - */ - configASSERT( ulImplementedPrioBits >= __NVIC_PRIO_BITS ); - } - #endif - - #ifdef configPRIO_BITS - { - /* - * Check that the number of implemented priority bits queried from - * hardware is at least as many as specified in the FreeRTOS - * configPRIO_BITS configuration macro. - */ - configASSERT( ulImplementedPrioBits >= configPRIO_BITS ); - } - #endif - /* Shift the priority group value back to its position within the AIRCR * register. */ ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT; diff --git a/portable/ThirdParty/GCC/ATmega/portmacro.h b/portable/ThirdParty/GCC/ATmega/portmacro.h index 8292f2d7ed9..e48ddb2195e 100644 --- a/portable/ThirdParty/GCC/ATmega/portmacro.h +++ b/portable/ThirdParty/GCC/ATmega/portmacro.h @@ -54,6 +54,8 @@ #define portLONG long #define portSHORT int +#define portPOINTER_SIZE_TYPE uint16_t + typedef uint8_t StackType_t; typedef int8_t BaseType_t; typedef uint8_t UBaseType_t; diff --git a/portable/ThirdParty/GCC/Posix/port.c b/portable/ThirdParty/GCC/Posix/port.c index 5ac570d9a59..23aec65526e 100644 --- a/portable/ThirdParty/GCC/Posix/port.c +++ b/portable/ThirdParty/GCC/Posix/port.c @@ -332,17 +332,17 @@ void vPortEnableInterrupts( void ) } /*-----------------------------------------------------------*/ -portBASE_TYPE xPortSetInterruptMask( void ) +UBaseType_t xPortSetInterruptMask( void ) { /* Interrupts are always disabled inside ISRs (signals * handlers). */ - return pdTRUE; + return ( UBaseType_t )0; } /*-----------------------------------------------------------*/ -void vPortClearInterruptMask( portBASE_TYPE xMask ) +void vPortClearInterruptMask( UBaseType_t uxMask ) { - ( void ) xMask; + ( void ) uxMask; } /*-----------------------------------------------------------*/ diff --git a/portable/ThirdParty/GCC/Posix/portmacro.h b/portable/ThirdParty/GCC/Posix/portmacro.h index a3ab7d32393..154a039758c 100644 --- a/portable/ThirdParty/GCC/Posix/portmacro.h +++ b/portable/ThirdParty/GCC/Posix/portmacro.h @@ -70,8 +70,6 @@ typedef unsigned long TickType_t; /*-----------------------------------------------------------*/ /* Architecture specifics. */ -#define portNORETURN __attribute__( ( noreturn ) ) - #define portSTACK_GROWTH ( -1 ) #define portHAS_STACK_OVERFLOW_CHECKING ( 1 ) #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) @@ -94,8 +92,8 @@ extern void vPortEnableInterrupts( void ); #define portSET_INTERRUPT_MASK() ( vPortDisableInterrupts() ) #define portCLEAR_INTERRUPT_MASK() ( vPortEnableInterrupts() ) -extern portBASE_TYPE xPortSetInterruptMask( void ); -extern void vPortClearInterruptMask( portBASE_TYPE xMask ); +extern UBaseType_t xPortSetInterruptMask( void ); +extern void vPortClearInterruptMask( UBaseType_t xMask ); extern void vPortEnterCritical( void ); extern void vPortExitCritical( void ); @@ -114,7 +112,7 @@ extern void vPortCancelThread( void *pxTaskToDelete ); #define portCLEAN_UP_TCB( pxTCB ) vPortCancelThread( pxTCB ) /*-----------------------------------------------------------*/ -#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters ) +#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters ) __attribute__( ( noreturn ) ) #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters ) /*-----------------------------------------------------------*/ diff --git a/portable/ThirdParty/GCC/RP2040/include/portmacro.h b/portable/ThirdParty/GCC/RP2040/include/portmacro.h index cec4f7fedeb..fffd8c66c2a 100644 --- a/portable/ThirdParty/GCC/RP2040/include/portmacro.h +++ b/portable/ThirdParty/GCC/RP2040/include/portmacro.h @@ -82,7 +82,6 @@ #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) #define portBYTE_ALIGNMENT 8 #define portDONT_DISCARD __attribute__( ( used ) ) - #define portNORETURN __attribute__( ( noreturn ) ) /* We have to use PICO_DIVIDER_DISABLE_INTERRUPTS as the source of truth rathern than our config, * as our FreeRTOSConfig.h header cannot be included by ASM code - which is what this affects in the SDK */ #define portUSE_DIVIDER_SAVE_RESTORE !PICO_DIVIDER_DISABLE_INTERRUPTS @@ -182,8 +181,8 @@ #else extern void vTaskEnterCritical( void ); extern void vTaskExitCritical( void ); - extern portBASE_TYPE vTaskEnterCriticalFromISR( void ); - extern void vTaskExitCriticalFromISR( portBASE_TYPE xSavedInterruptStatus ); + extern UBaseType_t vTaskEnterCriticalFromISR( void ); + extern void vTaskExitCriticalFromISR( UBaseType_t uxSavedInterruptStatus ); #define portENTER_CRITICAL() vTaskEnterCritical() #define portEXIT_CRITICAL() vTaskExitCritical() #define portENTER_CRITICAL_FROM_ISR() vTaskEnterCriticalFromISR() diff --git a/portable/ThirdParty/GCC/RP2040/library.cmake b/portable/ThirdParty/GCC/RP2040/library.cmake index 5ff4c0931d1..1db96517af6 100644 --- a/portable/ThirdParty/GCC/RP2040/library.cmake +++ b/portable/ThirdParty/GCC/RP2040/library.cmake @@ -6,6 +6,7 @@ add_library(FreeRTOS-Kernel-Core INTERFACE) target_sources(FreeRTOS-Kernel-Core INTERFACE + ${FREERTOS_KERNEL_PATH}/croutine.c ${FREERTOS_KERNEL_PATH}/event_groups.c ${FREERTOS_KERNEL_PATH}/list.c ${FREERTOS_KERNEL_PATH}/queue.c diff --git a/portable/ThirdParty/GCC/Xtensa_ESP32/include/portmacro.h b/portable/ThirdParty/GCC/Xtensa_ESP32/include/portmacro.h index 575659ac597..e87d560cfcd 100644 --- a/portable/ThirdParty/GCC/Xtensa_ESP32/include/portmacro.h +++ b/portable/ThirdParty/GCC/Xtensa_ESP32/include/portmacro.h @@ -335,8 +335,6 @@ /*-----------------------------------------------------------*/ /* Architecture specifics. */ - #define portNORETURN __attribute__( ( noreturn ) ) - #define portSTACK_GROWTH ( -1 ) #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) #define portBYTE_ALIGNMENT 4 diff --git a/portable/ThirdParty/xClang/XCOREAI/portmacro.h b/portable/ThirdParty/xClang/XCOREAI/portmacro.h index 019d29a3c7a..36907b258be 100644 --- a/portable/ThirdParty/xClang/XCOREAI/portmacro.h +++ b/portable/ThirdParty/xClang/XCOREAI/portmacro.h @@ -165,8 +165,8 @@ void vTaskExitCritical(void); #define portENTER_CRITICAL() vTaskEnterCritical() #define portEXIT_CRITICAL() vTaskExitCritical() -extern portBASE_TYPE vTaskEnterCriticalFromISR( void ); -extern void vTaskExitCriticalFromISR( portBASE_TYPE xSavedInterruptStatus ); +extern UBaseType_t vTaskEnterCriticalFromISR( void ); +extern void vTaskExitCriticalFromISR( UBaseType_t uxSavedInterruptStatus ); #define portENTER_CRITICAL_FROM_ISR vTaskEnterCriticalFromISR #define portEXIT_CRITICAL_FROM_ISR vTaskExitCriticalFromISR diff --git a/portable/WizC/PIC18/portmacro.h b/portable/WizC/PIC18/portmacro.h index ad70560e4ad..0fdba688eee 100644 --- a/portable/WizC/PIC18/portmacro.h +++ b/portable/WizC/PIC18/portmacro.h @@ -63,7 +63,7 @@ typedef unsigned char UBaseType_t; #define portMAX_DELAY ( TickType_t ) ( 0xFFFF ) #elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) typedef uint32_t TickType_t; - #define portMAX_DELAY ( TickType_t ) ( 0xFFFFFFFF ) + #define portMAX_DELAY ( TickType_t ) ( 0xFFFFFFFFUL ) #else #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #endif diff --git a/queue.c b/queue.c index 37ab1f24dff..e87db0f45e3 100644 --- a/queue.c +++ b/queue.c @@ -38,6 +38,10 @@ #include "task.h" #include "queue.h" +#if ( configUSE_CO_ROUTINES == 1 ) + #include "croutine.h" +#endif + /* Lint e9021, e961 and e750 are suppressed as a MISRA exception justified * because the MPU ports require MPU_WRAPPERS_INCLUDED_FROM_API_FILE to be defined * for the header files above, but not in this file, in order to generate the @@ -1107,7 +1111,7 @@ BaseType_t xQueueGenericSendFromISR( QueueHandle_t xQueue, const BaseType_t xCopyPosition ) { BaseType_t xReturn; - portBASE_TYPE xSavedInterruptStatus; + UBaseType_t uxSavedInterruptStatus; Queue_t * const pxQueue = xQueue; configASSERT( pxQueue ); @@ -1135,7 +1139,7 @@ BaseType_t xQueueGenericSendFromISR( QueueHandle_t xQueue, * read, instead return a flag to say whether a context switch is required or * not (i.e. has a task with a higher priority than us been woken by this * post). */ - xSavedInterruptStatus = taskENTER_CRITICAL_FROM_ISR(); + uxSavedInterruptStatus = taskENTER_CRITICAL_FROM_ISR(); { if( ( pxQueue->uxMessagesWaiting < pxQueue->uxLength ) || ( xCopyPosition == queueOVERWRITE ) ) { @@ -1260,7 +1264,7 @@ BaseType_t xQueueGenericSendFromISR( QueueHandle_t xQueue, xReturn = errQUEUE_FULL; } } - taskEXIT_CRITICAL_FROM_ISR( xSavedInterruptStatus ); + taskEXIT_CRITICAL_FROM_ISR( uxSavedInterruptStatus ); return xReturn; } @@ -1270,7 +1274,7 @@ BaseType_t xQueueGiveFromISR( QueueHandle_t xQueue, BaseType_t * const pxHigherPriorityTaskWoken ) { BaseType_t xReturn; - portBASE_TYPE xSavedInterruptStatus; + UBaseType_t uxSavedInterruptStatus; Queue_t * const pxQueue = xQueue; /* Similar to xQueueGenericSendFromISR() but used with semaphores where the @@ -1306,7 +1310,7 @@ BaseType_t xQueueGiveFromISR( QueueHandle_t xQueue, * link: https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ portASSERT_IF_INTERRUPT_PRIORITY_INVALID(); - xSavedInterruptStatus = taskENTER_CRITICAL_FROM_ISR(); + uxSavedInterruptStatus = taskENTER_CRITICAL_FROM_ISR(); { const UBaseType_t uxMessagesWaiting = pxQueue->uxMessagesWaiting; @@ -1426,7 +1430,7 @@ BaseType_t xQueueGiveFromISR( QueueHandle_t xQueue, xReturn = errQUEUE_FULL; } } - taskEXIT_CRITICAL_FROM_ISR( xSavedInterruptStatus ); + taskEXIT_CRITICAL_FROM_ISR( uxSavedInterruptStatus ); return xReturn; } @@ -1965,7 +1969,7 @@ BaseType_t xQueueReceiveFromISR( QueueHandle_t xQueue, BaseType_t * const pxHigherPriorityTaskWoken ) { BaseType_t xReturn; - portBASE_TYPE xSavedInterruptStatus; + UBaseType_t uxSavedInterruptStatus; Queue_t * const pxQueue = xQueue; configASSERT( pxQueue ); @@ -1987,7 +1991,7 @@ BaseType_t xQueueReceiveFromISR( QueueHandle_t xQueue, * link: https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ portASSERT_IF_INTERRUPT_PRIORITY_INVALID(); - xSavedInterruptStatus = taskENTER_CRITICAL_FROM_ISR(); + uxSavedInterruptStatus = taskENTER_CRITICAL_FROM_ISR(); { const UBaseType_t uxMessagesWaiting = pxQueue->uxMessagesWaiting; @@ -2047,7 +2051,7 @@ BaseType_t xQueueReceiveFromISR( QueueHandle_t xQueue, traceQUEUE_RECEIVE_FROM_ISR_FAILED( pxQueue ); } } - taskEXIT_CRITICAL_FROM_ISR( xSavedInterruptStatus ); + taskEXIT_CRITICAL_FROM_ISR( uxSavedInterruptStatus ); return xReturn; } @@ -2057,7 +2061,7 @@ BaseType_t xQueuePeekFromISR( QueueHandle_t xQueue, void * const pvBuffer ) { BaseType_t xReturn; - portBASE_TYPE xSavedInterruptStatus; + UBaseType_t uxSavedInterruptStatus; int8_t * pcOriginalReadPosition; Queue_t * const pxQueue = xQueue; @@ -2081,7 +2085,7 @@ BaseType_t xQueuePeekFromISR( QueueHandle_t xQueue, * link: https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ portASSERT_IF_INTERRUPT_PRIORITY_INVALID(); - xSavedInterruptStatus = taskENTER_CRITICAL_FROM_ISR(); + uxSavedInterruptStatus = taskENTER_CRITICAL_FROM_ISR(); { /* Cannot block in an ISR, so check there is data available. */ if( pxQueue->uxMessagesWaiting > ( UBaseType_t ) 0 ) @@ -2102,7 +2106,7 @@ BaseType_t xQueuePeekFromISR( QueueHandle_t xQueue, traceQUEUE_PEEK_FROM_ISR_FAILED( pxQueue ); } } - taskEXIT_CRITICAL_FROM_ISR( xSavedInterruptStatus ); + taskEXIT_CRITICAL_FROM_ISR( uxSavedInterruptStatus ); return xReturn; } @@ -2226,6 +2230,12 @@ void vQueueDelete( QueueHandle_t xQueue ) #endif /* configUSE_TRACE_FACILITY */ /*-----------------------------------------------------------*/ +UBaseType_t uxQueueGetQueueItemSize( QueueHandle_t xQueue ) /* PRIVILEGED_FUNCTION */ +{ + return ( ( Queue_t * ) xQueue )->uxItemSize; +} +/*-----------------------------------------------------------*/ + #if ( configUSE_MUTEXES == 1 ) static UBaseType_t prvGetDisinheritPriorityAfterTimeout( const Queue_t * const pxQueue ) @@ -2559,6 +2569,293 @@ BaseType_t xQueueIsQueueFullFromISR( const QueueHandle_t xQueue ) } /*lint !e818 xQueue could not be pointer to const because it is a typedef. */ /*-----------------------------------------------------------*/ +#if ( configUSE_CO_ROUTINES == 1 ) + + BaseType_t xQueueCRSend( QueueHandle_t xQueue, + const void * pvItemToQueue, + TickType_t xTicksToWait ) + { + BaseType_t xReturn; + Queue_t * const pxQueue = xQueue; + + /* If the queue is already full we may have to block. A critical section + * is required to prevent an interrupt removing something from the queue + * between the check to see if the queue is full and blocking on the queue. */ + portDISABLE_INTERRUPTS(); + { + if( prvIsQueueFull( pxQueue ) != pdFALSE ) + { + /* The queue is full - do we want to block or just leave without + * posting? */ + if( xTicksToWait > ( TickType_t ) 0 ) + { + /* As this is called from a coroutine we cannot block directly, but + * return indicating that we need to block. */ + vCoRoutineAddToDelayedList( xTicksToWait, &( pxQueue->xTasksWaitingToSend ) ); + portENABLE_INTERRUPTS(); + return errQUEUE_BLOCKED; + } + else + { + portENABLE_INTERRUPTS(); + return errQUEUE_FULL; + } + } + } + portENABLE_INTERRUPTS(); + + portDISABLE_INTERRUPTS(); + { + if( pxQueue->uxMessagesWaiting < pxQueue->uxLength ) + { + /* There is room in the queue, copy the data into the queue. */ + prvCopyDataToQueue( pxQueue, pvItemToQueue, queueSEND_TO_BACK ); + xReturn = pdPASS; + + /* Were any co-routines waiting for data to become available? */ + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) + { + /* In this instance the co-routine could be placed directly + * into the ready list as we are within a critical section. + * Instead the same pending ready list mechanism is used as if + * the event were caused from within an interrupt. */ + if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) + { + /* The co-routine waiting has a higher priority so record + * that a yield might be appropriate. */ + xReturn = errQUEUE_YIELD; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + xReturn = errQUEUE_FULL; + } + } + portENABLE_INTERRUPTS(); + + return xReturn; + } + +#endif /* configUSE_CO_ROUTINES */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_CO_ROUTINES == 1 ) + + BaseType_t xQueueCRReceive( QueueHandle_t xQueue, + void * pvBuffer, + TickType_t xTicksToWait ) + { + BaseType_t xReturn; + Queue_t * const pxQueue = xQueue; + + /* If the queue is already empty we may have to block. A critical section + * is required to prevent an interrupt adding something to the queue + * between the check to see if the queue is empty and blocking on the queue. */ + portDISABLE_INTERRUPTS(); + { + if( pxQueue->uxMessagesWaiting == ( UBaseType_t ) 0 ) + { + /* There are no messages in the queue, do we want to block or just + * leave with nothing? */ + if( xTicksToWait > ( TickType_t ) 0 ) + { + /* As this is a co-routine we cannot block directly, but return + * indicating that we need to block. */ + vCoRoutineAddToDelayedList( xTicksToWait, &( pxQueue->xTasksWaitingToReceive ) ); + portENABLE_INTERRUPTS(); + return errQUEUE_BLOCKED; + } + else + { + portENABLE_INTERRUPTS(); + return errQUEUE_FULL; + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + portENABLE_INTERRUPTS(); + + portDISABLE_INTERRUPTS(); + { + if( pxQueue->uxMessagesWaiting > ( UBaseType_t ) 0 ) + { + /* Data is available from the queue. */ + pxQueue->u.xQueue.pcReadFrom += pxQueue->uxItemSize; + + if( pxQueue->u.xQueue.pcReadFrom >= pxQueue->u.xQueue.pcTail ) + { + pxQueue->u.xQueue.pcReadFrom = pxQueue->pcHead; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + --( pxQueue->uxMessagesWaiting ); + ( void ) memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->u.xQueue.pcReadFrom, ( unsigned ) pxQueue->uxItemSize ); + + xReturn = pdPASS; + + /* Were any co-routines waiting for space to become available? */ + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE ) + { + /* In this instance the co-routine could be placed directly + * into the ready list as we are within a critical section. + * Instead the same pending ready list mechanism is used as if + * the event were caused from within an interrupt. */ + if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE ) + { + xReturn = errQUEUE_YIELD; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + xReturn = pdFAIL; + } + } + portENABLE_INTERRUPTS(); + + return xReturn; + } + +#endif /* configUSE_CO_ROUTINES */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_CO_ROUTINES == 1 ) + + BaseType_t xQueueCRSendFromISR( QueueHandle_t xQueue, + const void * pvItemToQueue, + BaseType_t xCoRoutinePreviouslyWoken ) + { + Queue_t * const pxQueue = xQueue; + + /* Cannot block within an ISR so if there is no space on the queue then + * exit without doing anything. */ + if( pxQueue->uxMessagesWaiting < pxQueue->uxLength ) + { + prvCopyDataToQueue( pxQueue, pvItemToQueue, queueSEND_TO_BACK ); + + /* We only want to wake one co-routine per ISR, so check that a + * co-routine has not already been woken. */ + if( xCoRoutinePreviouslyWoken == pdFALSE ) + { + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) + { + if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) + { + return pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + return xCoRoutinePreviouslyWoken; + } + +#endif /* configUSE_CO_ROUTINES */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_CO_ROUTINES == 1 ) + + BaseType_t xQueueCRReceiveFromISR( QueueHandle_t xQueue, + void * pvBuffer, + BaseType_t * pxCoRoutineWoken ) + { + BaseType_t xReturn; + Queue_t * const pxQueue = xQueue; + + /* We cannot block from an ISR, so check there is data available. If + * not then just leave without doing anything. */ + if( pxQueue->uxMessagesWaiting > ( UBaseType_t ) 0 ) + { + /* Copy the data from the queue. */ + pxQueue->u.xQueue.pcReadFrom += pxQueue->uxItemSize; + + if( pxQueue->u.xQueue.pcReadFrom >= pxQueue->u.xQueue.pcTail ) + { + pxQueue->u.xQueue.pcReadFrom = pxQueue->pcHead; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + --( pxQueue->uxMessagesWaiting ); + ( void ) memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->u.xQueue.pcReadFrom, ( unsigned ) pxQueue->uxItemSize ); + + if( ( *pxCoRoutineWoken ) == pdFALSE ) + { + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE ) + { + if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE ) + { + *pxCoRoutineWoken = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + xReturn = pdPASS; + } + else + { + xReturn = pdFAIL; + } + + return xReturn; + } + +#endif /* configUSE_CO_ROUTINES */ +/*-----------------------------------------------------------*/ + #if ( configQUEUE_REGISTRY_SIZE > 0 ) void vQueueAddToRegistry( QueueHandle_t xQueue, diff --git a/stream_buffer.c b/stream_buffer.c index 890202e601a..b7410fc0668 100644 --- a/stream_buffer.c +++ b/stream_buffer.c @@ -78,7 +78,7 @@ */ #if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) #define prvRECEIVE_COMPLETED( pxStreamBuffer ) \ - { \ + do { \ if( ( pxStreamBuffer )->pxReceiveCompletedCallback != NULL ) \ { \ ( pxStreamBuffer )->pxReceiveCompletedCallback( ( pxStreamBuffer ), pdFALSE, NULL ); \ @@ -87,7 +87,7 @@ { \ sbRECEIVE_COMPLETED( ( pxStreamBuffer ) ); \ } \ - } + } while( 0 ) #else /* if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) */ #define prvRECEIVE_COMPLETED( pxStreamBuffer ) sbRECEIVE_COMPLETED( ( pxStreamBuffer ) ) #endif /* if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) */ @@ -96,9 +96,9 @@ #define sbRECEIVE_COMPLETED_FROM_ISR( pxStreamBuffer, \ pxHigherPriorityTaskWoken ) \ do { \ - portBASE_TYPE xSavedInterruptStatus; \ + UBaseType_t uxSavedInterruptStatus; \ \ - xSavedInterruptStatus = taskENTER_CRITICAL_FROM_ISR(); \ + uxSavedInterruptStatus = taskENTER_CRITICAL_FROM_ISR(); \ { \ if( ( pxStreamBuffer )->xTaskWaitingToSend != NULL ) \ { \ @@ -109,14 +109,14 @@ ( pxStreamBuffer )->xTaskWaitingToSend = NULL; \ } \ } \ - taskEXIT_CRITICAL_FROM_ISR( xSavedInterruptStatus ); \ + taskEXIT_CRITICAL_FROM_ISR( uxSavedInterruptStatus ); \ } while( 0 ) #endif /* sbRECEIVE_COMPLETED_FROM_ISR */ #if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) #define prvRECEIVE_COMPLETED_FROM_ISR( pxStreamBuffer, \ pxHigherPriorityTaskWoken ) \ - { \ + do { \ if( ( pxStreamBuffer )->pxReceiveCompletedCallback != NULL ) \ { \ ( pxStreamBuffer )->pxReceiveCompletedCallback( ( pxStreamBuffer ), pdTRUE, ( pxHigherPriorityTaskWoken ) ); \ @@ -125,7 +125,7 @@ { \ sbRECEIVE_COMPLETED_FROM_ISR( ( pxStreamBuffer ), ( pxHigherPriorityTaskWoken ) ); \ } \ - } + } while( 0 ) #else /* if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) */ #define prvRECEIVE_COMPLETED_FROM_ISR( pxStreamBuffer, pxHigherPriorityTaskWoken ) \ sbRECEIVE_COMPLETED_FROM_ISR( ( pxStreamBuffer ), ( pxHigherPriorityTaskWoken ) ) @@ -173,9 +173,9 @@ #ifndef sbSEND_COMPLETE_FROM_ISR #define sbSEND_COMPLETE_FROM_ISR( pxStreamBuffer, pxHigherPriorityTaskWoken ) \ do { \ - portBASE_TYPE xSavedInterruptStatus; \ + UBaseType_t uxSavedInterruptStatus; \ \ - xSavedInterruptStatus = taskENTER_CRITICAL_FROM_ISR(); \ + uxSavedInterruptStatus = taskENTER_CRITICAL_FROM_ISR(); \ { \ if( ( pxStreamBuffer )->xTaskWaitingToReceive != NULL ) \ { \ @@ -186,7 +186,7 @@ ( pxStreamBuffer )->xTaskWaitingToReceive = NULL; \ } \ } \ - taskEXIT_CRITICAL_FROM_ISR( xSavedInterruptStatus ); \ + taskEXIT_CRITICAL_FROM_ISR( uxSavedInterruptStatus ); \ } while( 0 ) #endif /* sbSEND_COMPLETE_FROM_ISR */ @@ -436,11 +436,13 @@ static void prvInitialiseNewStreamBuffer( StreamBuffer_t * const pxStreamBuffer, configASSERT( xBufferSizeBytes > sbBYTES_TO_STORE_MESSAGE_LENGTH ); #if ( configASSERT_DEFINED == 1 ) - + { /* Sanity check that the size of the structure used to declare a * variable of type StaticStreamBuffer_t equals the size of the real * message buffer structure. */ - configASSERT( sizeof( StaticStreamBuffer_t ) == sizeof( StreamBuffer_t ) ); + volatile size_t xSize = sizeof( StaticStreamBuffer_t ); + configASSERT( xSize == sizeof( StreamBuffer_t ) ); + } /*lint !e529 xSize is referenced is configASSERT() is defined. */ #endif /* configASSERT_DEFINED */ if( ( pucStreamBufferStorageArea != NULL ) && ( pxStaticStreamBuffer != NULL ) ) @@ -478,7 +480,7 @@ static void prvInitialiseNewStreamBuffer( StreamBuffer_t * const pxStreamBuffer, StaticStreamBuffer_t ** ppxStaticStreamBuffer ) { BaseType_t xReturn; - const StreamBuffer_t * const pxStreamBuffer = xStreamBuffer; + StreamBuffer_t * const pxStreamBuffer = xStreamBuffer; configASSERT( pxStreamBuffer ); configASSERT( ppucStreamBufferStorageArea ); @@ -1214,11 +1216,11 @@ BaseType_t xStreamBufferSendCompletedFromISR( StreamBufferHandle_t xStreamBuffer { StreamBuffer_t * const pxStreamBuffer = xStreamBuffer; BaseType_t xReturn; - portBASE_TYPE xSavedInterruptStatus; + UBaseType_t uxSavedInterruptStatus; configASSERT( pxStreamBuffer ); - xSavedInterruptStatus = taskENTER_CRITICAL_FROM_ISR(); + uxSavedInterruptStatus = taskENTER_CRITICAL_FROM_ISR(); { if( ( pxStreamBuffer )->xTaskWaitingToReceive != NULL ) { @@ -1234,7 +1236,7 @@ BaseType_t xStreamBufferSendCompletedFromISR( StreamBufferHandle_t xStreamBuffer xReturn = pdFALSE; } } - taskEXIT_CRITICAL_FROM_ISR( xSavedInterruptStatus ); + taskEXIT_CRITICAL_FROM_ISR( uxSavedInterruptStatus ); return xReturn; } @@ -1245,11 +1247,11 @@ BaseType_t xStreamBufferReceiveCompletedFromISR( StreamBufferHandle_t xStreamBuf { StreamBuffer_t * const pxStreamBuffer = xStreamBuffer; BaseType_t xReturn; - portBASE_TYPE xSavedInterruptStatus; + UBaseType_t uxSavedInterruptStatus; configASSERT( pxStreamBuffer ); - xSavedInterruptStatus = taskENTER_CRITICAL_FROM_ISR(); + uxSavedInterruptStatus = taskENTER_CRITICAL_FROM_ISR(); { if( ( pxStreamBuffer )->xTaskWaitingToSend != NULL ) { @@ -1265,7 +1267,7 @@ BaseType_t xStreamBufferReceiveCompletedFromISR( StreamBufferHandle_t xStreamBuf xReturn = pdFALSE; } } - taskEXIT_CRITICAL_FROM_ISR( xSavedInterruptStatus ); + taskEXIT_CRITICAL_FROM_ISR( uxSavedInterruptStatus ); return xReturn; } diff --git a/tasks.c b/tasks.c index 0a4a1fe672b..b991b7da4bb 100644 --- a/tasks.c +++ b/tasks.c @@ -126,12 +126,12 @@ /* uxTopReadyPriority holds the priority of the highest priority ready * state task. */ #define taskRECORD_READY_PRIORITY( uxPriority ) \ - { \ + do { \ if( ( uxPriority ) > uxTopReadyPriority ) \ { \ uxTopReadyPriority = ( uxPriority ); \ } \ - } /* taskRECORD_READY_PRIORITY */ + } while( 0 ) /* taskRECORD_READY_PRIORITY */ /*-----------------------------------------------------------*/ @@ -549,9 +549,9 @@ static void prvInitialiseTaskLists( void ) PRIVILEGED_FUNCTION; * void prvMinimalIdleTask( void *pvParameters ); * */ -static portTASK_FUNCTION_PROTO( prvIdleTask, pvParameters ) portNORETURN PRIVILEGED_FUNCTION; +static portTASK_FUNCTION_PROTO( prvIdleTask, pvParameters ) PRIVILEGED_FUNCTION; #if ( configNUMBER_OF_CORES > 1 ) - static portTASK_FUNCTION_PROTO( prvMinimalIdleTask, pvParameters ) portNORETURN PRIVILEGED_FUNCTION; + static portTASK_FUNCTION_PROTO( prvMinimalIdleTask, pvParameters ) PRIVILEGED_FUNCTION; #endif /* @@ -1644,17 +1644,17 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode, { #if ( portSTACK_GROWTH < 0 ) { - pxNewTCB->pxTopOfStack = pxPortInitialiseStack( pxTopOfStack, pxNewTCB->pxStack, pxTaskCode, pvParameters, xRunPrivileged ); + pxNewTCB->pxTopOfStack = pxPortInitialiseStack( pxTopOfStack, pxNewTCB->pxStack, pxTaskCode, pvParameters, xRunPrivileged, &( pxNewTCB->xMPUSettings ) ); } #else /* portSTACK_GROWTH */ { - pxNewTCB->pxTopOfStack = pxPortInitialiseStack( pxTopOfStack, pxNewTCB->pxEndOfStack, pxTaskCode, pvParameters, xRunPrivileged ); + pxNewTCB->pxTopOfStack = pxPortInitialiseStack( pxTopOfStack, pxNewTCB->pxEndOfStack, pxTaskCode, pvParameters, xRunPrivileged, &( pxNewTCB->xMPUSettings ) ); } #endif /* portSTACK_GROWTH */ } #else /* portHAS_STACK_OVERFLOW_CHECKING */ { - pxNewTCB->pxTopOfStack = pxPortInitialiseStack( pxTopOfStack, pxTaskCode, pvParameters, xRunPrivileged ); + pxNewTCB->pxTopOfStack = pxPortInitialiseStack( pxTopOfStack, pxTaskCode, pvParameters, xRunPrivileged, &( pxNewTCB->xMPUSettings ) ); } #endif /* portHAS_STACK_OVERFLOW_CHECKING */ } @@ -2038,7 +2038,7 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode, * block. */ const TickType_t xConstTickCount = xTickCount; - configASSERT( uxSchedulerSuspended == 1 ); + configASSERT( uxSchedulerSuspended == 1U ); /* Generate the tick time at which the task wants to wake. */ xTimeToWake = *pxPreviousWakeTime + xTimeIncrement; @@ -2124,7 +2124,7 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode, { vTaskSuspendAll(); { - configASSERT( uxSchedulerSuspended == 1 ); + configASSERT( uxSchedulerSuspended == 1U ); traceTASK_DELAY(); @@ -2169,6 +2169,7 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode, { eTaskState eReturn; List_t const * pxStateList; + List_t const * pxEventList; List_t const * pxDelayedList; List_t const * pxOverflowedDelayedList; const TCB_t * const pxTCB = xTask; @@ -2187,12 +2188,20 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode, taskENTER_CRITICAL(); { pxStateList = listLIST_ITEM_CONTAINER( &( pxTCB->xStateListItem ) ); + pxEventList = listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ); pxDelayedList = pxDelayedTaskList; pxOverflowedDelayedList = pxOverflowDelayedTaskList; } taskEXIT_CRITICAL(); - if( ( pxStateList == pxDelayedList ) || ( pxStateList == pxOverflowedDelayedList ) ) + if( pxEventList == &xPendingReadyList ) + { + /* The task has been placed on the pending ready list, so its + * state is eReady regardless of what list the task's state list + * item is currently placed on. */ + eReturn = eReady; + } + else if( ( pxStateList == pxDelayedList ) || ( pxStateList == pxOverflowedDelayedList ) ) { /* The task being queried is referenced from one of the Blocked * lists. */ @@ -2310,7 +2319,7 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode, { TCB_t const * pxTCB; UBaseType_t uxReturn; - portBASE_TYPE xSavedInterruptState; + UBaseType_t uxSavedInterruptStatus; /* RTOS ports that support interrupt nesting have the concept of a * maximum system call (or maximum API call) interrupt priority. @@ -2330,14 +2339,14 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode, * https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ portASSERT_IF_INTERRUPT_PRIORITY_INVALID(); - xSavedInterruptState = taskENTER_CRITICAL_FROM_ISR(); + uxSavedInterruptStatus = taskENTER_CRITICAL_FROM_ISR(); { /* If null is passed in here then it is the priority of the calling * task that is being queried. */ pxTCB = prvGetTCBFromHandle( xTask ); uxReturn = pxTCB->uxPriority; } - taskEXIT_CRITICAL_FROM_ISR( xSavedInterruptState ); + taskEXIT_CRITICAL_FROM_ISR( uxSavedInterruptStatus ); return uxReturn; } @@ -2983,7 +2992,7 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode, { BaseType_t xYieldRequired = pdFALSE; TCB_t * const pxTCB = xTaskToResume; - portBASE_TYPE xSavedInterruptStatus; + UBaseType_t uxSavedInterruptStatus; configASSERT( xTaskToResume ); @@ -3005,7 +3014,7 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode, * https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ portASSERT_IF_INTERRUPT_PRIORITY_INVALID(); - xSavedInterruptStatus = taskENTER_CRITICAL_FROM_ISR(); + uxSavedInterruptStatus = taskENTER_CRITICAL_FROM_ISR(); { if( prvTaskIsTaskSuspended( pxTCB ) != pdFALSE ) { @@ -3061,7 +3070,7 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode, mtCOVERAGE_TEST_MARKER(); } } - taskEXIT_CRITICAL_FROM_ISR( xSavedInterruptStatus ); + taskEXIT_CRITICAL_FROM_ISR( uxSavedInterruptStatus ); return xYieldRequired; } @@ -3646,7 +3655,7 @@ TickType_t xTaskGetTickCount( void ) TickType_t xTaskGetTickCountFromISR( void ) { TickType_t xReturn; - portBASE_TYPE xSavedInterruptStatus; + UBaseType_t uxSavedInterruptStatus; /* RTOS ports that support interrupt nesting have the concept of a maximum * system call (or maximum API call) interrupt priority. Interrupts that are @@ -3664,11 +3673,11 @@ TickType_t xTaskGetTickCountFromISR( void ) * link: https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ portASSERT_IF_INTERRUPT_PRIORITY_INVALID(); - xSavedInterruptStatus = portTICK_TYPE_SET_INTERRUPT_MASK_FROM_ISR(); + uxSavedInterruptStatus = portTICK_TYPE_SET_INTERRUPT_MASK_FROM_ISR(); { xReturn = xTickCount; } - portTICK_TYPE_CLEAR_INTERRUPT_MASK_FROM_ISR( xSavedInterruptStatus ); + portTICK_TYPE_CLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); return xReturn; } @@ -4251,7 +4260,7 @@ BaseType_t xTaskIncrementTick( void ) * item at the head of the delayed list. This is the time * at which the task at the head of the delayed list must * be removed from the Blocked state. */ - pxTCB = listGET_OWNER_OF_HEAD_ENTRY( pxDelayedTaskList ); /*lint !e9079 void * is used as this macro is used with timers too. Alignment is known to be fine as the type of the pointer stored and retrieved is the same. */ + pxTCB = listGET_OWNER_OF_HEAD_ENTRY( pxDelayedTaskList ); /*lint !e9079 void * is used as this macro is used with timers and co-routines too. Alignment is known to be fine as the type of the pointer stored and retrieved is the same. */ xItemValue = listGET_LIST_ITEM_VALUE( &( pxTCB->xStateListItem ) ); if( xConstTickCount < xItemValue ) @@ -4496,18 +4505,18 @@ BaseType_t xTaskIncrementTick( void ) { TCB_t * pxTCB; TaskHookFunction_t xReturn; - portBASE_TYPE xSavedInterruptStatus; + UBaseType_t uxSavedInterruptStatus; /* If xTask is NULL then set the calling task's hook. */ pxTCB = prvGetTCBFromHandle( xTask ); /* Save the hook function in the TCB. A critical section is required as * the value can be accessed from an interrupt. */ - xSavedInterruptStatus = taskENTER_CRITICAL_FROM_ISR(); + uxSavedInterruptStatus = taskENTER_CRITICAL_FROM_ISR(); { xReturn = pxTCB->pxTaskTag; } - taskEXIT_CRITICAL_FROM_ISR( xSavedInterruptStatus ); + taskEXIT_CRITICAL_FROM_ISR( uxSavedInterruptStatus ); return xReturn; } @@ -4819,7 +4828,7 @@ BaseType_t xTaskRemoveFromEventList( const List_t * const pxEventList ) * * This function assumes that a check has already been made to ensure that * pxEventList is not empty. */ - pxUnblockedTCB = listGET_OWNER_OF_HEAD_ENTRY( pxEventList ); /*lint !e9079 void * is used as this macro is used with timers too. Alignment is known to be fine as the type of the pointer stored and retrieved is the same. */ + pxUnblockedTCB = listGET_OWNER_OF_HEAD_ENTRY( pxEventList ); /*lint !e9079 void * is used as this macro is used with timers and co-routines too. Alignment is known to be fine as the type of the pointer stored and retrieved is the same. */ configASSERT( pxUnblockedTCB ); listREMOVE_ITEM( &( pxUnblockedTCB->xEventListItem ) ); @@ -4902,7 +4911,7 @@ void vTaskRemoveFromUnorderedEventList( ListItem_t * pxEventListItem, /* Remove the event list form the event flag. Interrupts do not access * event flags. */ - pxUnblockedTCB = listGET_LIST_ITEM_OWNER( pxEventListItem ); /*lint !e9079 void * is used as this macro is used with timers too. Alignment is known to be fine as the type of the pointer stored and retrieved is the same. */ + pxUnblockedTCB = listGET_LIST_ITEM_OWNER( pxEventListItem ); /*lint !e9079 void * is used as this macro is used with timers and co-routines too. Alignment is known to be fine as the type of the pointer stored and retrieved is the same. */ configASSERT( pxUnblockedTCB ); listREMOVE_ITEM( pxEventListItem ); @@ -5599,6 +5608,18 @@ static void prvCheckTasksWaitingTermination( void ) } } #endif /* INCLUDE_vTaskSuspend */ + + /* Tasks can be in pending ready list and other state list at the + * same time. These tasks are in ready state no matter what state + * list the task is in. */ + taskENTER_CRITICAL(); + { + if( listIS_CONTAINED_WITHIN( &xPendingReadyList, &( pxTCB->xEventListItem ) ) != pdFALSE ) + { + pxTaskStatus->eCurrentState = eReady; + } + } + taskEXIT_CRITICAL(); } } else @@ -5641,7 +5662,7 @@ static void prvCheckTasksWaitingTermination( void ) if( listCURRENT_LIST_LENGTH( pxList ) > ( UBaseType_t ) 0 ) { - listGET_OWNER_OF_NEXT_ENTRY( pxFirstTCB, pxList ); /*lint !e9079 void * is used as this macro is used with timers too. Alignment is known to be fine as the type of the pointer stored and retrieved is the same. */ + listGET_OWNER_OF_NEXT_ENTRY( pxFirstTCB, pxList ); /*lint !e9079 void * is used as this macro is used with timers and co-routines too. Alignment is known to be fine as the type of the pointer stored and retrieved is the same. */ /* Populate an TaskStatus_t structure within the * pxTaskStatusArray array for each task that is referenced from @@ -5649,7 +5670,7 @@ static void prvCheckTasksWaitingTermination( void ) * meaning of each TaskStatus_t structure member. */ do { - listGET_OWNER_OF_NEXT_ENTRY( pxNextTCB, pxList ); /*lint !e9079 void * is used as this macro is used with timers too. Alignment is known to be fine as the type of the pointer stored and retrieved is the same. */ + listGET_OWNER_OF_NEXT_ENTRY( pxNextTCB, pxList ); /*lint !e9079 void * is used as this macro is used with timers and co-routines too. Alignment is known to be fine as the type of the pointer stored and retrieved is the same. */ vTaskGetInfo( ( TaskHandle_t ) pxNextTCB, &( pxTaskStatusArray[ uxTask ] ), pdTRUE, eState ); uxTask++; } while( pxNextTCB != pxFirstTCB ); @@ -5847,13 +5868,13 @@ static void prvResetNextTaskUnblockTime( void ) TaskHandle_t xTaskGetCurrentTaskHandle( void ) { TaskHandle_t xReturn; - portBASE_TYPE xSavedInterruptStatus; + UBaseType_t uxSavedInterruptStatus; - xSavedInterruptStatus = portSET_INTERRUPT_MASK(); + uxSavedInterruptStatus = portSET_INTERRUPT_MASK(); { xReturn = pxCurrentTCBs[ portGET_CORE_ID() ]; } - portCLEAR_INTERRUPT_MASK( xSavedInterruptStatus ); + portCLEAR_INTERRUPT_MASK( uxSavedInterruptStatus ); return xReturn; } @@ -6315,13 +6336,13 @@ static void prvResetNextTaskUnblockTime( void ) #if ( configNUMBER_OF_CORES > 1 ) - portBASE_TYPE vTaskEnterCriticalFromISR( void ) + UBaseType_t vTaskEnterCriticalFromISR( void ) { - portBASE_TYPE xSavedInterruptStatus = 0; + UBaseType_t uxSavedInterruptStatus = 0; if( xSchedulerRunning != pdFALSE ) { - xSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); + uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); if( portGET_CRITICAL_NESTING_COUNT() == 0U ) { @@ -6335,7 +6356,7 @@ static void prvResetNextTaskUnblockTime( void ) mtCOVERAGE_TEST_MARKER(); } - return xSavedInterruptStatus; + return uxSavedInterruptStatus; } #endif /* #if ( configNUMBER_OF_CORES > 1 ) */ @@ -6441,7 +6462,7 @@ static void prvResetNextTaskUnblockTime( void ) #if ( configNUMBER_OF_CORES > 1 ) - void vTaskExitCriticalFromISR( portBASE_TYPE xSavedInterruptStatus ) + void vTaskExitCriticalFromISR( UBaseType_t uxSavedInterruptStatus ) { if( xSchedulerRunning != pdFALSE ) { @@ -6456,7 +6477,7 @@ static void prvResetNextTaskUnblockTime( void ) if( portGET_CRITICAL_NESTING_COUNT() == 0U ) { portRELEASE_ISR_LOCK(); - portCLEAR_INTERRUPT_MASK_FROM_ISR( xSavedInterruptStatus ); + portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); } else { @@ -7087,7 +7108,7 @@ TickType_t uxTaskResetEventItemValue( void ) TCB_t * pxTCB; uint8_t ucOriginalNotifyState; BaseType_t xReturn = pdPASS; - portBASE_TYPE xSavedInterruptStatus; + UBaseType_t uxSavedInterruptStatus; configASSERT( xTaskToNotify ); configASSERT( uxIndexToNotify < configTASK_NOTIFICATION_ARRAY_ENTRIES ); @@ -7112,7 +7133,7 @@ TickType_t uxTaskResetEventItemValue( void ) pxTCB = xTaskToNotify; - xSavedInterruptStatus = taskENTER_CRITICAL_FROM_ISR(); + uxSavedInterruptStatus = taskENTER_CRITICAL_FROM_ISR(); { if( pulPreviousNotificationValue != NULL ) { @@ -7226,7 +7247,7 @@ TickType_t uxTaskResetEventItemValue( void ) #endif /* #if ( configNUMBER_OF_CORES == 1 ) */ } } - taskEXIT_CRITICAL_FROM_ISR( xSavedInterruptStatus ); + taskEXIT_CRITICAL_FROM_ISR( uxSavedInterruptStatus ); return xReturn; } @@ -7242,7 +7263,7 @@ TickType_t uxTaskResetEventItemValue( void ) { TCB_t * pxTCB; uint8_t ucOriginalNotifyState; - portBASE_TYPE xSavedInterruptStatus; + UBaseType_t uxSavedInterruptStatus; configASSERT( xTaskToNotify ); configASSERT( uxIndexToNotify < configTASK_NOTIFICATION_ARRAY_ENTRIES ); @@ -7267,7 +7288,7 @@ TickType_t uxTaskResetEventItemValue( void ) pxTCB = xTaskToNotify; - xSavedInterruptStatus = taskENTER_CRITICAL_FROM_ISR(); + uxSavedInterruptStatus = taskENTER_CRITICAL_FROM_ISR(); { ucOriginalNotifyState = pxTCB->ucNotifyState[ uxIndexToNotify ]; pxTCB->ucNotifyState[ uxIndexToNotify ] = taskNOTIFICATION_RECEIVED; @@ -7337,7 +7358,7 @@ TickType_t uxTaskResetEventItemValue( void ) #endif /* #if ( configNUMBER_OF_CORES == 1 ) */ } } - taskEXIT_CRITICAL_FROM_ISR( xSavedInterruptStatus ); + taskEXIT_CRITICAL_FROM_ISR( uxSavedInterruptStatus ); } #endif /* configUSE_TASK_NOTIFICATIONS */ @@ -7605,6 +7626,21 @@ static void prvAddCurrentTaskToDelayedList( TickType_t xTicksToWait, } #endif /* INCLUDE_vTaskSuspend */ } +/*-----------------------------------------------------------*/ + +#if ( portUSING_MPU_WRAPPERS == 1 ) + + xMPU_SETTINGS * xTaskGetMPUSettings( TaskHandle_t xTask ) + { + TCB_t * pxTCB; + + pxTCB = prvGetTCBFromHandle( xTask ); + + return &( pxTCB->xMPUSettings ); + } + +#endif /* portUSING_MPU_WRAPPERS */ +/*-----------------------------------------------------------*/ /* Code below here allows additional code to be inserted into this source file, * especially where access to file scope functions and data is needed (for example diff --git a/timers.c b/timers.c index cff986ae7ff..0028c334851 100644 --- a/timers.c +++ b/timers.c @@ -159,7 +159,7 @@ * task. Other tasks communicate with the timer service task using the * xTimerQueue queue. */ - static portTASK_FUNCTION_PROTO( prvTimerTask, pvParameters ) portNORETURN PRIVILEGED_FUNCTION; + static portTASK_FUNCTION_PROTO( prvTimerTask, pvParameters ) PRIVILEGED_FUNCTION; /* * Called by the timer service task to interpret and process a command it @@ -606,7 +606,7 @@ static void prvProcessExpiredTimer( const TickType_t xNextExpireTime, const TickType_t xTimeNow ) { - Timer_t * const pxTimer = ( Timer_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxCurrentTimerList ); /*lint !e9087 !e9079 void * is used as this macro is used with tasks too. Alignment is known to be fine as the type of the pointer stored and retrieved is the same. */ + Timer_t * const pxTimer = ( Timer_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxCurrentTimerList ); /*lint !e9087 !e9079 void * is used as this macro is used with tasks and co-routines too. Alignment is known to be fine as the type of the pointer stored and retrieved is the same. */ /* Remove the timer from the list of active timers. A check has already * been performed to ensure the list is not empty. */