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