7#ifndef _HARDWARE_SYNC_H
8#define _HARDWARE_SYNC_H
12#include "hardware/regs/sio.h"
49#ifndef PARAM_ASSERTIONS_ENABLED_SYNC
50#define PARAM_ASSERTIONS_ENABLED_SYNC 0
59#ifndef PICO_SPINLOCK_ID_IRQ
60#define PICO_SPINLOCK_ID_IRQ 9
64#ifndef PICO_SPINLOCK_ID_TIMER
65#define PICO_SPINLOCK_ID_TIMER 10
69#ifndef PICO_SPINLOCK_ID_HARDWARE_CLAIM
70#define PICO_SPINLOCK_ID_HARDWARE_CLAIM 11
74#ifndef PICO_SPINLOCK_ID_RAND
75#define PICO_SPINLOCK_ID_RAND 12
79#ifndef PICO_SPINLOCK_ID_OS1
80#define PICO_SPINLOCK_ID_OS1 14
84#ifndef PICO_SPINLOCK_ID_OS2
85#define PICO_SPINLOCK_ID_OS2 15
89#ifndef PICO_SPINLOCK_ID_STRIPED_FIRST
90#define PICO_SPINLOCK_ID_STRIPED_FIRST 16
94#ifndef PICO_SPINLOCK_ID_STRIPED_LAST
95#define PICO_SPINLOCK_ID_STRIPED_LAST 23
99#ifndef PICO_SPINLOCK_ID_CLAIM_FREE_FIRST
100#define PICO_SPINLOCK_ID_CLAIM_FREE_FIRST 24
103#ifdef PICO_SPINLOCK_ID_CLAIM_FREE_END
104#warning PICO_SPINLOCK_ID_CLAIM_FREE_END has been renamed to PICO_SPINLOCK_ID_CLAIM_FREE_LAST
108#ifndef PICO_SPINLOCK_ID_CLAIM_FREE_LAST
109#define PICO_SPINLOCK_ID_CLAIM_FREE_LAST 31
117#if !__has_builtin(__sev)
119 pico_default_asm_volatile (
"sev");
129#if !__has_builtin(__wfe)
131 pico_default_asm_volatile (
"wfe");
140#if !__has_builtin(__wfi)
142 pico_default_asm_volatile(
"wfi");
153 pico_default_asm_volatile(
"dmb" : : :
"memory");
164 pico_default_asm_volatile(
"dsb" : : :
"memory");
175 pico_default_asm_volatile(
"isb" :::
"memory");
216 pico_default_asm_volatile(
229 pico_default_asm_volatile(
"msr PRIMASK,%0"::
"r" (status) : );
239 invalid_params_if(SYNC, lock_num >= NUM_SPIN_LOCKS);
240 return (
spin_lock_t *) (SIO_BASE + SIO_SPINLOCK0_OFFSET + lock_num * 4);
250 invalid_params_if(SYNC, (uint) lock < SIO_BASE + SIO_SPINLOCK0_OFFSET ||
251 (uint) lock >= NUM_SPIN_LOCKS *
sizeof(
spin_lock_t) + SIO_BASE + SIO_SPINLOCK0_OFFSET ||
252 ((uint) lock - SIO_BASE + SIO_SPINLOCK0_OFFSET) %
sizeof(
spin_lock_t) != 0);
253 return (uint) (lock - (
spin_lock_t *) (SIO_BASE + SIO_SPINLOCK0_OFFSET));
265 while (__builtin_expect(!*lock, 0));
301 return 0 != (*(io_ro_32 *) (SIO_BASE + SIO_SPINLOCK_ST_OFFSET) & (1u << lock_num));
401#define remove_volatile_cast(t, x) ({__compiler_memory_barrier(); Clang_Pragma("clang diagnostic push"); Clang_Pragma("clang diagnostic ignored \"-Wcast-qual\""); (t)(x); Clang_Pragma("clang diagnostic pop"); })
static __force_inline uint32_t spin_lock_blocking(spin_lock_t *lock)
Acquire a spin lock safely.
Definition sync.h:287
int spin_lock_claim_unused(bool required)
Claim a free spin lock.
Definition sync.c:56
static __force_inline uint32_t save_and_disable_interrupts(void)
Save and disable interrupts.
Definition sync.h:214
void spin_lock_unclaim(uint lock_num)
Mark a spin lock as no longer used.
Definition sync.c:50
static __force_inline void __mem_fence_release(void)
Release a memory fence.
Definition sync.h:197
static __force_inline void spin_unlock_unsafe(spin_lock_t *lock)
Release a spin lock without re-enabling interrupts.
Definition sync.h:274
static __force_inline void spin_unlock(spin_lock_t *lock, uint32_t saved_irq)
Release a spin lock safely.
Definition sync.h:314
void spin_lock_claim_mask(uint32_t lock_num_mask)
Mark multiple spin locks as used.
Definition sync.c:44
static __force_inline void __sev(void)
Insert a SEV instruction in to the code path.
Definition sync.h:118
void spin_lock_claim(uint lock_num)
Mark a spin lock as used.
Definition sync.c:39
static __force_inline void __dmb(void)
Insert a DMB instruction in to the code path.
Definition sync.h:152
void spin_locks_reset(void)
Release all spin locks.
Definition sync.c:18
static __force_inline void __wfe(void)
Insert a WFE instruction in to the code path.
Definition sync.h:130
static __force_inline void restore_interrupts(uint32_t status)
Restore interrupts to a specified state.
Definition sync.h:228
static __force_inline spin_lock_t * spin_lock_instance(uint lock_num)
Get HW Spinlock instance from number.
Definition sync.h:238
uint next_striped_spin_lock_num(void)
Return a spin lock number from the striped range.
Definition sync.c:31
bool spin_lock_is_claimed(uint lock_num)
Determine if a spin lock is claimed.
Definition sync.c:60
static __force_inline void __mem_fence_acquire(void)
Acquire a memory fence.
Definition sync.h:181
static __force_inline void __wfi(void)
Insert a WFI instruction in to the code path.
Definition sync.h:141
static __force_inline void spin_lock_unsafe_blocking(spin_lock_t *lock)
Acquire a spin lock without disabling interrupts (hence unsafe)
Definition sync.h:261
volatile uint32_t spin_lock_t
A spin lock identifier.
Definition sync.h:56
spin_lock_t * spin_lock_init(uint lock_num)
Initialise a spin lock.
Definition sync.c:24
static __force_inline uint spin_lock_get_num(spin_lock_t *lock)
Get HW Spinlock number from instance.
Definition sync.h:249
static bool is_spin_locked(spin_lock_t *lock)
Check to see if a spinlock is currently acquired elsewhere.
Definition sync.h:298
static __force_inline void __isb(void)
Insert a ISB instruction in to the code path.
Definition sync.h:174
static __force_inline void __dsb(void)
Insert a DSB instruction in to the code path.
Definition sync.h:163