/* x86_64 hardware locks these are raw spinlocks with support for irq saving and restoring */ .global ml_hwlock_lock .type ml_hwlock_lock, @function /* %rdi = pointer to ml_hwlock_t (int) */ ml_hwlock_lock: push %rbp mov %rsp, %rbp mov $1, %ecx cli mfence 1: mov $0, %eax lock cmpxchg %ecx, (%rdi) jne 1b pop %rbp ret .global ml_hwlock_unlock .type ml_hwlock_unlock, @function /* %rdi = pointer to ml_hwlock_t (int) */ ml_hwlock_unlock: push %rbp mov %rsp, %rbp movl $0, (%rdi) mfence sti pop %rbp ret .global ml_hwlock_lock_irqsave .type ml_hwlock_lock_irqsave, @function /* %rdi = pointer to ml_hwlock_t (int) %rsi = pointer to quadword to store rflags in */ ml_hwlock_lock_irqsave: push %rbp mov %rsp, %rbp pushfq popq (%rsi) cli mov $1, %ecx mfence 1: mov $0, %eax lock cmpxchg %ecx, (%rdi) jne 1b pop %rbp ret .global ml_hwlock_unlock_irqrestore .type ml_hwlock_unlock_irqrestore, @function /* %rdi = pointer to ml_hwlock_t (int) %rsi = quadword with saved rflags */ ml_hwlock_unlock_irqrestore: push %rbp mov %rsp, %rbp movl $0, (%rdi) mfence pushfq popq %rax /* rax = the current rflags register */ /* rsi = the saved rflags register */ andq $0x200, %rsi /* we only want to copy IF (bit 9, 0x200) */ andq $0xFFFFFFFFFFFFFDFF, %rax orq %rsi, %rax pushq %rsi popfq pop %rbp ret .global get_rflags .type get_rflags, @function get_rflags: push %rbp mov %rsp, %rbp pushfq popq %rax pop %rbp ret