This source file includes following definitions.
- proc_trampoline
- sigcode
- svr4_sigcode
- linux_sigcode
- freebsd_sigcode
- fillw
- kcopy
- ovbcopy
- bcopy
- memcpy
- copyout
- copyin
- copy_fault
- copyoutstr
- copyinstr
- copystr_fault
- copystr
- lgdt
- setjmp
- longjmp
- setrunqueue
- remrunqueue
- idle
- idle_loop
- idle_start
- idle_exit
- switch_error
- cpu_switch
- switch_exit
- savectx
- resume_iret
- resume_pop_ds
- resume_pop_es
- resume_pop_gs
- resume_pop_fs
- alltraps
- bzero
- sse2_pagezero
- i686_pagezero
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
31
32
33
34
35
36
37
38
39 #include "npx.h"
40 #include "assym.h"
41 #include "apm.h"
42 #include "lapic.h"
43 #include "ioapic.h"
44 #include "pctr.h"
45 #include "ksyms.h"
46
47 #include <sys/errno.h>
48 #include <sys/syscall.h>
49 #ifdef COMPAT_SVR4
50 #include <compat/svr4/svr4_syscall.h>
51 #endif
52 #ifdef COMPAT_LINUX
53 #include <compat/linux/linux_syscall.h>
54 #endif
55 #ifdef COMPAT_FREEBSD
56 #include <compat/freebsd/freebsd_syscall.h>
57 #endif
58
59 #include <machine/cputypes.h>
60 #include <machine/param.h>
61 #include <machine/pte.h>
62 #include <machine/segments.h>
63 #include <machine/specialreg.h>
64 #include <machine/trap.h>
65
66 #include <dev/isa/isareg.h>
67
68 #if NLAPIC > 0
69 #include <machine/i82489reg.h>
70 #endif
71
72
73
74
75
76 #define ALIGN_DATA .align 4
77 #define ALIGN_TEXT .align 4,0x90
78 #define SUPERALIGN_TEXT .align 16,0x90
79 #define _ALIGN_TEXT ALIGN_TEXT
80 #include <machine/asm.h>
81
82 #define CPL _C_LABEL(lapic_tpr)
83
84 #define GET_CURPCB(reg) \
85 movl CPUVAR(CURPCB), reg
86
87 #define SET_CURPCB(reg) \
88 movl reg, CPUVAR(CURPCB)
89
90 #define CHECK_ASTPENDING(treg) \
91 movl CPUVAR(CURPROC),treg ; \
92 cmpl $0, treg ; \
93 je 1f ; \
94 cmpl $0,P_MD_ASTPENDING(treg) ; \
95 1:
96
97 #define CLEAR_ASTPENDING(cpreg) \
98 movl $0,P_MD_ASTPENDING(cpreg)
99
100
101
102
103 #define INTRENTRY \
104 pushl %eax ; \
105 pushl %ecx ; \
106 pushl %edx ; \
107 pushl %ebx ; \
108 pushl %ebp ; \
109 pushl %esi ; \
110 pushl %edi ; \
111 pushl %ds ; \
112 pushl %es ; \
113 pushl %gs ; \
114 movl $GSEL(GDATA_SEL, SEL_KPL),%eax ; \
115 movw %ax,%ds ; \
116 movw %ax,%es ; \
117 movw %ax,%gs ; \
118 pushl %fs ; \
119 movl $GSEL(GCPU_SEL, SEL_KPL),%eax ; \
120 movw %ax,%fs
121 #define INTRFASTEXIT \
122 popl %fs ; \
123 popl %gs ; \
124 popl %es ; \
125 popl %ds ; \
126 popl %edi ; \
127 popl %esi ; \
128 popl %ebp ; \
129 popl %ebx ; \
130 popl %edx ; \
131 popl %ecx ; \
132 popl %eax ; \
133 sti ; \
134 addl $8,%esp ; \
135 iret
136
137
138
139
140
141
142 .globl _C_LABEL(PTmap), _C_LABEL(PTD), _C_LABEL(PTDpde)
143 .set _C_LABEL(PTmap), (PDSLOT_PTE << PDSHIFT)
144 .set _C_LABEL(PTD), (_C_LABEL(PTmap) + PDSLOT_PTE * NBPG)
145 .set _C_LABEL(PTDpde), (_C_LABEL(PTD) + PDSLOT_PTE * 4) # XXX 4 == sizeof pde
146
147
148
149
150
151 .globl _C_LABEL(APTmap), _C_LABEL(APTD), _C_LABEL(APTDpde)
152 .set _C_LABEL(APTmap), (PDSLOT_APTE << PDSHIFT)
153 .set _C_LABEL(APTD), (_C_LABEL(APTmap) + PDSLOT_APTE * NBPG)
154
155 .set _C_LABEL(APTDpde), (_C_LABEL(PTD) + PDSLOT_APTE * 4)
156
157
158
159
160 .data
161
162 .globl _C_LABEL(cpu), _C_LABEL(cpu_id), _C_LABEL(cpu_vendor)
163 .globl _C_LABEL(cpu_brandstr)
164 .globl _C_LABEL(cpuid_level)
165 .globl _C_LABEL(cpu_miscinfo)
166 .globl _C_LABEL(cpu_feature), _C_LABEL(cpu_ecxfeature)
167 .globl _C_LABEL(cpu_cache_eax), _C_LABEL(cpu_cache_ebx)
168 .globl _C_LABEL(cpu_cache_ecx), _C_LABEL(cpu_cache_edx)
169 .globl _C_LABEL(cold), _C_LABEL(cnvmem), _C_LABEL(extmem)
170 .globl _C_LABEL(esym)
171 .globl _C_LABEL(boothowto), _C_LABEL(bootdev), _C_LABEL(atdevbase)
172 .globl _C_LABEL(proc0paddr), _C_LABEL(PTDpaddr), _C_LABEL(PTDsize)
173 .globl _C_LABEL(gdt)
174 .globl _C_LABEL(bootapiver), _C_LABEL(bootargc), _C_LABEL(bootargv)
175 .globl _C_LABEL(lapic_tpr)
176
177 #if NLAPIC > 0
178 #ifdef __ELF__
179 .align NBPG
180 #else
181 .align 12
182 #endif
183 .globl _C_LABEL(local_apic), _C_LABEL(lapic_id)
184 _C_LABEL(local_apic):
185 .space LAPIC_ID
186 _C_LABEL(lapic_id):
187 .long 0x00000000
188 .space LAPIC_TPRI-(LAPIC_ID+4)
189 _C_LABEL(lapic_tpr):
190 .space LAPIC_PPRI-LAPIC_TPRI
191 _C_LABEL(lapic_ppr):
192 .space LAPIC_ISR-LAPIC_PPRI
193 _C_LABEL(lapic_isr):
194 .space NBPG-LAPIC_ISR
195 #else
196 _C_LABEL(lapic_tpr):
197 .long 0
198 #endif
199
200 _C_LABEL(cpu): .long 0 # are we 386, 386sx, 486, 586 or 686
201 _C_LABEL(cpu_id): .long 0 # saved from 'cpuid' instruction
202 _C_LABEL(cpu_miscinfo): .long 0 # misc info (apic/brand id) from 'cpuid'
203 _C_LABEL(cpu_feature): .long 0 # feature flags from 'cpuid' instruction
204 _C_LABEL(cpu_ecxfeature):.long 0 # extended feature flags from 'cpuid'
205 _C_LABEL(cpuid_level): .long -1 # max. lvl accepted by 'cpuid' insn
206 _C_LABEL(cpu_cache_eax):.long 0
207 _C_LABEL(cpu_cache_ebx):.long 0
208 _C_LABEL(cpu_cache_ecx):.long 0
209 _C_LABEL(cpu_cache_edx):.long 0
210 _C_LABEL(cpu_vendor): .space 16 # vendor string returned by 'cpuid' instruction
211 _C_LABEL(cpu_brandstr): .space 48 # brand string returned by 'cpuid'
212 _C_LABEL(cold): .long 1 # cold till we are not
213 _C_LABEL(esym): .long 0 # ptr to end of syms
214 _C_LABEL(cnvmem): .long 0 # conventional memory size
215 _C_LABEL(extmem): .long 0 # extended memory size
216 _C_LABEL(atdevbase): .long 0 # location of start of iomem in virtual
217 _C_LABEL(bootapiver): .long 0 # /boot API version
218 _C_LABEL(bootargc): .long 0 # /boot argc
219 _C_LABEL(bootargv): .long 0 # /boot argv
220 _C_LABEL(bootdev): .long 0 # device we booted from
221 _C_LABEL(proc0paddr): .long 0
222 _C_LABEL(PTDpaddr): .long 0 # paddr of PTD, for libkvm
223 _C_LABEL(PTDsize): .long NBPG # size of PTD, for libkvm
224
225 .space 512
226 tmpstk:
227
228
229 #define RELOC(x) ((x) - KERNBASE)
230
231 .text
232 .globl start
233 .globl _C_LABEL(kernel_text)
234 _C_LABEL(kernel_text) = KERNTEXTOFF
235 start: movw $0x1234,0x472 # warm boot
236
237
238
239
240
241
242 movl 4(%esp),%eax
243 movl %eax,RELOC(_C_LABEL(boothowto))
244 movl 8(%esp),%eax
245 movl %eax,RELOC(_C_LABEL(bootdev))
246 movl 16(%esp),%eax
247 testl %eax,%eax
248 jz 1f
249 addl $KERNBASE,%eax
250 1: movl %eax,RELOC(_C_LABEL(esym))
251
252 movl 12(%esp),%eax
253 movl %eax,RELOC(_C_LABEL(bootapiver))
254 movl 28(%esp), %eax
255 movl %eax, RELOC(_C_LABEL(bootargc))
256 movl 32(%esp), %eax
257 movl %eax, RELOC(_C_LABEL(bootargv))
258
259
260 pushl $PSL_MBO
261 popfl
262
263
264 xorl %eax,%eax
265 movw %ax,%fs
266 movw %ax,%gs
267
268
269
270 try386:
271 pushfl
272 popl %eax
273 movl %eax,%ecx
274 orl $PSL_AC,%eax
275 pushl %eax
276 popfl
277 pushfl
278 popl %eax
279 xorl %ecx,%eax
280 andl $PSL_AC,%eax
281 pushl %ecx
282 popfl
283
284 testl %eax,%eax
285 jnz try486
286
287
288
289
290
291
292 movl $0x5555,%eax
293 xorl %edx,%edx
294 movl $2,%ecx
295 divl %ecx
296 jnz is386
297
298 isnx586:
299
300
301
302
303 movl $CPU_NX586,RELOC(_C_LABEL(cpu))
304 jmp 2f
305
306 is386:
307 movl $CPU_386,RELOC(_C_LABEL(cpu))
308 jmp 2f
309
310 try486:
311 pushfl
312 popl %eax
313 movl %eax,%ecx
314 xorl $PSL_ID,%eax
315 pushl %eax
316 popfl
317 pushfl
318 popl %eax
319 xorl %ecx,%eax
320 andl $PSL_ID,%eax
321 pushl %ecx
322 popfl
323
324 testl %eax,%eax
325 jnz try586
326 is486: movl $CPU_486,RELOC(_C_LABEL(cpu))
327
328
329
330
331
332
333
334
335 pushfl
336 movl $0x5555, %eax
337 xorl %edx, %edx
338 movl $2, %ecx
339 clc
340 divl %ecx
341 jnc trycyrix486
342 popfl
343 jmp 2f
344 trycyrix486:
345 movl $CPU_6x86,RELOC(_C_LABEL(cpu)) # set CPU type
346
347
348
349
350
351 xorl %edx,%edx
352 cmpl %edx,%edx # set flags to known state
353 pushfl
354 popl %ecx # store flags in ecx
355 movl $-1,%eax
356 movl $4,%ebx
357 divl %ebx # do a long division
358 pushfl
359 popl %eax
360 xorl %ecx,%eax # are the flags different?
361 testl $0x8d5,%eax # only check C|PF|AF|Z|N|V
362 jne 2f # yes; must not be Cyrix CPU
363 movl $CPU_486DLC,RELOC(_C_LABEL(cpu)) # set CPU type
364
365 #ifndef CYRIX_CACHE_WORKS
366
367 invd
368 movb $CCR0,%al # Configuration Register index (CCR0)
369 outb %al,$0x22
370 inb $0x23,%al
371 orb $(CCR0_NC1|CCR0_BARB),%al
372 movb %al,%ah
373 movb $CCR0,%al
374 outb %al,$0x22
375 movb %ah,%al
376 outb %al,$0x23
377 invd
378 #else
379
380 invd # Start with guaranteed clean cache
381 movb $CCR0,%al # Configuration Register index (CCR0)
382 outb %al,$0x22
383 inb $0x23,%al
384 andb $~CCR0_NC0,%al
385 #ifndef CYRIX_CACHE_REALLY_WORKS
386 orb $(CCR0_NC1|CCR0_BARB),%al
387 #else
388 orb $CCR0_NC1,%al
389 #endif
390 movb %al,%ah
391 movb $CCR0,%al
392 outb %al,$0x22
393 movb %ah,%al
394 outb %al,$0x23
395
396 movb $(NCR1+2),%al
397 outb %al,$0x22
398 movb $NCR_SIZE_0K,%al
399 outb %al,$0x23
400
401 movb $(NCR2+2),%al
402 outb %al,$0x22
403 movb $NCR_SIZE_0K,%al
404 outb %al,$0x23
405
406 movb $(NCR3+2),%al
407 outb %al,$0x22
408 movb $NCR_SIZE_0K,%al
409 outb %al,$0x23
410
411 movb $(NCR4+2),%al
412 outb %al,$0x22
413 movb $NCR_SIZE_0K,%al
414 outb %al,$0x23
415
416 movl %cr0,%eax
417 andl $~(CR0_CD|CR0_NW),%eax
418 movl %eax,%cr0
419 invd
420 #endif
421
422 jmp 2f
423
424 try586:
425 xorl %eax,%eax
426 cpuid
427 movl %eax,RELOC(_C_LABEL(cpuid_level))
428 movl %ebx,RELOC(_C_LABEL(cpu_vendor)) # store vendor string
429 movl %edx,RELOC(_C_LABEL(cpu_vendor))+4
430 movl %ecx,RELOC(_C_LABEL(cpu_vendor))+8
431 movl $0, RELOC(_C_LABEL(cpu_vendor))+12
432
433 movl $1,%eax
434 cpuid
435 movl %eax,RELOC(_C_LABEL(cpu_id)) # store cpu_id and features
436 movl %ebx,RELOC(_C_LABEL(cpu_miscinfo))
437 movl %edx,RELOC(_C_LABEL(cpu_feature))
438 movl %ecx,RELOC(_C_LABEL(cpu_ecxfeature))
439
440 movl RELOC(_C_LABEL(cpuid_level)),%eax
441 cmp $2,%eax
442 jl 1f
443
444 movl $2,%eax
445 cpuid
446
447
448
449
450
451 movl %eax,RELOC(_C_LABEL(cpu_cache_eax))
452 movl %ebx,RELOC(_C_LABEL(cpu_cache_ebx))
453 movl %ecx,RELOC(_C_LABEL(cpu_cache_ecx))
454 movl %edx,RELOC(_C_LABEL(cpu_cache_edx))
455
456 1:
457
458 movl $0x80000000,%eax
459 cpuid
460 cmpl $0x80000000,%eax
461 jbe 2f
462 movl $0x80000002,%eax
463 cpuid
464 movl %eax,RELOC(_C_LABEL(cpu_brandstr))
465 movl %ebx,RELOC(_C_LABEL(cpu_brandstr))+4
466 movl %ecx,RELOC(_C_LABEL(cpu_brandstr))+8
467 movl %edx,RELOC(_C_LABEL(cpu_brandstr))+12
468 movl $0x80000003,%eax
469 cpuid
470 movl %eax,RELOC(_C_LABEL(cpu_brandstr))+16
471 movl %ebx,RELOC(_C_LABEL(cpu_brandstr))+20
472 movl %ecx,RELOC(_C_LABEL(cpu_brandstr))+24
473 movl %edx,RELOC(_C_LABEL(cpu_brandstr))+28
474 movl $0x80000004,%eax
475 cpuid
476 movl %eax,RELOC(_C_LABEL(cpu_brandstr))+32
477 movl %ebx,RELOC(_C_LABEL(cpu_brandstr))+36
478 movl %ecx,RELOC(_C_LABEL(cpu_brandstr))+40
479 andl $0x00ffffff,%edx
480 movl %edx,RELOC(_C_LABEL(cpu_brandstr))+44
481
482 2:
483
484
485
486
487
488
489
490
491
492
493
494
495 movl $RELOC(tmpstk),%esp # bootstrap stack end location
496
497
498
499
500
501
502
503 #define PROC0STACK ((0) * NBPG)
504 #define PROC0PDIR (( UPAGES) * NBPG)
505 #define SYSMAP ((1+UPAGES) * NBPG)
506 #define TABLESIZE ((1+UPAGES) * NBPG)
507
508
509 movl $RELOC(_C_LABEL(end)),%edi
510 #if (defined(DDB) || NKSYMS > 0) && !defined(SYMTAB_SPACE)
511
512 movl RELOC(_C_LABEL(esym)),%eax
513 testl %eax,%eax
514 jz 1f
515 subl $KERNBASE,%eax
516 movl %eax,%edi
517 1:
518 #endif
519
520
521 movl %edi,%esi # edi = esym ? esym : end
522 addl $PGOFSET, %esi # page align up
523 andl $~PGOFSET, %esi
524
525
526
527
528
529 movl RELOC(_C_LABEL(nkpde)),%ecx # get nkpde
530 cmpl $NKPTP_MIN,%ecx # larger than min?
531 jge 1f
532 movl $NKPTP_MIN,%ecx # set at min
533 jmp 2f
534 1: cmpl $NKPTP_MAX,%ecx # larger than max?
535 jle 2f
536 movl $NKPTP_MAX,%ecx
537 2: movl %ecx,RELOC(_C_LABEL(nkpde)) # and store it back
538
539
540 shll $PGSHIFT,%ecx
541 addl $TABLESIZE,%ecx
542 addl %esi,%ecx # end of tables
543 subl %edi,%ecx # size of tables
544 shrl $2,%ecx
545 xorl %eax, %eax
546 cld
547 rep
548 stosl
549
550
551
552
553
554
555
556 #define fillkpt \
557 1: movl %eax,(%ebx) ; \
558 addl $NBPG,%eax ; \
559 addl $4,%ebx ; \
560 loop 1b ;
561
562
563
564
565
566 leal (RELOC(_C_LABEL(etext))+PGOFSET),%edx
567 andl $~PGOFSET,%edx
568
569
570 movl $RELOC(KERNTEXTOFF),%eax
571 movl %eax,%ecx
572 shrl $PGSHIFT,%ecx
573 leal (SYSMAP)(%esi,%ecx,4),%ebx
574
575
576 movl %edx,%ecx
577 subl %eax,%ecx
578 shrl $PGSHIFT,%ecx
579 #ifdef DDB
580 orl $(PG_V|PG_KW),%eax
581 #else
582 orl $(PG_V|PG_KR),%eax
583 #endif
584 fillkpt
585
586
587 leal (PG_V|PG_KW)(%edx),%eax
588 movl RELOC(_C_LABEL(nkpde)),%ecx
589 shll $PGSHIFT,%ecx
590 addl $TABLESIZE,%ecx
591 addl %esi,%ecx # end of tables
592 subl %edx,%ecx # subtract end of text
593 shrl $PGSHIFT,%ecx
594 fillkpt
595
596
597 movl $(IOM_BEGIN|PG_V|PG_KW),%eax # having these bits set
598 movl $(IOM_SIZE>>PGSHIFT),%ecx # for this many pte s,
599 fillkpt
600
601
602
603
604 movl RELOC(_C_LABEL(nkpde)),%ecx # count of pde s,
605 leal (PROC0PDIR+0*4)(%esi),%ebx # where temp maps!
606 leal (SYSMAP+PG_V|PG_KW)(%esi),%eax # pte for KPT in proc 0
607 fillkpt
608
609
610
611
612
613 movl RELOC(_C_LABEL(nkpde)),%ecx # count of pde s,
614 leal (PROC0PDIR+PDSLOT_KERN*4)(%esi),%ebx # map them high
615 leal (SYSMAP+PG_V|PG_KW)(%esi),%eax # pte for KPT in proc 0
616 fillkpt
617
618
619 leal (PROC0PDIR+PG_V|PG_KW)(%esi),%eax # pte for ptd
620 movl %eax,(PROC0PDIR+PDSLOT_PTE*4)(%esi) # recursive PD slot
621
622
623 leal (PROC0PDIR)(%esi),%eax # phys address of ptd in proc 0
624 movl %eax,RELOC(_C_LABEL(PTDpaddr))
625
626
627 movl %eax,%cr3 # load ptd addr into mmu
628 movl %cr0,%eax # get control word
629
630 orl $(CR0_PE|CR0_PG|CR0_NE|CR0_TS|CR0_EM|CR0_MP),%eax
631 movl %eax,%cr0 # and let's page NOW!
632
633 pushl $begin # jump to high mem
634 ret
635
636 begin:
637
638 movl _C_LABEL(nkpde),%ecx # for this many pde s,
639 leal (PROC0PDIR+0*4)(%esi),%ebx # which is where temp maps!
640 addl $(KERNBASE), %ebx # now use relocated address
641 1: movl $0,(%ebx)
642 addl $4,%ebx # next pde
643 loop 1b
644
645
646 movl _C_LABEL(nkpde),%edx
647 shll $PGSHIFT,%edx
648 addl $(TABLESIZE+KERNBASE),%edx
649 addl %esi,%edx
650 movl %edx,_C_LABEL(atdevbase)
651
652
653 leal (PROC0STACK+KERNBASE)(%esi),%eax
654 movl %eax,_C_LABEL(proc0paddr)
655 leal (USPACE-FRAMESIZE)(%eax),%esp
656 leal (PROC0PDIR)(%esi),%ebx # phys address of ptd in proc 0
657 movl %ebx,PCB_CR3(%eax) # pcb->pcb_cr3
658 xorl %ebp,%ebp # mark end of frames
659
660 movl _C_LABEL(nkpde),%eax
661 shll $PGSHIFT,%eax
662 addl $TABLESIZE,%eax
663 addl %esi,%eax # skip past stack and page tables
664 pushl %eax
665 call _C_LABEL(init386) # wire 386 chip for unix operation
666 addl $4,%esp
667
668 call _C_LABEL(main)
669
670 NENTRY(proc_trampoline)
671 #ifdef MULTIPROCESSOR
672 call _C_LABEL(proc_trampoline_mp)
673 #endif
674 movl $IPL_NONE,CPL
675 pushl %ebx
676 call *%esi
677 addl $4,%esp
678 INTRFASTEXIT
679
680
681
682
683
684
685
686 NENTRY(sigcode)
687 movl SIGF_FPSTATE(%esp),%esi # FPU state area if need saving
688 testl %esi,%esi
689 jz 1f
690 fnsave (%esi)
691 1: call *SIGF_HANDLER(%esp)
692 testl %esi,%esi
693 jz 2f
694 frstor (%esi)
695 jmp 2f
696
697 .globl _C_LABEL(sigcode_xmm)
698 _C_LABEL(sigcode_xmm):
699 movl SIGF_FPSTATE(%esp),%esi # FPU state area if need saving
700 testl %esi,%esi
701 jz 1f
702 fxsave (%esi)
703 fninit
704 1: call *SIGF_HANDLER(%esp)
705 testl %esi,%esi
706 jz 2f
707 fxrstor (%esi)
708
709 2: leal SIGF_SC(%esp),%eax # scp (the call may have clobbered the
710
711 pushl %eax
712 pushl %eax # junk to fake return address
713 movl $SYS_sigreturn,%eax
714 int $0x80 # enter kernel with args on stack
715 movl $SYS_exit,%eax
716 int $0x80 # exit if sigreturn fails
717 .globl _C_LABEL(esigcode)
718 _C_LABEL(esigcode):
719
720
721
722 #ifdef COMPAT_SVR4
723 NENTRY(svr4_sigcode)
724 call *SVR4_SIGF_HANDLER(%esp)
725 leal SVR4_SIGF_UC(%esp),%eax # ucp (the call may have clobbered the
726
727 pushl %eax
728 pushl $1 # setcontext(p) == syscontext(1, p)
729 pushl %eax # junk to fake return address
730 movl $SVR4_SYS_context,%eax
731 int $0x80 # enter kernel with args on stack
732 movl $SVR4_SYS_exit,%eax
733 int $0x80 # exit if sigreturn fails
734 .globl _C_LABEL(svr4_esigcode)
735 _C_LABEL(svr4_esigcode):
736 #endif
737
738
739
740 #ifdef COMPAT_LINUX
741
742
743
744 NENTRY(linux_sigcode)
745 call *LINUX_SIGF_HANDLER(%esp)
746 leal LINUX_SIGF_SC(%esp),%ebx # scp (the call may have clobbered the
747
748 pushl %eax # junk to fake return address
749 movl $LINUX_SYS_sigreturn,%eax
750 int $0x80 # enter kernel with args on stack
751 movl $LINUX_SYS_exit,%eax
752 int $0x80 # exit if sigreturn fails
753 .globl _C_LABEL(linux_esigcode)
754 _C_LABEL(linux_esigcode):
755 #endif
756
757
758
759 #ifdef COMPAT_FREEBSD
760
761
762
763 NENTRY(freebsd_sigcode)
764 call *FREEBSD_SIGF_HANDLER(%esp)
765 leal FREEBSD_SIGF_SC(%esp),%eax # scp (the call may have clobbered
766
767 pushl %eax
768 pushl %eax # junk to fake return address
769 movl $FREEBSD_SYS_sigreturn,%eax
770 int $0x80 # enter kernel with args on stack
771 movl $FREEBSD_SYS_exit,%eax
772 int $0x80 # exit if sigreturn fails
773 .globl _C_LABEL(freebsd_esigcode)
774 _C_LABEL(freebsd_esigcode):
775 #endif
776
777
778
779
780
781
782
783
784
785
786
787 ENTRY(fillw)
788 pushl %edi
789 movl 8(%esp),%eax
790 movl 12(%esp),%edi
791 movw %ax,%cx
792 rorl $16,%eax
793 movw %cx,%ax
794 cld
795 movl 16(%esp),%ecx
796 shrl %ecx # do longwords
797 rep
798 stosl
799 movl 16(%esp),%ecx
800 andl $1,%ecx # do remainder
801 rep
802 stosw
803 popl %edi
804 ret
805
806
807
808 #ifdef DDB
809 #define FPADD 4
810 #else
811 #define FPADD 0
812 #endif
813
814
815
816
817
818 ENTRY(kcopy)
819 #ifdef DDB
820 pushl %ebp
821 movl %esp,%ebp
822 #endif
823 pushl %esi
824 pushl %edi
825 GET_CURPCB(%eax) # load curpcb into eax and set on-fault
826 pushl PCB_ONFAULT(%eax)
827 movl $_C_LABEL(copy_fault), PCB_ONFAULT(%eax)
828
829 movl 16+FPADD(%esp),%esi
830 movl 20+FPADD(%esp),%edi
831 movl 24+FPADD(%esp),%ecx
832 movl %edi,%eax
833 subl %esi,%eax
834 cmpl %ecx,%eax # overlapping?
835 jb 1f
836 cld # nope, copy forward
837 shrl $2,%ecx # copy by 32-bit words
838 rep
839 movsl
840 movl 24+FPADD(%esp),%ecx
841 andl $3,%ecx # any bytes left?
842 rep
843 movsb
844
845 GET_CURPCB(%edx) # XXX save curpcb?
846 popl PCB_ONFAULT(%edx)
847 popl %edi
848 popl %esi
849 xorl %eax,%eax
850 #ifdef DDB
851 leave
852 #endif
853 ret
854
855 ALIGN_TEXT
856 1: addl %ecx,%edi # copy backward
857 addl %ecx,%esi
858 std
859 andl $3,%ecx # any fractional bytes?
860 decl %edi
861 decl %esi
862 rep
863 movsb
864 movl 24+FPADD(%esp),%ecx # copy remainder by 32-bit words
865 shrl $2,%ecx
866 subl $3,%esi
867 subl $3,%edi
868 rep
869 movsl
870 cld
871
872 GET_CURPCB(%edx)
873 popl PCB_ONFAULT(%edx)
874 popl %edi
875 popl %esi
876 xorl %eax,%eax
877 #ifdef DDB
878 leave
879 #endif
880 ret
881
882
883
884
885
886 ALTENTRY(ovbcopy)
887 ENTRY(bcopy)
888 pushl %esi
889 pushl %edi
890 movl 12(%esp),%esi
891 movl 16(%esp),%edi
892 movl 20(%esp),%ecx
893 movl %edi,%eax
894 subl %esi,%eax
895 cmpl %ecx,%eax # overlapping?
896 jb 1f
897 cld # nope, copy forward
898 shrl $2,%ecx # copy by 32-bit words
899 rep
900 movsl
901 movl 20(%esp),%ecx
902 andl $3,%ecx # any bytes left?
903 rep
904 movsb
905 popl %edi
906 popl %esi
907 ret
908
909 ALIGN_TEXT
910 1: addl %ecx,%edi # copy backward
911 addl %ecx,%esi
912 std
913 andl $3,%ecx # any fractional bytes?
914 decl %edi
915 decl %esi
916 rep
917 movsb
918 movl 20(%esp),%ecx # copy remainder by 32-bit words
919 shrl $2,%ecx
920 subl $3,%esi
921 subl $3,%edi
922 rep
923 movsl
924 popl %edi
925 popl %esi
926 cld
927 ret
928
929
930
931
932 ENTRY(memcpy)
933 movl 4(%esp),%ecx
934 xchg 8(%esp),%ecx
935 movl %ecx,4(%esp)
936 jmp _C_LABEL(bcopy)
937
938
939
940
941
942
943
944
945
946
947
948
949 ENTRY(copyout)
950 #ifdef DDB
951 pushl %ebp
952 movl %esp,%ebp
953 #endif
954 pushl %esi
955 pushl %edi
956 pushl $0
957
958 movl 16+FPADD(%esp),%esi
959 movl 20+FPADD(%esp),%edi
960 movl 24+FPADD(%esp),%eax
961
962
963
964
965
966
967
968
969 movl %edi,%edx
970 addl %eax,%edx
971 jc _C_LABEL(copy_fault)
972 cmpl $VM_MAXUSER_ADDRESS,%edx
973 ja _C_LABEL(copy_fault)
974
975 3: GET_CURPCB(%edx)
976 movl $_C_LABEL(copy_fault),PCB_ONFAULT(%edx)
977
978
979 cld
980 movl %eax,%ecx
981 shrl $2,%ecx
982 rep
983 movsl
984 movl %eax,%ecx
985 andl $3,%ecx
986 rep
987 movsb
988
989 popl PCB_ONFAULT(%edx)
990 popl %edi
991 popl %esi
992 xorl %eax,%eax
993 #ifdef DDB
994 leave
995 #endif
996 ret
997
998
999
1000
1001
1002 ENTRY(copyin)
1003 #ifdef DDB
1004 pushl %ebp
1005 movl %esp,%ebp
1006 #endif
1007 pushl %esi
1008 pushl %edi
1009 GET_CURPCB(%eax)
1010 pushl $0
1011 movl $_C_LABEL(copy_fault),PCB_ONFAULT(%eax)
1012
1013 movl 16+FPADD(%esp),%esi
1014 movl 20+FPADD(%esp),%edi
1015 movl 24+FPADD(%esp),%eax
1016
1017
1018
1019
1020
1021
1022 movl %esi,%edx
1023 addl %eax,%edx
1024 jc _C_LABEL(copy_fault)
1025 cmpl $VM_MAXUSER_ADDRESS,%edx
1026 ja _C_LABEL(copy_fault)
1027
1028 3:
1029 cld
1030 movl %eax,%ecx
1031 shrl $2,%ecx
1032 rep
1033 movsl
1034 movb %al,%cl
1035 andb $3,%cl
1036 rep
1037 movsb
1038
1039 GET_CURPCB(%edx)
1040 popl PCB_ONFAULT(%edx)
1041 popl %edi
1042 popl %esi
1043 xorl %eax,%eax
1044 #ifdef DDB
1045 leave
1046 #endif
1047 ret
1048
1049 ENTRY(copy_fault)
1050 GET_CURPCB(%edx)
1051 popl PCB_ONFAULT(%edx)
1052 popl %edi
1053 popl %esi
1054 movl $EFAULT,%eax
1055 #ifdef DDB
1056 leave
1057 #endif
1058 ret
1059
1060
1061
1062
1063
1064
1065
1066
1067 ENTRY(copyoutstr)
1068 #ifdef DDB
1069 pushl %ebp
1070 movl %esp,%ebp
1071 #endif
1072 pushl %esi
1073 pushl %edi
1074
1075 movl 12+FPADD(%esp),%esi # esi = from
1076 movl 16+FPADD(%esp),%edi # edi = to
1077 movl 20+FPADD(%esp),%edx # edx = maxlen
1078
1079 5: GET_CURPCB(%eax)
1080 movl $_C_LABEL(copystr_fault),PCB_ONFAULT(%eax)
1081
1082
1083
1084 movl $VM_MAXUSER_ADDRESS,%eax
1085 subl %edi,%eax
1086 jbe _C_LABEL(copystr_fault) # die if CF == 1 || ZF == 1
1087
1088
1089
1090 cmpl %edx,%eax
1091 jae 1f
1092 movl %eax,%edx
1093 movl %eax,20+FPADD(%esp)
1094
1095 1: incl %edx
1096 cld
1097
1098 1: decl %edx
1099 jz 2f
1100 lodsb
1101 stosb
1102 testb %al,%al
1103 jnz 1b
1104
1105
1106 decl %edx
1107 xorl %eax,%eax
1108 jmp copystr_return
1109
1110 2:
1111 cmpl $VM_MAXUSER_ADDRESS,%edi
1112 jae _C_LABEL(copystr_fault)
1113 movl $ENAMETOOLONG,%eax
1114 jmp copystr_return
1115
1116
1117
1118
1119
1120
1121
1122
1123 ENTRY(copyinstr)
1124 #ifdef DDB
1125 pushl %ebp
1126 movl %esp,%ebp
1127 #endif
1128 pushl %esi
1129 pushl %edi
1130 GET_CURPCB(%ecx)
1131 movl $_C_LABEL(copystr_fault),PCB_ONFAULT(%ecx)
1132
1133 movl 12+FPADD(%esp),%esi # %esi = from
1134 movl 16+FPADD(%esp),%edi # %edi = to
1135 movl 20+FPADD(%esp),%edx # %edx = maxlen
1136
1137
1138
1139
1140 movl $VM_MAXUSER_ADDRESS,%eax
1141 subl %esi,%eax
1142 jbe _C_LABEL(copystr_fault) # Error if CF == 1 || ZF == 1
1143
1144
1145 cmpl %edx,%eax
1146 jae 1f
1147 movl %eax,%edx
1148 movl %eax,20+FPADD(%esp)
1149
1150 1: incl %edx
1151 cld
1152
1153 1: decl %edx
1154 jz 2f
1155 lodsb
1156 stosb
1157 testb %al,%al
1158 jnz 1b
1159
1160
1161 decl %edx
1162 xorl %eax,%eax
1163 jmp copystr_return
1164
1165 2:
1166 cmpl $VM_MAXUSER_ADDRESS,%esi
1167 jae _C_LABEL(copystr_fault)
1168 movl $ENAMETOOLONG,%eax
1169 jmp copystr_return
1170
1171 ENTRY(copystr_fault)
1172 movl $EFAULT,%eax
1173
1174 copystr_return:
1175
1176 GET_CURPCB(%ecx)
1177 movl $0,PCB_ONFAULT(%ecx)
1178 movl 20+FPADD(%esp),%ecx
1179 subl %edx,%ecx
1180 movl 24+FPADD(%esp),%edx
1181 testl %edx,%edx
1182 jz 8f
1183 movl %ecx,(%edx)
1184
1185 8: popl %edi
1186 popl %esi
1187 #ifdef DDB
1188 leave
1189 #endif
1190 ret
1191
1192
1193
1194
1195
1196
1197
1198 ENTRY(copystr)
1199 #ifdef DDB
1200 pushl %ebp
1201 movl %esp,%ebp
1202 #endif
1203 pushl %esi
1204 pushl %edi
1205
1206 movl 12+FPADD(%esp),%esi # esi = from
1207 movl 16+FPADD(%esp),%edi # edi = to
1208 movl 20+FPADD(%esp),%edx # edx = maxlen
1209 incl %edx
1210 cld
1211
1212 1: decl %edx
1213 jz 4f
1214 lodsb
1215 stosb
1216 testb %al,%al
1217 jnz 1b
1218
1219
1220 decl %edx
1221 xorl %eax,%eax
1222 jmp 6f
1223
1224 4:
1225 movl $ENAMETOOLONG,%eax
1226
1227 6:
1228 movl 20+FPADD(%esp),%ecx
1229 subl %edx,%ecx
1230 movl 24+FPADD(%esp),%edx
1231 testl %edx,%edx
1232 jz 7f
1233 movl %ecx,(%edx)
1234
1235 7: popl %edi
1236 popl %esi
1237 #ifdef DDB
1238 leave
1239 #endif
1240 ret
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252 NENTRY(lgdt)
1253
1254 movl 4(%esp),%eax
1255 lgdt (%eax)
1256
1257 jmp 1f
1258 nop
1259 1:
1260 movl $GSEL(GDATA_SEL, SEL_KPL),%eax
1261 movw %ax,%ds
1262 movw %ax,%es
1263 movw %ax,%ss
1264 movl $GSEL(GCPU_SEL, SEL_KPL),%eax
1265 movw %ax,%fs
1266
1267 popl %eax
1268 pushl $GSEL(GCODE_SEL, SEL_KPL)
1269 pushl %eax
1270 lret
1271
1272 ENTRY(setjmp)
1273 movl 4(%esp),%eax
1274 movl %ebx,(%eax) # save ebx
1275 movl %esp,4(%eax) # save esp
1276 movl %ebp,8(%eax) # save ebp
1277 movl %esi,12(%eax) # save esi
1278 movl %edi,16(%eax) # save edi
1279 movl (%esp),%edx # get rta
1280 movl %edx,20(%eax) # save eip
1281 xorl %eax,%eax # return (0);
1282 ret
1283
1284 ENTRY(longjmp)
1285 movl 4(%esp),%eax
1286 movl (%eax),%ebx # restore ebx
1287 movl 4(%eax),%esp # restore esp
1288 movl 8(%eax),%ebp # restore ebp
1289 movl 12(%eax),%esi # restore esi
1290 movl 16(%eax),%edi # restore edi
1291 movl 20(%eax),%edx # get rta
1292 movl %edx,(%esp) # put in return frame
1293 xorl %eax,%eax # return (1);
1294 incl %eax
1295 ret
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307 .globl _C_LABEL(whichqs),_C_LABEL(qs),_C_LABEL(uvmexp),_C_LABEL(panic)
1308
1309
1310
1311
1312 NENTRY(setrunqueue)
1313 movl 4(%esp),%eax
1314 #ifdef DIAGNOSTIC
1315 cmpl $0,P_BACK(%eax) # should not be on q already
1316 jne 1f
1317 cmpl $0,P_WCHAN(%eax)
1318 jne 1f
1319 cmpb $SRUN,P_STAT(%eax)
1320 jne 1f
1321 #endif
1322 movzbl P_PRIORITY(%eax),%edx
1323 shrl $2,%edx
1324 btsl %edx,_C_LABEL(whichqs) # set q full bit
1325 leal _C_LABEL(qs)(,%edx,8),%edx # locate q hdr
1326 movl P_BACK(%edx),%ecx
1327 movl %edx,P_FORW(%eax) # link process on tail of q
1328 movl %eax,P_BACK(%edx)
1329 movl %eax,P_FORW(%ecx)
1330 movl %ecx,P_BACK(%eax)
1331 ret
1332 #ifdef DIAGNOSTIC
1333 1: pushl $2f
1334 call _C_LABEL(panic)
1335
1336 2: .asciz "setrunqueue"
1337 #endif
1338
1339
1340
1341
1342
1343 NENTRY(remrunqueue)
1344 movl 4(%esp),%ecx
1345 movzbl P_PRIORITY(%ecx),%eax
1346 #ifdef DIAGNOSTIC
1347 shrl $2,%eax
1348 btl %eax,_C_LABEL(whichqs)
1349 jnc 1f
1350 #endif
1351 movl P_BACK(%ecx),%edx # unlink process
1352 movl $0,P_BACK(%ecx) # zap reverse link to indicate off list
1353 movl P_FORW(%ecx),%ecx
1354 movl %ecx,P_FORW(%edx)
1355 movl %edx,P_BACK(%ecx)
1356 cmpl %ecx,%edx # q still has something?
1357 jne 2f
1358 #ifndef DIAGNOSTIC
1359 shrl $2,%eax
1360 #endif
1361 btrl %eax,_C_LABEL(whichqs) # no; clear bit
1362 2: ret
1363 #ifdef DIAGNOSTIC
1364 1: pushl $3f
1365 call _C_LABEL(panic)
1366
1367 3: .asciz "remrunqueue"
1368 #endif
1369
1370 #if NAPM > 0
1371 .globl _C_LABEL(apm_cpu_idle),_C_LABEL(apm_cpu_busy)
1372 #endif
1373
1374
1375
1376
1377 ENTRY(idle)
1378
1379 testl %esi,%esi
1380 jz 1f
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392 pushl %esi
1393 call _C_LABEL(pmap_deactivate) # pmap_deactivate(oldproc)
1394 addl $4,%esp
1395
1396 movl P_ADDR(%esi),%esi
1397
1398
1399 movl %esp,PCB_ESP(%esi)
1400 movl %ebp,PCB_EBP(%esi)
1401
1402
1403 #ifndef MULTIPROCESSOR
1404 movl $_C_LABEL(proc0),%ebx
1405 movl P_ADDR(%ebx),%edi
1406 movl P_MD_TSS_SEL(%ebx),%edx
1407 #else
1408 movl CPUVAR(IDLE_PCB), %edi
1409 movl CPUVAR(IDLE_TSS_SEL), %edx
1410 #endif
1411
1412
1413 cli
1414
1415
1416 movl PCB_ESP(%edi),%esp
1417 movl PCB_EBP(%edi),%ebp
1418
1419
1420
1421 movl PCB_CR3(%edi),%ecx
1422 movl %ecx,%cr3
1423
1424
1425 movl CPUVAR(GDT), %eax
1426 andl $~0x0200,4-SEL_KPL(%eax,%edx,1)
1427 ltr %dx
1428
1429
1430
1431
1432 movl PCB_CR0(%edi),%ecx
1433 movl %ecx,%cr0
1434
1435
1436 SET_CURPCB(%edi)
1437
1438 xorl %esi,%esi
1439 sti
1440
1441 1:
1442 #if defined(MULTIPROCESSOR) || defined(LOCKDEBUG)
1443 call _C_LABEL(sched_unlock_idle)
1444 #endif
1445
1446 movl $IPL_NONE,CPL # spl0()
1447 call _C_LABEL(Xspllower) # process pending interrupts
1448 jmp _C_LABEL(idle_start)
1449
1450 ENTRY(idle_loop)
1451 #if NAPM > 0
1452 call _C_LABEL(apm_cpu_idle)
1453 #else
1454 #if NPCTR > 0
1455 addl $1,_C_LABEL(pctr_idlcnt)
1456 adcl $0,_C_LABEL(pctr_idlcnt)+4
1457 #endif
1458 sti
1459 hlt
1460 #endif
1461 ENTRY(idle_start)
1462 cli
1463 cmpl $0,_C_LABEL(whichqs)
1464 jz _C_LABEL(idle_loop)
1465
1466 ENTRY(idle_exit)
1467 movl $IPL_HIGH,CPL # splhigh
1468 sti
1469 #if defined(MULTIPROCESSOR) || defined(LOCKDEBUG)
1470 call _C_LABEL(sched_lock_idle)
1471 #endif
1472 #if NAPM > 0
1473 call _C_LABEL(apm_cpu_busy)
1474 #endif
1475 jmp switch_search
1476
1477 #ifdef DIAGNOSTIC
1478 NENTRY(switch_error)
1479 pushl $1f
1480 call _C_LABEL(panic)
1481
1482 1: .asciz "cpu_switch"
1483 #endif
1484
1485
1486
1487
1488
1489
1490
1491 ENTRY(cpu_switch)
1492 pushl %ebx
1493 pushl %esi
1494 pushl %edi
1495 pushl CPL
1496
1497 movl CPUVAR(CURPROC), %esi
1498
1499
1500
1501
1502
1503
1504
1505
1506 movl $0, CPUVAR(CURPROC)
1507
1508 switch_search:
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522 movl _C_LABEL(whichqs),%ecx
1523 bsfl %ecx,%ebx # find a full q
1524 jz _C_LABEL(idle) # if none, idle
1525 leal _C_LABEL(qs)(,%ebx,8),%eax # select q
1526 movl P_FORW(%eax),%edi # unlink from front of process q
1527 #ifdef DIAGNOSTIC
1528 cmpl %edi,%eax # linked to self (i.e. nothing queued)?
1529 je _C_LABEL(switch_error) # not possible
1530 #endif
1531 movl P_FORW(%edi),%edx
1532 movl %edx,P_FORW(%eax)
1533 movl %eax,P_BACK(%edx)
1534
1535 cmpl %edx,%eax # q empty?
1536 jne 3f
1537
1538 btrl %ebx,%ecx # yes, clear to indicate empty
1539 movl %ecx,_C_LABEL(whichqs) # update q status
1540
1541 3: xorl %eax, %eax
1542
1543 movl $0, CPUVAR(RESCHED)
1544
1545 #ifdef DIAGNOSTIC
1546 cmpl %eax,P_WCHAN(%edi) # Waiting for something?
1547 jne _C_LABEL(switch_error) # Yes; shouldn't be queued.
1548 cmpb $SRUN,P_STAT(%edi) # In run state?
1549 jne _C_LABEL(switch_error) # No; shouldn't be queued.
1550 #endif
1551
1552
1553 movl %eax,P_BACK(%edi)
1554
1555
1556 movb $SONPROC,P_STAT(%edi) # p->p_stat = SONPROC
1557 movl CPUVAR(SELF), %ecx
1558 movl %edi, CPUVAR(CURPROC)
1559 movl %ecx, P_CPU(%edi)
1560
1561
1562 cmpl %edi,%esi
1563 je switch_return
1564
1565
1566 testl %esi,%esi
1567 jz switch_exited
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578 pushl %esi
1579 call _C_LABEL(pmap_deactivate)
1580 addl $4,%esp
1581
1582 movl P_ADDR(%esi),%esi
1583
1584
1585 movl %esp,PCB_ESP(%esi)
1586 movl %ebp,PCB_EBP(%esi)
1587
1588 switch_exited:
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599 cli
1600 movl P_ADDR(%edi),%esi
1601
1602
1603 movl PCB_ESP(%esi),%esp
1604 movl PCB_EBP(%esi),%ebp
1605
1606 #if 0
1607
1608 testl $P_SYSTEM,P_FLAG(%edi)
1609 jnz switch_restored
1610 #endif
1611
1612
1613
1614
1615
1616
1617
1618 pushl %edi
1619 call _C_LABEL(pmap_activate)
1620 addl $4,%esp
1621
1622
1623 movl CPUVAR(GDT),%eax
1624 movl P_MD_TSS_SEL(%edi),%edx
1625
1626
1627 andl $~0x0200,4-SEL_KPL(%eax,%edx,1)
1628 ltr %dx
1629
1630 #ifdef USER_LDT
1631
1632
1633
1634
1635
1636
1637
1638 movl PCB_LDT_SEL(%esi),%edx
1639 lldt %dx
1640 #endif
1641
1642 switch_restored:
1643
1644 movl PCB_CR0(%esi),%ecx
1645 #ifdef MULTIPROCESSOR
1646
1647
1648
1649
1650 movl CPUVAR(SELF), %ebx
1651 cmpl PCB_FPCPU(%esi),%ebx
1652 jz 1f
1653 orl $CR0_TS,%ecx
1654 1:
1655 #endif
1656 movl %ecx,%cr0
1657
1658
1659 SET_CURPCB(%esi)
1660
1661
1662 sti
1663
1664 switch_return:
1665 #if 0
1666 pushl %edi
1667 movl CPUVAR(NAME), %ebx
1668 leal CPU_INFO_NAME(%ebx),%ebx
1669 pushl %ebx
1670 pushl $1f
1671 call _C_LABEL(printf)
1672 addl $0xc,%esp
1673 #endif
1674 #if defined(MULTIPROCESSOR) || defined(LOCKDEBUG)
1675 call _C_LABEL(sched_unlock_idle)
1676 #endif
1677
1678
1679
1680
1681 popl CPL
1682
1683 movl %edi,%eax # return (p);
1684 popl %edi
1685 popl %esi
1686 popl %ebx
1687 ret
1688 1: .asciz "%s: scheduled %x\n"
1689
1690
1691
1692
1693
1694
1695 #ifndef MULTIPROCESSOR
1696 .globl _C_LABEL(proc0)
1697 #endif
1698 ENTRY(switch_exit)
1699 movl 4(%esp),%edi # old process
1700 #ifndef MULTIPROCESSOR
1701 movl $_C_LABEL(proc0),%ebx
1702 movl P_ADDR(%ebx),%esi
1703 movl P_MD_TSS_SEL(%ebx),%edx
1704 #else
1705 movl CPUVAR(IDLE_PCB), %esi
1706 movl CPUVAR(IDLE_TSS_SEL), %edx
1707 #endif
1708
1709
1710 movl $0, CPUVAR(CURPROC)
1711
1712
1713 cli
1714
1715
1716 movl PCB_ESP(%esi),%esp
1717 movl PCB_EBP(%esi),%ebp
1718
1719
1720 movl CPUVAR(GDT), %eax
1721
1722
1723 movl PCB_CR3(%esi),%ecx
1724 movl %ecx,%cr3
1725
1726
1727 andl $~0x0200,4-SEL_KPL(%eax,%edx,1)
1728 ltr %dx
1729
1730
1731
1732
1733 xorl %ecx,%ecx
1734 movw %cx,%gs
1735
1736
1737 movl $GSEL(GCPU_SEL, SEL_KPL),%ecx
1738 movw %cx,%fs
1739
1740
1741 movl PCB_CR0(%esi),%ecx
1742 movl %ecx,%cr0
1743
1744
1745 SET_CURPCB(%esi)
1746
1747
1748 sti
1749
1750
1751
1752
1753 pushl %edi
1754 call _C_LABEL(exit2)
1755 addl $4,%esp
1756
1757
1758 xorl %esi,%esi
1759 movl $0, CPUVAR(CURPROC)
1760 jmp switch_search
1761
1762
1763
1764
1765
1766 ENTRY(savectx)
1767 movl 4(%esp),%edx # edx = p->p_addr
1768
1769
1770 movl %esp,PCB_ESP(%edx)
1771 movl %ebp,PCB_EBP(%edx)
1772
1773 ret
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790 #define IDTVEC(name) ALIGN_TEXT; .globl Xname; Xname:
1791
1792 #define TRAP(a) pushl $(a) ; jmp _C_LABEL(alltraps)
1793 #define ZTRAP(a) pushl $0 ; TRAP(a)
1794 #define BPTTRAP(a) testb $(PSL_I>>8),13(%esp) ; jz 1f ; sti ; 1: ; \
1795 TRAP(a)
1796
1797 .text
1798 IDTVEC(div)
1799 ZTRAP(T_DIVIDE)
1800 IDTVEC(dbg)
1801 subl $4,%esp
1802 pushl %eax
1803 movl %dr6,%eax
1804 movl %eax,4(%esp)
1805 andb $~0xf,%al
1806 movl %eax,%dr6
1807 popl %eax
1808 BPTTRAP(T_TRCTRAP)
1809 IDTVEC(nmi)
1810 ZTRAP(T_NMI)
1811 IDTVEC(bpt)
1812 pushl $0
1813 BPTTRAP(T_BPTFLT)
1814 IDTVEC(ofl)
1815 ZTRAP(T_OFLOW)
1816 IDTVEC(bnd)
1817 ZTRAP(T_BOUND)
1818 IDTVEC(ill)
1819 ZTRAP(T_PRIVINFLT)
1820 IDTVEC(dna)
1821 #if NNPX > 0
1822 pushl $0 # dummy error code
1823 pushl $T_DNA
1824 INTRENTRY
1825 #ifdef MULTIPROCESSOR
1826 pushl CPUVAR(SELF)
1827 #else
1828 pushl $_C_LABEL(cpu_info_primary)
1829 #endif
1830 call *_C_LABEL(npxdna_func)
1831 addl $4,%esp
1832 testl %eax,%eax
1833 jz calltrap
1834 INTRFASTEXIT
1835 #else
1836 ZTRAP(T_DNA)
1837 #endif
1838 IDTVEC(dble)
1839 TRAP(T_DOUBLEFLT)
1840 IDTVEC(fpusegm)
1841 ZTRAP(T_FPOPFLT)
1842 IDTVEC(tss)
1843 TRAP(T_TSSFLT)
1844 IDTVEC(missing)
1845 TRAP(T_SEGNPFLT)
1846 IDTVEC(stk)
1847 TRAP(T_STKFLT)
1848 IDTVEC(prot)
1849 TRAP(T_PROTFLT)
1850 #ifdef I586_CPU
1851 IDTVEC(f00f_redirect)
1852 pushl $T_PAGEFLT
1853 INTRENTRY
1854 testb $PGEX_U,TF_ERR(%esp)
1855 jnz calltrap
1856 movl %cr2,%eax
1857 subl _C_LABEL(idt),%eax
1858 cmpl $(6*8),%eax
1859 jne calltrap
1860 movb $T_PRIVINFLT,TF_TRAPNO(%esp)
1861 jmp calltrap
1862 #endif
1863 IDTVEC(page)
1864 TRAP(T_PAGEFLT)
1865 IDTVEC(rsvd)
1866 ZTRAP(T_RESERVED)
1867 IDTVEC(mchk)
1868 ZTRAP(T_MACHK)
1869 IDTVEC(simd)
1870 ZTRAP(T_XFTRAP)
1871 IDTVEC(intrspurious)
1872
1873
1874
1875
1876
1877
1878
1879
1880 iret
1881 IDTVEC(fpu)
1882 #if NNPX > 0
1883
1884
1885
1886
1887
1888 pushl $0 # dummy error code
1889 pushl $T_ASTFLT
1890 INTRENTRY
1891 pushl CPL # if_ppl in intrframe
1892 pushl %esp # push address of intrframe
1893 incl _C_LABEL(uvmexp)+V_TRAP
1894 call _C_LABEL(npxintr)
1895 addl $8,%esp # pop address and if_ppl
1896 INTRFASTEXIT
1897 #else
1898 ZTRAP(T_ARITHTRAP)
1899 #endif
1900 IDTVEC(align)
1901 ZTRAP(T_ALIGNFLT)
1902
1903
1904
1905
1906
1907
1908
1909
1910 NENTRY(resume_iret)
1911 ZTRAP(T_PROTFLT)
1912 NENTRY(resume_pop_ds)
1913 pushl %es
1914 movl $GSEL(GDATA_SEL, SEL_KPL),%eax
1915 movw %ax,%es
1916 NENTRY(resume_pop_es)
1917 pushl %gs
1918 movl $GSEL(GDATA_SEL, SEL_KPL),%eax
1919 movw %ax,%gs
1920 NENTRY(resume_pop_gs)
1921 pushl %fs
1922 movl $GSEL(GCPU_SEL, SEL_KPL),%eax
1923 movw %ax,%fs
1924 NENTRY(resume_pop_fs)
1925 movl $T_PROTFLT,TF_TRAPNO(%esp)
1926 jmp calltrap
1927
1928 NENTRY(alltraps)
1929 INTRENTRY
1930 calltrap:
1931 #ifdef DIAGNOSTIC
1932 movl CPL,%ebx
1933 #endif
1934 call _C_LABEL(trap)
1935 2:
1936 cli
1937 CHECK_ASTPENDING(%ecx)
1938 je 1f
1939 testb $SEL_RPL,TF_CS(%esp)
1940 #ifdef VM86
1941 jnz 5f
1942 testl $PSL_VM,TF_EFLAGS(%esp)
1943 #endif
1944 jz 1f
1945 5: CLEAR_ASTPENDING(%ecx)
1946 sti
1947 movl $T_ASTFLT,TF_TRAPNO(%esp)
1948 call _C_LABEL(trap)
1949 jmp 2b
1950 #ifndef DIAGNOSTIC
1951 1: INTRFASTEXIT
1952 #else
1953 1: cmpl CPL,%ebx
1954 jne 3f
1955 INTRFASTEXIT
1956 3: sti
1957 pushl $4f
1958 call _C_LABEL(printf)
1959 addl $4,%esp
1960 #if defined(DDB) && 0
1961 int $3
1962 #endif
1963 movl %ebx,CPL
1964 jmp 2b
1965 4: .asciz "WARNING: SPL NOT LOWERED ON TRAP EXIT\n"
1966 #endif
1967
1968
1969
1970
1971 IDTVEC(osyscall)
1972
1973 pushfl
1974 popl 8(%esp)
1975
1976 pushfl
1977 andb $~((PSL_T|PSL_NT)>>8),1(%esp)
1978 popfl
1979 pushl $7 # size of instruction for restart
1980 jmp syscall1
1981 IDTVEC(osyscall_end)
1982
1983
1984
1985
1986 IDTVEC(syscall)
1987 pushl $2 # size of instruction for restart
1988 syscall1:
1989 pushl $T_ASTFLT # trap # for doing ASTs
1990 INTRENTRY
1991 call _C_LABEL(syscall)
1992 2:
1993 cli
1994 CHECK_ASTPENDING(%ecx)
1995 je 1f
1996
1997 CLEAR_ASTPENDING(%ecx)
1998 sti
1999
2000 call _C_LABEL(trap)
2001 jmp 2b
2002 1: INTRFASTEXIT
2003
2004 #include <i386/i386/vector.s>
2005 #include <i386/isa/icu.s>
2006
2007
2008
2009
2010
2011
2012 ENTRY(bzero)
2013 pushl %edi
2014 movl 8(%esp),%edi
2015 movl 12(%esp),%edx
2016
2017 cld
2018 xorl %eax,%eax
2019
2020
2021
2022
2023
2024
2025 cmpl $16,%edx
2026 jb 7f
2027
2028 movl %edi,%ecx
2029 negl %ecx
2030 andl $3,%ecx
2031 subl %ecx,%edx
2032 rep
2033 stosb
2034
2035 #if defined(I486_CPU)
2036 #if defined(I586_CPU) || defined(I686_CPU)
2037 cmpl $CPUCLASS_486,_C_LABEL(cpu_class)
2038 jne 8f
2039 #endif
2040
2041 movl %edx,%ecx
2042 shrl $6,%ecx
2043 jz 8f
2044 andl $63,%edx
2045 1: movl %eax,(%edi)
2046 movl %eax,4(%edi)
2047 movl %eax,8(%edi)
2048 movl %eax,12(%edi)
2049 movl %eax,16(%edi)
2050 movl %eax,20(%edi)
2051 movl %eax,24(%edi)
2052 movl %eax,28(%edi)
2053 movl %eax,32(%edi)
2054 movl %eax,36(%edi)
2055 movl %eax,40(%edi)
2056 movl %eax,44(%edi)
2057 movl %eax,48(%edi)
2058 movl %eax,52(%edi)
2059 movl %eax,56(%edi)
2060 movl %eax,60(%edi)
2061 addl $64,%edi
2062 decl %ecx
2063 jnz 1b
2064 #endif
2065
2066 8: movl %edx,%ecx
2067 shrl $2,%ecx
2068 andl $3,%edx
2069 rep
2070 stosl
2071
2072 7: movl %edx,%ecx
2073 rep
2074 stosb
2075
2076 popl %edi
2077 ret
2078
2079 #if defined(I686_CPU) && !defined(SMALL_KERNEL)
2080 ENTRY(sse2_pagezero)
2081 pushl %ebx
2082 movl 8(%esp),%ecx
2083 movl %ecx,%eax
2084 addl $4096,%eax
2085 xor %ebx,%ebx
2086 1:
2087 movnti %ebx,(%ecx)
2088 addl $4,%ecx
2089 cmpl %ecx,%eax
2090 jne 1b
2091 sfence
2092 popl %ebx
2093 ret
2094
2095 ENTRY(i686_pagezero)
2096 pushl %edi
2097 pushl %ebx
2098
2099 movl 12(%esp), %edi
2100 movl $1024, %ecx
2101 cld
2102
2103 ALIGN_TEXT
2104 1:
2105 xorl %eax, %eax
2106 repe
2107 scasl
2108 jnz 2f
2109
2110 popl %ebx
2111 popl %edi
2112 ret
2113
2114 ALIGN_TEXT
2115
2116 2:
2117 incl %ecx
2118 subl $4, %edi
2119
2120 movl %ecx, %edx
2121 cmpl $16, %ecx
2122
2123 jge 3f
2124
2125 movl %edi, %ebx
2126 andl $0x3f, %ebx
2127 shrl %ebx
2128 shrl %ebx
2129 movl $16, %ecx
2130 subl %ebx, %ecx
2131
2132 3:
2133 subl %ecx, %edx
2134 rep
2135 stosl
2136
2137 movl %edx, %ecx
2138 testl %edx, %edx
2139 jnz 1b
2140
2141 popl %ebx
2142 popl %edi
2143 ret
2144 #endif
2145
2146 #if NLAPIC > 0
2147 #include <i386/i386/apicvec.s>
2148 #endif
2149
2150 #include <i386/i386/mutex.S>