glue.s 4.42 KB
Newer Older
Henry K. Sun's avatar
Henry K. Sun committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#============================================================================
# Keep a pointer to the main scheduler context.  This variable should be
# initialized to %rsp, which is done in the __sthread_start routine.
#
        .data
        .align 8
scheduler_context:      .quad   0


#============================================================================
# __sthread_switch is the main entry point for the thread scheduler.
# It has three parts:
#
#    1. Save the context of the current thread on the stack.
#       The context includes all of the integer registers and RFLAGS.
#
#    2. Call __sthread_scheduler (the C scheduler function), passing the
#       context as an argument.  The scheduler stack *must* be restored by
#       setting %rsp to the scheduler_context before __sthread_scheduler is
#       called.
#
#    3. __sthread_scheduler will return the context of a new thread.
#       Restore the context, and return to the thread.
#
        .text
        .align 8
        .globl __sthread_switch
__sthread_switch:

        # Save the process state onto its stack
Nikhil Ghosh's avatar
Nikhil Ghosh committed
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
        pushq   %rax
        pushq   %rbx
        pushq   %rcx
        pushq   %rdx
        pushq   %rsi
        pushq   %rdi
        pushq   %rbp

        pushq   %r8
        pushq   %r9
        pushq   %r10
        pushq   %r11
        pushq   %r12
        pushq   %r13
        pushq   %r14
        pushq   %r15

        pushf
Henry K. Sun's avatar
Henry K. Sun committed
49
50
51
52
53
54
55
56
57
58

        # Call the high-level scheduler with the current context as an argument
        movq    %rsp, %rdi
        movq    scheduler_context(%rip), %rsp
        call    __sthread_scheduler

        # The scheduler will return a context to start.
        # Restore the context to resume the thread.
__sthread_restore:

Nikhil Ghosh's avatar
Nikhil Ghosh committed
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
        # returned context is new stack
        movq %rax, %rsp

        popf 

        popq   %r15
        popq   %r14
        popq   %r13
        popq   %r12
        popq   %r11
        popq   %r10
        popq   %r9
        popq   %r8

        popq   %rbp
        popq   %rdi
        popq   %rsi
        popq   %rdx
        popq   %rcx
        popq   %rbx
        popq   %rax
Henry K. Sun's avatar
Henry K. Sun committed
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101

        ret


#============================================================================
# Initialize a process context, given:
#    1. the stack for the process
#    2. the function to start
#    3. its argument
# The context should be consistent with that saved in the __sthread_switch
# routine.
#
# A pointer to the newly initialized context is returned to the caller.
# (This is the thread's stack-pointer after its context has been set up.)
#
# This function is described in more detail in sthread.c.
#
#
        .align 8
        .globl __sthread_initialize_context
__sthread_initialize_context:

Nikhil Ghosh's avatar
Nikhil Ghosh committed
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
        # %rdi - stackp, %rsi - f, %rdx - arg
        # return value in %rax is the stack pointer,
        # leave 144 bytes for thread context details and return address.
        movq    %rdi, %rax
        subq    $144, %rax

        leaq    __sthread_finish(%rip), %rdi      
        movq    %rdi,  136(%rax)          # kill thread when done with f
        movq    %rsi,  128(%rax)          # address of f to come back to
        movq    $0,    120(%rax)          # rax = 0
        movq    $0,    112(%rax)          # rcx = 0
        movq    $0,    96(%rax)           # rdx = 0
        movq    $0,    88(%rax)           # rsi = 0
        movq    %rdx,  80(%rax)           # rdi = arg
        movq    $0,    72(%rax)           # rbp = 0
        movq    $0,    64(%rax)           # r9  = 0
        movq    $0,    48(%rax)           # r10 = 0
        movq    $0,    40(%rax)           # r11 = 0
        movq    $0,    32(%rax)           # r12 = 0
        movq    $0,    24(%rax)           # r13 = 0
        movq    $0,    16(%rax)           # r14 = 0
        movq    $0,    8(%rax)            # r15 = 0
        movq    $0,    (%rax)             # rflags = 0
Henry K. Sun's avatar
Henry K. Sun committed
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147

        ret


#============================================================================
# The start routine initializes the scheduler_context variable, and calls
# the __sthread_scheduler with a NULL context.
#
# The scheduler will return a context to resume.
#
        .align 8
        .globl __sthread_start
__sthread_start:
        # Remember the context
        movq    %rsp, scheduler_context(%rip)

        # Call the scheduler with no context
        movl    $0, %edi  # Also clears upper 4 bytes of %rdi
        call    __sthread_scheduler

        # Restore the context returned by the scheduler
        jmp     __sthread_restore