# os/src/task/switch.S

.altmacro
.macro SAVE_SN n
    sd s\n, (\n+2)*8(a0)  # 将寄存器s(n)的值保存到当前任务的上下文中
.endm

.macro LOAD_SN n
    ld s\n, (\n+2)*8(a1)  # 从下一个任务的上下文中加载寄存器s(n)的值
.endm
    .section .text
    .globl __switch

__switch:
    # 阶段 [1]
    # __switch(
    #     current_task_cx_ptr: *mut TaskContext,
    #     next_task_cx_ptr: *const TaskContext
    # )

    # 阶段 [2] 保存当前寄存器状态到 current_task_cx_ptr
    # save kernel stack of current task
    sd sp, 8(a0)  # 将当前任务的在内核栈顶 保存到当前任务current_task_cx_ptr的上下文中
    # save ra & s0~s11 of current execution
    sd ra, 0(a0)  # 将当前执行的ra和s0~s11寄存器的值保存到当前任务current_task_cx_ptr的上下文中
    .set n, 0
    .rept 12
        SAVE_SN %n  # 保存寄存器s0~s11的值到当前任务的上下文中
        .set n, n + 1
    .endr

    # 阶段 [3] 恢复next_task_cx_ptr 的状态
    # restore ra & s0~s11 of next execution
    ld ra, 0(a1)  # 从下一个任务的上下文中加载ra寄存器的值
    .set n, 0
    .rept 12
        LOAD_SN %n  # 从下一个任务的上下文中加载寄存器s0~s11的值
        .set n, n + 1
    .endr
    # restore kernel stack of next task
    ld sp, 8(a1)  # 从下一个任务的上下文中加载内核栈栈顶的值
    # 阶段 [4]
    ret  # 返回到下一个任务的执行点
