GitHub

Original file line numberDiff line numberDiff line change

@@ -0,0 +1,75 @@

1+

[EXTERN _current_task_small]

2+

[EXTERN _task_context_offset]

3+

[EXTERN task_die]

4+
5+

[GLOBAL context_switch]

6+

[GLOBAL _task_bootstrap]

7+

[GLOBAL _first_context_switch]

8+
9+

_first_context_switch:

10+

; Save arg to function containing task to switch to in ecx

11+

mov rcx, rdi

12+

jmp _context_switch_restore_state

13+
14+
15+

context_switch:

16+

; Save arg to function containing task to switch to in ecx

17+

mov rcx, rdi

18+
19+

;Save the old task's state

20+

; Save registers that are supposed to be callee-saved

21+

push rax

22+

push rbx

23+

push rsi

24+

push rdi

25+

push rbp

26+
27+

; Save preempted task's esp as _current_task->machine_state

28+

mov rax, [_current_task_small]

29+

mov rbx, [_task_context_offset]

30+

add rax, rbx

31+

mov [rax], rsp

32+
33+

;Load the new task's state

34+

_context_switch_restore_state:

35+

; Set the provided argument to _current_task_small

36+

mov [_current_task_small], rcx

37+
38+

; Load rsp with _current_task->machine_state

39+

mov rbx, [_task_context_offset]

40+

add rcx, rbx

41+

mov rsp,[rcx]

42+
43+

; Restore registers that were callee-saved

44+

pop rbp

45+

pop rdi

46+

pop rsi

47+

pop rbx

48+

pop rax

49+
50+

; Return to the new task's EIP (that was stored on its stack)

51+

sti

52+

ret

53+
54+
55+

_task_bootstrap:

56+

; rsp+8: entry point pointer

57+

; rsp+16: entry point arg1

58+

; rsp+24: entry point arg2

59+

; rsp+32: entry point arg3

60+

; Entry point arg1

61+

mov rdi, [rsp+16]

62+

; Entry point arg2

63+

mov rsi, [rsp+24]

64+

; Entry point arg3

65+

mov rdx, [rsp+32]

66+

; Entry point

67+

call [rsp+8]

68+
69+

mov rdx, rax

70+

call task_die

71+

; Should never execute...

72+

; Try to force a page fault

73+

mov rax, 0x0

74+

call rax

75+

ret

Read the original on github.com ↗