12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697 |
- use core::arch::{asm, global_asm};
- use crate::interrupt;
- #[inline(always)]
- pub fn halt() {
- unsafe {
- asm!("hlt", options(att_syntax, nostack));
- }
- }
- #[inline(always)]
- pub fn pause() {
- unsafe {
- asm!("pause", options(att_syntax, nostack));
- }
- }
- #[inline(always)]
- pub fn freeze() -> ! {
- loop {
- interrupt::disable();
- halt();
- }
- }
- global_asm!(
- r"
- .macro movcfi reg, offset
- mov \reg, \offset(%rsp)
- .cfi_rel_offset \reg, \offset
- .endm
- .macro movrst reg, offset
- mov \offset(%rsp), \reg
- .cfi_restore \reg
- .endm
- .globl __context_switch_light
- .type __context_switch_light @function
- __context_switch_light:
- .cfi_startproc
- pushf
- .cfi_def_cfa_offset 0x10
- sub $0x38, %rsp # extra 8 bytes to align to 16 bytes
- .cfi_def_cfa_offset 0x48
- movcfi %rbx, 0x08
- movcfi %rbp, 0x10
- movcfi %r12, 0x18
- movcfi %r13, 0x20
- movcfi %r14, 0x28
- movcfi %r15, 0x30
- push (%rdi) # save sp of previous stack frame of current
- # acts as saving bp
- .cfi_def_cfa_offset 0x50
- mov %rsp, (%rdi) # save sp of current stack
- mov (%rsi), %rsp # load sp of target stack
- pop (%rsi) # load sp of previous stack frame of target
- # acts as restoring previous bp
- .cfi_def_cfa_offset 0x48
- pop %rax # align to 16 bytes
- .cfi_def_cfa_offset 0x40
- mov 0x28(%rsp), %r15
- mov 0x20(%rsp), %r14
- mov 0x18(%rsp), %r13
- mov 0x10(%rsp), %r12
- mov 0x08(%rsp), %rbp
- mov 0x00(%rsp), %rbx
- add $0x30, %rsp
- .cfi_def_cfa_offset 0x10
- popf
- .cfi_def_cfa_offset 0x08
- ret
- .cfi_endproc
- ",
- options(att_syntax),
- );
- extern "C" {
- fn __context_switch_light(current_task_sp: *mut usize, next_task_sp: *mut usize);
- }
- #[inline(always)]
- pub fn context_switch_light(current_task_sp: *mut usize, next_task_sp: *mut usize) {
- unsafe { __context_switch_light(current_task_sp, next_task_sp) }
- }
|