compare_set.c 1.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041
  1. /*
  2. * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. #include "soc/compare_set.h"
  7. #include "soc/spinlock.h"
  8. #include "soc/soc_caps.h"
  9. #if __XTENSA__ && SOC_SPIRAM_SUPPORTED
  10. static spinlock_t global_extram_lock = SPINLOCK_INITIALIZER;
  11. void compare_and_set_extram(volatile uint32_t *addr, uint32_t compare, uint32_t *set)
  12. {
  13. uint32_t intlevel, old_value;
  14. __asm__ __volatile__ ("rsil %0, " XTSTR(XCHAL_EXCM_LEVEL) "\n"
  15. : "=r"(intlevel));
  16. spinlock_acquire(&global_extram_lock, SPINLOCK_WAIT_FOREVER);
  17. old_value = *addr;
  18. if (old_value == compare) {
  19. *addr = *set;
  20. }
  21. spinlock_release(&global_extram_lock);
  22. __asm__ __volatile__ ("memw \n"
  23. "wsr %0, ps\n"
  24. :: "r"(intlevel));
  25. *set = old_value;
  26. }
  27. #else // __XTENSA__ && SOC_SPIRAM_SUPPORTED
  28. void compare_and_set_extram(volatile uint32_t *addr, uint32_t compare, uint32_t *set)
  29. {
  30. compare_and_set_native(addr, compare, set);
  31. }
  32. #endif // endif