mirror of
https://github.com/espressif/esp-idf.git
synced 2025-08-04 21:24:32 +02:00
feat(spinlock): added spinlock base support on p4
This commit is contained in:
committed by
Armando (Dou Yiwen)
parent
019e68bb15
commit
c156e56684
@@ -466,8 +466,31 @@ exit:
|
|||||||
ret = xt_utils_compare_and_set(addr, compare_value, new_value);
|
ret = xt_utils_compare_and_set(addr, compare_value, new_value);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
#else // __XTENSA__
|
|
||||||
|
//TODO: IDF-7771
|
||||||
|
#else // __riscv
|
||||||
|
#if SOC_CPU_CORES_NUM > 1
|
||||||
|
/* We use lr.w and sc.w pair for riscv TAS. lr.w will read the memory and register a cpu lock signal
|
||||||
|
* The state of the lock signal is internal to core, and it is not possible for another core to
|
||||||
|
* interface. sc.w will assert the address is registered. Then write memory and release the lock
|
||||||
|
* signal. During the lr.w and sc.w time, if other core acquires the same address, will wait
|
||||||
|
*/
|
||||||
|
volatile uint32_t old_value = 0xB33FFFFF;
|
||||||
|
volatile int error = 1;
|
||||||
|
|
||||||
|
__asm__ __volatile__(
|
||||||
|
"0: lr.w %0, 0(%2) \n"
|
||||||
|
" bne %0, %3, 1f \n"
|
||||||
|
" sc.w %1, %4, 0(%2) \n"
|
||||||
|
" bnez %1, 0b \n"
|
||||||
|
"1: \n"
|
||||||
|
: "+r" (old_value), "+r" (error)
|
||||||
|
: "r" (addr), "r" (compare_value), "r" (new_value)
|
||||||
|
);
|
||||||
|
return (old_value == compare_value);
|
||||||
|
#else
|
||||||
// Single core targets don't have atomic CAS instruction. So access method is the same for internal and external RAM
|
// Single core targets don't have atomic CAS instruction. So access method is the same for internal and external RAM
|
||||||
return rv_utils_compare_and_set(addr, compare_value, new_value);
|
return rv_utils_compare_and_set(addr, compare_value, new_value);
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
@@ -13,8 +13,13 @@
|
|||||||
#if __XTENSA__
|
#if __XTENSA__
|
||||||
#include "xtensa/xtruntime.h"
|
#include "xtensa/xtruntime.h"
|
||||||
#include "xt_utils.h"
|
#include "xt_utils.h"
|
||||||
|
#else
|
||||||
|
#include "riscv/rv_utils.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
//TODO: IDF-7771, P4, see jira to know what changed and what need to be checked
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
@@ -72,11 +77,18 @@ static inline bool __attribute__((always_inline)) spinlock_acquire(spinlock_t *l
|
|||||||
esp_cpu_cycle_count_t start_count;
|
esp_cpu_cycle_count_t start_count;
|
||||||
|
|
||||||
assert(lock);
|
assert(lock);
|
||||||
|
#if __XTENSA__
|
||||||
irq_status = XTOS_SET_INTLEVEL(XCHAL_EXCM_LEVEL);
|
irq_status = XTOS_SET_INTLEVEL(XCHAL_EXCM_LEVEL);
|
||||||
|
|
||||||
// Note: The core IDs are the full 32 bit (CORE_ID_REGVAL_PRO/CORE_ID_REGVAL_APP) values
|
// Note: The core IDs are the full 32 bit (CORE_ID_REGVAL_PRO/CORE_ID_REGVAL_APP) values
|
||||||
core_id = xt_utils_get_raw_core_id();
|
core_id = xt_utils_get_raw_core_id();
|
||||||
other_core_id = CORE_ID_REGVAL_XOR_SWAP ^ core_id;
|
other_core_id = CORE_ID_REGVAL_XOR_SWAP ^ core_id;
|
||||||
|
#else //__riscv
|
||||||
|
irq_status = rv_utils_set_intlevel(RVHAL_EXCM_LEVEL);
|
||||||
|
|
||||||
|
core_id = rv_utils_get_core_id();
|
||||||
|
other_core_id = 1 - core_id;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* lock->owner should be one of SPINLOCK_FREE, CORE_ID_REGVAL_PRO,
|
/* lock->owner should be one of SPINLOCK_FREE, CORE_ID_REGVAL_PRO,
|
||||||
* CORE_ID_REGVAL_APP:
|
* CORE_ID_REGVAL_APP:
|
||||||
@@ -89,7 +101,11 @@ static inline bool __attribute__((always_inline)) spinlock_acquire(spinlock_t *l
|
|||||||
if (lock->owner == core_id) {
|
if (lock->owner == core_id) {
|
||||||
assert(lock->count > 0 && lock->count < 0xFF); // Bad count value implies memory corruption
|
assert(lock->count > 0 && lock->count < 0xFF); // Bad count value implies memory corruption
|
||||||
lock->count++;
|
lock->count++;
|
||||||
|
#if __XTENSA__
|
||||||
XTOS_RESTORE_INTLEVEL(irq_status);
|
XTOS_RESTORE_INTLEVEL(irq_status);
|
||||||
|
#else
|
||||||
|
rv_utils_restore_intlevel(irq_status);
|
||||||
|
#endif
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -126,7 +142,11 @@ exit:
|
|||||||
assert(lock->count < 0xFF); // Bad count value implies memory corruption
|
assert(lock->count < 0xFF); // Bad count value implies memory corruption
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if __XTENSA__
|
||||||
XTOS_RESTORE_INTLEVEL(irq_status);
|
XTOS_RESTORE_INTLEVEL(irq_status);
|
||||||
|
#else
|
||||||
|
rv_utils_restore_intlevel(irq_status);
|
||||||
|
#endif
|
||||||
return lock_set;
|
return lock_set;
|
||||||
|
|
||||||
#else // !CONFIG_FREERTOS_UNICORE
|
#else // !CONFIG_FREERTOS_UNICORE
|
||||||
@@ -154,9 +174,15 @@ static inline void __attribute__((always_inline)) spinlock_release(spinlock_t *l
|
|||||||
uint32_t core_id;
|
uint32_t core_id;
|
||||||
|
|
||||||
assert(lock);
|
assert(lock);
|
||||||
|
#if __XTENSA__
|
||||||
irq_status = XTOS_SET_INTLEVEL(XCHAL_EXCM_LEVEL);
|
irq_status = XTOS_SET_INTLEVEL(XCHAL_EXCM_LEVEL);
|
||||||
|
|
||||||
core_id = xt_utils_get_raw_core_id();
|
core_id = xt_utils_get_raw_core_id();
|
||||||
|
#else
|
||||||
|
irq_status = rv_utils_set_intlevel(RVHAL_EXCM_LEVEL);
|
||||||
|
|
||||||
|
core_id = rv_utils_get_core_id();
|
||||||
|
#endif
|
||||||
assert(core_id == lock->owner); // This is a lock that we didn't acquire, or the lock is corrupt
|
assert(core_id == lock->owner); // This is a lock that we didn't acquire, or the lock is corrupt
|
||||||
lock->count--;
|
lock->count--;
|
||||||
|
|
||||||
@@ -166,8 +192,12 @@ static inline void __attribute__((always_inline)) spinlock_release(spinlock_t *l
|
|||||||
assert(lock->count < 0x100); // Indicates memory corruption
|
assert(lock->count < 0x100); // Indicates memory corruption
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if __XTENSA__
|
||||||
XTOS_RESTORE_INTLEVEL(irq_status);
|
XTOS_RESTORE_INTLEVEL(irq_status);
|
||||||
#endif
|
#else
|
||||||
|
rv_utils_restore_intlevel(irq_status);
|
||||||
|
#endif //#if __XTENSA__
|
||||||
|
#endif //#if !CONFIG_FREERTOS_UNICORE && !BOOTLOADER_BUILD
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@@ -24,6 +24,9 @@ extern "C" {
|
|||||||
#define CSR_PCMR_MACHINE 0x7e1
|
#define CSR_PCMR_MACHINE 0x7e1
|
||||||
#define CSR_PCCR_MACHINE 0x7e2
|
#define CSR_PCCR_MACHINE 0x7e2
|
||||||
|
|
||||||
|
//TODO: IDF-7771
|
||||||
|
#define RVHAL_EXCM_LEVEL 4
|
||||||
|
|
||||||
/* --------------------------------------------------- CPU Control -----------------------------------------------------
|
/* --------------------------------------------------- CPU Control -----------------------------------------------------
|
||||||
*
|
*
|
||||||
* ------------------------------------------------------------------------------------------------------------------ */
|
* ------------------------------------------------------------------------------------------------------------------ */
|
||||||
|
Reference in New Issue
Block a user