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/i386/i386/Attic/exception.s,v 1.21 2004/01/15 00:03:08 dillon Exp $
39 #include <machine/asmacros.h>
40 #include <machine/ipl.h>
41 #include <machine/lock.h>
42 #include <machine/psl.h>
43 #include <machine/trap.h>
45 #include <machine/smptests.h> /** various SMP options */
50 #define SEL_RPL_MASK 0x0003
54 #ifdef DEBUG_INTERRUPTS
59 .long Xrsvd1 , Xrsvd2 , Xrsvd3 , Xrsvd4 , Xrsvd5 , Xrsvd6 , Xrsvd7 , Xrsvd8
60 .long Xrsvd9 , Xrsvd10 , Xrsvd11 , Xrsvd12 , Xrsvd13 , Xrsvd14 , Xrsvd15 , Xrsvd16
61 .long Xrsvd17 , Xrsvd18 , Xrsvd19 , Xrsvd20 , Xrsvd21 , Xrsvd22 , Xrsvd23 , Xrsvd24
62 .long Xrsvd25 , Xrsvd26 , Xrsvd27 , Xrsvd28 , Xrsvd29 , Xrsvd30 , Xrsvd31 , Xrsvd32
63 .long Xrsvd33 , Xrsvd34 , Xrsvd35 , Xrsvd36 , Xrsvd37 , Xrsvd38 , Xrsvd39 , Xrsvd40
64 .long Xrsvd41 , Xrsvd42 , Xrsvd43 , Xrsvd44 , Xrsvd45 , Xrsvd46 , Xrsvd47 , Xrsvd48
65 .long Xrsvd49 , Xrsvd50 , Xrsvd51 , Xrsvd52 , Xrsvd53 , Xrsvd54 , Xrsvd55 , Xrsvd56
66 .long Xrsvd57 , Xrsvd58 , Xrsvd59 , Xrsvd60 , Xrsvd61 , Xrsvd62 , Xrsvd63 , Xrsvd64
67 .long Xrsvd65 , Xrsvd66 , Xrsvd67 , Xrsvd68 , Xrsvd69 , Xrsvd70 , Xrsvd71 , Xrsvd72
68 .long Xrsvd73 , Xrsvd74 , Xrsvd75 , Xrsvd76 , Xrsvd77 , Xrsvd78 , Xrsvd79 , Xrsvd80
69 .long Xrsvd81 , Xrsvd82 , Xrsvd83 , Xrsvd84 , Xrsvd85 , Xrsvd86 , Xrsvd87 , Xrsvd88
70 .long Xrsvd89 , Xrsvd90 , Xrsvd91 , Xrsvd92 , Xrsvd93 , Xrsvd94 , Xrsvd95 , Xrsvd96
71 .long Xrsvd97 , Xrsvd98 , Xrsvd99 , Xrsvd100, Xrsvd101, Xrsvd102, Xrsvd103, Xrsvd104
72 .long Xrsvd105, Xrsvd106, Xrsvd107, Xrsvd108, Xrsvd109, Xrsvd110, Xrsvd111, Xrsvd112
73 .long Xrsvd113, Xrsvd114, Xrsvd115, Xrsvd116, Xrsvd117, Xrsvd118, Xrsvd119, Xrsvd120
74 .long Xrsvd121, Xrsvd122, Xrsvd123, Xrsvd124, Xrsvd125, Xrsvd126, Xrsvd127, Xrsvd128
75 .long Xrsvd129, Xrsvd130, Xrsvd131, Xrsvd132, Xrsvd133, Xrsvd134, Xrsvd135, Xrsvd136
76 .long Xrsvd137, Xrsvd138, Xrsvd139, Xrsvd140, Xrsvd141, Xrsvd142, Xrsvd143, Xrsvd144
77 .long Xrsvd145, Xrsvd146, Xrsvd147, Xrsvd148, Xrsvd149, Xrsvd150, Xrsvd151, Xrsvd152
78 .long Xrsvd153, Xrsvd154, Xrsvd155, Xrsvd156, Xrsvd157, Xrsvd158, Xrsvd159, Xrsvd160
79 .long Xrsvd161, Xrsvd162, Xrsvd163, Xrsvd164, Xrsvd165, Xrsvd166, Xrsvd167, Xrsvd168
80 .long Xrsvd169, Xrsvd170, Xrsvd171, Xrsvd172, Xrsvd173, Xrsvd174, Xrsvd175, Xrsvd176
81 .long Xrsvd177, Xrsvd178, Xrsvd179, Xrsvd180, Xrsvd181, Xrsvd182, Xrsvd183, Xrsvd184
82 .long Xrsvd185, Xrsvd186, Xrsvd187, Xrsvd188, Xrsvd189, Xrsvd190, Xrsvd191, Xrsvd192
83 .long Xrsvd193, Xrsvd194, Xrsvd195, Xrsvd196, Xrsvd197, Xrsvd198, Xrsvd199, Xrsvd200
84 .long Xrsvd201, Xrsvd202, Xrsvd203, Xrsvd204, Xrsvd205, Xrsvd206, Xrsvd207, Xrsvd208
85 .long Xrsvd209, Xrsvd210, Xrsvd211, Xrsvd212, Xrsvd213, Xrsvd214, Xrsvd215, Xrsvd216
86 .long Xrsvd217, Xrsvd218, Xrsvd219, Xrsvd220, Xrsvd221, Xrsvd222, Xrsvd223, Xrsvd224
87 .long Xrsvd225, Xrsvd226, Xrsvd227, Xrsvd228, Xrsvd229, Xrsvd230, Xrsvd231, Xrsvd232
88 .long Xrsvd233, Xrsvd234, Xrsvd235, Xrsvd236, Xrsvd237, Xrsvd238, Xrsvd239, Xrsvd240
89 .long Xrsvd241, Xrsvd242, Xrsvd243, Xrsvd244, Xrsvd245, Xrsvd246, Xrsvd247, Xrsvd248
90 .long Xrsvd249, Xrsvd250, Xrsvd251, Xrsvd252, Xrsvd253, Xrsvd254, Xrsvd255
94 /*****************************************************************************/
96 /*****************************************************************************/
98 * Trap and fault vector routines.
100 * Most traps are 'trap gates', SDT_SYS386TGT. A trap gate pushes state on
101 * the stack that mostly looks like an interrupt, but does not disable
102 * interrupts. A few of the traps we are use are interrupt gates,
103 * SDT_SYS386IGT, which are nearly the same thing except interrupts are
106 * The cpu will push a certain amount of state onto the kernel stack for
107 * the current process. The amount of state depends on the type of trap
108 * and whether the trap crossed rings or not. See i386/include/frame.h.
109 * At the very least the current EFLAGS (status register, which includes
110 * the interrupt disable state prior to the trap), the code segment register,
111 * and the return instruction pointer are pushed by the cpu. The cpu
112 * will also push an 'error' code for certain traps. We push a dummy
113 * error code for those traps where the cpu doesn't in order to maintain
114 * a consistent frame. We also push a contrived 'trap number'.
116 * The cpu does not push the general registers, we must do that, and we
117 * must restore them prior to calling 'iret'. The cpu adjusts the %cs and
118 * %ss segment registers, but does not mess with %ds, %es, or %fs. Thus we
119 * must load them with appropriate values for supervisor mode operation.
121 * On entry to a trap or interrupt WE DO NOT OWN THE MP LOCK. This means
122 * that we must be careful in regards to accessing global variables. We
123 * save (push) the current cpl (our software interrupt disable mask), call
124 * the trap function, then jump to doreti to restore the cpl and deal with
125 * ASTs (software interrupts). doreti will determine if the restoration
126 * of the cpl unmasked any pending interrupts and will issue those interrupts
127 * synchronously prior to doing the iret.
129 #define IDTVEC(name) ALIGN_TEXT; .globl __CONCAT(X,name); \
130 .type __CONCAT(X,name),@function; __CONCAT(X,name):
131 #define TRAP(a) pushl $(a) ; jmp alltraps
134 #define BDBTRAP(name) \
136 cmpb $0,bdb_exists ; \
138 testb $SEL_RPL_MASK,4(%esp) ; \
141 .globl __CONCAT(__CONCAT(bdb_,name),_ljmp); \
142 __CONCAT(__CONCAT(bdb_,name),_ljmp): \
146 #define BDBTRAP(name)
149 #define BPTTRAP(a) testl $PSL_I,4+8(%esp) ; je 1f ; sti ; 1: ; TRAP(a)
155 pushl $0; TRAP(T_DIVIDE)
158 pushl $0; BPTTRAP(T_TRCTRAP)
160 pushl $0; TRAP(T_NMI)
163 pushl $0; BPTTRAP(T_BPTFLT)
165 pushl $0; TRAP(T_OFLOW)
167 pushl $0; TRAP(T_BOUND)
169 pushl $0; TRAP(T_PRIVINFLT)
171 pushl $0; TRAP(T_DNA)
173 pushl $0; TRAP(T_FPOPFLT)
185 pushl $0; TRAP(T_MCHK)
188 pushl $0; TRAP(T_RESERVED)
190 #ifdef DEBUG_INTERRUPTS
193 pushl $1; TRAP(T_RESERVED)
195 pushl $2; TRAP(T_RESERVED)
197 pushl $3; TRAP(T_RESERVED)
199 pushl $4; TRAP(T_RESERVED)
201 pushl $5; TRAP(T_RESERVED)
203 pushl $6; TRAP(T_RESERVED)
205 pushl $7; TRAP(T_RESERVED)
207 pushl $8; TRAP(T_RESERVED)
209 pushl $9; TRAP(T_RESERVED)
211 pushl $10; TRAP(T_RESERVED)
213 pushl $11; TRAP(T_RESERVED)
215 pushl $12; TRAP(T_RESERVED)
217 pushl $13; TRAP(T_RESERVED)
219 pushl $14; TRAP(T_RESERVED)
221 pushl $15; TRAP(T_RESERVED)
223 pushl $16; TRAP(T_RESERVED)
225 pushl $17; TRAP(T_RESERVED)
227 pushl $18; TRAP(T_RESERVED)
229 pushl $19; TRAP(T_RESERVED)
231 pushl $20; TRAP(T_RESERVED)
233 pushl $21; TRAP(T_RESERVED)
235 pushl $22; TRAP(T_RESERVED)
237 pushl $23; TRAP(T_RESERVED)
239 pushl $24; TRAP(T_RESERVED)
241 pushl $25; TRAP(T_RESERVED)
243 pushl $26; TRAP(T_RESERVED)
245 pushl $27; TRAP(T_RESERVED)
247 pushl $28; TRAP(T_RESERVED)
249 pushl $29; TRAP(T_RESERVED)
251 pushl $30; TRAP(T_RESERVED)
253 pushl $31; TRAP(T_RESERVED)
255 pushl $32; TRAP(T_RESERVED)
257 pushl $33; TRAP(T_RESERVED)
259 pushl $34; TRAP(T_RESERVED)
261 pushl $35; TRAP(T_RESERVED)
263 pushl $36; TRAP(T_RESERVED)
265 pushl $37; TRAP(T_RESERVED)
267 pushl $38; TRAP(T_RESERVED)
269 pushl $39; TRAP(T_RESERVED)
271 pushl $40; TRAP(T_RESERVED)
273 pushl $41; TRAP(T_RESERVED)
275 pushl $42; TRAP(T_RESERVED)
277 pushl $43; TRAP(T_RESERVED)
279 pushl $44; TRAP(T_RESERVED)
281 pushl $45; TRAP(T_RESERVED)
283 pushl $46; TRAP(T_RESERVED)
285 pushl $47; TRAP(T_RESERVED)
287 pushl $48; TRAP(T_RESERVED)
289 pushl $49; TRAP(T_RESERVED)
291 pushl $50; TRAP(T_RESERVED)
293 pushl $51; TRAP(T_RESERVED)
295 pushl $52; TRAP(T_RESERVED)
297 pushl $53; TRAP(T_RESERVED)
299 pushl $54; TRAP(T_RESERVED)
301 pushl $55; TRAP(T_RESERVED)
303 pushl $56; TRAP(T_RESERVED)
305 pushl $57; TRAP(T_RESERVED)
307 pushl $58; TRAP(T_RESERVED)
309 pushl $59; TRAP(T_RESERVED)
311 pushl $60; TRAP(T_RESERVED)
313 pushl $61; TRAP(T_RESERVED)
315 pushl $62; TRAP(T_RESERVED)
317 pushl $63; TRAP(T_RESERVED)
319 pushl $64; TRAP(T_RESERVED)
321 pushl $65; TRAP(T_RESERVED)
323 pushl $66; TRAP(T_RESERVED)
325 pushl $67; TRAP(T_RESERVED)
327 pushl $68; TRAP(T_RESERVED)
329 pushl $69; TRAP(T_RESERVED)
331 pushl $70; TRAP(T_RESERVED)
333 pushl $71; TRAP(T_RESERVED)
335 pushl $72; TRAP(T_RESERVED)
337 pushl $73; TRAP(T_RESERVED)
339 pushl $74; TRAP(T_RESERVED)
341 pushl $75; TRAP(T_RESERVED)
343 pushl $76; TRAP(T_RESERVED)
345 pushl $77; TRAP(T_RESERVED)
347 pushl $78; TRAP(T_RESERVED)
349 pushl $79; TRAP(T_RESERVED)
351 pushl $80; TRAP(T_RESERVED)
353 pushl $81; TRAP(T_RESERVED)
355 pushl $82; TRAP(T_RESERVED)
357 pushl $83; TRAP(T_RESERVED)
359 pushl $84; TRAP(T_RESERVED)
361 pushl $85; TRAP(T_RESERVED)
363 pushl $86; TRAP(T_RESERVED)
365 pushl $87; TRAP(T_RESERVED)
367 pushl $88; TRAP(T_RESERVED)
369 pushl $89; TRAP(T_RESERVED)
371 pushl $90; TRAP(T_RESERVED)
373 pushl $91; TRAP(T_RESERVED)
375 pushl $92; TRAP(T_RESERVED)
377 pushl $93; TRAP(T_RESERVED)
379 pushl $94; TRAP(T_RESERVED)
381 pushl $95; TRAP(T_RESERVED)
383 pushl $96; TRAP(T_RESERVED)
385 pushl $97; TRAP(T_RESERVED)
387 pushl $98; TRAP(T_RESERVED)
389 pushl $99; TRAP(T_RESERVED)
391 pushl $100; TRAP(T_RESERVED)
393 pushl $101; TRAP(T_RESERVED)
395 pushl $102; TRAP(T_RESERVED)
397 pushl $103; TRAP(T_RESERVED)
399 pushl $104; TRAP(T_RESERVED)
401 pushl $105; TRAP(T_RESERVED)
403 pushl $106; TRAP(T_RESERVED)
405 pushl $107; TRAP(T_RESERVED)
407 pushl $108; TRAP(T_RESERVED)
409 pushl $109; TRAP(T_RESERVED)
411 pushl $110; TRAP(T_RESERVED)
413 pushl $111; TRAP(T_RESERVED)
415 pushl $112; TRAP(T_RESERVED)
417 pushl $113; TRAP(T_RESERVED)
419 pushl $114; TRAP(T_RESERVED)
421 pushl $115; TRAP(T_RESERVED)
423 pushl $116; TRAP(T_RESERVED)
425 pushl $117; TRAP(T_RESERVED)
427 pushl $118; TRAP(T_RESERVED)
429 pushl $119; TRAP(T_RESERVED)
431 pushl $120; TRAP(T_RESERVED)
433 pushl $121; TRAP(T_RESERVED)
435 pushl $122; TRAP(T_RESERVED)
437 pushl $123; TRAP(T_RESERVED)
439 pushl $124; TRAP(T_RESERVED)
441 pushl $125; TRAP(T_RESERVED)
443 pushl $126; TRAP(T_RESERVED)
445 pushl $127; TRAP(T_RESERVED)
447 pushl $128; TRAP(T_RESERVED)
449 pushl $129; TRAP(T_RESERVED)
451 pushl $130; TRAP(T_RESERVED)
453 pushl $131; TRAP(T_RESERVED)
455 pushl $132; TRAP(T_RESERVED)
457 pushl $133; TRAP(T_RESERVED)
459 pushl $134; TRAP(T_RESERVED)
461 pushl $135; TRAP(T_RESERVED)
463 pushl $136; TRAP(T_RESERVED)
465 pushl $137; TRAP(T_RESERVED)
467 pushl $138; TRAP(T_RESERVED)
469 pushl $139; TRAP(T_RESERVED)
471 pushl $140; TRAP(T_RESERVED)
473 pushl $141; TRAP(T_RESERVED)
475 pushl $142; TRAP(T_RESERVED)
477 pushl $143; TRAP(T_RESERVED)
479 pushl $144; TRAP(T_RESERVED)
481 pushl $145; TRAP(T_RESERVED)
483 pushl $146; TRAP(T_RESERVED)
485 pushl $147; TRAP(T_RESERVED)
487 pushl $148; TRAP(T_RESERVED)
489 pushl $149; TRAP(T_RESERVED)
491 pushl $150; TRAP(T_RESERVED)
493 pushl $151; TRAP(T_RESERVED)
495 pushl $152; TRAP(T_RESERVED)
497 pushl $153; TRAP(T_RESERVED)
499 pushl $154; TRAP(T_RESERVED)
501 pushl $155; TRAP(T_RESERVED)
503 pushl $156; TRAP(T_RESERVED)
505 pushl $157; TRAP(T_RESERVED)
507 pushl $158; TRAP(T_RESERVED)
509 pushl $159; TRAP(T_RESERVED)
511 pushl $160; TRAP(T_RESERVED)
513 pushl $161; TRAP(T_RESERVED)
515 pushl $162; TRAP(T_RESERVED)
517 pushl $163; TRAP(T_RESERVED)
519 pushl $164; TRAP(T_RESERVED)
521 pushl $165; TRAP(T_RESERVED)
523 pushl $166; TRAP(T_RESERVED)
525 pushl $167; TRAP(T_RESERVED)
527 pushl $168; TRAP(T_RESERVED)
529 pushl $169; TRAP(T_RESERVED)
531 pushl $170; TRAP(T_RESERVED)
533 pushl $171; TRAP(T_RESERVED)
535 pushl $172; TRAP(T_RESERVED)
537 pushl $173; TRAP(T_RESERVED)
539 pushl $174; TRAP(T_RESERVED)
541 pushl $175; TRAP(T_RESERVED)
543 pushl $176; TRAP(T_RESERVED)
545 pushl $177; TRAP(T_RESERVED)
547 pushl $178; TRAP(T_RESERVED)
549 pushl $179; TRAP(T_RESERVED)
551 pushl $180; TRAP(T_RESERVED)
553 pushl $181; TRAP(T_RESERVED)
555 pushl $182; TRAP(T_RESERVED)
557 pushl $183; TRAP(T_RESERVED)
559 pushl $184; TRAP(T_RESERVED)
561 pushl $185; TRAP(T_RESERVED)
563 pushl $186; TRAP(T_RESERVED)
565 pushl $187; TRAP(T_RESERVED)
567 pushl $188; TRAP(T_RESERVED)
569 pushl $189; TRAP(T_RESERVED)
571 pushl $190; TRAP(T_RESERVED)
573 pushl $191; TRAP(T_RESERVED)
575 pushl $192; TRAP(T_RESERVED)
577 pushl $193; TRAP(T_RESERVED)
579 pushl $194; TRAP(T_RESERVED)
581 pushl $195; TRAP(T_RESERVED)
583 pushl $196; TRAP(T_RESERVED)
585 pushl $197; TRAP(T_RESERVED)
587 pushl $198; TRAP(T_RESERVED)
589 pushl $199; TRAP(T_RESERVED)
591 pushl $200; TRAP(T_RESERVED)
593 pushl $201; TRAP(T_RESERVED)
595 pushl $202; TRAP(T_RESERVED)
597 pushl $203; TRAP(T_RESERVED)
599 pushl $204; TRAP(T_RESERVED)
601 pushl $205; TRAP(T_RESERVED)
603 pushl $206; TRAP(T_RESERVED)
605 pushl $207; TRAP(T_RESERVED)
607 pushl $208; TRAP(T_RESERVED)
609 pushl $209; TRAP(T_RESERVED)
611 pushl $210; TRAP(T_RESERVED)
613 pushl $211; TRAP(T_RESERVED)
615 pushl $212; TRAP(T_RESERVED)
617 pushl $213; TRAP(T_RESERVED)
619 pushl $214; TRAP(T_RESERVED)
621 pushl $215; TRAP(T_RESERVED)
623 pushl $216; TRAP(T_RESERVED)
625 pushl $217; TRAP(T_RESERVED)
627 pushl $218; TRAP(T_RESERVED)
629 pushl $219; TRAP(T_RESERVED)
631 pushl $220; TRAP(T_RESERVED)
633 pushl $221; TRAP(T_RESERVED)
635 pushl $222; TRAP(T_RESERVED)
637 pushl $223; TRAP(T_RESERVED)
639 pushl $224; TRAP(T_RESERVED)
641 pushl $225; TRAP(T_RESERVED)
643 pushl $226; TRAP(T_RESERVED)
645 pushl $227; TRAP(T_RESERVED)
647 pushl $228; TRAP(T_RESERVED)
649 pushl $229; TRAP(T_RESERVED)
651 pushl $230; TRAP(T_RESERVED)
653 pushl $231; TRAP(T_RESERVED)
655 pushl $232; TRAP(T_RESERVED)
657 pushl $233; TRAP(T_RESERVED)
659 pushl $234; TRAP(T_RESERVED)
661 pushl $235; TRAP(T_RESERVED)
663 pushl $236; TRAP(T_RESERVED)
665 pushl $237; TRAP(T_RESERVED)
667 pushl $238; TRAP(T_RESERVED)
669 pushl $239; TRAP(T_RESERVED)
671 pushl $240; TRAP(T_RESERVED)
673 pushl $241; TRAP(T_RESERVED)
675 pushl $242; TRAP(T_RESERVED)
677 pushl $243; TRAP(T_RESERVED)
679 pushl $244; TRAP(T_RESERVED)
681 pushl $245; TRAP(T_RESERVED)
683 pushl $246; TRAP(T_RESERVED)
685 pushl $247; TRAP(T_RESERVED)
687 pushl $248; TRAP(T_RESERVED)
689 pushl $249; TRAP(T_RESERVED)
691 pushl $250; TRAP(T_RESERVED)
693 pushl $251; TRAP(T_RESERVED)
695 pushl $252; TRAP(T_RESERVED)
697 pushl $253; TRAP(T_RESERVED)
699 pushl $254; TRAP(T_RESERVED)
701 pushl $255; TRAP(T_RESERVED)
708 * Handle like an interrupt (except for accounting) so that we can
709 * call npx_intr to clear the error. It would be better to handle
710 * npx interrupts as traps. Nested interrupts would probably have
711 * to be converted to ASTs.
713 pushl $0 /* dummy error code */
714 pushl $0 /* dummy trap type */
717 pushl %es /* now stack frame is a trap frame */
724 FAKE_MCOUNT(13*4(%esp))
726 movl PCPU(curthread),%ebx /* save original cpl */
727 movl TD_CPL(%ebx), %ebx
728 incl PCPU(cnt)+V_TRAP
730 /* additional dummy pushes to fake an interrupt frame */
732 pushl $0 /* vector */
734 /* warning, trap frame dummy arg, no extra reg pushes */
735 call npx_intr /* note: call might mess w/ argument */
737 /* convert back to a trapframe for doreti */
743 pushl $0; TRAP(T_ARITHTRAP)
744 #endif /* NNPX > 0 */
750 pushl $0; TRAP(T_XMMFLT)
753 * _alltraps entry point. Interrupts are enabled if this was a trap
754 * gate (TGT), else disabled if this was an interrupt gate (IGT).
755 * Note that int0x80_syscall is a trap gate. Only page faults
756 * use an interrupt gate.
758 * Note that we are MP through to the call to trap().
763 .type alltraps,@function
769 alltraps_with_regs_pushed:
775 FAKE_MCOUNT(13*4(%esp))
777 FAKE_MCOUNT(btrap) /* init "from" _btrap -> calltrap */
778 incl PCPU(cnt)+V_TRAP
779 movl PCPU(curthread),%eax /* keep orig cpl here during call */
780 movl TD_CPL(%eax),%ebx
781 /* warning, trap frame dummy arg, no extra reg pushes */
785 * Return via doreti to handle ASTs. Have to change trap frame
786 * to interrupt frame.
788 pushl %ebx /* cpl to restore */
793 * SYSCALL CALL GATE (old entry point for a.out binaries)
795 * The intersegment call has been set up to specify one dummy parameter.
797 * This leaves a place to put eflags so that the call frame can be
798 * converted to a trap frame. Note that the eflags is (semi-)bogusly
799 * pushed into (what will be) tf_err and then copied later into the
800 * final spot. It has to be done this way because esp can't be just
801 * temporarily altered for the pushfl - an interrupt might come in
802 * and clobber the saved cs/eip.
804 * We do not obtain the MP lock, but the call to syscall2 might. If it
805 * does it will release the lock prior to returning.
809 pushfl /* save eflags in tf_err for now */
810 subl $4,%esp /* skip over tf_trapno */
815 mov $KDSEL,%ax /* switch to kernel segments */
820 movl TF_ERR(%esp),%eax /* copy saved eflags to final spot */
821 movl %eax,TF_EFLAGS(%esp)
822 movl $7,TF_ERR(%esp) /* sizeof "lcall 7,0" */
823 FAKE_MCOUNT(13*4(%esp))
824 incl PCPU(cnt)+V_SYSCALL /* YYY per-cpu */
825 /* warning, trap frame dummy arg, no extra reg pushes */
828 cli /* atomic reqflags interlock w/iret */
829 cmpl $0,PCPU(reqflags)
830 je doreti_syscall_ret
831 pushl $0 /* cpl to restore */
835 * Trap gate entry for FreeBSD ELF and Linux/NetBSD syscall (int 0x80)
837 * Even though the name says 'int0x80', this is actually a TGT (trap gate)
838 * rather then an IGT (interrupt gate). Thus interrupts are enabled on
839 * entry just as they are for a normal syscall.
841 * We do not obtain the MP lock, but the call to syscall2 might. If it
842 * does it will release the lock prior to returning.
845 IDTVEC(int0x80_syscall)
846 subl $8,%esp /* skip over tf_trapno and tf_err */
851 mov $KDSEL,%ax /* switch to kernel segments */
856 movl $2,TF_ERR(%esp) /* sizeof "int 0x80" */
857 FAKE_MCOUNT(13*4(%esp))
858 incl PCPU(cnt)+V_SYSCALL
859 /* warning, trap frame dummy arg, no extra reg pushes */
862 cli /* atomic reqflags interlock w/irq */
863 cmpl $0,PCPU(reqflags)
864 je doreti_syscall_ret
865 pushl $0 /* cpl to restore */
869 * Trap gate entry for FreeBSD syscall messaging interface (int 0x81).
870 * Arguments are passed in registers, the return value is placed in %eax.
872 * eax:error = int0x81(eax:port, ecx:msg, edx:msgsize)
874 * Performs message sending, message and port waiting, and flushing
878 IDTVEC(int0x81_syscall)
879 subl $8,%esp /* skip over tf_trapno and tf_err */
884 mov $KDSEL,%ax /* switch to kernel segments */
889 /* note: tf_err is not used */
890 FAKE_MCOUNT(13*4(%esp))
891 incl PCPU(cnt)+V_SENDSYS
892 /* warning, trap frame dummy arg, no extra reg pushes */
895 cli /* atomic reqflags interlock w/irq */
896 cmpl $0,PCPU(reqflags)
897 je doreti_syscall_ret
898 pushl $0 /* cpl to restore */
902 * This function is what cpu_heavy_restore jumps to after a new process
903 * is created. The LWKT subsystem switches while holding a critical
904 * section and we maintain that abstraction here (e.g. because
905 * cpu_heavy_restore needs it due to PCB_*() manipulation), then get out of
906 * it before calling the initial function (typically fork_return()) and/or
907 * returning to user mode.
909 * The MP lock is held on entry, but for processes fork_return(esi)
910 * releases it. 'doreti' always runs without the MP lock.
912 ENTRY(fork_trampoline)
913 movl PCPU(curthread),%eax
914 subl $TDPRI_CRIT,TD_PRI(%eax)
917 * cpu_set_fork_handler intercepts this function call to
918 * have this call a non-return function to stay in kernel mode.
920 * initproc has its own fork handler, start_init(), which DOES
923 pushl %ebx /* arg1 */
924 call *%esi /* function */
926 /* cut from syscall */
932 #if defined(INVARIANTS) && defined(SMP)
933 movl PCPU(curthread),%eax
934 cmpl $0,TD_MPCOUNT(%eax)
937 pushl TD_MPCOUNT(%eax)
940 pmsg4: .asciz "fork_trampoline mpcount %d after calling %p"
945 * Return via doreti to handle ASTs.
947 pushl $0 /* cpl to restore */
953 * Include vm86 call routines, which want to call doreti.
955 #include "i386/i386/vm86bios.s"
958 * Include what was once config+isa-dependent code.
959 * XXX it should be in a stand-alone file. It's still icu-dependent and
960 * belongs in i386/isa.
962 #include "i386/isa/vector.s"
965 * Include what was once icu-dependent code.
966 * XXX it should be merged into this file (also move the definition of
967 * imen to vector.s or isa.c).
968 * Before including it, set up a normal asm environment so that vector.s
969 * doesn't have to know that stuff is included after it.
975 #include "i386/isa/ipl.s"