#include <string.h>
#include <stdio.h>
-#include <sys/lock.h>
#include <byteswap.h>
#include <assert.h>
return SHA_1_CONTINUE_REG + sha_type * 0x10;
}
-/* Single lock for SHA engine memory block
+/* Single spinlock for SHA engine memory block
*/
-static _lock_t memory_block_lock;
+static portMUX_TYPE memory_block_lock = portMUX_INITIALIZER_UNLOCKED;
/* Binary semaphore managing the state of each concurrent SHA engine.
static uint8_t engines_in_use;
-/* Lock for engines_in_use counter
+/* Spinlock for engines_in_use counter
*/
-static _lock_t engines_in_use_lock;
+static portMUX_TYPE engines_in_use_lock = portMUX_INITIALIZER_UNLOCKED;
/* Index into the engine_states array */
inline static size_t sha_engine_index(esp_sha_type type) {
void esp_sha_lock_memory_block(void)
{
- _lock_acquire(&memory_block_lock);
+ portENTER_CRITICAL(&memory_block_lock);
}
void esp_sha_unlock_memory_block(void)
{
- _lock_release(&memory_block_lock);
+ portEXIT_CRITICAL(&memory_block_lock);
}
static SemaphoreHandle_t sha_get_engine_state(esp_sha_type sha_type)
return false;
}
- _lock_acquire(&engines_in_use_lock);
+ portENTER_CRITICAL(&engines_in_use_lock);
if (engines_in_use == 0) {
/* Just locked first engine,
engines_in_use++;
assert(engines_in_use <= 3);
- _lock_release(&engines_in_use_lock);
+ portEXIT_CRITICAL(&engines_in_use_lock);
return true;
}
{
SemaphoreHandle_t *engine_state = sha_get_engine_state(sha_type);
- _lock_acquire(&engines_in_use_lock);
+ portENTER_CRITICAL(&engines_in_use_lock);
engines_in_use--;
periph_module_disable(PERIPH_SHA_MODULE);
}
- _lock_release(&engines_in_use_lock);
+ portEXIT_CRITICAL(&engines_in_use_lock);
xSemaphoreGive(engine_state);
}
}
#endif
+ // preemptively do this before entering the critical section, then re-check once in it
+ esp_sha_wait_idle();
+
esp_sha_lock_memory_block();
esp_sha_wait_idle();
}
#endif
+ // preemptively do this before entering the critical section, then re-check once in it
+ esp_sha_wait_idle();
+
esp_sha_lock_memory_block();
esp_sha_wait_idle();
* while it is in use by the SHA engine. Caller should use esp_sha_wait_idle()
* to ensure the SHA engine is not reading from the memory block in hardware.
*
+ * @note This function enters a critical section. Do not block while holding this lock.
+ *
* @note You do not need to lock the memory block before calling esp_sha_block() or esp_sha_read_digest_state(), these functions handle memory block locking internally.
*
* Call esp_sha_unlock_memory_block() when done.
*
* Caller should have already locked a SHA engine before calling this function.
*
+ * This function releases the critical section entered by esp_sha_lock_memory_block().
+ *
* Call following esp_sha_lock_memory_block().
*/
void esp_sha_unlock_memory_block(void);