/* ** 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