Committer:
leothedragon
Date:
Sun Apr 18 15:20:23 2021 +0000
Revision:
0:25fa8795676b
DS

Who changed what in which revision?

UserRevisionLine numberNew contents of line
leothedragon 0:25fa8795676b 1 // ----------------------------------------------------------------------------
leothedragon 0:25fa8795676b 2 // Copyright 2015-2017 ARM Ltd.
leothedragon 0:25fa8795676b 3 //
leothedragon 0:25fa8795676b 4 // SPDX-License-Identifier: Apache-2.0
leothedragon 0:25fa8795676b 5 //
leothedragon 0:25fa8795676b 6 // Licensed under the Apache License, Version 2.0 (the "License");
leothedragon 0:25fa8795676b 7 // you may not use this file except in compliance with the License.
leothedragon 0:25fa8795676b 8 // You may obtain a copy of the License at
leothedragon 0:25fa8795676b 9 //
leothedragon 0:25fa8795676b 10 // http://www.apache.org/licenses/LICENSE-2.0
leothedragon 0:25fa8795676b 11 //
leothedragon 0:25fa8795676b 12 // Unless required by applicable law or agreed to in writing, software
leothedragon 0:25fa8795676b 13 // distributed under the License is distributed on an "AS IS" BASIS,
leothedragon 0:25fa8795676b 14 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
leothedragon 0:25fa8795676b 15 // See the License for the specific language governing permissions and
leothedragon 0:25fa8795676b 16 // limitations under the License.
leothedragon 0:25fa8795676b 17 // ----------------------------------------------------------------------------
leothedragon 0:25fa8795676b 18
leothedragon 0:25fa8795676b 19 // This critical section implementation is generic for mbed OS targets,
leothedragon 0:25fa8795676b 20 // except Nordic ones
leothedragon 0:25fa8795676b 21 #if defined(TARGET_LIKE_MBED) && !defined(TARGET_NORDIC)
leothedragon 0:25fa8795676b 22
leothedragon 0:25fa8795676b 23 #include <stdint.h> // uint32_t, UINT32_MAX
leothedragon 0:25fa8795676b 24 #include <stddef.h> // NULL
leothedragon 0:25fa8795676b 25
leothedragon 0:25fa8795676b 26 #if defined(YOTTA_CFG_MBED_OS)
leothedragon 0:25fa8795676b 27 #include "cmsis-core/core_generic.h" //__disable_irq, __enable_irq
leothedragon 0:25fa8795676b 28 #else
leothedragon 0:25fa8795676b 29 #include "cmsis.h"
leothedragon 0:25fa8795676b 30 #endif
leothedragon 0:25fa8795676b 31
leothedragon 0:25fa8795676b 32 #include <assert.h>
leothedragon 0:25fa8795676b 33
leothedragon 0:25fa8795676b 34 // Module include
leothedragon 0:25fa8795676b 35 #include "aq_critical.h"
leothedragon 0:25fa8795676b 36
leothedragon 0:25fa8795676b 37 static volatile uint32_t interruptEnableCounter = 0;
leothedragon 0:25fa8795676b 38 static volatile uint32_t critical_primask = 0;
leothedragon 0:25fa8795676b 39
leothedragon 0:25fa8795676b 40 void aq_critical_section_enter()
leothedragon 0:25fa8795676b 41 {
leothedragon 0:25fa8795676b 42 uint32_t primask;
leothedragon 0:25fa8795676b 43 #if defined(__CORTEX_A9)
leothedragon 0:25fa8795676b 44 primask = __get_CPSR(); // get the current interrupt enabled state
leothedragon 0:25fa8795676b 45 #else
leothedragon 0:25fa8795676b 46 primask = __get_PRIMASK(); // get the current interrupt enabled state
leothedragon 0:25fa8795676b 47 #endif
leothedragon 0:25fa8795676b 48 __disable_irq();
leothedragon 0:25fa8795676b 49
leothedragon 0:25fa8795676b 50 // Save the interrupt enabled state as it was prior to any nested critical section lock use
leothedragon 0:25fa8795676b 51 if (!interruptEnableCounter) {
leothedragon 0:25fa8795676b 52 #if defined(__CORTEX_A9)
leothedragon 0:25fa8795676b 53 critical_primask = primask & 0x80;
leothedragon 0:25fa8795676b 54 #else
leothedragon 0:25fa8795676b 55 critical_primask = primask & 0x1;
leothedragon 0:25fa8795676b 56 #endif
leothedragon 0:25fa8795676b 57 }
leothedragon 0:25fa8795676b 58 #if 0
leothedragon 0:25fa8795676b 59 /* If the interruptEnableCounter overflows or we are in a nested critical section and interrupts
leothedragon 0:25fa8795676b 60 are enabled, then something has gone badly wrong thus assert an error.
leothedragon 0:25fa8795676b 61 */
leothedragon 0:25fa8795676b 62
leothedragon 0:25fa8795676b 63 /* FIXME: This assertion needs to be commented out for the moment, as it
leothedragon 0:25fa8795676b 64 * triggers a fault when uVisor is enabled. For more information on
leothedragon 0:25fa8795676b 65 * the fault please checkout ARMmbed/mbed-drivers#176. */
leothedragon 0:25fa8795676b 66
leothedragon 0:25fa8795676b 67 assert(interruptEnableCounter < UINT32_MAX);
leothedragon 0:25fa8795676b 68 if (interruptEnableCounter > 0) {
leothedragon 0:25fa8795676b 69 assert(primask & 0x1);
leothedragon 0:25fa8795676b 70 }
leothedragon 0:25fa8795676b 71 #endif
leothedragon 0:25fa8795676b 72
leothedragon 0:25fa8795676b 73 if (interruptEnableCounter < UINT32_MAX) {
leothedragon 0:25fa8795676b 74 interruptEnableCounter++;
leothedragon 0:25fa8795676b 75 }
leothedragon 0:25fa8795676b 76 }
leothedragon 0:25fa8795676b 77
leothedragon 0:25fa8795676b 78 void aq_critical_section_exit(void)
leothedragon 0:25fa8795676b 79 {
leothedragon 0:25fa8795676b 80 // If critical_section_enter has not previously been called, do nothing
leothedragon 0:25fa8795676b 81 if (interruptEnableCounter) {
leothedragon 0:25fa8795676b 82 #if 0
leothedragon 0:25fa8795676b 83 /* FIXME: This assertion needs to be commented out for the moment, as it
leothedragon 0:25fa8795676b 84 * triggers a fault when uVisor is enabled. For more information
leothedragon 0:25fa8795676b 85 * on the fault please checkout ARMmbed/mbed-drivers#176. */
leothedragon 0:25fa8795676b 86
leothedragon 0:25fa8795676b 87 uint32_t primask;
leothedragon 0:25fa8795676b 88 #if defined(__CORTEX_A9)
leothedragon 0:25fa8795676b 89 primask = __get_CPSR(); // get the current interrupt enabled state
leothedragon 0:25fa8795676b 90 #else
leothedragon 0:25fa8795676b 91 primask = __get_PRIMASK(); // get the current interrupt enabled state
leothedragon 0:25fa8795676b 92 #endif
leothedragon 0:25fa8795676b 93 assert(primask & 0x1); // Interrupts must be disabled on invoking an exit from a critical section
leothedragon 0:25fa8795676b 94 #endif
leothedragon 0:25fa8795676b 95
leothedragon 0:25fa8795676b 96 interruptEnableCounter--;
leothedragon 0:25fa8795676b 97
leothedragon 0:25fa8795676b 98
leothedragon 0:25fa8795676b 99 /* Only re-enable interrupts if we are exiting the last of the nested critical sections and
leothedragon 0:25fa8795676b 100 interrupts were enabled on entry to the first critical section.
leothedragon 0:25fa8795676b 101 */
leothedragon 0:25fa8795676b 102 if (!interruptEnableCounter && !critical_primask) {
leothedragon 0:25fa8795676b 103 __enable_irq();
leothedragon 0:25fa8795676b 104 }
leothedragon 0:25fa8795676b 105 }
leothedragon 0:25fa8795676b 106 }
leothedragon 0:25fa8795676b 107
leothedragon 0:25fa8795676b 108 #endif // defined(TARGET_LIKE_MBED) && !defined(TARGET_NORDIC)