101 lines
3.4 KiB
C
101 lines
3.4 KiB
C
#ifndef __ASM_METAG_GLOBAL_LOCK_H
|
|
#define __ASM_METAG_GLOBAL_LOCK_H
|
|
|
|
#include <asm/metag_mem.h>
|
|
|
|
/**
|
|
* __global_lock1() - Acquire global voluntary lock (LOCK1).
|
|
* @flags: Variable to store flags into.
|
|
*
|
|
* Acquires the Meta global voluntary lock (LOCK1), also taking care to disable
|
|
* all triggers so we cannot be interrupted, and to enforce a compiler barrier
|
|
* so that the compiler cannot reorder memory accesses across the lock.
|
|
*
|
|
* No other hardware thread will be able to acquire the voluntary or exclusive
|
|
* locks until the voluntary lock is released with @__global_unlock1, but they
|
|
* may continue to execute as long as they aren't trying to acquire either of
|
|
* the locks.
|
|
*/
|
|
#define __global_lock1(flags) do { \
|
|
unsigned int __trval; \
|
|
asm volatile("MOV %0,#0\n\t" \
|
|
"SWAP %0,TXMASKI\n\t" \
|
|
"LOCK1" \
|
|
: "=r" (__trval) \
|
|
: \
|
|
: "memory"); \
|
|
(flags) = __trval; \
|
|
} while (0)
|
|
|
|
/**
|
|
* __global_unlock1() - Release global voluntary lock (LOCK1).
|
|
* @flags: Variable to restore flags from.
|
|
*
|
|
* Releases the Meta global voluntary lock (LOCK1) acquired with
|
|
* @__global_lock1, also taking care to re-enable triggers, and to enforce a
|
|
* compiler barrier so that the compiler cannot reorder memory accesses across
|
|
* the unlock.
|
|
*
|
|
* This immediately allows another hardware thread to acquire the voluntary or
|
|
* exclusive locks.
|
|
*/
|
|
#define __global_unlock1(flags) do { \
|
|
unsigned int __trval = (flags); \
|
|
asm volatile("LOCK0\n\t" \
|
|
"MOV TXMASKI,%0" \
|
|
: \
|
|
: "r" (__trval) \
|
|
: "memory"); \
|
|
} while (0)
|
|
|
|
/**
|
|
* __global_lock2() - Acquire global exclusive lock (LOCK2).
|
|
* @flags: Variable to store flags into.
|
|
*
|
|
* Acquires the Meta global voluntary lock and global exclusive lock (LOCK2),
|
|
* also taking care to disable all triggers so we cannot be interrupted, to take
|
|
* the atomic lock (system event) and to enforce a compiler barrier so that the
|
|
* compiler cannot reorder memory accesses across the lock.
|
|
*
|
|
* No other hardware thread will be able to execute code until the locks are
|
|
* released with @__global_unlock2.
|
|
*/
|
|
#define __global_lock2(flags) do { \
|
|
unsigned int __trval; \
|
|
unsigned int __aloc_hi = LINSYSEVENT_WR_ATOMIC_LOCK & 0xFFFF0000; \
|
|
asm volatile("MOV %0,#0\n\t" \
|
|
"SWAP %0,TXMASKI\n\t" \
|
|
"LOCK2\n\t" \
|
|
"SETD [%1+#0x40],D1RtP" \
|
|
: "=r&" (__trval) \
|
|
: "u" (__aloc_hi) \
|
|
: "memory"); \
|
|
(flags) = __trval; \
|
|
} while (0)
|
|
|
|
/**
|
|
* __global_unlock2() - Release global exclusive lock (LOCK2).
|
|
* @flags: Variable to restore flags from.
|
|
*
|
|
* Releases the Meta global exclusive lock (LOCK2) and global voluntary lock
|
|
* acquired with @__global_lock2, also taking care to release the atomic lock
|
|
* (system event), re-enable triggers, and to enforce a compiler barrier so that
|
|
* the compiler cannot reorder memory accesses across the unlock.
|
|
*
|
|
* This immediately allows other hardware threads to continue executing and one
|
|
* of them to acquire locks.
|
|
*/
|
|
#define __global_unlock2(flags) do { \
|
|
unsigned int __trval = (flags); \
|
|
unsigned int __alock_hi = LINSYSEVENT_WR_ATOMIC_LOCK & 0xFFFF0000; \
|
|
asm volatile("SETD [%1+#0x00],D1RtP\n\t" \
|
|
"LOCK0\n\t" \
|
|
"MOV TXMASKI,%0" \
|
|
: \
|
|
: "r" (__trval), \
|
|
"u" (__alock_hi) \
|
|
: "memory"); \
|
|
} while (0)
|
|
|
|
#endif /* __ASM_METAG_GLOBAL_LOCK_H */
|