diff --git a/ch3/os/src/task/mod.rs b/ch3/os/src/task/mod.rs index 019f068..d541cf9 100644 --- a/ch3/os/src/task/mod.rs +++ b/ch3/os/src/task/mod.rs @@ -1 +1,2 @@ -mod context; \ No newline at end of file +mod context; +mod switch; \ No newline at end of file diff --git a/ch3/os/src/task/switch.S b/ch3/os/src/task/switch.S new file mode 100644 index 0000000..a451f88 --- /dev/null +++ b/ch3/os/src/task/switch.S @@ -0,0 +1,43 @@ +# 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 # 返回到下一个任务的执行点 diff --git a/ch3/os/src/task/switch.rs b/ch3/os/src/task/switch.rs new file mode 100644 index 0000000..6766699 --- /dev/null +++ b/ch3/os/src/task/switch.rs @@ -0,0 +1,11 @@ +use core::arch::global_asm; +global_asm!(include_str!("switch.S")); // 读入switch.S 到当前代码 + +use super::context::TaskContext; +extern "C" { + // 引入 switch.S 中的切换函数 + pub fn __switch( + current_task_cx_ptr: *mut TaskContext, + next_task_cx_ptr: *const TaskContext + ); +}