Commit | Line | Data |
---|---|---|
4bd1c0bf WN |
1 | /*- |
2 | * Copyright (c) 1990 The Regents of the University of California. | |
3 | * All rights reserved. | |
4 | * | |
5 | * This code is derived from software contributed to Berkeley by | |
6 | * William Jolitz. | |
876e2d36 | 7 | * |
4bd1c0bf WN |
8 | * %sccs.include.386.c% |
9 | * | |
9c09b4f2 | 10 | * @(#)locore.s 5.5 (Berkeley) %G% |
4bd1c0bf WN |
11 | */ |
12 | ||
13 | /* | |
14 | * locore.s: 4BSD machine support for the Intel 386 | |
15 | * Preliminary version | |
16 | * Written by William F. Jolitz, 386BSD Project | |
876e2d36 BJ |
17 | */ |
18 | ||
19 | #include "psl.h" | |
20 | #include "pte.h" | |
21 | ||
22 | #include "errno.h" | |
23 | #include "cmap.h" | |
24 | ||
25 | #include "../i386/trap.h" | |
876e2d36 | 26 | |
4bd1c0bf WN |
27 | /* |
28 | * Note: This version greatly munged to avoid various assembler errors | |
29 | * that may be fixed in newer versions of gas. Perhaps newer versions | |
30 | * will have more pleasant appearance. | |
31 | */ | |
876e2d36 BJ |
32 | |
33 | .set IDXSHIFT,10 | |
34 | .set SYSTEM,0xFE000000 # virtual address of system start | |
35 | /*note: gas copys sign bit (e.g. arithmetic >>), can't do SYSTEM>>22! */ | |
36 | .set SYSPDROFF,0x3F8 # Page dir | |
37 | ||
38 | .set IOPHYSmem,0xa0000 | |
39 | ||
4bd1c0bf | 40 | /* IBM "compatible" nop - sensitive macro on "fast" 386 machines */ |
8cbc2ebb | 41 | #define NOP jmp 7f ; nop ; 7: jmp 7f ; nop ; 7: |
6595ba46 | 42 | |
876e2d36 BJ |
43 | /* |
44 | * User structure is UPAGES at top of user space. | |
45 | */ | |
46 | .set _u,0xFDFFE000 | |
47 | .globl _u | |
48 | .set UPDROFF,0x3F7 | |
49 | .set UPTEOFF,0x3FE | |
50 | ||
ec13cb01 | 51 | #define ENTRY(name) \ |
4bd1c0bf | 52 | .globl _/**/name; _/**/name: |
ec13cb01 | 53 | #define ALTENTRY(name) \ |
4bd1c0bf | 54 | .globl _/**/name; _/**/name: |
876e2d36 BJ |
55 | |
56 | /* | |
57 | * System page table | |
58 | * Mbmap and Usrptmap are enlarged by CLSIZE entries | |
59 | * as they are managed by resource maps starting with index 1 or CLSIZE. | |
60 | */ | |
61 | #define SYSMAP(mname, vname, npte) \ | |
4bd1c0bf | 62 | _/**/mname: .globl _/**/mname; \ |
876e2d36 | 63 | .space (npte)*4; \ |
8cbc2ebb | 64 | .set _/**/vname,ptes*NBPG+SYSTEM; \ |
4bd1c0bf | 65 | .globl _/**/vname; \ |
876e2d36 BJ |
66 | .set ptes,ptes + npte |
67 | #define ZSYSMAP(mname, vname, npte) \ | |
4bd1c0bf | 68 | _/**/mname: .globl _/**/mname; \ |
8cbc2ebb | 69 | .set _/**/vname,ptes*NBPG+SYSTEM; \ |
4bd1c0bf | 70 | .globl _/**/vname; |
876e2d36 BJ |
71 | |
72 | .data | |
73 | # assumed to start at data mod 4096 | |
74 | .set ptes,0 | |
75 | SYSMAP(Sysmap,Sysbase,SYSPTSIZE) | |
76 | SYSMAP(Forkmap,forkutl,UPAGES) | |
77 | SYSMAP(Xswapmap,xswaputl,UPAGES) | |
78 | SYSMAP(Xswap2map,xswap2utl,UPAGES) | |
79 | SYSMAP(Swapmap,swaputl,UPAGES) | |
80 | SYSMAP(Pushmap,pushutl,UPAGES) | |
81 | SYSMAP(Vfmap,vfutl,UPAGES) | |
82 | SYSMAP(CMAP1,CADDR1,1) | |
83 | SYSMAP(CMAP2,CADDR2,1) | |
84 | SYSMAP(mmap,vmmap,1) | |
85 | SYSMAP(alignmap,alignutl,1) /* XXX */ | |
86 | SYSMAP(msgbufmap,msgbuf,MSGBUFPTECNT) | |
8cbc2ebb BJ |
87 | /* SYSMAP(EMCmap,EMCbase,1) */ |
88 | SYSMAP(Npxmap,npxutl,UPAGES) | |
89 | SYSMAP(Swtchmap,Swtchbase,UPAGES) | |
876e2d36 BJ |
90 | .set mbxxx,(NMBCLUSTERS*MCLBYTES) |
91 | .set mbyyy,(mbxxx>>PGSHIFT) | |
92 | .set mbpgs,(mbyyy+CLSIZE) | |
93 | SYSMAP(Mbmap,mbutl,mbpgs) | |
94 | /* | |
95 | * XXX: NEED way to compute kmem size from maxusers, | |
96 | * device complement | |
97 | */ | |
98 | SYSMAP(kmempt,kmembase,300*CLSIZE) | |
99 | #ifdef GPROF | |
100 | SYSMAP(profmap,profbase,600*CLSIZE) | |
101 | #endif | |
102 | .set atmemsz,0x100000-0xa0000 | |
103 | .set atpgs,(atmemsz>>PGSHIFT) | |
104 | SYSMAP(ATDevmem,atdevbase,atpgs) | |
8cbc2ebb | 105 | /*#define USRIOSIZE 30*/ |
ec13cb01 | 106 | SYSMAP(Usriomap,usrio,USRIOSIZE+CLSIZE) /* for PHYSIO */ |
876e2d36 | 107 | ZSYSMAP(ekmempt,kmemlimit,0) |
876e2d36 BJ |
108 | SYSMAP(Usrptmap,usrpt,USRPTSIZE+CLSIZE) |
109 | ||
110 | eSysmap: | |
111 | # .set _Syssize,(eSysmap-_Sysmap)/4 | |
112 | .set _Syssize,ptes | |
113 | .globl _Syssize | |
114 | ||
115 | /* align on next page boundary */ | |
116 | # . = . + NBPG - 1 & -NBPG /* align to page boundry-does not work*/ | |
117 | # .space (PGSIZE - ((eSysmap-_Sysmap) % PGSIZE)) % PGSIZE | |
118 | .set sz,(4*ptes)%NBPG | |
119 | # .set rptes,(ptes)%1024 | |
120 | # .set rptes,1024-rptes | |
121 | # .set ptes,ptes+rptes | |
8cbc2ebb BJ |
122 | .set Npdes,10 |
123 | # .space (NBPG - sz) | |
876e2d36 | 124 | |
876e2d36 BJ |
125 | /* |
126 | * Initialization | |
127 | */ | |
128 | .data | |
8cbc2ebb BJ |
129 | .globl _cpu, _boothowto, _bootdev, _cyloffset, _Maxmem |
130 | _cpu: .long 0 # are we 386, 386sx, or 486 | |
876e2d36 BJ |
131 | .text |
132 | .globl start | |
4bd1c0bf | 133 | start: # This is assumed to be location zero! |
ec13cb01 BJ |
134 | movw $0x1234,%ax |
135 | movw %ax,0x472 # warm boot | |
136 | jmp 1f | |
8cbc2ebb BJ |
137 | .space 0x500 # skip over warm boot shit |
138 | ||
139 | /* enable a20! yecchh!! */ | |
140 | 1: inb $0x64,%al | |
141 | andb $2,%al | |
142 | jnz 1b | |
143 | movb $0xd1,%al | |
144 | NOP | |
145 | outb %al,$0x64 | |
146 | NOP | |
147 | 1: inb $0x64,%al | |
148 | andb $2,%al | |
149 | jnz 1b | |
150 | movb $0xdf,%al | |
151 | NOP | |
152 | outb %al,$0x60 | |
153 | ||
154 | /* pass parameters on stack (howto, bootdev, unit, cyloffset) */ | |
155 | ||
156 | movl 4(%esp),%eax | |
157 | movl %eax,_boothowto-SYSTEM | |
158 | movl 8(%esp),%eax | |
159 | movl %eax,_bootdev-SYSTEM | |
160 | movl 12(%esp),%eax | |
161 | movl %eax, _cyloffset-SYSTEM | |
162 | ||
163 | /* count up memory */ | |
164 | ||
876e2d36 | 165 | xorl %eax,%eax # start with base memory at 0x0 |
8cbc2ebb BJ |
166 | #movl $ 0xA0000/NBPG,%ecx # look every 4K up to 640K |
167 | movl $ 0xA0,%ecx # look every 4K up to 640K | |
876e2d36 BJ |
168 | 1: movl 0(%eax),%ebx # save location to check |
169 | movl $0xa55a5aa5,0(%eax) # write test pattern | |
170 | cmpl $0xa55a5aa5,0(%eax) # does not check yet for rollover | |
171 | jne 2f | |
172 | movl %ebx,0(%eax) # restore memory | |
4bd1c0bf | 173 | addl $ NBPG,%eax |
876e2d36 | 174 | loop 1b |
8cbc2ebb BJ |
175 | 2: shrl $12,%eax |
176 | movl %eax,_Maxmem-SYSTEM | |
876e2d36 BJ |
177 | |
178 | movl $0x100000,%eax # next, talley remaining memory | |
8cbc2ebb BJ |
179 | #movl $((0xFFF000-0x100000)/NBPG),%ecx |
180 | movl $(0xFFF-0x100),%ecx | |
876e2d36 BJ |
181 | 1: movl 0(%eax),%ebx # save location to check |
182 | movl $0xa55a5aa5,0(%eax) # write test pattern | |
183 | cmpl $0xa55a5aa5,0(%eax) # does not check yet for rollover | |
184 | jne 2f | |
185 | movl %ebx,0(%eax) # restore memory | |
4bd1c0bf | 186 | addl $ NBPG,%eax |
876e2d36 | 187 | loop 1b |
8cbc2ebb BJ |
188 | 2: shrl $12,%eax |
189 | movl %eax,_Maxmem-SYSTEM | |
ec13cb01 | 190 | |
4bd1c0bf | 191 | /* clear memory. */ |
876e2d36 BJ |
192 | movl $_edata-SYSTEM,%edi |
193 | movl $_end-SYSTEM,%ecx | |
4bd1c0bf | 194 | addl $ NBPG-1,%ecx |
876e2d36 BJ |
195 | andl $~(NBPG-1),%ecx |
196 | movl %ecx,%esi | |
197 | subl %edi,%ecx | |
198 | addl $(UPAGES*NBPG)+NBPG+NBPG+NBPG,%ecx | |
199 | # txt+data+proc zero pt+u. | |
200 | # any other junk? | |
8cbc2ebb BJ |
201 | # addl $ NBPG-1,%ecx |
202 | # andl $~(NBPG-1),%ecx | |
876e2d36 BJ |
203 | # shrl $2,%ecx # convert to long word count |
204 | xorl %eax,%eax # pattern | |
205 | cld | |
206 | rep | |
207 | stosb | |
208 | ||
8cbc2ebb BJ |
209 | /* pass parameters on stack (howto, bootdev, unit, cyloffset) */ |
210 | ||
211 | movl 4(%esp),%eax | |
212 | movl %eax,_boothowto-SYSTEM | |
213 | movl 8(%esp),%eax | |
214 | movl %eax,_bootdev-SYSTEM | |
215 | movl 12(%esp),%eax | |
216 | movl %eax, _cyloffset-SYSTEM | |
217 | ||
218 | #ifdef notdef | |
219 | ||
220 | movl $0x36000,%edi | |
221 | movl $0x68000,%ecx | |
222 | xorl %eax,%eax # pattern | |
223 | cld | |
224 | rep | |
225 | stosb | |
226 | ||
227 | #endif | |
228 | movl $0x100000,%edi | |
229 | movl $0x200000,%ecx | |
230 | xorl %eax,%eax # pattern | |
231 | cld | |
232 | rep | |
233 | stosb | |
876e2d36 BJ |
234 | /* |
235 | * Map Kernel | |
236 | * N.B. don't bother with making kernel text RO, as 386 | |
4bd1c0bf | 237 | * ignores R/W AND U/S bits on kernel access (only v works) ! |
8cbc2ebb BJ |
238 | * |
239 | * First step - build page tables | |
876e2d36 | 240 | */ |
876e2d36 | 241 | movl %esi,%ecx # this much memory, |
4bd1c0bf WN |
242 | shrl $ PGSHIFT,%ecx # for this many pte s |
243 | movl $ PG_V,%eax # having these bits set, | |
876e2d36 BJ |
244 | movl $_Sysmap-SYSTEM,%ebx # in the kernel page table, |
245 | # fill in kernel page table. | |
246 | 1: movl %eax,0(%ebx) | |
4bd1c0bf | 247 | addl $ NBPG,%eax # increment physical address |
876e2d36 BJ |
248 | addl $4,%ebx # next pte |
249 | loop 1b | |
250 | ||
251 | /* temporary double map virt == real */ | |
252 | ||
253 | movl $1024,%ecx # for this many pte s, | |
4bd1c0bf | 254 | movl $ PG_V,%eax # having these bits set, |
8cbc2ebb | 255 | movl $_Sysmap+4096-SYSTEM,%ebx # in the temporary page table, |
876e2d36 BJ |
256 | # fill in kernel page table. |
257 | 1: movl %eax,0(%ebx) | |
4bd1c0bf | 258 | addl $ NBPG,%eax # increment physical address |
876e2d36 BJ |
259 | addl $4,%ebx # next pte |
260 | loop 1b | |
261 | ||
876e2d36 BJ |
262 | /* map I/O memory map */ |
263 | ||
264 | movl $atpgs,%ecx # for this many pte s, | |
265 | movl $(IOPHYSmem|PG_V),%eax # having these bits set, (perhaps URW?) | |
266 | movl $_ATDevmem-SYSTEM,%ebx # in the temporary page table, | |
267 | # fill in kernel page table. | |
268 | 1: movl %eax,0(%ebx) | |
4bd1c0bf | 269 | addl $ NBPG,%eax # increment physical address |
876e2d36 BJ |
270 | addl $4,%ebx # next pte |
271 | loop 1b | |
272 | ||
8cbc2ebb BJ |
273 | /* map proc 0's page table (P1 region) */ |
274 | ||
876e2d36 BJ |
275 | movl $_Usrptmap-SYSTEM,%ebx # get pt map address |
276 | lea (0*NBPG)(%esi),%eax # physical address of pt in proc 0 | |
4bd1c0bf | 277 | orl $ PG_V,%eax # having these bits set, |
876e2d36 BJ |
278 | movl %eax,0(%ebx) |
279 | ||
8cbc2ebb BJ |
280 | /* map proc 0's _u */ |
281 | ||
4bd1c0bf | 282 | movl $ UPAGES,%ecx # for this many pte s, |
ec13cb01 | 283 | lea (2*NBPG)(%esi),%eax # physical address of _u in proc 0 |
4bd1c0bf | 284 | orl $ PG_V|PG_URKW,%eax # having these bits set, |
876e2d36 BJ |
285 | lea (0*NBPG)(%esi),%ebx # physical address of stack pt in proc 0 |
286 | addl $(UPTEOFF*4),%ebx | |
287 | # fill in proc 0 stack page table. | |
288 | 1: movl %eax,0(%ebx) | |
4bd1c0bf | 289 | addl $ NBPG,%eax # increment physical address |
876e2d36 BJ |
290 | addl $4,%ebx # next pte |
291 | loop 1b | |
292 | ||
ec13cb01 BJ |
293 | /*# map proc 0's page directory*/ |
294 | lea (1*NBPG)(%esi),%eax # physical address of ptd in proc 0 | |
295 | movl %eax,%edi # remember ptd physical address | |
8cbc2ebb | 296 | #ifdef dubious |
4bd1c0bf | 297 | orl $ PG_V|PG_URKW,%eax # having these bits set, |
ec13cb01 BJ |
298 | lea (0*NBPG)(%esi),%ebx # physical address of stack pt in proc 0 |
299 | addl $(UPTEOFF*4),%ebx | |
300 | addl $(UPAGES*4),%ebx | |
301 | movl %eax,0(%ebx) | |
8cbc2ebb | 302 | #endif |
ec13cb01 | 303 | |
876e2d36 BJ |
304 | /* |
305 | * Construct a page table directory | |
306 | * (of page directory elements - pde's) | |
307 | */ | |
308 | /* kernel pde's */ | |
309 | movl $_Sysmap-SYSTEM,%eax # physical address of kernel page table | |
4bd1c0bf WN |
310 | orl $ PG_V,%eax # pde entry is valid |
311 | movl $ Npdes,%ecx # for this many pde s, | |
ec13cb01 | 312 | movl %edi,%ebx # phys address of ptd in proc 0 |
876e2d36 BJ |
313 | addl $(SYSPDROFF*4), %ebx # offset of pde for kernel |
314 | 1: movl %eax,0(%ebx) | |
4bd1c0bf | 315 | addl $ NBPG,%eax # increment physical address |
876e2d36 BJ |
316 | addl $4,%ebx # next pde |
317 | loop 1b | |
318 | # install a pde for temporary double map | |
8cbc2ebb BJ |
319 | movl $_Sysmap+4096-SYSTEM,%eax # physical address of temp page table |
320 | # movl $_Sysmap-SYSTEM,%eax # physical address of temp page table | |
4bd1c0bf | 321 | orl $ PG_V,%eax # pde entry is valid |
ec13cb01 | 322 | movl %edi,%ebx # phys address of ptd in proc 0 |
876e2d36 | 323 | movl %eax,0(%ebx) # which is where temp maps! |
876e2d36 BJ |
324 | # install a pde to map _u for proc 0 |
325 | lea (0*NBPG)(%esi),%eax # physical address of pt in proc 0 | |
4bd1c0bf | 326 | orl $ PG_V,%eax # pde entry is valid |
ec13cb01 | 327 | movl %edi,%ebx # phys address of ptd in proc 0 |
876e2d36 BJ |
328 | addl $(UPDROFF*4), %ebx # offset of pde for kernel |
329 | movl %eax,0(%ebx) # which is where _u maps! | |
330 | ||
ec13cb01 | 331 | movl %edi,%eax # phys address of ptd in proc 0 |
b82cb0f0 | 332 | orl $ I386_CR3PAT,%eax |
e28d0f21 DA |
333 | movl %eax,%cr3 # load ptd addr into mmu |
334 | movl %cr0,%eax # get control word | |
335 | orl $0x80000001,%eax # and let s page! | |
336 | movl %eax,%cr0 # NOW! | |
876e2d36 BJ |
337 | |
338 | pushl $begin # jump to high mem! | |
4bd1c0bf | 339 | ret # jmp $begin does not work |
876e2d36 | 340 | begin: |
4bd1c0bf | 341 | movl $_Sysbase,%eax # kernel stack just below system |
876e2d36 | 342 | movl %eax,%esp |
4bd1c0bf | 343 | xorl %eax,%eax # mark end of frames |
876e2d36 | 344 | movl %eax,%ebp |
4bd1c0bf WN |
345 | |
346 | movl _Crtat,%eax # initialize Crt video ram address | |
347 | subl $ IOPHYSmem,%eax | |
876e2d36 BJ |
348 | addl $_atdevbase,%eax |
349 | movl %eax,_Crtat | |
4bd1c0bf WN |
350 | |
351 | call _init386 # wire 386 chip for unix operation | |
352 | ||
ec13cb01 BJ |
353 | /* initialize (slightly) the pcb */ |
354 | movl $_u,%eax # proc0 u-area | |
355 | movl $_usrpt,%ecx | |
356 | movl %ecx,PCB_P0BR(%eax) # p0br: SVA of text/data user PT | |
357 | xorl %ecx,%ecx | |
358 | movl %ecx,PCB_P0LR(%eax) # p0lr: 0 (doesn t really exist) | |
359 | movl $_usrpt+NBPG,%ecx # addr of end of PT | |
4bd1c0bf | 360 | subl $ P1PAGES*4,%ecx # backwards size of P1 region |
ec13cb01 | 361 | movl %ecx,PCB_P1BR(%eax) # p1br: P1PAGES from end of PT |
4bd1c0bf WN |
362 | movl $ P1PAGES-UPAGES,PCB_P1LR(%eax) # p1lr: vax style |
363 | movl $ CLSIZE,PCB_SZPT(%eax) # page table size | |
9c09b4f2 BJ |
364 | # fninit |
365 | # pushl $0x262 | |
366 | # fldcw 0(%esp) | |
367 | # popl %ecx | |
368 | # fnsave PCB_SAVEFPU(%eax) | |
8cbc2ebb | 369 | movl %edi,PCB_CR3(%eax) |
ec13cb01 BJ |
370 | pushl %edi # cr3 |
371 | movl %esi,%eax | |
ec13cb01 | 372 | addl $(UPAGES*NBPG)+NBPG+NBPG+NBPG,%eax |
4bd1c0bf | 373 | shrl $ PGSHIFT,%eax |
ec13cb01 BJ |
374 | pushl %eax # firstaddr |
375 | ||
4bd1c0bf | 376 | pushl $20 # install signal trampoline code |
ec13cb01 BJ |
377 | pushl $_u+PCB_SIGC |
378 | pushl $sigcode | |
379 | call _bcopy | |
380 | addl $12,%esp | |
381 | ||
876e2d36 | 382 | call _main |
ec13cb01 BJ |
383 | |
384 | .globl __ucodesel,__udatasel | |
385 | movzwl __ucodesel,%eax | |
386 | movzwl __udatasel,%ecx | |
387 | # build outer stack frame | |
4bd1c0bf WN |
388 | pushl %ecx # user ss |
389 | pushl $_u # user esp | |
ec13cb01 BJ |
390 | pushl %eax # user cs |
391 | pushl $0 # user ip | |
392 | movw %cx,%ds | |
393 | movw %cx,%es | |
4bd1c0bf WN |
394 | movw %ax,%fs # double map cs to fs |
395 | movw %cx,%gs # and ds to gs | |
ec13cb01 | 396 | lret # goto user! |
ec13cb01 BJ |
397 | |
398 | .globl __exit | |
399 | __exit: | |
8cbc2ebb | 400 | call _reset_cpu |
4bd1c0bf WN |
401 | lidt xaxa # invalidate interrupt descriptor |
402 | movl $0,%esp # hardware "freeze" fault | |
876e2d36 BJ |
403 | ret |
404 | xaxa: .long 0,0 | |
4bd1c0bf | 405 | |
ec13cb01 BJ |
406 | .set exec,11 |
407 | .set exit,1 | |
408 | .globl _icode | |
409 | .globl _initflags | |
410 | .globl _szicode | |
411 | /* gas fucks up offset -- */ | |
412 | #define LCALL(x,y) .byte 0x9a ; .long y; .word x | |
413 | /* | |
414 | * Icode is copied out to process 1 to exec /etc/init. | |
415 | * If the exec fails, process 1 exits. | |
416 | */ | |
417 | _icode: | |
418 | # pushl $argv-_icode | |
419 | movl $argv,%eax | |
420 | subl $_icode,%eax | |
421 | pushl %eax | |
422 | ||
423 | # pushl $init-_icode | |
424 | movl $init,%eax | |
425 | subl $_icode,%eax | |
426 | pushl %eax | |
427 | pushl %eax # dummy out rta | |
428 | ||
429 | movl %esp,%ebp | |
430 | movl $exec,%eax | |
431 | LCALL(0x7,0x0) | |
432 | pushl %eax | |
433 | movl $exit,%eax | |
434 | pushl %eax # dummy out rta | |
435 | LCALL(0x7,0x0) | |
436 | ||
ec13cb01 BJ |
437 | init: .asciz "/etc/init" |
438 | .align 2 | |
439 | _initflags: | |
440 | .long 0 | |
441 | argv: .long init-_icode | |
442 | .long _initflags-_icode | |
443 | .long 0 | |
444 | _szicode: | |
445 | .long _szicode-_icode | |
446 | sigcode: | |
447 | movl 12(%esp),%eax # unsure if call will dec stack 1st | |
448 | call %eax | |
449 | xorl %eax,%eax # smaller movl $103,%eax | |
450 | movb $103,%al # sigreturn() | |
451 | LCALL(0x7,0) # enter kernel with args on stack | |
452 | hlt # never gets here | |
876e2d36 | 453 | |
876e2d36 | 454 | |
ec13cb01 BJ |
455 | .globl ___udivsi3 |
456 | ___udivsi3: | |
457 | movl 4(%esp),%eax | |
458 | xorl %edx,%edx | |
459 | divl 8(%esp) | |
460 | ret | |
876e2d36 | 461 | |
ec13cb01 BJ |
462 | .globl ___divsi3 |
463 | ___divsi3: | |
464 | movl 4(%esp),%eax | |
465 | xorl %edx,%edx | |
466 | cltd | |
467 | idivl 8(%esp) | |
468 | ret | |
876e2d36 | 469 | |
ec13cb01 BJ |
470 | .globl _inb |
471 | _inb: movl 4(%esp),%edx | |
472 | subl %eax,%eax # clr eax | |
6595ba46 | 473 | NOP |
ec13cb01 | 474 | inb %dx,%al |
6595ba46 | 475 | NOP |
ec13cb01 | 476 | ret |
876e2d36 | 477 | |
ec13cb01 BJ |
478 | .globl _outb |
479 | _outb: movl 4(%esp),%edx | |
480 | movl 8(%esp),%eax | |
6595ba46 | 481 | NOP |
ec13cb01 | 482 | outb %al,%dx |
6595ba46 | 483 | NOP |
876e2d36 BJ |
484 | ret |
485 | ||
ec13cb01 BJ |
486 | # |
487 | # bzero (base,cnt) | |
488 | # | |
489 | ||
490 | .globl _bzero | |
491 | .globl _blkclr | |
492 | _bzero: | |
493 | _blkclr: | |
494 | pushl %edi | |
495 | movl 8(%esp),%edi | |
496 | movl 12(%esp),%ecx | |
4bd1c0bf WN |
497 | xorl %eax,%eax |
498 | shrl $2,%ecx | |
ec13cb01 BJ |
499 | cld |
500 | rep | |
4bd1c0bf WN |
501 | stosl |
502 | movl 12(%esp),%ecx | |
503 | andl $3,%ecx | |
504 | rep | |
ec13cb01 BJ |
505 | stosb |
506 | popl %edi | |
876e2d36 | 507 | ret |
ec13cb01 | 508 | |
8cbc2ebb BJ |
509 | # |
510 | # fillw (pat,base,cnt) | |
511 | # | |
512 | ||
513 | .globl _fillw | |
514 | _fillw: | |
515 | pushl %edi | |
516 | movl 8(%esp),%eax | |
517 | movl 12(%esp),%edi | |
518 | movl 16(%esp),%ecx | |
519 | # xorl %eax,%eax | |
520 | cld | |
521 | rep | |
522 | stosw | |
523 | popl %edi | |
524 | ret | |
525 | ||
ec13cb01 BJ |
526 | # |
527 | # bcopy (src,dst,cnt) | |
528 | # NOTE: does not (yet) handle overlapped copies | |
529 | # | |
530 | ||
531 | .globl _bcopy | |
ec13cb01 | 532 | _bcopy: |
6595ba46 BJ |
533 | pushl %esi |
534 | pushl %edi | |
535 | movl 12(%esp),%esi | |
536 | movl 16(%esp),%edi | |
537 | movl 20(%esp),%ecx | |
4bd1c0bf WN |
538 | shrl $2,%ecx |
539 | cld | |
540 | rep | |
541 | movsl | |
542 | movl 20(%esp),%ecx | |
543 | andl $3,%ecx | |
6595ba46 BJ |
544 | rep |
545 | movsb | |
546 | popl %edi | |
547 | popl %esi | |
548 | xorl %eax,%eax | |
549 | ret | |
550 | ||
551 | .globl _copyout | |
ec13cb01 | 552 | _copyout: |
6595ba46 BJ |
553 | movl $cpyflt,_nofault # in case we page/protection violate |
554 | pushl %esi | |
555 | pushl %edi | |
556 | movl 12(%esp),%esi | |
557 | movl 16(%esp),%edi | |
558 | movl 20(%esp),%ecx | |
4bd1c0bf | 559 | shrl $2,%ecx |
6595ba46 | 560 | cld |
4bd1c0bf WN |
561 | rep |
562 | movsl | |
563 | movl 20(%esp),%ecx | |
564 | andl $3,%ecx | |
6595ba46 BJ |
565 | rep |
566 | movsb | |
567 | popl %edi | |
568 | popl %esi | |
569 | xorl %eax,%eax | |
570 | movl %eax,_nofault | |
571 | ret | |
572 | ||
573 | .globl _copyin | |
ec13cb01 | 574 | _copyin: |
6595ba46 | 575 | movl $cpyflt,_nofault # in case we page/protection violate |
ec13cb01 BJ |
576 | pushl %esi |
577 | pushl %edi | |
578 | movl 12(%esp),%esi | |
579 | movl 16(%esp),%edi | |
580 | movl 20(%esp),%ecx | |
4bd1c0bf | 581 | shrl $2,%ecx |
ec13cb01 | 582 | cld |
4bd1c0bf WN |
583 | rep |
584 | movsl | |
585 | movl 20(%esp),%ecx | |
586 | andl $3,%ecx | |
ec13cb01 BJ |
587 | rep |
588 | movsb | |
589 | popl %edi | |
590 | popl %esi | |
6595ba46 BJ |
591 | xorl %eax,%eax |
592 | movl %eax,_nofault | |
876e2d36 BJ |
593 | ret |
594 | ||
6595ba46 BJ |
595 | cpyflt: popl %edi |
596 | popl %esi | |
597 | xorl %eax,%eax | |
598 | movl %eax,_nofault | |
4bd1c0bf | 599 | movl $ EFAULT,%eax |
6595ba46 BJ |
600 | ret |
601 | ||
8cbc2ebb BJ |
602 | # insb(port,addr,cnt) |
603 | .globl _insb | |
604 | _insb: | |
605 | pushl %edi | |
606 | movw 8(%esp),%dx | |
607 | movl 12(%esp),%edi | |
608 | movl 16(%esp),%ecx | |
609 | cld | |
610 | NOP | |
611 | rep | |
612 | insb | |
613 | NOP | |
614 | movl %edi,%eax | |
615 | popl %edi | |
616 | ret | |
6595ba46 | 617 | |
ec13cb01 BJ |
618 | # insw(port,addr,cnt) |
619 | .globl _insw | |
620 | _insw: | |
621 | pushl %edi | |
622 | movw 8(%esp),%dx | |
623 | movl 12(%esp),%edi | |
624 | movl 16(%esp),%ecx | |
625 | cld | |
6595ba46 | 626 | NOP |
ec13cb01 | 627 | .byte 0x66,0xf2,0x6d # rep insw |
6595ba46 | 628 | NOP |
ec13cb01 BJ |
629 | movl %edi,%eax |
630 | popl %edi | |
876e2d36 | 631 | ret |
ec13cb01 BJ |
632 | |
633 | # outsw(port,addr,cnt) | |
634 | .globl _outsw | |
635 | _outsw: | |
636 | pushl %esi | |
637 | movw 8(%esp),%dx | |
638 | movl 12(%esp),%esi | |
639 | movl 16(%esp),%ecx | |
640 | cld | |
6595ba46 | 641 | NOP |
ec13cb01 | 642 | .byte 0x66,0xf2,0x6f # rep outsw |
6595ba46 | 643 | NOP |
ec13cb01 BJ |
644 | movl %esi,%eax |
645 | popl %esi | |
876e2d36 BJ |
646 | ret |
647 | ||
ec13cb01 BJ |
648 | # lgdt(*gdt, ngdt) |
649 | .globl _lgdt | |
650 | # .globl _gdt | |
651 | xxx: .word 31 | |
652 | .long 0 | |
653 | _lgdt: | |
654 | movl 4(%esp),%eax | |
655 | movl %eax,xxx+2 | |
656 | movl 8(%esp),%eax | |
657 | movw %ax,xxx | |
658 | lgdt xxx | |
659 | jmp 1f | |
6595ba46 | 660 | NOP |
ec13cb01 BJ |
661 | 1: movw $0x10,%ax |
662 | movw %ax,%ds | |
663 | movw %ax,%es | |
664 | movw %ax,%ss | |
665 | movl 0(%esp),%eax | |
666 | pushl %eax | |
667 | movl $8,4(%esp) | |
668 | lret | |
669 | ||
670 | # lidt(*idt, nidt) | |
671 | .globl _lidt | |
ec13cb01 | 672 | yyy: .word 255 |
4bd1c0bf | 673 | .long 0 |
ec13cb01 BJ |
674 | _lidt: |
675 | movl 4(%esp),%eax | |
676 | movl %eax,yyy+2 | |
677 | movl 8(%esp),%eax | |
678 | movw %ax,yyy | |
679 | lidt yyy | |
680 | ret | |
876e2d36 | 681 | |
ec13cb01 BJ |
682 | # lldt(sel) |
683 | .globl _lldt | |
684 | _lldt: | |
685 | movl 4(%esp),%eax | |
686 | lldt %eax | |
687 | ret | |
876e2d36 | 688 | |
ec13cb01 BJ |
689 | # ltr(sel) |
690 | .globl _ltr | |
691 | _ltr: | |
692 | movl 4(%esp),%eax | |
693 | ltr %eax | |
694 | ret | |
876e2d36 | 695 | |
ec13cb01 BJ |
696 | # lcr3(cr3) |
697 | .globl _lcr3 | |
698 | .globl _load_cr3 | |
699 | _load_cr3: | |
700 | _lcr3: | |
701 | movl 4(%esp),%eax | |
b82cb0f0 | 702 | orl $ I386_CR3PAT,%eax |
ec13cb01 BJ |
703 | movl %eax,%cr3 |
704 | movl %cr3,%eax | |
705 | ret | |
876e2d36 | 706 | |
ec13cb01 BJ |
707 | # lcr0(cr0) |
708 | .globl _lcr0 | |
709 | _lcr0: | |
710 | movl 4(%esp),%eax | |
711 | movl %eax,%cr0 | |
712 | ret | |
713 | ||
714 | # rcr0() | |
715 | .globl _rcr0 | |
716 | _rcr0: | |
717 | movl %cr0,%eax | |
718 | ret | |
719 | ||
720 | # rcr2() | |
721 | .globl _rcr2 | |
722 | _rcr2: | |
723 | movl %cr2,%eax | |
724 | ret | |
725 | ||
726 | # rcr3() | |
727 | .globl _rcr3 | |
728 | .globl __cr3 | |
729 | __cr3: | |
730 | _rcr3: | |
731 | movl %cr3,%eax | |
732 | ret | |
733 | ||
734 | # ssdtosd(*ssdp,*sdp) | |
735 | .globl _ssdtosd | |
736 | _ssdtosd: | |
737 | pushl %ebx | |
738 | movl 8(%esp),%ecx | |
739 | movl 8(%ecx),%ebx | |
740 | shll $16,%ebx | |
741 | movl (%ecx),%edx | |
742 | roll $16,%edx | |
743 | movb %dh,%bl | |
744 | movb %dl,%bh | |
745 | rorl $8,%ebx | |
746 | movl 4(%ecx),%eax | |
747 | movw %ax,%dx | |
748 | andl $0xf0000,%eax | |
749 | orl %eax,%ebx | |
750 | movl 12(%esp),%ecx | |
751 | movl %edx,(%ecx) | |
752 | movl %ebx,4(%ecx) | |
753 | popl %ebx | |
876e2d36 BJ |
754 | ret |
755 | ||
876e2d36 | 756 | /* |
4bd1c0bf | 757 | * {fu,su},{byte,word} |
876e2d36 | 758 | */ |
ec13cb01 BJ |
759 | ALTENTRY(fuiword) |
760 | ENTRY(fuword) | |
761 | movl $fusufault,_nofault # in case we page/protection violate | |
762 | movl 4(%esp),%edx | |
4bd1c0bf | 763 | .byte 0x65 # use gs |
ec13cb01 BJ |
764 | movl 0(%edx),%eax |
765 | xorl %edx,%edx | |
766 | movl %edx,_nofault | |
767 | ret | |
768 | ||
769 | ENTRY(fusword) | |
770 | movl $fusufault,_nofault # in case we page/protection violate | |
771 | movl 4(%esp),%edx | |
4bd1c0bf | 772 | .byte 0x65 # use gs |
ec13cb01 BJ |
773 | movzwl 0(%edx),%eax |
774 | xorl %edx,%edx | |
775 | movl %edx,_nofault | |
776 | ret | |
777 | ||
778 | ALTENTRY(fuibyte) | |
779 | ENTRY(fubyte) | |
780 | movl $fusufault,_nofault # in case we page/protection violate | |
781 | movl 4(%esp),%edx | |
4bd1c0bf | 782 | .byte 0x65 # use gs |
ec13cb01 BJ |
783 | movzbl 0(%edx),%eax |
784 | xorl %edx,%edx | |
785 | movl %edx,_nofault | |
786 | ret | |
787 | ||
788 | fusufault: | |
789 | xorl %eax,%eax | |
790 | movl %eax,_nofault | |
791 | decl %eax | |
876e2d36 BJ |
792 | ret |
793 | ||
ec13cb01 BJ |
794 | ALTENTRY(suiword) |
795 | ENTRY(suword) | |
796 | movl $fusufault,_nofault # in case we page/protection violate | |
797 | movl 4(%esp),%edx | |
798 | movl 8(%esp),%eax | |
4bd1c0bf | 799 | .byte 0x65 # use gs |
ec13cb01 BJ |
800 | movl %eax,0(%edx) |
801 | xorl %eax,%eax | |
802 | movl %eax,_nofault | |
803 | ret | |
804 | ||
805 | ENTRY(susword) | |
806 | movl $fusufault,_nofault # in case we page/protection violate | |
807 | movl 4(%esp),%edx | |
808 | movl 8(%esp),%eax | |
4bd1c0bf WN |
809 | .byte 0x65 # use gs |
810 | movw %ax,0(%edx) | |
ec13cb01 BJ |
811 | xorl %eax,%eax |
812 | movl %eax,_nofault | |
813 | ret | |
876e2d36 | 814 | |
ec13cb01 BJ |
815 | ALTENTRY(suibyte) |
816 | ENTRY(subyte) | |
817 | movl $fusufault,_nofault # in case we page/protection violate | |
818 | movl 4(%esp),%edx | |
819 | movl 8(%esp),%eax | |
4bd1c0bf WN |
820 | .byte 0x65 # use gs |
821 | movb %eax,0(%edx) | |
ec13cb01 BJ |
822 | xorl %eax,%eax |
823 | movl %eax,_nofault | |
824 | ret | |
876e2d36 | 825 | |
ec13cb01 BJ |
826 | ALTENTRY(savectx) |
827 | ENTRY(setjmp) | |
828 | movl 4(%esp),%eax | |
829 | movl %ebx, 0(%eax) # save ebx | |
830 | movl %esp, 4(%eax) # save esp | |
831 | movl %ebp, 8(%eax) # save ebp | |
832 | movl %esi,12(%eax) # save esi | |
833 | movl %edi,16(%eax) # save edi | |
834 | movl (%esp),%edx # get rta | |
835 | movl %edx,20(%eax) # save eip | |
e28d0f21 | 836 | xorl %eax,%eax # return (0); |
ec13cb01 | 837 | ret |
876e2d36 | 838 | |
ec13cb01 BJ |
839 | ENTRY(longjmp) |
840 | movl 4(%esp),%eax | |
841 | movl 0(%eax),%ebx # restore ebx | |
842 | movl 4(%eax),%esp # restore esp | |
843 | movl 8(%eax),%ebp # restore ebp | |
844 | movl 12(%eax),%esi # restore esi | |
845 | movl 16(%eax),%edi # restore edi | |
846 | movl 20(%eax),%edx # get rta | |
847 | movl %edx,(%esp) # put in return frame | |
848 | xorl %eax,%eax # return (1); | |
849 | incl %eax | |
850 | ret | |
876e2d36 | 851 | /* |
ec13cb01 BJ |
852 | * The following primitives manipulate the run queues. |
853 | * _whichqs tells which of the 32 queues _qs | |
876e2d36 BJ |
854 | * have processes in them. Setrq puts processes into queues, Remrq |
855 | * removes them from queues. The running process is on no queue, | |
856 | * other processes are on a queue related to p->p_pri, divided by 4 | |
857 | * actually to shrink the 0-127 range of priorities into the 32 available | |
858 | * queues. | |
859 | */ | |
860 | ||
4bd1c0bf | 861 | .globl _whichqs,_qs,_cnt,_panic |
ec13cb01 BJ |
862 | .comm _noproc,4 |
863 | .comm _runrun,4 | |
ec13cb01 | 864 | |
876e2d36 | 865 | /* |
ec13cb01 | 866 | * Setrq(p) |
876e2d36 | 867 | * |
ec13cb01 | 868 | * Call should be made at spl6(), and p->p_stat should be SRUN |
876e2d36 | 869 | */ |
ec13cb01 BJ |
870 | ENTRY(setrq) |
871 | movl 4(%esp),%eax | |
872 | cmpl $0,P_RLINK(%eax) # should not be on q already | |
873 | je set1 | |
874 | pushl $set2 | |
875 | call _panic | |
876e2d36 | 876 | set1: |
ec13cb01 BJ |
877 | movzbl P_PRI(%eax),%edx |
878 | shrl $2,%edx | |
879 | btsl %edx,_whichqs # set q full bit | |
880 | shll $3,%edx | |
881 | addl $_qs,%edx # locate q hdr | |
882 | movl %edx,P_LINK(%eax) # link process on tail of q | |
883 | movl P_RLINK(%edx),%ecx | |
884 | movl %ecx,P_RLINK(%eax) | |
885 | movl %eax,P_RLINK(%edx) | |
886 | movl %eax,P_LINK(%ecx) | |
887 | ret | |
876e2d36 | 888 | |
ec13cb01 | 889 | set2: .asciz "setrq" |
876e2d36 BJ |
890 | |
891 | /* | |
ec13cb01 | 892 | * Remrq(p) |
876e2d36 | 893 | * |
ec13cb01 | 894 | * Call should be made at spl6(). |
876e2d36 | 895 | */ |
ec13cb01 BJ |
896 | ENTRY(remrq) |
897 | movl 4(%esp),%eax | |
898 | movzbl P_PRI(%eax),%edx | |
899 | shrl $2,%edx | |
900 | btrl %edx,_whichqs # clear full bit, panic if clear already | |
901 | jb rem1 | |
902 | pushl $rem3 | |
903 | call _panic | |
876e2d36 | 904 | rem1: |
ec13cb01 BJ |
905 | pushl %edx |
906 | movl P_LINK(%eax),%ecx # unlink process | |
907 | movl P_RLINK(%eax),%edx | |
908 | movl %edx,P_RLINK(%ecx) | |
909 | movl P_RLINK(%eax),%ecx | |
910 | movl P_LINK(%eax),%edx | |
911 | movl %edx,P_LINK(%ecx) | |
912 | popl %edx | |
913 | movl $_qs,%ecx | |
914 | shll $3,%edx | |
915 | addl %edx,%ecx | |
916 | cmpl P_LINK(%ecx),%ecx # q still has something? | |
917 | je rem2 | |
918 | shrl $3,%edx # yes, set bit as still full | |
919 | btsl %edx,_whichqs | |
876e2d36 | 920 | rem2: |
ec13cb01 BJ |
921 | movl $0,P_RLINK(%eax) # zap reverse link to indicate off list |
922 | ret | |
876e2d36 BJ |
923 | |
924 | rem3: .asciz "remrq" | |
876e2d36 | 925 | sw0: .asciz "swtch" |
ec13cb01 BJ |
926 | sw01: .asciz "swtch1" |
927 | sw02: .asciz "swtch2" | |
876e2d36 BJ |
928 | |
929 | /* | |
930 | * When no processes are on the runq, Swtch branches to idle | |
931 | * to wait for something to come ready. | |
932 | */ | |
933 | .globl Idle | |
ec13cb01 BJ |
934 | Idle: |
935 | idle: | |
936 | call _spl0 | |
937 | cmpl $0,_whichqs | |
938 | jne sw1 | |
939 | hlt # wait for interrupt | |
940 | jmp idle | |
941 | ||
942 | badsw: | |
943 | pushl $sw0 | |
944 | call _panic | |
876e2d36 BJ |
945 | /*NOTREACHED*/ |
946 | ||
947 | /* | |
ec13cb01 | 948 | * Swtch() |
876e2d36 | 949 | */ |
ec13cb01 | 950 | ENTRY(swtch) |
8cbc2ebb BJ |
951 | movl _cpl,%eax |
952 | movl %eax,_u+PCB_IML | |
ec13cb01 BJ |
953 | movl $1,%eax |
954 | movl %eax,_noproc | |
876e2d36 | 955 | incl _cnt+V_SWTCH |
ec13cb01 | 956 | sw1: |
8cbc2ebb | 957 | cli |
ec13cb01 BJ |
958 | bsfl _whichqs,%eax # find a full q |
959 | jz idle # if none, idle | |
960 | swfnd: | |
ec13cb01 BJ |
961 | btrl %eax,_whichqs # clear q full status |
962 | jnb sw1 # if it was clear, look for another | |
963 | pushl %eax # save which one we are using | |
964 | shll $3,%eax | |
965 | addl $_qs,%eax # select q | |
966 | pushl %eax | |
967 | ||
968 | cmpl P_LINK(%eax),%eax # linked to self? (e.g. not on list) | |
969 | je badsw # not possible | |
970 | movl P_LINK(%eax),%ecx # unlink from front of process q | |
971 | movl P_LINK(%ecx),%edx | |
972 | movl %edx,P_LINK(%eax) | |
973 | movl P_RLINK(%ecx),%eax | |
974 | movl %eax,P_RLINK(%edx) | |
975 | ||
976 | popl %eax | |
977 | popl %edx | |
978 | cmpl P_LINK(%ecx),%eax # q empty | |
979 | je sw2 | |
980 | btsl %edx,_whichqs # nope, indicate full | |
876e2d36 | 981 | sw2: |
ec13cb01 BJ |
982 | movl $0,%eax |
983 | movl %eax,_noproc | |
984 | movl %eax,_runrun | |
985 | cmpl $0,P_WCHAN(%ecx) | |
986 | jne badsw | |
4bd1c0bf | 987 | cmpb $ SRUN,P_STAT(%ecx) |
ec13cb01 BJ |
988 | jne badsw |
989 | movl %eax,P_RLINK(%ecx) | |
8cbc2ebb BJ |
990 | |
991 | movl P_ADDR(%ecx),%edx | |
992 | movl (%edx),%eax | |
993 | movl %eax,_Swtchmap | |
994 | movl 4(%edx),%eax | |
995 | movl %eax,_Swtchmap+4 | |
9c09b4f2 BJ |
996 | # movl %cr3,%eax |
997 | # orl $ I386_CR3PAT,%eax | |
998 | # movl %eax,%cr3 | |
8cbc2ebb BJ |
999 | movl _Swtchbase+PCB_CR3,%edx |
1000 | ||
1001 | # pushal; pushl %edx ; pushl P_CR3(%ecx); pushl $l2; call _pg; popl %eax ; popl %eax; popl %eax ; popal ; .data ; l2: .asciz "s %x %x " ; .text | |
ec13cb01 BJ |
1002 | |
1003 | /* switch to new process. first, save context as needed */ | |
1004 | movl $_u,%ecx | |
1005 | ||
1006 | movl (%esp),%eax # Hardware registers | |
1007 | movl %eax, PCB_EIP(%ecx) | |
1008 | movl %ebx, PCB_EBX(%ecx) | |
1009 | movl %esp, PCB_ESP(%ecx) | |
1010 | movl %ebp, PCB_EBP(%ecx) | |
1011 | movl %esi, PCB_ESI(%ecx) | |
1012 | movl %edi, PCB_EDI(%ecx) | |
1013 | ||
8cbc2ebb | 1014 | fsave PCB_SAVEFPU(%ecx) |
876e2d36 | 1015 | |
ec13cb01 BJ |
1016 | movl _CMAP2,%eax # save temporary map PTE |
1017 | movl %eax,PCB_CMAP2(%ecx) # in our context | |
876e2d36 | 1018 | |
b82cb0f0 | 1019 | orl $ I386_CR3PAT,%edx |
ec13cb01 | 1020 | movl %edx,%cr3 # context switch |
876e2d36 | 1021 | |
4bd1c0bf | 1022 | movl $_u,%ecx |
8cbc2ebb BJ |
1023 | # .globl __gsel_tss |
1024 | # movw __gsel_tss,%ax | |
4bd1c0bf | 1025 | # ltr %ax |
876e2d36 | 1026 | |
ec13cb01 BJ |
1027 | /* restore context */ |
1028 | movl PCB_EBX(%ecx), %ebx | |
1029 | movl PCB_ESP(%ecx), %esp | |
1030 | movl PCB_EBP(%ecx), %ebp | |
1031 | movl PCB_ESI(%ecx), %esi | |
1032 | movl PCB_EDI(%ecx), %edi | |
1033 | movl PCB_EIP(%ecx), %eax | |
1034 | movl %eax, (%esp) | |
1035 | ||
8cbc2ebb | 1036 | frstor PCB_SAVEFPU(%ecx) |
ec13cb01 | 1037 | |
4bd1c0bf | 1038 | movl PCB_CMAP2(%ecx),%eax # get temporary map |
ec13cb01 BJ |
1039 | movl %eax,_CMAP2 # reload temporary map PTE |
1040 | #ifdef FPUNOTYET | |
1041 | #endif | |
4bd1c0bf | 1042 | cmpl $0,PCB_SSWAP(%ecx) # do an alternate return? |
ec13cb01 | 1043 | jne res3 # yes, go reload regs |
8cbc2ebb BJ |
1044 | |
1045 | pushl PCB_IML(%ecx) | |
1046 | call _splx | |
1047 | popl %eax | |
1048 | movl $0,%eax | |
ec13cb01 | 1049 | ret |
8cbc2ebb | 1050 | |
ec13cb01 BJ |
1051 | res3: |
1052 | xorl %eax,%eax # inline restore context | |
4bd1c0bf WN |
1053 | xchgl PCB_SSWAP(%ecx),%eax # addr of saved context, clear it |
1054 | ||
1055 | #pushal; pushl 20(%eax); pushl $l2; call _printf; popl %eax ; popl %eax; popal ; .data ; l2: .asciz "s %x\n" ; .text | |
1056 | ||
ec13cb01 BJ |
1057 | movl 0(%eax),%ebx # restore ebx |
1058 | movl 4(%eax),%esp # restore esp | |
1059 | movl 8(%eax),%ebp # restore ebp | |
1060 | movl 12(%eax),%esi # restore esi | |
1061 | movl 16(%eax),%edi # restore edi | |
1062 | movl 20(%eax),%edx # get rta | |
1063 | movl %edx,(%esp) # put in return frame | |
8cbc2ebb | 1064 | call _spl0 |
ec13cb01 BJ |
1065 | xorl %eax,%eax # return (1); |
1066 | incl %eax | |
876e2d36 BJ |
1067 | ret |
1068 | ||
1069 | /* | |
ec13cb01 BJ |
1070 | * Resume(p_addr) |
1071 | * current just used to fillout u. tss so fork can fake a return to swtch | |
1072 | * [ all thats really needed is esp and eip ] | |
876e2d36 | 1073 | */ |
ec13cb01 | 1074 | ENTRY(resume) |
e28d0f21 DA |
1075 | # movl 4(%esp),%ecx |
1076 | movl $_u,%ecx | |
ec13cb01 BJ |
1077 | movl (%esp),%eax |
1078 | movl %eax, PCB_EIP(%ecx) | |
1079 | movl %ebx, PCB_EBX(%ecx) | |
1080 | movl %esp, PCB_ESP(%ecx) | |
1081 | movl %ebp, PCB_EBP(%ecx) | |
1082 | movl %esi, PCB_ESI(%ecx) | |
1083 | movl %edi, PCB_EDI(%ecx) | |
1084 | #ifdef FPUNOTYET | |
1085 | #endif | |
8cbc2ebb BJ |
1086 | fsave PCB_SAVEFPU(%ecx) |
1087 | movl _cpl,%eax | |
1088 | movl %eax,PCB_IML(%ecx) | |
ec13cb01 | 1089 | movl $0,%eax |
876e2d36 BJ |
1090 | ret |
1091 | ||
ec13cb01 BJ |
1092 | .data |
1093 | .globl _cyloffset | |
1094 | _cyloffset: .long 0 | |
1095 | .globl _nofault | |
1096 | _nofault: .long 0 | |
1097 | .text | |
1098 | # To be done: | |
1099 | .globl _addupc | |
1100 | .globl _astoff | |
1101 | .globl _doadump | |
1102 | .globl _inittodr | |
ec13cb01 BJ |
1103 | .globl _physaddr |
1104 | _addupc: | |
1105 | .byte 0xcc | |
1106 | _astoff: | |
876e2d36 | 1107 | ret |
ec13cb01 BJ |
1108 | _doadump: |
1109 | .byte 0xcc | |
ec13cb01 BJ |
1110 | _physaddr: |
1111 | .byte 0xcc | |
4bd1c0bf | 1112 | |
9c09b4f2 BJ |
1113 | #define IDTVEC(name) .align 4; .globl _X/**/name; _X/**/name: |
1114 | /*#define PANIC(msg) xorl %eax,%eax; movl %eax,_waittime; pushl 1f; \ | |
1115 | call _panic; 1: .asciz msg*/ | |
1116 | #define PRINTF(n,msg) pushal ; pushl 1f; call _printf; MSG(msg) ; popl %eax ; popal | |
1117 | #define MSG(msg) .data; 1: .asciz msg; .text | |
876e2d36 | 1118 | |
9c09b4f2 BJ |
1119 | .text |
1120 | ||
1121 | /* | |
1122 | * Trap and fault vector routines | |
1123 | */ | |
1124 | #define TRAP(a) pushl $ a; jmp alltraps | |
1125 | ||
1126 | IDTVEC(div) | |
1127 | pushl $0; TRAP(T_DIVIDE) | |
1128 | IDTVEC(dbg) | |
1129 | pushl $0; TRAP(T_TRCTRAP) | |
1130 | IDTVEC(nmi) | |
1131 | pushl $0; TRAP(T_NMI) | |
1132 | IDTVEC(bpt) | |
1133 | pushl $0; TRAP(T_BPTFLT) | |
1134 | IDTVEC(ofl) | |
1135 | pushl $0; TRAP(T_OFLOW) | |
1136 | IDTVEC(bnd) | |
1137 | pushl $0; TRAP(T_BOUND) | |
1138 | IDTVEC(ill) | |
1139 | pushl $0; TRAP(T_PRIVINFLT) | |
1140 | IDTVEC(dna) | |
1141 | pushl $0; TRAP(T_DNA) | |
1142 | IDTVEC(dble) | |
1143 | TRAP(T_DOUBLEFLT) | |
1144 | /*PANIC("Double Fault");*/ | |
1145 | IDTVEC(fpusegm) | |
1146 | pushl $0; TRAP(T_FPOPFLT) | |
1147 | IDTVEC(tss) | |
1148 | TRAP(T_TSSFLT) | |
1149 | /*PANIC("TSS not valid");*/ | |
1150 | IDTVEC(missing) | |
1151 | TRAP(T_SEGNPFLT) | |
1152 | IDTVEC(stk) | |
1153 | TRAP(T_STKFLT) | |
1154 | IDTVEC(prot) | |
1155 | TRAP(T_PROTFLT) | |
1156 | IDTVEC(page) | |
1157 | TRAP(T_PAGEFLT) | |
1158 | IDTVEC(rsvd) | |
1159 | pushl $0; TRAP(T_RESERVED) | |
1160 | IDTVEC(fpu) | |
1161 | pushl $0; TRAP(T_ARITHTRAP) | |
1162 | /* 17 - 31 reserved for future exp */ | |
1163 | IDTVEC(rsvd0) | |
1164 | pushl $0; TRAP(17) | |
1165 | IDTVEC(rsvd1) | |
1166 | pushl $0; TRAP(18) | |
1167 | IDTVEC(rsvd2) | |
1168 | pushl $0; TRAP(19) | |
1169 | IDTVEC(rsvd3) | |
1170 | pushl $0; TRAP(20) | |
1171 | IDTVEC(rsvd4) | |
1172 | pushl $0; TRAP(21) | |
1173 | IDTVEC(rsvd5) | |
1174 | pushl $0; TRAP(22) | |
1175 | IDTVEC(rsvd6) | |
1176 | pushl $0; TRAP(23) | |
1177 | IDTVEC(rsvd7) | |
1178 | pushl $0; TRAP(24) | |
1179 | IDTVEC(rsvd8) | |
1180 | pushl $0; TRAP(25) | |
1181 | IDTVEC(rsvd9) | |
1182 | pushl $0; TRAP(26) | |
1183 | IDTVEC(rsvd10) | |
1184 | pushl $0; TRAP(27) | |
1185 | IDTVEC(rsvd11) | |
1186 | pushl $0; TRAP(28) | |
1187 | IDTVEC(rsvd12) | |
1188 | pushl $0; TRAP(29) | |
1189 | IDTVEC(rsvd13) | |
1190 | pushl $0; TRAP(30) | |
1191 | IDTVEC(rsvd14) | |
1192 | pushl $0; TRAP(31) | |
1193 | ||
1194 | alltraps: | |
1195 | pushal | |
1196 | push %ds | |
1197 | push %es | |
1198 | movw $0x10,%ax | |
1199 | movw %ax,%ds | |
1200 | movw %ax,%es | |
1201 | incl _cnt+V_TRAP | |
1202 | call _trap | |
1203 | ||
1204 | #ifdef junk | |
1205 | cmpl $0xfc000000,12*4(%esp) # is it a user pc | |
1206 | ja 1f | |
1207 | cmpw $0x1f,13*4(%esp) # is it a user cs | |
1208 | je 1f | |
1209 | .data ; lx: .asciz "t user cs %x?" ; .text | |
1210 | 2: | |
1211 | movl 13*4(%esp),%eax | |
1212 | pushl %eax | |
1213 | pushl $lx | |
1214 | call _pg | |
1215 | popl %eax ; popl %eax | |
1216 | jmp 2b | |
1217 | 1: | |
1218 | #endif junk | |
1219 | ||
1220 | pop %es | |
1221 | pop %ds | |
1222 | popal | |
1223 | addl $8,%esp # pop type, code | |
1224 | iret | |
1225 | ||
1226 | /* | |
1227 | * Call gate entry for syscall | |
1228 | */ | |
1229 | ||
1230 | IDTVEC(syscall) | |
1231 | pushfl # only for stupid carry bit and more stupid wait3 cc kludge | |
1232 | pushal # only need eax,ecx,edx - trap resaves others | |
1233 | movw $0x10,%ax # switch to kernel segments | |
1234 | movw %ax,%ds | |
1235 | movw %ax,%es | |
1236 | call _syscall | |
1237 | ||
1238 | #ifdef notdef | |
1239 | cmpw $0x1f,10*4(%esp) # is user cs what it should be? | |
1240 | jz 1f | |
1241 | .data ; lz: .asciz "s user cs %x?" ; .text | |
1242 | 2: | |
1243 | movl 10*4(%esp),%eax | |
1244 | pushl %eax | |
1245 | pushl $lz | |
1246 | call _pg | |
1247 | jmp 2b | |
1248 | 1: | |
1249 | #endif | |
1250 | ||
1251 | movw __udatasel,%ax # switch back to user segments | |
1252 | movw %ax,%ds | |
1253 | movw %ax,%es | |
1254 | popal | |
1255 | popfl | |
1256 | lret # back we go, we hope! | |
ec13cb01 | 1257 |