

// TCB的字段 用来保存cpu 在内核切换人物的时候 寄存器还有栈顶的信息, 这个结构体将来会传到 switch.S 中的汇编中
#[derive(Copy, Clone)]
#[repr(C)]
pub struct TaskContext{
    ra: usize,  // 保存了进行切换完毕之后需要 跳转继续执行的地址
    sp: usize,  // 当前任务的在内核中的内核栈的栈顶, 这个会被switch 保存与恢复
    s: [usize; 12]  // 当前任务内核 有必要 保存的寄存器
}


impl TaskContext{
    // 初始的内容
    pub fn new() -> Self {
        Self {
            ra: 0,
            sp: 0,
            s: [0; 12],
        }
    }

    // 从kernel_stack_ptr 创建一个 任务上下文
    // 并把任务上下文的返回地址设置为 trap.S的返回符号的地方
    pub fn from(kernel_stack_ptr: usize) -> Self{
        extern "C" {
            fn __restore();
        }
        Self {
            ra: __restore as usize,  // 新创建的任务, 在switch ret 之后 直接进入 trap返回函数
            sp: kernel_stack_ptr,  // 这里设置 应用内核栈的栈顶了, 后面会被switch 恢复, 所以我们在trap.S中 注释mv sp, a0
            s: [0; 12],
        }
    }
}
