2 * Copyright (c) 1990 The Regents of the University of California.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * $FreeBSD: src/sys/i386/i386/exception.s,v 1.65.2.3 2001/08/15 01:23:49 peter Exp $
38 #include <machine/asmacros.h>
39 #include <machine/segments.h>
40 #include <machine/lock.h>
41 #include <machine/psl.h>
42 #include <machine/trap.h>
48 .globl lwkt_switch_return
50 #ifdef DEBUG_INTERRUPTS
55 .long Xrsvd1 , Xrsvd2 , Xrsvd3 , Xrsvd4 , Xrsvd5 , Xrsvd6 , Xrsvd7 , Xrsvd8
56 .long Xrsvd9 , Xrsvd10 , Xrsvd11 , Xrsvd12 , Xrsvd13 , Xrsvd14 , Xrsvd15 , Xrsvd16
57 .long Xrsvd17 , Xrsvd18 , Xrsvd19 , Xrsvd20 , Xrsvd21 , Xrsvd22 , Xrsvd23 , Xrsvd24
58 .long Xrsvd25 , Xrsvd26 , Xrsvd27 , Xrsvd28 , Xrsvd29 , Xrsvd30 , Xrsvd31 , Xrsvd32
59 .long Xrsvd33 , Xrsvd34 , Xrsvd35 , Xrsvd36 , Xrsvd37 , Xrsvd38 , Xrsvd39 , Xrsvd40
60 .long Xrsvd41 , Xrsvd42 , Xrsvd43 , Xrsvd44 , Xrsvd45 , Xrsvd46 , Xrsvd47 , Xrsvd48
61 .long Xrsvd49 , Xrsvd50 , Xrsvd51 , Xrsvd52 , Xrsvd53 , Xrsvd54 , Xrsvd55 , Xrsvd56
62 .long Xrsvd57 , Xrsvd58 , Xrsvd59 , Xrsvd60 , Xrsvd61 , Xrsvd62 , Xrsvd63 , Xrsvd64
63 .long Xrsvd65 , Xrsvd66 , Xrsvd67 , Xrsvd68 , Xrsvd69 , Xrsvd70 , Xrsvd71 , Xrsvd72
64 .long Xrsvd73 , Xrsvd74 , Xrsvd75 , Xrsvd76 , Xrsvd77 , Xrsvd78 , Xrsvd79 , Xrsvd80
65 .long Xrsvd81 , Xrsvd82 , Xrsvd83 , Xrsvd84 , Xrsvd85 , Xrsvd86 , Xrsvd87 , Xrsvd88
66 .long Xrsvd89 , Xrsvd90 , Xrsvd91 , Xrsvd92 , Xrsvd93 , Xrsvd94 , Xrsvd95 , Xrsvd96
67 .long Xrsvd97 , Xrsvd98 , Xrsvd99 , Xrsvd100, Xrsvd101, Xrsvd102, Xrsvd103, Xrsvd104
68 .long Xrsvd105, Xrsvd106, Xrsvd107, Xrsvd108, Xrsvd109, Xrsvd110, Xrsvd111, Xrsvd112
69 .long Xrsvd113, Xrsvd114, Xrsvd115, Xrsvd116, Xrsvd117, Xrsvd118, Xrsvd119, Xrsvd120
70 .long Xrsvd121, Xrsvd122, Xrsvd123, Xrsvd124, Xrsvd125, Xrsvd126, Xrsvd127, Xrsvd128
71 .long Xrsvd129, Xrsvd130, Xrsvd131, Xrsvd132, Xrsvd133, Xrsvd134, Xrsvd135, Xrsvd136
72 .long Xrsvd137, Xrsvd138, Xrsvd139, Xrsvd140, Xrsvd141, Xrsvd142, Xrsvd143, Xrsvd144
73 .long Xrsvd145, Xrsvd146, Xrsvd147, Xrsvd148, Xrsvd149, Xrsvd150, Xrsvd151, Xrsvd152
74 .long Xrsvd153, Xrsvd154, Xrsvd155, Xrsvd156, Xrsvd157, Xrsvd158, Xrsvd159, Xrsvd160
75 .long Xrsvd161, Xrsvd162, Xrsvd163, Xrsvd164, Xrsvd165, Xrsvd166, Xrsvd167, Xrsvd168
76 .long Xrsvd169, Xrsvd170, Xrsvd171, Xrsvd172, Xrsvd173, Xrsvd174, Xrsvd175, Xrsvd176
77 .long Xrsvd177, Xrsvd178, Xrsvd179, Xrsvd180, Xrsvd181, Xrsvd182, Xrsvd183, Xrsvd184
78 .long Xrsvd185, Xrsvd186, Xrsvd187, Xrsvd188, Xrsvd189, Xrsvd190, Xrsvd191, Xrsvd192
79 .long Xrsvd193, Xrsvd194, Xrsvd195, Xrsvd196, Xrsvd197, Xrsvd198, Xrsvd199, Xrsvd200
80 .long Xrsvd201, Xrsvd202, Xrsvd203, Xrsvd204, Xrsvd205, Xrsvd206, Xrsvd207, Xrsvd208
81 .long Xrsvd209, Xrsvd210, Xrsvd211, Xrsvd212, Xrsvd213, Xrsvd214, Xrsvd215, Xrsvd216
82 .long Xrsvd217, Xrsvd218, Xrsvd219, Xrsvd220, Xrsvd221, Xrsvd222, Xrsvd223, Xrsvd224
83 .long Xrsvd225, Xrsvd226, Xrsvd227, Xrsvd228, Xrsvd229, Xrsvd230, Xrsvd231, Xrsvd232
84 .long Xrsvd233, Xrsvd234, Xrsvd235, Xrsvd236, Xrsvd237, Xrsvd238, Xrsvd239, Xrsvd240
85 .long Xrsvd241, Xrsvd242, Xrsvd243, Xrsvd244, Xrsvd245, Xrsvd246, Xrsvd247, Xrsvd248
86 .long Xrsvd249, Xrsvd250, Xrsvd251, Xrsvd252, Xrsvd253, Xrsvd254, Xrsvd255
90 /*****************************************************************************/
92 /*****************************************************************************/
94 * Trap and fault vector routines.
96 * Most traps are 'trap gates', SDT_SYS386TGT. A trap gate pushes state on
97 * the stack that mostly looks like an interrupt, but does not disable
98 * interrupts. A few of the traps we are use are interrupt gates,
99 * SDT_SYS386IGT, which are nearly the same thing except interrupts are
102 * The cpu will push a certain amount of state onto the kernel stack for
103 * the current process. The amount of state depends on the type of trap
104 * and whether the trap crossed rings or not. See i386/include/frame.h.
105 * At the very least the current EFLAGS (status register, which includes
106 * the interrupt disable state prior to the trap), the code segment register,
107 * and the return instruction pointer are pushed by the cpu. The cpu
108 * will also push an 'error' code for certain traps. We push a dummy
109 * error code for those traps where the cpu doesn't in order to maintain
110 * a consistent frame. We also push a contrived 'trap number'.
112 * The cpu does not push the general registers, we must do that, and we
113 * must restore them prior to calling 'iret'. The cpu adjusts the %cs and
114 * %ss segment registers, but does not mess with %ds, %es, %fs, or %gs.
115 * Thus we must load the ones we use (which is most of them) with appropriate
116 * values for supervisor mode operation.
118 * On entry to a trap or interrupt WE DO NOT OWN THE MP LOCK. This means
119 * that we must be careful in regards to accessing global variables. We
120 * save (push) the current cpl (our software interrupt disable mask), call
121 * the trap function, then jump to doreti to restore the cpl and deal with
122 * ASTs (software interrupts). doreti will determine if the restoration
123 * of the cpl unmasked any pending interrupts and will issue those interrupts
124 * synchronously prior to doing the iret.
127 #define TRAP(a) pushl $(a) ; jmp alltraps
128 #define BPTTRAP(a) testl $PSL_I,4+8(%esp) ; je 1f ; sti ; 1: ; TRAP(a)
134 pushl $0; TRAP(T_DIVIDE)
136 pushl $0; BPTTRAP(T_TRCTRAP)
138 pushl $0; TRAP(T_NMI)
140 pushl $0; BPTTRAP(T_BPTFLT)
142 pushl $0; TRAP(T_OFLOW)
144 pushl $0; TRAP(T_BOUND)
146 pushl $0; TRAP(T_PRIVINFLT)
148 pushl $0; TRAP(T_DNA)
150 pushl $0; TRAP(T_FPOPFLT)
162 pushl $0; TRAP(T_MCHK)
165 pushl $0; TRAP(T_RESERVED)
167 #ifdef DEBUG_INTERRUPTS
170 pushl $1; TRAP(T_RESERVED)
172 pushl $2; TRAP(T_RESERVED)
174 pushl $3; TRAP(T_RESERVED)
176 pushl $4; TRAP(T_RESERVED)
178 pushl $5; TRAP(T_RESERVED)
180 pushl $6; TRAP(T_RESERVED)
182 pushl $7; TRAP(T_RESERVED)
184 pushl $8; TRAP(T_RESERVED)
186 pushl $9; TRAP(T_RESERVED)
188 pushl $10; TRAP(T_RESERVED)
190 pushl $11; TRAP(T_RESERVED)
192 pushl $12; TRAP(T_RESERVED)
194 pushl $13; TRAP(T_RESERVED)
196 pushl $14; TRAP(T_RESERVED)
198 pushl $15; TRAP(T_RESERVED)
200 pushl $16; TRAP(T_RESERVED)
202 pushl $17; TRAP(T_RESERVED)
204 pushl $18; TRAP(T_RESERVED)
206 pushl $19; TRAP(T_RESERVED)
208 pushl $20; TRAP(T_RESERVED)
210 pushl $21; TRAP(T_RESERVED)
212 pushl $22; TRAP(T_RESERVED)
214 pushl $23; TRAP(T_RESERVED)
216 pushl $24; TRAP(T_RESERVED)
218 pushl $25; TRAP(T_RESERVED)
220 pushl $26; TRAP(T_RESERVED)
222 pushl $27; TRAP(T_RESERVED)
224 pushl $28; TRAP(T_RESERVED)
226 pushl $29; TRAP(T_RESERVED)
228 pushl $30; TRAP(T_RESERVED)
230 pushl $31; TRAP(T_RESERVED)
232 pushl $32; TRAP(T_RESERVED)
234 pushl $33; TRAP(T_RESERVED)
236 pushl $34; TRAP(T_RESERVED)
238 pushl $35; TRAP(T_RESERVED)
240 pushl $36; TRAP(T_RESERVED)
242 pushl $37; TRAP(T_RESERVED)
244 pushl $38; TRAP(T_RESERVED)
246 pushl $39; TRAP(T_RESERVED)
248 pushl $40; TRAP(T_RESERVED)
250 pushl $41; TRAP(T_RESERVED)
252 pushl $42; TRAP(T_RESERVED)
254 pushl $43; TRAP(T_RESERVED)
256 pushl $44; TRAP(T_RESERVED)
258 pushl $45; TRAP(T_RESERVED)
260 pushl $46; TRAP(T_RESERVED)
262 pushl $47; TRAP(T_RESERVED)
264 pushl $48; TRAP(T_RESERVED)
266 pushl $49; TRAP(T_RESERVED)
268 pushl $50; TRAP(T_RESERVED)
270 pushl $51; TRAP(T_RESERVED)
272 pushl $52; TRAP(T_RESERVED)
274 pushl $53; TRAP(T_RESERVED)
276 pushl $54; TRAP(T_RESERVED)
278 pushl $55; TRAP(T_RESERVED)
280 pushl $56; TRAP(T_RESERVED)
282 pushl $57; TRAP(T_RESERVED)
284 pushl $58; TRAP(T_RESERVED)
286 pushl $59; TRAP(T_RESERVED)
288 pushl $60; TRAP(T_RESERVED)
290 pushl $61; TRAP(T_RESERVED)
292 pushl $62; TRAP(T_RESERVED)
294 pushl $63; TRAP(T_RESERVED)
296 pushl $64; TRAP(T_RESERVED)
298 pushl $65; TRAP(T_RESERVED)
300 pushl $66; TRAP(T_RESERVED)
302 pushl $67; TRAP(T_RESERVED)
304 pushl $68; TRAP(T_RESERVED)
306 pushl $69; TRAP(T_RESERVED)
308 pushl $70; TRAP(T_RESERVED)
310 pushl $71; TRAP(T_RESERVED)
312 pushl $72; TRAP(T_RESERVED)
314 pushl $73; TRAP(T_RESERVED)
316 pushl $74; TRAP(T_RESERVED)
318 pushl $75; TRAP(T_RESERVED)
320 pushl $76; TRAP(T_RESERVED)
322 pushl $77; TRAP(T_RESERVED)
324 pushl $78; TRAP(T_RESERVED)
326 pushl $79; TRAP(T_RESERVED)
328 pushl $80; TRAP(T_RESERVED)
330 pushl $81; TRAP(T_RESERVED)
332 pushl $82; TRAP(T_RESERVED)
334 pushl $83; TRAP(T_RESERVED)
336 pushl $84; TRAP(T_RESERVED)
338 pushl $85; TRAP(T_RESERVED)
340 pushl $86; TRAP(T_RESERVED)
342 pushl $87; TRAP(T_RESERVED)
344 pushl $88; TRAP(T_RESERVED)
346 pushl $89; TRAP(T_RESERVED)
348 pushl $90; TRAP(T_RESERVED)
350 pushl $91; TRAP(T_RESERVED)
352 pushl $92; TRAP(T_RESERVED)
354 pushl $93; TRAP(T_RESERVED)
356 pushl $94; TRAP(T_RESERVED)
358 pushl $95; TRAP(T_RESERVED)
360 pushl $96; TRAP(T_RESERVED)
362 pushl $97; TRAP(T_RESERVED)
364 pushl $98; TRAP(T_RESERVED)
366 pushl $99; TRAP(T_RESERVED)
368 pushl $100; TRAP(T_RESERVED)
370 pushl $101; TRAP(T_RESERVED)
372 pushl $102; TRAP(T_RESERVED)
374 pushl $103; TRAP(T_RESERVED)
376 pushl $104; TRAP(T_RESERVED)
378 pushl $105; TRAP(T_RESERVED)
380 pushl $106; TRAP(T_RESERVED)
382 pushl $107; TRAP(T_RESERVED)
384 pushl $108; TRAP(T_RESERVED)
386 pushl $109; TRAP(T_RESERVED)
388 pushl $110; TRAP(T_RESERVED)
390 pushl $111; TRAP(T_RESERVED)
392 pushl $112; TRAP(T_RESERVED)
394 pushl $113; TRAP(T_RESERVED)
396 pushl $114; TRAP(T_RESERVED)
398 pushl $115; TRAP(T_RESERVED)
400 pushl $116; TRAP(T_RESERVED)
402 pushl $117; TRAP(T_RESERVED)
404 pushl $118; TRAP(T_RESERVED)
406 pushl $119; TRAP(T_RESERVED)
408 pushl $120; TRAP(T_RESERVED)
410 pushl $121; TRAP(T_RESERVED)
412 pushl $122; TRAP(T_RESERVED)
414 pushl $123; TRAP(T_RESERVED)
416 pushl $124; TRAP(T_RESERVED)
418 pushl $125; TRAP(T_RESERVED)
420 pushl $126; TRAP(T_RESERVED)
422 pushl $127; TRAP(T_RESERVED)
424 pushl $128; TRAP(T_RESERVED)
426 pushl $129; TRAP(T_RESERVED)
428 pushl $130; TRAP(T_RESERVED)
430 pushl $131; TRAP(T_RESERVED)
432 pushl $132; TRAP(T_RESERVED)
434 pushl $133; TRAP(T_RESERVED)
436 pushl $134; TRAP(T_RESERVED)
438 pushl $135; TRAP(T_RESERVED)
440 pushl $136; TRAP(T_RESERVED)
442 pushl $137; TRAP(T_RESERVED)
444 pushl $138; TRAP(T_RESERVED)
446 pushl $139; TRAP(T_RESERVED)
448 pushl $140; TRAP(T_RESERVED)
450 pushl $141; TRAP(T_RESERVED)
452 pushl $142; TRAP(T_RESERVED)
454 pushl $143; TRAP(T_RESERVED)
456 pushl $144; TRAP(T_RESERVED)
458 pushl $145; TRAP(T_RESERVED)
460 pushl $146; TRAP(T_RESERVED)
462 pushl $147; TRAP(T_RESERVED)
464 pushl $148; TRAP(T_RESERVED)
466 pushl $149; TRAP(T_RESERVED)
468 pushl $150; TRAP(T_RESERVED)
470 pushl $151; TRAP(T_RESERVED)
472 pushl $152; TRAP(T_RESERVED)
474 pushl $153; TRAP(T_RESERVED)
476 pushl $154; TRAP(T_RESERVED)
478 pushl $155; TRAP(T_RESERVED)
480 pushl $156; TRAP(T_RESERVED)
482 pushl $157; TRAP(T_RESERVED)
484 pushl $158; TRAP(T_RESERVED)
486 pushl $159; TRAP(T_RESERVED)
488 pushl $160; TRAP(T_RESERVED)
490 pushl $161; TRAP(T_RESERVED)
492 pushl $162; TRAP(T_RESERVED)
494 pushl $163; TRAP(T_RESERVED)
496 pushl $164; TRAP(T_RESERVED)
498 pushl $165; TRAP(T_RESERVED)
500 pushl $166; TRAP(T_RESERVED)
502 pushl $167; TRAP(T_RESERVED)
504 pushl $168; TRAP(T_RESERVED)
506 pushl $169; TRAP(T_RESERVED)
508 pushl $170; TRAP(T_RESERVED)
510 pushl $171; TRAP(T_RESERVED)
512 pushl $172; TRAP(T_RESERVED)
514 pushl $173; TRAP(T_RESERVED)
516 pushl $174; TRAP(T_RESERVED)
518 pushl $175; TRAP(T_RESERVED)
520 pushl $176; TRAP(T_RESERVED)
522 pushl $177; TRAP(T_RESERVED)
524 pushl $178; TRAP(T_RESERVED)
526 pushl $179; TRAP(T_RESERVED)
528 pushl $180; TRAP(T_RESERVED)
530 pushl $181; TRAP(T_RESERVED)
532 pushl $182; TRAP(T_RESERVED)
534 pushl $183; TRAP(T_RESERVED)
536 pushl $184; TRAP(T_RESERVED)
538 pushl $185; TRAP(T_RESERVED)
540 pushl $186; TRAP(T_RESERVED)
542 pushl $187; TRAP(T_RESERVED)
544 pushl $188; TRAP(T_RESERVED)
546 pushl $189; TRAP(T_RESERVED)
548 pushl $190; TRAP(T_RESERVED)
550 pushl $191; TRAP(T_RESERVED)
552 pushl $192; TRAP(T_RESERVED)
554 pushl $193; TRAP(T_RESERVED)
556 pushl $194; TRAP(T_RESERVED)
558 pushl $195; TRAP(T_RESERVED)
560 pushl $196; TRAP(T_RESERVED)
562 pushl $197; TRAP(T_RESERVED)
564 pushl $198; TRAP(T_RESERVED)
566 pushl $199; TRAP(T_RESERVED)
568 pushl $200; TRAP(T_RESERVED)
570 pushl $201; TRAP(T_RESERVED)
572 pushl $202; TRAP(T_RESERVED)
574 pushl $203; TRAP(T_RESERVED)
576 pushl $204; TRAP(T_RESERVED)
578 pushl $205; TRAP(T_RESERVED)
580 pushl $206; TRAP(T_RESERVED)
582 pushl $207; TRAP(T_RESERVED)
584 pushl $208; TRAP(T_RESERVED)
586 pushl $209; TRAP(T_RESERVED)
588 pushl $210; TRAP(T_RESERVED)
590 pushl $211; TRAP(T_RESERVED)
592 pushl $212; TRAP(T_RESERVED)
594 pushl $213; TRAP(T_RESERVED)
596 pushl $214; TRAP(T_RESERVED)
598 pushl $215; TRAP(T_RESERVED)
600 pushl $216; TRAP(T_RESERVED)
602 pushl $217; TRAP(T_RESERVED)
604 pushl $218; TRAP(T_RESERVED)
606 pushl $219; TRAP(T_RESERVED)
608 pushl $220; TRAP(T_RESERVED)
610 pushl $221; TRAP(T_RESERVED)
612 pushl $222; TRAP(T_RESERVED)
614 pushl $223; TRAP(T_RESERVED)
616 pushl $224; TRAP(T_RESERVED)
618 pushl $225; TRAP(T_RESERVED)
620 pushl $226; TRAP(T_RESERVED)
622 pushl $227; TRAP(T_RESERVED)
624 pushl $228; TRAP(T_RESERVED)
626 pushl $229; TRAP(T_RESERVED)
628 pushl $230; TRAP(T_RESERVED)
630 pushl $231; TRAP(T_RESERVED)
632 pushl $232; TRAP(T_RESERVED)
634 pushl $233; TRAP(T_RESERVED)
636 pushl $234; TRAP(T_RESERVED)
638 pushl $235; TRAP(T_RESERVED)
640 pushl $236; TRAP(T_RESERVED)
642 pushl $237; TRAP(T_RESERVED)
644 pushl $238; TRAP(T_RESERVED)
646 pushl $239; TRAP(T_RESERVED)
648 pushl $240; TRAP(T_RESERVED)
650 pushl $241; TRAP(T_RESERVED)
652 pushl $242; TRAP(T_RESERVED)
654 pushl $243; TRAP(T_RESERVED)
656 pushl $244; TRAP(T_RESERVED)
658 pushl $245; TRAP(T_RESERVED)
660 pushl $246; TRAP(T_RESERVED)
662 pushl $247; TRAP(T_RESERVED)
664 pushl $248; TRAP(T_RESERVED)
666 pushl $249; TRAP(T_RESERVED)
668 pushl $250; TRAP(T_RESERVED)
670 pushl $251; TRAP(T_RESERVED)
672 pushl $252; TRAP(T_RESERVED)
674 pushl $253; TRAP(T_RESERVED)
676 pushl $254; TRAP(T_RESERVED)
678 pushl $255; TRAP(T_RESERVED)
685 * Handle like an interrupt (except for accounting) so that we can
686 * call npx_intr to clear the error. It would be better to handle
687 * npx interrupts as traps. Nested interrupts would probably have
688 * to be converted to ASTs.
690 * Convert everything to a full trapframe
692 pushl $0 /* dummy error code */
693 pushl $0 /* dummy trap type */
694 pushl $0 /* dummy xflags */
707 FAKE_MCOUNT(15*4(%esp))
709 incl PCPU(cnt)+V_TRAP
711 /* additional dummy pushes to fake an interrupt frame */
713 pushl $0 /* vector */
715 /* warning, trap frame dummy arg, no extra reg pushes */
716 call npx_intr /* note: call might mess w/ argument */
718 /* convert back to a trapframe for doreti */
720 movl $0,(%esp) /* DUMMY CPL FOR DORETI */
724 pushl $0; TRAP(T_ARITHTRAP)
725 #endif /* NNPX > 0 */
731 pushl $0; TRAP(T_XMMFLT)
734 * _alltraps entry point. Interrupts are enabled if this was a trap
735 * gate (TGT), else disabled if this was an interrupt gate (IGT).
736 * Note that int0x80_syscall is a trap gate. Only page faults
737 * use an interrupt gate.
739 * Note that we are MP through to the call to trap().
744 .type alltraps,@function
746 pushl $0 /* xflags (inherits hardware err on pagefault) */
752 .globl alltraps_with_regs_pushed
753 alltraps_with_regs_pushed:
760 FAKE_MCOUNT(15*4(%esp))
762 FAKE_MCOUNT(btrap) /* init "from" _btrap -> calltrap */
763 incl PCPU(cnt)+V_TRAP
764 /* warning, trap frame dummy arg, no extra reg pushes */
766 pushl %esp /* pass frame by reference */
771 * Return via doreti to handle ASTs. Have to change trap frame
772 * to interrupt frame.
774 pushl $0 /* DUMMY CPL FOR DORETI */
779 * SYSCALL CALL GATE (old entry point for a.out binaries)
781 * The intersegment call has been set up to specify one dummy parameter.
783 * This leaves a place to put eflags so that the call frame can be
784 * converted to a trap frame. Note that the eflags is (semi-)bogusly
785 * pushed into (what will be) tf_err and then copied later into the
786 * final spot. It has to be done this way because esp can't be just
787 * temporarily altered for the pushfl - an interrupt might come in
788 * and clobber the saved cs/eip.
790 * We do not obtain the MP lock, but the call to syscall2 might. If it
791 * does it will release the lock prior to returning.
795 pushfl /* save eflags in tf_err for now */
796 pushl $T_SYSCALL80 /* tf_trapno */
797 pushl $0 /* tf_xflags */
804 mov $KDSEL,%ax /* switch to kernel segments */
810 movl TF_ERR(%esp),%eax /* copy saved eflags to final spot */
811 movl %eax,TF_EFLAGS(%esp)
812 movl $7,TF_ERR(%esp) /* sizeof "lcall 7,0" */
813 FAKE_MCOUNT(15*4(%esp))
814 incl PCPU(cnt)+V_SYSCALL /* YYY per-cpu */
815 /* warning, trap frame dummy arg, no extra reg pushes */
816 push %esp /* pass frame by reference */
820 cli /* atomic reqflags interlock w/iret */
821 cmpl $0,PCPU(reqflags)
822 je doreti_syscall_ret
823 pushl $0 /* cpl to restore */
827 * Trap gate entry for FreeBSD ELF and Linux/NetBSD syscall (int 0x80)
829 * Even though the name says 'int0x80', this is actually a TGT (trap gate)
830 * rather then an IGT (interrupt gate). Thus interrupts are enabled on
831 * entry just as they are for a normal syscall.
833 * We do not obtain the MP lock, but the call to syscall2 might. If it
834 * does it will release the lock prior to returning.
837 IDTVEC(int0x80_syscall)
838 pushl $0 /* tf_err */
839 pushl $T_SYSCALL80 /* tf_trapno */
840 pushl $0 /* tf_xflags */
847 mov $KDSEL,%ax /* switch to kernel segments */
853 movl $2,TF_ERR(%esp) /* sizeof "int 0x80" */
854 FAKE_MCOUNT(15*4(%esp))
855 incl PCPU(cnt)+V_SYSCALL
856 /* warning, trap frame dummy arg, no extra reg pushes */
857 push %esp /* pass frame by reference */
861 cli /* atomic reqflags interlock w/irq */
862 cmpl $0,PCPU(reqflags)
863 je doreti_syscall_ret
864 pushl $0 /* cpl to restore */
868 * This function is what cpu_heavy_restore jumps to after a new process
869 * is created. The LWKT subsystem switches while holding a critical
870 * section and we maintain that abstraction here (e.g. because
871 * cpu_heavy_restore needs it due to PCB_*() manipulation), then get out of
872 * it before calling the initial function (typically fork_return()) and/or
873 * returning to user mode.
875 * The MP lock is not held at any point but the critcount is bumped
876 * on entry to prevent interruption of the trampoline at a bad point.
878 * This is effectively what td->td_switch() returns to. It 'returns' the
879 * old thread in %eax and since this is not returning to a td->td_switch()
880 * call from lwkt_switch() we must handle the cleanup for the old thread
881 * by calling lwkt_switch_return().
883 * fork_trampoline(%eax:otd, %esi:func, %ebx:arg)
885 ENTRY(fork_trampoline)
887 call lwkt_switch_return
889 movl PCPU(curthread),%eax
890 decl TD_CRITCOUNT(%eax)
893 * cpu_set_fork_handler intercepts this function call to
894 * have this call a non-return function to stay in kernel mode.
896 * initproc has its own fork handler, start_init(), which DOES
899 * The function (set in pcb_esi) gets passed two arguments,
900 * the primary parameter set in pcb_ebx and a pointer to the
902 * void (func)(int arg, struct trapframe *frame);
904 pushl %esp /* pass frame by reference */
905 pushl %ebx /* arg1 */
906 call *%esi /* function */
908 /* cut from syscall */
914 * Return via doreti to handle ASTs.
916 pushl $0 /* cpl to restore */
922 * Include vm86 call routines, which want to call doreti.
924 #include "vm86bios.s"