| 1 | /*- |
| 2 | * Copyright (c) 1990 The Regents of the University of California. |
| 3 | * All rights reserved. |
| 4 | * |
| 5 | * Redistribution and use in source and binary forms, with or without |
| 6 | * modification, are permitted provided that the following conditions |
| 7 | * are met: |
| 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. |
| 20 | * |
| 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 |
| 31 | * SUCH DAMAGE. |
| 32 | * |
| 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.31 2007/01/22 19:37:04 corecode Exp $ |
| 35 | */ |
| 36 | |
| 37 | #include "use_npx.h" |
| 38 | |
| 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> |
| 44 | |
| 45 | #include "assym.s" |
| 46 | |
| 47 | .text |
| 48 | |
| 49 | #ifdef DEBUG_INTERRUPTS |
| 50 | .globl Xrsvdary |
| 51 | |
| 52 | Xrsvdary: |
| 53 | .long Xrsvd0 |
| 54 | .long Xrsvd1 , Xrsvd2 , Xrsvd3 , Xrsvd4 , Xrsvd5 , Xrsvd6 , Xrsvd7 , Xrsvd8 |
| 55 | .long Xrsvd9 , Xrsvd10 , Xrsvd11 , Xrsvd12 , Xrsvd13 , Xrsvd14 , Xrsvd15 , Xrsvd16 |
| 56 | .long Xrsvd17 , Xrsvd18 , Xrsvd19 , Xrsvd20 , Xrsvd21 , Xrsvd22 , Xrsvd23 , Xrsvd24 |
| 57 | .long Xrsvd25 , Xrsvd26 , Xrsvd27 , Xrsvd28 , Xrsvd29 , Xrsvd30 , Xrsvd31 , Xrsvd32 |
| 58 | .long Xrsvd33 , Xrsvd34 , Xrsvd35 , Xrsvd36 , Xrsvd37 , Xrsvd38 , Xrsvd39 , Xrsvd40 |
| 59 | .long Xrsvd41 , Xrsvd42 , Xrsvd43 , Xrsvd44 , Xrsvd45 , Xrsvd46 , Xrsvd47 , Xrsvd48 |
| 60 | .long Xrsvd49 , Xrsvd50 , Xrsvd51 , Xrsvd52 , Xrsvd53 , Xrsvd54 , Xrsvd55 , Xrsvd56 |
| 61 | .long Xrsvd57 , Xrsvd58 , Xrsvd59 , Xrsvd60 , Xrsvd61 , Xrsvd62 , Xrsvd63 , Xrsvd64 |
| 62 | .long Xrsvd65 , Xrsvd66 , Xrsvd67 , Xrsvd68 , Xrsvd69 , Xrsvd70 , Xrsvd71 , Xrsvd72 |
| 63 | .long Xrsvd73 , Xrsvd74 , Xrsvd75 , Xrsvd76 , Xrsvd77 , Xrsvd78 , Xrsvd79 , Xrsvd80 |
| 64 | .long Xrsvd81 , Xrsvd82 , Xrsvd83 , Xrsvd84 , Xrsvd85 , Xrsvd86 , Xrsvd87 , Xrsvd88 |
| 65 | .long Xrsvd89 , Xrsvd90 , Xrsvd91 , Xrsvd92 , Xrsvd93 , Xrsvd94 , Xrsvd95 , Xrsvd96 |
| 66 | .long Xrsvd97 , Xrsvd98 , Xrsvd99 , Xrsvd100, Xrsvd101, Xrsvd102, Xrsvd103, Xrsvd104 |
| 67 | .long Xrsvd105, Xrsvd106, Xrsvd107, Xrsvd108, Xrsvd109, Xrsvd110, Xrsvd111, Xrsvd112 |
| 68 | .long Xrsvd113, Xrsvd114, Xrsvd115, Xrsvd116, Xrsvd117, Xrsvd118, Xrsvd119, Xrsvd120 |
| 69 | .long Xrsvd121, Xrsvd122, Xrsvd123, Xrsvd124, Xrsvd125, Xrsvd126, Xrsvd127, Xrsvd128 |
| 70 | .long Xrsvd129, Xrsvd130, Xrsvd131, Xrsvd132, Xrsvd133, Xrsvd134, Xrsvd135, Xrsvd136 |
| 71 | .long Xrsvd137, Xrsvd138, Xrsvd139, Xrsvd140, Xrsvd141, Xrsvd142, Xrsvd143, Xrsvd144 |
| 72 | .long Xrsvd145, Xrsvd146, Xrsvd147, Xrsvd148, Xrsvd149, Xrsvd150, Xrsvd151, Xrsvd152 |
| 73 | .long Xrsvd153, Xrsvd154, Xrsvd155, Xrsvd156, Xrsvd157, Xrsvd158, Xrsvd159, Xrsvd160 |
| 74 | .long Xrsvd161, Xrsvd162, Xrsvd163, Xrsvd164, Xrsvd165, Xrsvd166, Xrsvd167, Xrsvd168 |
| 75 | .long Xrsvd169, Xrsvd170, Xrsvd171, Xrsvd172, Xrsvd173, Xrsvd174, Xrsvd175, Xrsvd176 |
| 76 | .long Xrsvd177, Xrsvd178, Xrsvd179, Xrsvd180, Xrsvd181, Xrsvd182, Xrsvd183, Xrsvd184 |
| 77 | .long Xrsvd185, Xrsvd186, Xrsvd187, Xrsvd188, Xrsvd189, Xrsvd190, Xrsvd191, Xrsvd192 |
| 78 | .long Xrsvd193, Xrsvd194, Xrsvd195, Xrsvd196, Xrsvd197, Xrsvd198, Xrsvd199, Xrsvd200 |
| 79 | .long Xrsvd201, Xrsvd202, Xrsvd203, Xrsvd204, Xrsvd205, Xrsvd206, Xrsvd207, Xrsvd208 |
| 80 | .long Xrsvd209, Xrsvd210, Xrsvd211, Xrsvd212, Xrsvd213, Xrsvd214, Xrsvd215, Xrsvd216 |
| 81 | .long Xrsvd217, Xrsvd218, Xrsvd219, Xrsvd220, Xrsvd221, Xrsvd222, Xrsvd223, Xrsvd224 |
| 82 | .long Xrsvd225, Xrsvd226, Xrsvd227, Xrsvd228, Xrsvd229, Xrsvd230, Xrsvd231, Xrsvd232 |
| 83 | .long Xrsvd233, Xrsvd234, Xrsvd235, Xrsvd236, Xrsvd237, Xrsvd238, Xrsvd239, Xrsvd240 |
| 84 | .long Xrsvd241, Xrsvd242, Xrsvd243, Xrsvd244, Xrsvd245, Xrsvd246, Xrsvd247, Xrsvd248 |
| 85 | .long Xrsvd249, Xrsvd250, Xrsvd251, Xrsvd252, Xrsvd253, Xrsvd254, Xrsvd255 |
| 86 | |
| 87 | #endif |
| 88 | |
| 89 | /*****************************************************************************/ |
| 90 | /* Trap handling */ |
| 91 | /*****************************************************************************/ |
| 92 | /* |
| 93 | * Trap and fault vector routines. |
| 94 | * |
| 95 | * Most traps are 'trap gates', SDT_SYS386TGT. A trap gate pushes state on |
| 96 | * the stack that mostly looks like an interrupt, but does not disable |
| 97 | * interrupts. A few of the traps we are use are interrupt gates, |
| 98 | * SDT_SYS386IGT, which are nearly the same thing except interrupts are |
| 99 | * disabled on entry. |
| 100 | * |
| 101 | * The cpu will push a certain amount of state onto the kernel stack for |
| 102 | * the current process. The amount of state depends on the type of trap |
| 103 | * and whether the trap crossed rings or not. See i386/include/frame.h. |
| 104 | * At the very least the current EFLAGS (status register, which includes |
| 105 | * the interrupt disable state prior to the trap), the code segment register, |
| 106 | * and the return instruction pointer are pushed by the cpu. The cpu |
| 107 | * will also push an 'error' code for certain traps. We push a dummy |
| 108 | * error code for those traps where the cpu doesn't in order to maintain |
| 109 | * a consistent frame. We also push a contrived 'trap number'. |
| 110 | * |
| 111 | * The cpu does not push the general registers, we must do that, and we |
| 112 | * must restore them prior to calling 'iret'. The cpu adjusts the %cs and |
| 113 | * %ss segment registers, but does not mess with %ds, %es, %fs, or %gs. |
| 114 | * Thus we must load the ones we use (which is most of them) with appropriate |
| 115 | * values for supervisor mode operation. |
| 116 | * |
| 117 | * On entry to a trap or interrupt WE DO NOT OWN THE MP LOCK. This means |
| 118 | * that we must be careful in regards to accessing global variables. We |
| 119 | * save (push) the current cpl (our software interrupt disable mask), call |
| 120 | * the trap function, then jump to doreti to restore the cpl and deal with |
| 121 | * ASTs (software interrupts). doreti will determine if the restoration |
| 122 | * of the cpl unmasked any pending interrupts and will issue those interrupts |
| 123 | * synchronously prior to doing the iret. |
| 124 | */ |
| 125 | |
| 126 | #define TRAP(a) pushl $(a) ; jmp alltraps |
| 127 | |
| 128 | #ifdef BDE_DEBUGGER |
| 129 | #define BDBTRAP(name) \ |
| 130 | ss ; \ |
| 131 | cmpb $0,bdb_exists ; \ |
| 132 | je 1f ; \ |
| 133 | testb $SEL_RPL_MASK,4(%esp) ; \ |
| 134 | jne 1f ; \ |
| 135 | ss ; \ |
| 136 | .globl __CONCAT(__CONCAT(bdb_,name),_ljmp); \ |
| 137 | __CONCAT(__CONCAT(bdb_,name),_ljmp): \ |
| 138 | ljmp $0,$0 ; \ |
| 139 | 1: |
| 140 | #else |
| 141 | #define BDBTRAP(name) |
| 142 | #endif |
| 143 | |
| 144 | #define BPTTRAP(a) testl $PSL_I,4+8(%esp) ; je 1f ; sti ; 1: ; TRAP(a) |
| 145 | |
| 146 | MCOUNT_LABEL(user) |
| 147 | MCOUNT_LABEL(btrap) |
| 148 | |
| 149 | IDTVEC(div) |
| 150 | pushl $0; TRAP(T_DIVIDE) |
| 151 | IDTVEC(dbg) |
| 152 | BDBTRAP(dbg) |
| 153 | pushl $0; BPTTRAP(T_TRCTRAP) |
| 154 | IDTVEC(nmi) |
| 155 | pushl $0; TRAP(T_NMI) |
| 156 | IDTVEC(bpt) |
| 157 | BDBTRAP(bpt) |
| 158 | pushl $0; BPTTRAP(T_BPTFLT) |
| 159 | IDTVEC(ofl) |
| 160 | pushl $0; TRAP(T_OFLOW) |
| 161 | IDTVEC(bnd) |
| 162 | pushl $0; TRAP(T_BOUND) |
| 163 | IDTVEC(ill) |
| 164 | pushl $0; TRAP(T_PRIVINFLT) |
| 165 | IDTVEC(dna) |
| 166 | pushl $0; TRAP(T_DNA) |
| 167 | IDTVEC(fpusegm) |
| 168 | pushl $0; TRAP(T_FPOPFLT) |
| 169 | IDTVEC(tss) |
| 170 | TRAP(T_TSSFLT) |
| 171 | IDTVEC(missing) |
| 172 | TRAP(T_SEGNPFLT) |
| 173 | IDTVEC(stk) |
| 174 | TRAP(T_STKFLT) |
| 175 | IDTVEC(prot) |
| 176 | TRAP(T_PROTFLT) |
| 177 | IDTVEC(page) |
| 178 | TRAP(T_PAGEFLT) |
| 179 | IDTVEC(mchk) |
| 180 | pushl $0; TRAP(T_MCHK) |
| 181 | |
| 182 | IDTVEC(rsvd0) |
| 183 | pushl $0; TRAP(T_RESERVED) |
| 184 | |
| 185 | #ifdef DEBUG_INTERRUPTS |
| 186 | |
| 187 | IDTVEC(rsvd1) |
| 188 | pushl $1; TRAP(T_RESERVED) |
| 189 | IDTVEC(rsvd2) |
| 190 | pushl $2; TRAP(T_RESERVED) |
| 191 | IDTVEC(rsvd3) |
| 192 | pushl $3; TRAP(T_RESERVED) |
| 193 | IDTVEC(rsvd4) |
| 194 | pushl $4; TRAP(T_RESERVED) |
| 195 | IDTVEC(rsvd5) |
| 196 | pushl $5; TRAP(T_RESERVED) |
| 197 | IDTVEC(rsvd6) |
| 198 | pushl $6; TRAP(T_RESERVED) |
| 199 | IDTVEC(rsvd7) |
| 200 | pushl $7; TRAP(T_RESERVED) |
| 201 | IDTVEC(rsvd8) |
| 202 | pushl $8; TRAP(T_RESERVED) |
| 203 | IDTVEC(rsvd9) |
| 204 | pushl $9; TRAP(T_RESERVED) |
| 205 | IDTVEC(rsvd10) |
| 206 | pushl $10; TRAP(T_RESERVED) |
| 207 | IDTVEC(rsvd11) |
| 208 | pushl $11; TRAP(T_RESERVED) |
| 209 | IDTVEC(rsvd12) |
| 210 | pushl $12; TRAP(T_RESERVED) |
| 211 | IDTVEC(rsvd13) |
| 212 | pushl $13; TRAP(T_RESERVED) |
| 213 | IDTVEC(rsvd14) |
| 214 | pushl $14; TRAP(T_RESERVED) |
| 215 | IDTVEC(rsvd15) |
| 216 | pushl $15; TRAP(T_RESERVED) |
| 217 | IDTVEC(rsvd16) |
| 218 | pushl $16; TRAP(T_RESERVED) |
| 219 | IDTVEC(rsvd17) |
| 220 | pushl $17; TRAP(T_RESERVED) |
| 221 | IDTVEC(rsvd18) |
| 222 | pushl $18; TRAP(T_RESERVED) |
| 223 | IDTVEC(rsvd19) |
| 224 | pushl $19; TRAP(T_RESERVED) |
| 225 | IDTVEC(rsvd20) |
| 226 | pushl $20; TRAP(T_RESERVED) |
| 227 | IDTVEC(rsvd21) |
| 228 | pushl $21; TRAP(T_RESERVED) |
| 229 | IDTVEC(rsvd22) |
| 230 | pushl $22; TRAP(T_RESERVED) |
| 231 | IDTVEC(rsvd23) |
| 232 | pushl $23; TRAP(T_RESERVED) |
| 233 | IDTVEC(rsvd24) |
| 234 | pushl $24; TRAP(T_RESERVED) |
| 235 | IDTVEC(rsvd25) |
| 236 | pushl $25; TRAP(T_RESERVED) |
| 237 | IDTVEC(rsvd26) |
| 238 | pushl $26; TRAP(T_RESERVED) |
| 239 | IDTVEC(rsvd27) |
| 240 | pushl $27; TRAP(T_RESERVED) |
| 241 | IDTVEC(rsvd28) |
| 242 | pushl $28; TRAP(T_RESERVED) |
| 243 | IDTVEC(rsvd29) |
| 244 | pushl $29; TRAP(T_RESERVED) |
| 245 | IDTVEC(rsvd30) |
| 246 | pushl $30; TRAP(T_RESERVED) |
| 247 | IDTVEC(rsvd31) |
| 248 | pushl $31; TRAP(T_RESERVED) |
| 249 | IDTVEC(rsvd32) |
| 250 | pushl $32; TRAP(T_RESERVED) |
| 251 | IDTVEC(rsvd33) |
| 252 | pushl $33; TRAP(T_RESERVED) |
| 253 | IDTVEC(rsvd34) |
| 254 | pushl $34; TRAP(T_RESERVED) |
| 255 | IDTVEC(rsvd35) |
| 256 | pushl $35; TRAP(T_RESERVED) |
| 257 | IDTVEC(rsvd36) |
| 258 | pushl $36; TRAP(T_RESERVED) |
| 259 | IDTVEC(rsvd37) |
| 260 | pushl $37; TRAP(T_RESERVED) |
| 261 | IDTVEC(rsvd38) |
| 262 | pushl $38; TRAP(T_RESERVED) |
| 263 | IDTVEC(rsvd39) |
| 264 | pushl $39; TRAP(T_RESERVED) |
| 265 | IDTVEC(rsvd40) |
| 266 | pushl $40; TRAP(T_RESERVED) |
| 267 | IDTVEC(rsvd41) |
| 268 | pushl $41; TRAP(T_RESERVED) |
| 269 | IDTVEC(rsvd42) |
| 270 | pushl $42; TRAP(T_RESERVED) |
| 271 | IDTVEC(rsvd43) |
| 272 | pushl $43; TRAP(T_RESERVED) |
| 273 | IDTVEC(rsvd44) |
| 274 | pushl $44; TRAP(T_RESERVED) |
| 275 | IDTVEC(rsvd45) |
| 276 | pushl $45; TRAP(T_RESERVED) |
| 277 | IDTVEC(rsvd46) |
| 278 | pushl $46; TRAP(T_RESERVED) |
| 279 | IDTVEC(rsvd47) |
| 280 | pushl $47; TRAP(T_RESERVED) |
| 281 | IDTVEC(rsvd48) |
| 282 | pushl $48; TRAP(T_RESERVED) |
| 283 | IDTVEC(rsvd49) |
| 284 | pushl $49; TRAP(T_RESERVED) |
| 285 | IDTVEC(rsvd50) |
| 286 | pushl $50; TRAP(T_RESERVED) |
| 287 | IDTVEC(rsvd51) |
| 288 | pushl $51; TRAP(T_RESERVED) |
| 289 | IDTVEC(rsvd52) |
| 290 | pushl $52; TRAP(T_RESERVED) |
| 291 | IDTVEC(rsvd53) |
| 292 | pushl $53; TRAP(T_RESERVED) |
| 293 | IDTVEC(rsvd54) |
| 294 | pushl $54; TRAP(T_RESERVED) |
| 295 | IDTVEC(rsvd55) |
| 296 | pushl $55; TRAP(T_RESERVED) |
| 297 | IDTVEC(rsvd56) |
| 298 | pushl $56; TRAP(T_RESERVED) |
| 299 | IDTVEC(rsvd57) |
| 300 | pushl $57; TRAP(T_RESERVED) |
| 301 | IDTVEC(rsvd58) |
| 302 | pushl $58; TRAP(T_RESERVED) |
| 303 | IDTVEC(rsvd59) |
| 304 | pushl $59; TRAP(T_RESERVED) |
| 305 | IDTVEC(rsvd60) |
| 306 | pushl $60; TRAP(T_RESERVED) |
| 307 | IDTVEC(rsvd61) |
| 308 | pushl $61; TRAP(T_RESERVED) |
| 309 | IDTVEC(rsvd62) |
| 310 | pushl $62; TRAP(T_RESERVED) |
| 311 | IDTVEC(rsvd63) |
| 312 | pushl $63; TRAP(T_RESERVED) |
| 313 | IDTVEC(rsvd64) |
| 314 | pushl $64; TRAP(T_RESERVED) |
| 315 | IDTVEC(rsvd65) |
| 316 | pushl $65; TRAP(T_RESERVED) |
| 317 | IDTVEC(rsvd66) |
| 318 | pushl $66; TRAP(T_RESERVED) |
| 319 | IDTVEC(rsvd67) |
| 320 | pushl $67; TRAP(T_RESERVED) |
| 321 | IDTVEC(rsvd68) |
| 322 | pushl $68; TRAP(T_RESERVED) |
| 323 | IDTVEC(rsvd69) |
| 324 | pushl $69; TRAP(T_RESERVED) |
| 325 | IDTVEC(rsvd70) |
| 326 | pushl $70; TRAP(T_RESERVED) |
| 327 | IDTVEC(rsvd71) |
| 328 | pushl $71; TRAP(T_RESERVED) |
| 329 | IDTVEC(rsvd72) |
| 330 | pushl $72; TRAP(T_RESERVED) |
| 331 | IDTVEC(rsvd73) |
| 332 | pushl $73; TRAP(T_RESERVED) |
| 333 | IDTVEC(rsvd74) |
| 334 | pushl $74; TRAP(T_RESERVED) |
| 335 | IDTVEC(rsvd75) |
| 336 | pushl $75; TRAP(T_RESERVED) |
| 337 | IDTVEC(rsvd76) |
| 338 | pushl $76; TRAP(T_RESERVED) |
| 339 | IDTVEC(rsvd77) |
| 340 | pushl $77; TRAP(T_RESERVED) |
| 341 | IDTVEC(rsvd78) |
| 342 | pushl $78; TRAP(T_RESERVED) |
| 343 | IDTVEC(rsvd79) |
| 344 | pushl $79; TRAP(T_RESERVED) |
| 345 | IDTVEC(rsvd80) |
| 346 | pushl $80; TRAP(T_RESERVED) |
| 347 | IDTVEC(rsvd81) |
| 348 | pushl $81; TRAP(T_RESERVED) |
| 349 | IDTVEC(rsvd82) |
| 350 | pushl $82; TRAP(T_RESERVED) |
| 351 | IDTVEC(rsvd83) |
| 352 | pushl $83; TRAP(T_RESERVED) |
| 353 | IDTVEC(rsvd84) |
| 354 | pushl $84; TRAP(T_RESERVED) |
| 355 | IDTVEC(rsvd85) |
| 356 | pushl $85; TRAP(T_RESERVED) |
| 357 | IDTVEC(rsvd86) |
| 358 | pushl $86; TRAP(T_RESERVED) |
| 359 | IDTVEC(rsvd87) |
| 360 | pushl $87; TRAP(T_RESERVED) |
| 361 | IDTVEC(rsvd88) |
| 362 | pushl $88; TRAP(T_RESERVED) |
| 363 | IDTVEC(rsvd89) |
| 364 | pushl $89; TRAP(T_RESERVED) |
| 365 | IDTVEC(rsvd90) |
| 366 | pushl $90; TRAP(T_RESERVED) |
| 367 | IDTVEC(rsvd91) |
| 368 | pushl $91; TRAP(T_RESERVED) |
| 369 | IDTVEC(rsvd92) |
| 370 | pushl $92; TRAP(T_RESERVED) |
| 371 | IDTVEC(rsvd93) |
| 372 | pushl $93; TRAP(T_RESERVED) |
| 373 | IDTVEC(rsvd94) |
| 374 | pushl $94; TRAP(T_RESERVED) |
| 375 | IDTVEC(rsvd95) |
| 376 | pushl $95; TRAP(T_RESERVED) |
| 377 | IDTVEC(rsvd96) |
| 378 | pushl $96; TRAP(T_RESERVED) |
| 379 | IDTVEC(rsvd97) |
| 380 | pushl $97; TRAP(T_RESERVED) |
| 381 | IDTVEC(rsvd98) |
| 382 | pushl $98; TRAP(T_RESERVED) |
| 383 | IDTVEC(rsvd99) |
| 384 | pushl $99; TRAP(T_RESERVED) |
| 385 | IDTVEC(rsvd100) |
| 386 | pushl $100; TRAP(T_RESERVED) |
| 387 | IDTVEC(rsvd101) |
| 388 | pushl $101; TRAP(T_RESERVED) |
| 389 | IDTVEC(rsvd102) |
| 390 | pushl $102; TRAP(T_RESERVED) |
| 391 | IDTVEC(rsvd103) |
| 392 | pushl $103; TRAP(T_RESERVED) |
| 393 | IDTVEC(rsvd104) |
| 394 | pushl $104; TRAP(T_RESERVED) |
| 395 | IDTVEC(rsvd105) |
| 396 | pushl $105; TRAP(T_RESERVED) |
| 397 | IDTVEC(rsvd106) |
| 398 | pushl $106; TRAP(T_RESERVED) |
| 399 | IDTVEC(rsvd107) |
| 400 | pushl $107; TRAP(T_RESERVED) |
| 401 | IDTVEC(rsvd108) |
| 402 | pushl $108; TRAP(T_RESERVED) |
| 403 | IDTVEC(rsvd109) |
| 404 | pushl $109; TRAP(T_RESERVED) |
| 405 | IDTVEC(rsvd110) |
| 406 | pushl $110; TRAP(T_RESERVED) |
| 407 | IDTVEC(rsvd111) |
| 408 | pushl $111; TRAP(T_RESERVED) |
| 409 | IDTVEC(rsvd112) |
| 410 | pushl $112; TRAP(T_RESERVED) |
| 411 | IDTVEC(rsvd113) |
| 412 | pushl $113; TRAP(T_RESERVED) |
| 413 | IDTVEC(rsvd114) |
| 414 | pushl $114; TRAP(T_RESERVED) |
| 415 | IDTVEC(rsvd115) |
| 416 | pushl $115; TRAP(T_RESERVED) |
| 417 | IDTVEC(rsvd116) |
| 418 | pushl $116; TRAP(T_RESERVED) |
| 419 | IDTVEC(rsvd117) |
| 420 | pushl $117; TRAP(T_RESERVED) |
| 421 | IDTVEC(rsvd118) |
| 422 | pushl $118; TRAP(T_RESERVED) |
| 423 | IDTVEC(rsvd119) |
| 424 | pushl $119; TRAP(T_RESERVED) |
| 425 | IDTVEC(rsvd120) |
| 426 | pushl $120; TRAP(T_RESERVED) |
| 427 | IDTVEC(rsvd121) |
| 428 | pushl $121; TRAP(T_RESERVED) |
| 429 | IDTVEC(rsvd122) |
| 430 | pushl $122; TRAP(T_RESERVED) |
| 431 | IDTVEC(rsvd123) |
| 432 | pushl $123; TRAP(T_RESERVED) |
| 433 | IDTVEC(rsvd124) |
| 434 | pushl $124; TRAP(T_RESERVED) |
| 435 | IDTVEC(rsvd125) |
| 436 | pushl $125; TRAP(T_RESERVED) |
| 437 | IDTVEC(rsvd126) |
| 438 | pushl $126; TRAP(T_RESERVED) |
| 439 | IDTVEC(rsvd127) |
| 440 | pushl $127; TRAP(T_RESERVED) |
| 441 | IDTVEC(rsvd128) |
| 442 | pushl $128; TRAP(T_RESERVED) |
| 443 | IDTVEC(rsvd129) |
| 444 | pushl $129; TRAP(T_RESERVED) |
| 445 | IDTVEC(rsvd130) |
| 446 | pushl $130; TRAP(T_RESERVED) |
| 447 | IDTVEC(rsvd131) |
| 448 | pushl $131; TRAP(T_RESERVED) |
| 449 | IDTVEC(rsvd132) |
| 450 | pushl $132; TRAP(T_RESERVED) |
| 451 | IDTVEC(rsvd133) |
| 452 | pushl $133; TRAP(T_RESERVED) |
| 453 | IDTVEC(rsvd134) |
| 454 | pushl $134; TRAP(T_RESERVED) |
| 455 | IDTVEC(rsvd135) |
| 456 | pushl $135; TRAP(T_RESERVED) |
| 457 | IDTVEC(rsvd136) |
| 458 | pushl $136; TRAP(T_RESERVED) |
| 459 | IDTVEC(rsvd137) |
| 460 | pushl $137; TRAP(T_RESERVED) |
| 461 | IDTVEC(rsvd138) |
| 462 | pushl $138; TRAP(T_RESERVED) |
| 463 | IDTVEC(rsvd139) |
| 464 | pushl $139; TRAP(T_RESERVED) |
| 465 | IDTVEC(rsvd140) |
| 466 | pushl $140; TRAP(T_RESERVED) |
| 467 | IDTVEC(rsvd141) |
| 468 | pushl $141; TRAP(T_RESERVED) |
| 469 | IDTVEC(rsvd142) |
| 470 | pushl $142; TRAP(T_RESERVED) |
| 471 | IDTVEC(rsvd143) |
| 472 | pushl $143; TRAP(T_RESERVED) |
| 473 | IDTVEC(rsvd144) |
| 474 | pushl $144; TRAP(T_RESERVED) |
| 475 | IDTVEC(rsvd145) |
| 476 | pushl $145; TRAP(T_RESERVED) |
| 477 | IDTVEC(rsvd146) |
| 478 | pushl $146; TRAP(T_RESERVED) |
| 479 | IDTVEC(rsvd147) |
| 480 | pushl $147; TRAP(T_RESERVED) |
| 481 | IDTVEC(rsvd148) |
| 482 | pushl $148; TRAP(T_RESERVED) |
| 483 | IDTVEC(rsvd149) |
| 484 | pushl $149; TRAP(T_RESERVED) |
| 485 | IDTVEC(rsvd150) |
| 486 | pushl $150; TRAP(T_RESERVED) |
| 487 | IDTVEC(rsvd151) |
| 488 | pushl $151; TRAP(T_RESERVED) |
| 489 | IDTVEC(rsvd152) |
| 490 | pushl $152; TRAP(T_RESERVED) |
| 491 | IDTVEC(rsvd153) |
| 492 | pushl $153; TRAP(T_RESERVED) |
| 493 | IDTVEC(rsvd154) |
| 494 | pushl $154; TRAP(T_RESERVED) |
| 495 | IDTVEC(rsvd155) |
| 496 | pushl $155; TRAP(T_RESERVED) |
| 497 | IDTVEC(rsvd156) |
| 498 | pushl $156; TRAP(T_RESERVED) |
| 499 | IDTVEC(rsvd157) |
| 500 | pushl $157; TRAP(T_RESERVED) |
| 501 | IDTVEC(rsvd158) |
| 502 | pushl $158; TRAP(T_RESERVED) |
| 503 | IDTVEC(rsvd159) |
| 504 | pushl $159; TRAP(T_RESERVED) |
| 505 | IDTVEC(rsvd160) |
| 506 | pushl $160; TRAP(T_RESERVED) |
| 507 | IDTVEC(rsvd161) |
| 508 | pushl $161; TRAP(T_RESERVED) |
| 509 | IDTVEC(rsvd162) |
| 510 | pushl $162; TRAP(T_RESERVED) |
| 511 | IDTVEC(rsvd163) |
| 512 | pushl $163; TRAP(T_RESERVED) |
| 513 | IDTVEC(rsvd164) |
| 514 | pushl $164; TRAP(T_RESERVED) |
| 515 | IDTVEC(rsvd165) |
| 516 | pushl $165; TRAP(T_RESERVED) |
| 517 | IDTVEC(rsvd166) |
| 518 | pushl $166; TRAP(T_RESERVED) |
| 519 | IDTVEC(rsvd167) |
| 520 | pushl $167; TRAP(T_RESERVED) |
| 521 | IDTVEC(rsvd168) |
| 522 | pushl $168; TRAP(T_RESERVED) |
| 523 | IDTVEC(rsvd169) |
| 524 | pushl $169; TRAP(T_RESERVED) |
| 525 | IDTVEC(rsvd170) |
| 526 | pushl $170; TRAP(T_RESERVED) |
| 527 | IDTVEC(rsvd171) |
| 528 | pushl $171; TRAP(T_RESERVED) |
| 529 | IDTVEC(rsvd172) |
| 530 | pushl $172; TRAP(T_RESERVED) |
| 531 | IDTVEC(rsvd173) |
| 532 | pushl $173; TRAP(T_RESERVED) |
| 533 | IDTVEC(rsvd174) |
| 534 | pushl $174; TRAP(T_RESERVED) |
| 535 | IDTVEC(rsvd175) |
| 536 | pushl $175; TRAP(T_RESERVED) |
| 537 | IDTVEC(rsvd176) |
| 538 | pushl $176; TRAP(T_RESERVED) |
| 539 | IDTVEC(rsvd177) |
| 540 | pushl $177; TRAP(T_RESERVED) |
| 541 | IDTVEC(rsvd178) |
| 542 | pushl $178; TRAP(T_RESERVED) |
| 543 | IDTVEC(rsvd179) |
| 544 | pushl $179; TRAP(T_RESERVED) |
| 545 | IDTVEC(rsvd180) |
| 546 | pushl $180; TRAP(T_RESERVED) |
| 547 | IDTVEC(rsvd181) |
| 548 | pushl $181; TRAP(T_RESERVED) |
| 549 | IDTVEC(rsvd182) |
| 550 | pushl $182; TRAP(T_RESERVED) |
| 551 | IDTVEC(rsvd183) |
| 552 | pushl $183; TRAP(T_RESERVED) |
| 553 | IDTVEC(rsvd184) |
| 554 | pushl $184; TRAP(T_RESERVED) |
| 555 | IDTVEC(rsvd185) |
| 556 | pushl $185; TRAP(T_RESERVED) |
| 557 | IDTVEC(rsvd186) |
| 558 | pushl $186; TRAP(T_RESERVED) |
| 559 | IDTVEC(rsvd187) |
| 560 | pushl $187; TRAP(T_RESERVED) |
| 561 | IDTVEC(rsvd188) |
| 562 | pushl $188; TRAP(T_RESERVED) |
| 563 | IDTVEC(rsvd189) |
| 564 | pushl $189; TRAP(T_RESERVED) |
| 565 | IDTVEC(rsvd190) |
| 566 | pushl $190; TRAP(T_RESERVED) |
| 567 | IDTVEC(rsvd191) |
| 568 | pushl $191; TRAP(T_RESERVED) |
| 569 | IDTVEC(rsvd192) |
| 570 | pushl $192; TRAP(T_RESERVED) |
| 571 | IDTVEC(rsvd193) |
| 572 | pushl $193; TRAP(T_RESERVED) |
| 573 | IDTVEC(rsvd194) |
| 574 | pushl $194; TRAP(T_RESERVED) |
| 575 | IDTVEC(rsvd195) |
| 576 | pushl $195; TRAP(T_RESERVED) |
| 577 | IDTVEC(rsvd196) |
| 578 | pushl $196; TRAP(T_RESERVED) |
| 579 | IDTVEC(rsvd197) |
| 580 | pushl $197; TRAP(T_RESERVED) |
| 581 | IDTVEC(rsvd198) |
| 582 | pushl $198; TRAP(T_RESERVED) |
| 583 | IDTVEC(rsvd199) |
| 584 | pushl $199; TRAP(T_RESERVED) |
| 585 | IDTVEC(rsvd200) |
| 586 | pushl $200; TRAP(T_RESERVED) |
| 587 | IDTVEC(rsvd201) |
| 588 | pushl $201; TRAP(T_RESERVED) |
| 589 | IDTVEC(rsvd202) |
| 590 | pushl $202; TRAP(T_RESERVED) |
| 591 | IDTVEC(rsvd203) |
| 592 | pushl $203; TRAP(T_RESERVED) |
| 593 | IDTVEC(rsvd204) |
| 594 | pushl $204; TRAP(T_RESERVED) |
| 595 | IDTVEC(rsvd205) |
| 596 | pushl $205; TRAP(T_RESERVED) |
| 597 | IDTVEC(rsvd206) |
| 598 | pushl $206; TRAP(T_RESERVED) |
| 599 | IDTVEC(rsvd207) |
| 600 | pushl $207; TRAP(T_RESERVED) |
| 601 | IDTVEC(rsvd208) |
| 602 | pushl $208; TRAP(T_RESERVED) |
| 603 | IDTVEC(rsvd209) |
| 604 | pushl $209; TRAP(T_RESERVED) |
| 605 | IDTVEC(rsvd210) |
| 606 | pushl $210; TRAP(T_RESERVED) |
| 607 | IDTVEC(rsvd211) |
| 608 | pushl $211; TRAP(T_RESERVED) |
| 609 | IDTVEC(rsvd212) |
| 610 | pushl $212; TRAP(T_RESERVED) |
| 611 | IDTVEC(rsvd213) |
| 612 | pushl $213; TRAP(T_RESERVED) |
| 613 | IDTVEC(rsvd214) |
| 614 | pushl $214; TRAP(T_RESERVED) |
| 615 | IDTVEC(rsvd215) |
| 616 | pushl $215; TRAP(T_RESERVED) |
| 617 | IDTVEC(rsvd216) |
| 618 | pushl $216; TRAP(T_RESERVED) |
| 619 | IDTVEC(rsvd217) |
| 620 | pushl $217; TRAP(T_RESERVED) |
| 621 | IDTVEC(rsvd218) |
| 622 | pushl $218; TRAP(T_RESERVED) |
| 623 | IDTVEC(rsvd219) |
| 624 | pushl $219; TRAP(T_RESERVED) |
| 625 | IDTVEC(rsvd220) |
| 626 | pushl $220; TRAP(T_RESERVED) |
| 627 | IDTVEC(rsvd221) |
| 628 | pushl $221; TRAP(T_RESERVED) |
| 629 | IDTVEC(rsvd222) |
| 630 | pushl $222; TRAP(T_RESERVED) |
| 631 | IDTVEC(rsvd223) |
| 632 | pushl $223; TRAP(T_RESERVED) |
| 633 | IDTVEC(rsvd224) |
| 634 | pushl $224; TRAP(T_RESERVED) |
| 635 | IDTVEC(rsvd225) |
| 636 | pushl $225; TRAP(T_RESERVED) |
| 637 | IDTVEC(rsvd226) |
| 638 | pushl $226; TRAP(T_RESERVED) |
| 639 | IDTVEC(rsvd227) |
| 640 | pushl $227; TRAP(T_RESERVED) |
| 641 | IDTVEC(rsvd228) |
| 642 | pushl $228; TRAP(T_RESERVED) |
| 643 | IDTVEC(rsvd229) |
| 644 | pushl $229; TRAP(T_RESERVED) |
| 645 | IDTVEC(rsvd230) |
| 646 | pushl $230; TRAP(T_RESERVED) |
| 647 | IDTVEC(rsvd231) |
| 648 | pushl $231; TRAP(T_RESERVED) |
| 649 | IDTVEC(rsvd232) |
| 650 | pushl $232; TRAP(T_RESERVED) |
| 651 | IDTVEC(rsvd233) |
| 652 | pushl $233; TRAP(T_RESERVED) |
| 653 | IDTVEC(rsvd234) |
| 654 | pushl $234; TRAP(T_RESERVED) |
| 655 | IDTVEC(rsvd235) |
| 656 | pushl $235; TRAP(T_RESERVED) |
| 657 | IDTVEC(rsvd236) |
| 658 | pushl $236; TRAP(T_RESERVED) |
| 659 | IDTVEC(rsvd237) |
| 660 | pushl $237; TRAP(T_RESERVED) |
| 661 | IDTVEC(rsvd238) |
| 662 | pushl $238; TRAP(T_RESERVED) |
| 663 | IDTVEC(rsvd239) |
| 664 | pushl $239; TRAP(T_RESERVED) |
| 665 | IDTVEC(rsvd240) |
| 666 | pushl $240; TRAP(T_RESERVED) |
| 667 | IDTVEC(rsvd241) |
| 668 | pushl $241; TRAP(T_RESERVED) |
| 669 | IDTVEC(rsvd242) |
| 670 | pushl $242; TRAP(T_RESERVED) |
| 671 | IDTVEC(rsvd243) |
| 672 | pushl $243; TRAP(T_RESERVED) |
| 673 | IDTVEC(rsvd244) |
| 674 | pushl $244; TRAP(T_RESERVED) |
| 675 | IDTVEC(rsvd245) |
| 676 | pushl $245; TRAP(T_RESERVED) |
| 677 | IDTVEC(rsvd246) |
| 678 | pushl $246; TRAP(T_RESERVED) |
| 679 | IDTVEC(rsvd247) |
| 680 | pushl $247; TRAP(T_RESERVED) |
| 681 | IDTVEC(rsvd248) |
| 682 | pushl $248; TRAP(T_RESERVED) |
| 683 | IDTVEC(rsvd249) |
| 684 | pushl $249; TRAP(T_RESERVED) |
| 685 | IDTVEC(rsvd250) |
| 686 | pushl $250; TRAP(T_RESERVED) |
| 687 | IDTVEC(rsvd251) |
| 688 | pushl $251; TRAP(T_RESERVED) |
| 689 | IDTVEC(rsvd252) |
| 690 | pushl $252; TRAP(T_RESERVED) |
| 691 | IDTVEC(rsvd253) |
| 692 | pushl $253; TRAP(T_RESERVED) |
| 693 | IDTVEC(rsvd254) |
| 694 | pushl $254; TRAP(T_RESERVED) |
| 695 | IDTVEC(rsvd255) |
| 696 | pushl $255; TRAP(T_RESERVED) |
| 697 | |
| 698 | #endif |
| 699 | |
| 700 | IDTVEC(fpu) |
| 701 | #if NNPX > 0 |
| 702 | /* |
| 703 | * Handle like an interrupt (except for accounting) so that we can |
| 704 | * call npx_intr to clear the error. It would be better to handle |
| 705 | * npx interrupts as traps. Nested interrupts would probably have |
| 706 | * to be converted to ASTs. |
| 707 | * |
| 708 | * Convert everything to a full trapframe |
| 709 | */ |
| 710 | pushl $0 /* dummy error code */ |
| 711 | pushl $0 /* dummy trap type */ |
| 712 | pushl $0 /* dummy xflags */ |
| 713 | pushal |
| 714 | pushl %ds |
| 715 | pushl %es |
| 716 | pushl %fs |
| 717 | pushl %gs |
| 718 | mov $KDSEL,%ax |
| 719 | mov %ax,%ds |
| 720 | mov %ax,%es |
| 721 | mov %ax,%gs |
| 722 | mov $KPSEL,%ax |
| 723 | mov %ax,%fs |
| 724 | FAKE_MCOUNT(15*4(%esp)) |
| 725 | |
| 726 | incl PCPU(cnt)+V_TRAP |
| 727 | |
| 728 | /* additional dummy pushes to fake an interrupt frame */ |
| 729 | pushl $0 /* ppl */ |
| 730 | pushl $0 /* vector */ |
| 731 | |
| 732 | /* warning, trap frame dummy arg, no extra reg pushes */ |
| 733 | call npx_intr /* note: call might mess w/ argument */ |
| 734 | |
| 735 | /* convert back to a trapframe for doreti */ |
| 736 | addl $4,%esp |
| 737 | movl $0,(%esp) /* DUMMY CPL FOR DORETI */ |
| 738 | MEXITCOUNT |
| 739 | jmp doreti |
| 740 | #else /* NNPX > 0 */ |
| 741 | pushl $0; TRAP(T_ARITHTRAP) |
| 742 | #endif /* NNPX > 0 */ |
| 743 | |
| 744 | IDTVEC(align) |
| 745 | TRAP(T_ALIGNFLT) |
| 746 | |
| 747 | IDTVEC(xmm) |
| 748 | pushl $0; TRAP(T_XMMFLT) |
| 749 | |
| 750 | /* |
| 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. |
| 755 | * |
| 756 | * Note that we are MP through to the call to trap(). |
| 757 | */ |
| 758 | |
| 759 | SUPERALIGN_TEXT |
| 760 | .globl alltraps |
| 761 | .type alltraps,@function |
| 762 | alltraps: |
| 763 | pushl $0 /* xflags (inherits hardware err on pagefault) */ |
| 764 | pushal |
| 765 | pushl %ds |
| 766 | pushl %es |
| 767 | pushl %fs |
| 768 | pushl %gs |
| 769 | .globl alltraps_with_regs_pushed |
| 770 | alltraps_with_regs_pushed: |
| 771 | mov $KDSEL,%ax |
| 772 | mov %ax,%ds |
| 773 | mov %ax,%es |
| 774 | mov %ax,%gs |
| 775 | mov $KPSEL,%ax |
| 776 | mov %ax,%fs |
| 777 | FAKE_MCOUNT(15*4(%esp)) |
| 778 | calltrap: |
| 779 | FAKE_MCOUNT(btrap) /* init "from" _btrap -> calltrap */ |
| 780 | incl PCPU(cnt)+V_TRAP |
| 781 | /* warning, trap frame dummy arg, no extra reg pushes */ |
| 782 | pushl %esp /* pass frame by reference */ |
| 783 | call trap |
| 784 | addl $4,%esp |
| 785 | |
| 786 | /* |
| 787 | * Return via doreti to handle ASTs. Have to change trap frame |
| 788 | * to interrupt frame. |
| 789 | */ |
| 790 | pushl $0 /* DUMMY CPL FOR DORETI */ |
| 791 | MEXITCOUNT |
| 792 | jmp doreti |
| 793 | |
| 794 | /* |
| 795 | * SYSCALL CALL GATE (old entry point for a.out binaries) |
| 796 | * |
| 797 | * The intersegment call has been set up to specify one dummy parameter. |
| 798 | * |
| 799 | * This leaves a place to put eflags so that the call frame can be |
| 800 | * converted to a trap frame. Note that the eflags is (semi-)bogusly |
| 801 | * pushed into (what will be) tf_err and then copied later into the |
| 802 | * final spot. It has to be done this way because esp can't be just |
| 803 | * temporarily altered for the pushfl - an interrupt might come in |
| 804 | * and clobber the saved cs/eip. |
| 805 | * |
| 806 | * We do not obtain the MP lock, but the call to syscall2 might. If it |
| 807 | * does it will release the lock prior to returning. |
| 808 | */ |
| 809 | SUPERALIGN_TEXT |
| 810 | IDTVEC(syscall) |
| 811 | pushfl /* save eflags in tf_err for now */ |
| 812 | pushl $T_SYSCALL80 /* tf_trapno */ |
| 813 | pushl $0 /* tf_xflags */ |
| 814 | pushal |
| 815 | pushl %ds |
| 816 | pushl %es |
| 817 | pushl %fs |
| 818 | pushl %gs |
| 819 | mov $KDSEL,%ax /* switch to kernel segments */ |
| 820 | mov %ax,%ds |
| 821 | mov %ax,%es |
| 822 | mov %ax,%gs |
| 823 | mov $KPSEL,%ax |
| 824 | mov %ax,%fs |
| 825 | movl TF_ERR(%esp),%eax /* copy saved eflags to final spot */ |
| 826 | movl %eax,TF_EFLAGS(%esp) |
| 827 | movl $7,TF_ERR(%esp) /* sizeof "lcall 7,0" */ |
| 828 | FAKE_MCOUNT(15*4(%esp)) |
| 829 | incl PCPU(cnt)+V_SYSCALL /* YYY per-cpu */ |
| 830 | /* warning, trap frame dummy arg, no extra reg pushes */ |
| 831 | push %esp /* pass frame by reference */ |
| 832 | call syscall2 |
| 833 | addl $4,%esp |
| 834 | MEXITCOUNT |
| 835 | cli /* atomic reqflags interlock w/iret */ |
| 836 | cmpl $0,PCPU(reqflags) |
| 837 | je doreti_syscall_ret |
| 838 | pushl $0 /* cpl to restore */ |
| 839 | jmp doreti |
| 840 | |
| 841 | /* |
| 842 | * Trap gate entry for FreeBSD ELF and Linux/NetBSD syscall (int 0x80) |
| 843 | * |
| 844 | * Even though the name says 'int0x80', this is actually a TGT (trap gate) |
| 845 | * rather then an IGT (interrupt gate). Thus interrupts are enabled on |
| 846 | * entry just as they are for a normal syscall. |
| 847 | * |
| 848 | * We do not obtain the MP lock, but the call to syscall2 might. If it |
| 849 | * does it will release the lock prior to returning. |
| 850 | */ |
| 851 | SUPERALIGN_TEXT |
| 852 | IDTVEC(int0x80_syscall) |
| 853 | pushl $0 /* tf_err */ |
| 854 | pushl $T_SYSCALL80 /* tf_trapno */ |
| 855 | pushl $0 /* tf_xflags */ |
| 856 | pushal |
| 857 | pushl %ds |
| 858 | pushl %es |
| 859 | pushl %fs |
| 860 | pushl %gs |
| 861 | mov $KDSEL,%ax /* switch to kernel segments */ |
| 862 | mov %ax,%ds |
| 863 | mov %ax,%es |
| 864 | mov %ax,%gs |
| 865 | mov $KPSEL,%ax |
| 866 | mov %ax,%fs |
| 867 | movl $2,TF_ERR(%esp) /* sizeof "int 0x80" */ |
| 868 | FAKE_MCOUNT(15*4(%esp)) |
| 869 | incl PCPU(cnt)+V_SYSCALL |
| 870 | /* warning, trap frame dummy arg, no extra reg pushes */ |
| 871 | push %esp /* pass frame by reference */ |
| 872 | call syscall2 |
| 873 | addl $4,%esp |
| 874 | MEXITCOUNT |
| 875 | cli /* atomic reqflags interlock w/irq */ |
| 876 | cmpl $0,PCPU(reqflags) |
| 877 | je doreti_syscall_ret |
| 878 | pushl $0 /* cpl to restore */ |
| 879 | jmp doreti |
| 880 | |
| 881 | /* |
| 882 | * This function is what cpu_heavy_restore jumps to after a new process |
| 883 | * is created. The LWKT subsystem switches while holding a critical |
| 884 | * section and we maintain that abstraction here (e.g. because |
| 885 | * cpu_heavy_restore needs it due to PCB_*() manipulation), then get out of |
| 886 | * it before calling the initial function (typically fork_return()) and/or |
| 887 | * returning to user mode. |
| 888 | * |
| 889 | * The MP lock is held on entry, but for processes fork_return(esi) |
| 890 | * releases it. 'doreti' always runs without the MP lock. |
| 891 | */ |
| 892 | ENTRY(fork_trampoline) |
| 893 | movl PCPU(curthread),%eax |
| 894 | subl $TDPRI_CRIT,TD_PRI(%eax) |
| 895 | |
| 896 | /* |
| 897 | * cpu_set_fork_handler intercepts this function call to |
| 898 | * have this call a non-return function to stay in kernel mode. |
| 899 | * |
| 900 | * initproc has its own fork handler, start_init(), which DOES |
| 901 | * return. |
| 902 | * |
| 903 | * The function (set in pcb_esi) gets passed two arguments, |
| 904 | * the primary parameter set in pcb_ebx and a pointer to the |
| 905 | * trapframe. |
| 906 | * void (func)(int arg, struct trapframe *frame); |
| 907 | */ |
| 908 | pushl %esp /* pass frame by reference */ |
| 909 | pushl %ebx /* arg1 */ |
| 910 | call *%esi /* function */ |
| 911 | addl $8,%esp |
| 912 | /* cut from syscall */ |
| 913 | |
| 914 | sti |
| 915 | call splz |
| 916 | |
| 917 | #if defined(INVARIANTS) && defined(SMP) |
| 918 | movl PCPU(curthread),%eax |
| 919 | cmpl $0,TD_MPCOUNT(%eax) |
| 920 | je 1f |
| 921 | pushl %esi |
| 922 | pushl TD_MPCOUNT(%eax) |
| 923 | pushl $pmsg4 |
| 924 | call panic |
| 925 | pmsg4: .asciz "fork_trampoline mpcount %d after calling %p" |
| 926 | .p2align 2 |
| 927 | 1: |
| 928 | #endif |
| 929 | /* |
| 930 | * Return via doreti to handle ASTs. |
| 931 | */ |
| 932 | pushl $0 /* cpl to restore */ |
| 933 | MEXITCOUNT |
| 934 | jmp doreti |
| 935 | |
| 936 | |
| 937 | /* |
| 938 | * Include vm86 call routines, which want to call doreti. |
| 939 | */ |
| 940 | #include "vm86bios.s" |
| 941 | |