1 /**************************************************************************/ /**
2  * @file
3  * @brief OS abstraction layer primitives for platform/security on CMSIS RTOS2
4  *******************************************************************************
5  * # License
6  * <b>Copyright 2024 Silicon Laboratories Inc. www.silabs.com</b>
7  *******************************************************************************
8  *
9  * SPDX-License-Identifier: Zlib
10  *
11  * The licensor of this software is Silicon Laboratories Inc.
12  *
13  * This software is provided 'as-is', without any express or implied
14  * warranty. In no event will the authors be held liable for any damages
15  * arising from the use of this software.
16  *
17  * Permission is granted to anyone to use this software for any purpose,
18  * including commercial applications, and to alter it and redistribute it
19  * freely, subject to the following restrictions:
20  *
21  * 1. The origin of this software must not be misrepresented; you must not
22  *    claim that you wrote the original software. If you use this software
23  *    in a product, an acknowledgment in the product documentation would be
24  *    appreciated but is not required.
25  * 2. Altered source versions must be plainly marked as such, and must not be
26  *    misrepresented as being the original software.
27  * 3. This notice may not be removed or altered from any source distribution.
28  *
29  ******************************************************************************/
30 
31 // -----------------------------------------------------------------------------
32 // Includes
33 #include "sl_common.h"
34 #include "sli_psec_osal_cmsis_rtos2.h"
35 
36 // -----------------------------------------------------------------------------
37 // Functions
38 
39 /// Check if lock is open for calling thread
SL_CODE_CLASSIFY(SL_CODE_COMPONENT_PSEC_OSAL,SL_CODE_CLASS_TIME_CRITICAL)40 SL_CODE_CLASSIFY(SL_CODE_COMPONENT_PSEC_OSAL, SL_CODE_CLASS_TIME_CRITICAL)
41 sl_status_t sli_psec_osal_lock_is_accessible(sli_psec_osal_lock_t *lock)
42 {
43   sl_status_t sl_status;
44   CORE_DECLARE_IRQ_STATE;
45   if (lock == NULL) {
46     return SL_STATUS_FAIL;
47   }
48   CORE_ENTER_CRITICAL();
49   osThreadId_t mutex_owner = osMutexGetOwner(lock->mutex_ID);
50   if (mutex_owner == NULL) {
51     sl_status = SL_STATUS_OK;
52   } else {
53     if (mutex_owner != osThreadGetId()) {
54       sl_status = SL_STATUS_FAIL;
55     } else {
56       if (lock->mutex_attr.attr_bits & osMutexRecursive) {
57         sl_status = SL_STATUS_OK;
58       } else {
59         sl_status = SL_STATUS_FAIL;
60       }
61     }
62   }
63   CORE_EXIT_CRITICAL();
64   return sl_status;
65 }
66 
67 /// Attempt to take ownership or lock. Wait until available if already locked, or timeout.
sli_psec_osal_take_lock_timeout(sli_psec_osal_lock_t * lock,uint32_t timeout)68 sl_status_t sli_psec_osal_take_lock_timeout(sli_psec_osal_lock_t *lock, uint32_t timeout)
69 {
70   if (lock == NULL) {
71     return SL_STATUS_FAIL;
72   }
73 
74   osStatus_t status = osOK;
75   if (osKernelGetState() == osKernelRunning) {
76     if (CORE_IRQ_DISABLED()) {
77       return sli_psec_osal_lock_is_accessible(lock);
78     } else {
79       status = osMutexAcquire(lock->mutex_ID, timeout);
80     }
81   }
82   return (status == osOK ? SL_STATUS_OK : SL_STATUS_FAIL);
83 }
84 
85 /// Release ownership of a lock.
sli_psec_osal_give_lock(sli_psec_osal_lock_t * lock)86 sl_status_t sli_psec_osal_give_lock(sli_psec_osal_lock_t *lock)
87 {
88   if (lock == NULL) {
89     return SL_STATUS_FAIL;
90   }
91 
92   osStatus_t status = osOK;
93   if (osKernelGetState() == osKernelRunning) {
94     if (CORE_IRQ_DISABLED()) {
95       return sli_psec_osal_lock_is_accessible(lock);
96     } else {
97       status = osMutexRelease(lock->mutex_ID);
98     }
99   }
100 
101   return (status == osOK ? SL_STATUS_OK : SL_STATUS_FAIL);
102 }
103