OpenCores
URL https://opencores.org/ocsvn/mips32r1/mips32r1/trunk

Subversion Repositories mips32r1

[/] [mips32r1/] [trunk/] [Software/] [demos/] [XD5_Threads/] [src/] [os/] [kernel.asm] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 ayersg
###############################################################################
2
# TITLE: Thread kernel demo
3
# AUTHOR: Grant Ayers (ayers@cs.utah.edu)
4
# DATE: 30 June 2012
5
# FILENAME: kernel.asm
6
# PROJECT: University of Utah XUM Single Core
7
# DESCRIPTION:
8
#    Switches between 8 simultaneously-running threads.
9
#    Demonstrates interrupts and llsc atomic operations.
10
#
11
###############################################################################
12
 
13
 
14
        .text
15
        .balign 4
16
        .global kernel
17
        .ent    kernel
18
        .set    noreorder
19
        .set    noat
20
kernel:
21
        addiu   $sp, $sp, -1152         # Room for 9*32 registers
22
 
23
        # Set the stack pointer ($29) for each of 8 threads
24
        lui     $t0, 0x0007
25
        ori     $t0, $t0, 0x4000
26
        sw      $t0, 1140($sp)
27
        addiu   $t0, $t0, 0x4000
28
        sw      $t0, 1012($sp)
29
        addiu   $t0, $t0, 0x4000
30
        sw      $t0, 884($sp)
31
        addiu   $t0, $t0, 0x4000
32
        sw      $t0, 756($sp)
33
        addiu   $t0, $t0, 0x4000
34
        sw      $t0, 628($sp)
35
        addiu   $t0, $t0, 0x4000
36
        sw      $t0, 500($sp)
37
        addiu   $t0, $t0, 0x4000
38
        sw      $t0, 372($sp)
39
        addiu   $t0, $t0, 0x4000
40
        sw      $t0, 244($sp)
41
 
42
        # Set the global pointer ($28) for each of 8 threads
43
        sw      $gp, 240($sp)
44
        sw      $gp, 368($sp)
45
        sw      $gp, 496($sp)
46
        sw      $gp, 624($sp)
47
        sw      $gp, 752($sp)
48
        sw      $gp, 880($sp)
49
        sw      $gp, 1008($sp)
50
        sw      $gp, 1136($sp)
51
 
52
        # Set the EPC for each of 8 threads to start at main
53
        lui     $t0, main
54
        ori     $t0, $t0, main
55
        sw      $t0, 128($sp)
56
        sw      $t0, 256($sp)
57
        sw      $t0, 384($sp)
58
        sw      $t0, 512($sp)
59
        sw      $t0, 640($sp)
60
        sw      $t0, 768($sp)
61
        sw      $t0, 896($sp)
62
        sw      $t0, 1024($sp)
63
 
64
        sw      $zero, 0($sp)           # Current thread stored in 0($sp)
65
        mfc0    $k0, $12, 0             # Enable timer interrupt
66
        ori     $k0, $k0, 0x8000
67
        mtc0    $k0, $12, 0
68
 
69
$wait:
70
        j       $wait                   # Wait for interrupt to begin schedule
71
        nop
72
        .end    kernel
73
 
74
 
75
 
76
 
77
        .global scheduler
78
        .ent    scheduler
79
scheduler:
80
        addu    $k0, $0, $sp            # Recover the kernel stack pointer
81
        la      $sp, _sp
82
        addiu   $sp, $sp, -1152
83
        sw      $25, 4($sp)             # Free four registers for use
84
        sw      $28, 8($sp)
85
        sw      $30, 12($sp)
86
        sw      $31, 16($sp)
87
        lw      $k1, 0($sp)             # Current TID to k1
88
        beq     $k1, $zero, $skip_save  # Don't save kernel's registers
89
        nop
90
        jal     save_registers
91
        nop
92
$skip_save:
93
        lw      $t0, 0($sp)             # Increment TID
94
        addiu   $t0, $t0, 1
95
        addiu   $t1, $zero, 9           # Move TID back to 1 if it reaches 9
96
        beq     $t0, $t1, $reset_tid
97
        nop
98
$tid_done:
99
        sw      $t0, 0($sp)
100
        jal     restore_registers       # Load registers for next thread
101
        nop
