/*
 * Copyright (c) 2026, Chloe M.
 * Provided under the BSD-3 clause.
 *
 * Description: AMD64 bugcheck wrapper
 * Author:      Chloe M.
 */

    .text
    .globl KeBugCheck
KeBugCheck:
    cli                 /* Disable interrupts */
    cld                 /* Just in case */
    mov $1, %rax        /* Prep the lock */
    xchg %rax, MpLock   /* Acquire the lock */
    or %rax, %rax       /* Are we another core? */
    jnz .LockOut        /* Yes, lock out */

    /*
     * During most cases in which an interrupt occurs, the processor
     * is to automatically switch to its own interrupt stack and during
     * such cases it is guaranteed that the stack is safe. However, we still
     * cannot trust the stack as we do not know if we are coming from an interrupt
     * or not and thus need to update it to avoid dodgy states from worsening our
     * problem... Whatever it is...
     */
    lea StackTop(%rip), %rsp

    /* From here we can call the actual bugcheck handler */
    call KiBugCheck
.LockOut:
    hlt
    jmp .LockOut

    .section .data
MpLock: .quad 0

/* Our bugcheck stack */
Stack:  .fill 4096, 1, 0
StackTop:
