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