task.rs 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. use core::arch::{asm, global_asm};
  2. use crate::interrupt;
  3. #[inline(always)]
  4. pub fn halt() {
  5. unsafe {
  6. asm!("hlt", options(att_syntax, nostack));
  7. }
  8. }
  9. #[inline(always)]
  10. pub fn pause() {
  11. unsafe {
  12. asm!("pause", options(att_syntax, nostack));
  13. }
  14. }
  15. #[inline(always)]
  16. pub fn freeze() -> ! {
  17. loop {
  18. interrupt::disable();
  19. halt();
  20. }
  21. }
  22. global_asm!(
  23. r"
  24. .macro movcfi reg, offset
  25. mov \reg, \offset(%rsp)
  26. .cfi_rel_offset \reg, \offset
  27. .endm
  28. .macro movrst reg, offset
  29. mov \offset(%rsp), \reg
  30. .cfi_restore \reg
  31. .endm
  32. .globl __context_switch_light
  33. .type __context_switch_light @function
  34. __context_switch_light:
  35. .cfi_startproc
  36. pushf
  37. .cfi_def_cfa_offset 0x10
  38. sub $0x38, %rsp # extra 8 bytes to align to 16 bytes
  39. .cfi_def_cfa_offset 0x48
  40. movcfi %rbx, 0x08
  41. movcfi %rbp, 0x10
  42. movcfi %r12, 0x18
  43. movcfi %r13, 0x20
  44. movcfi %r14, 0x28
  45. movcfi %r15, 0x30
  46. push (%rdi) # save sp of previous stack frame of current
  47. # acts as saving bp
  48. .cfi_def_cfa_offset 0x50
  49. mov %rsp, (%rdi) # save sp of current stack
  50. mov (%rsi), %rsp # load sp of target stack
  51. pop (%rsi) # load sp of previous stack frame of target
  52. # acts as restoring previous bp
  53. .cfi_def_cfa_offset 0x48
  54. pop %rax # align to 16 bytes
  55. .cfi_def_cfa_offset 0x40
  56. mov 0x28(%rsp), %r15
  57. mov 0x20(%rsp), %r14
  58. mov 0x18(%rsp), %r13
  59. mov 0x10(%rsp), %r12
  60. mov 0x08(%rsp), %rbp
  61. mov 0x00(%rsp), %rbx
  62. add $0x30, %rsp
  63. .cfi_def_cfa_offset 0x10
  64. popf
  65. .cfi_def_cfa_offset 0x08
  66. ret
  67. .cfi_endproc
  68. ",
  69. options(att_syntax),
  70. );
  71. extern "C" {
  72. fn __context_switch_light(current_task_sp: *mut usize, next_task_sp: *mut usize);
  73. }
  74. #[inline(always)]
  75. pub fn context_switch_light(current_task_sp: *mut usize, next_task_sp: *mut usize) {
  76. unsafe { __context_switch_light(current_task_sp, next_task_sp) }
  77. }