102
        la      $k1, _sp                # Recover kernel stack pointer again
103
        addiu   $k1, $k1, -1152
104
        lw      $k1, 0($k1)             # Load TID to k1 for main function
105
        mfc0    $26, $9, 0              # Read Count to clear timer interrupt
106
        eret                            # Run thread
107
$reset_tid:
108
        addiu   $t0, $zero, 1
109
        j       $tid_done
110
        nop
111
        .end    scheduler
112
 
113
 
114
save_registers:
115
        # Requires: k0 hold thread stack pointer
116
        #           k1 holds TID
117
        #           sp points to kernel stack
118
        # Destroys:
119
 
120
        # Find offset for register table in kernel space
121
        addiu   $25, $zero, 128
122
        mul     $25, $25, $k1
123
        addu    $25, $25, $sp
124
 
125
        # Store thread stack pointer
126
        sw      $k0, 116($25)
127
        addu    $k0, $0, $25
128
 
129
        # Store EPC from CP0
130
        mfc0    $25, $14, 0
131
        sw      $25, 0($k0)
132
 
133
        # Store remaining registers
134
        sw      $1, 4($k0)
135
        sw      $2, 8($k0)
136
        sw      $3, 12($k0)
137
        sw      $4, 16($k0)
138
        sw      $5, 20($k0)
139
        sw      $6, 24($k0)
140
        sw      $7, 28($k0)
141
        sw      $8, 32($k0)
142
        sw      $9, 36($k0)
143
        sw      $10, 40($k0)
144
        sw      $11, 44($k0)
145
        sw      $12, 48($k0)
146
        sw      $13, 52($k0)
147
        sw      $14, 56($k0)
148
        sw      $15, 60($k0)
149
        sw      $16, 64($k0)
150
        sw      $17, 68($k0)
151
        sw      $18, 72($k0)
152
        sw      $19, 76($k0)
153
        sw      $20, 80($k0)
154
        sw      $21, 84($k0)
155
        sw      $22, 88($k0)
156
        sw      $23, 92($k0)
157
        sw      $24, 96($k0)
158
        lw      $25, 4($sp)
159
        sw      $25, 100($k0)
160
        lw      $28, 8($sp)
161
        sw      $28, 112($k0)
162
        lw      $30, 12($sp)
163
        sw      $30, 120($k0)
164
        addu    $k1, $0, $31
165
        lw      $31, 16($sp)
166
        sw      $31, 124($k0)
167
        jr      $k1
168
        nop
169
 
170
 
171
restore_registers:
172
        # Requires: t0 specifies which thread (1-8)
173
        #           sp points to kernel stack
174
        # Destroys: All registers
175
 
176
        # Find offset for register table in kernel space
177
        addiu   $k1, $zero, 128
178
        mul     $k0, $t0, $k1
179
        addu    $k0, $k0, $sp
180
 
181
 
182
        # Load EPC to CP0
183
        lw      $k1, 0($k0)
184
        mtc0    $k1, $14, 0
185
        # Load remaining registers
186
        lw      $1, 4($k0)
187
        lw      $2, 8($k0)
188
        lw      $3, 12($k0)
189
        lw      $4, 16($k0)
190
        lw      $5, 20($k0)
191
        lw      $6, 24($k0)
192
        lw      $7, 28($k0)
193
        lw      $8, 32($k0)
194
        lw      $9, 36($k0)
195
        lw      $10, 40($k0)
196
        lw      $11, 44($k0)
197
        lw      $12, 48($k0)
198
        lw      $13, 52($k0)
199
        lw      $14, 56($k0)
200
        lw      $15, 60($k0)
201
        lw      $16, 64($k0)
202
        lw      $17, 68($k0)
203
        lw      $18, 72($k0)
204
        lw      $19, 76($k0)
205
        lw      $20, 80($k0)
206
        lw      $21, 84($k0)
207
        lw      $22, 88($k0)
208
        lw      $23, 92($k0)
209
        lw      $24, 96($k0)
210
        lw      $25, 100($k0)
211
        lw      $28, 112($k0)
212
        lw      $29, 116($k0)
213
        lw      $30, 120($k0)
214
        addu    $k1, $0, $31
215
        lw      $31, 124($k0)
216
        jr      $k1
217
        nop
218
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.