gint-with-thread/src/kernel/atomic.S

88 lines
1.5 KiB
ArmAsm

/*
** gint:thread:atomic - Thread atomic helper
*/
.text
.align 2
.global _atomic_begin
.type _atomic_begin, @function
/* thread_atomic_begin(): Mask interrupts and exceptions */
_atomic_begin:
/* Check if the user is currently into an atomic state and update
atomic counter. */
mov.l atomic_counter, r1
mov.l @r1, r2
tst r2, r2
add #1, r2
mov.l r2, @r1
bf/s atomic_begin_exit
mov #-1, r0
/* Block all interrupts by setting IMASK=15 */
mov #0xf, r1
shll2 r1
shll2 r1
stc sr, r0
or r0, r1
ldc r1, sr
/* Save "old" SR register. */
mov.l atomic_sr_save, r1
mov.l r0, @r1
atomic_begin_exit:
rts
nop
.global _atomic_end
.type _atomic_end, @function
/* atomic_end(): Unmask (if possible) interrupts / exceptions signals */
_atomic_end:
/* Check if the device is currently into an atomic operation, then
update the counter and, if needed, restore the SR register. */
mov.l atomic_counter, r1
mov.l @r1, r0
tst r0, r0
bt atomic_end_error
cmp/eq #1, r0
add #-1, r0
mov.l r0, @r1
bf/s atomic_end_exit
mov #0, r0
/* Restore saved SR register data. */
mov.l atomic_sr_save, r1
mov.l @r1, r0
ldc r0, sr
bra atomic_end_exit
nop
atomic_end_error:
mov #-1, r0
atomic_end_exit:
rts
nop
.align 4
atomic_counter: .long _atomic_counter
atomic_sr_save: .long _atomic_sr_save
/*
** Global symbols
*/
.global _atomic_sr_save
.type _atomic_sr_save, @object
.global _atomic_counter
.type _atomic_counter, @object
.align 4
_atomic_sr_save: .long 0x00000000
_atomic_counter: .long 0x00000000