1/*- 2 * Copyright (c) 1990 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * William Jolitz. 7 * 8 * %sccs.include.386.c% 9 * 10 * @(#)icu.s 5.4 (Berkeley) 11/18/90 11 */ 12 13/* 14 * AT/386 15 * Vector interrupt control section 16 * Copyright (C) 1989,90 W. Jolitz 17 */ 18 19 .data 20 .globl _imen 21 .globl _cpl 22_cpl: .long 0xffff # current priority level (all off) 23_imen: .long 0xffff # interrupt mask enable (all off) 24 .globl _highmask 25_highmask: .long 0xffff 26 .globl _ttymask 27_ttymask: .long 0 28 .globl _biomask 29_biomask: .long 0 30 .globl _netmask 31_netmask: .long 0 32 33 .text 34/* 35 * Handle return from interrupt after device handler finishes 36 */ 37doreti: 38 cli 39 popl %ebx # remove intr number 40 popl %eax # get previous priority 41 # now interrupt frame is a trap frame! 42 movw %ax,%cx 43 movw %ax,_cpl 44 orw _imen,%ax 45 NOP 46 outb %al,$ IO_ICU1+1 # re-enable intr? 47 NOP 48 movb %ah,%al 49 NOP 50 outb %al,$ IO_ICU2+1 51 NOP 52 53 andw $0xffff,%cx 54 cmpw $0,%cx # returning to zero? 55 je 1f 56 57 pop %es # nope, going to non-zero level 58 pop %ds 59 popa 60 addl $8,%esp 61 iret 62 631: cmpl $0,_netisr # check for softint s/traps 64 jne 1f 65 66 pop %es # none, going back to base pri 67 pop %ds 68 popa 69 addl $8,%esp 70 iret 71 72#include "../net/netisr.h" 73 741: 75 76#define DONET(s, c) ; \ 77 .globl c ; \ 78 movl $ s ,%eax ; \ 79 btrl %eax,_netisr ; \ 80 jnb 1f ; \ 81 call c ; \ 821: 83 84 call _splnet 85 pushl %eax 86 87 DONET(NETISR_RAW,_rawintr) 88#ifdef INET 89 DONET(NETISR_IP,_ipintr) 90#endif 91#ifdef IMP 92 DONET(NETISR_IMP,_impintr) 93#endif 94#ifdef NS 95 DONET(NETISR_NS,_nsintr) 96#endif 97 98 popl %eax 99 movw %ax,_cpl 100 orw _imen,%ax 101 NOP 102 outb %al,$ IO_ICU1+1 # re-enable intr? 103 NOP 104 movb %ah,%al 105 NOP 106 outb %al,$ IO_ICU2+1 107 NOP 108 109 # btrl $ NETISR_SCLK,_netisr 110 movl $ NETISR_SCLK,%eax # stupid assembler, as usual 111 btrl %eax,_netisr 112 jnb 1f 113 # back to an interrupt frame for a moment 114 call _splsoftclock 115 pushl %eax 116 pushl $0xff # dummy intr 117 call _softclock 118 popl %eax 119 call _splx 120 popl %eax 121 122 jmp 2f 123 124 /* 1: btrl $NETISR_AST,_netisr*/ 1251: 126 cmpw $0x1f,13*4(%esp) # to user? 127 jne 2f # nope, leave 128 movl $ NETISR_AST,%eax # stupid assembler, as usual 129 btrl %eax,_netisr 130 jnb 2f 131 call _trap 132 1332: pop %es 134 pop %ds 135 popal 136 addl $8,%esp 137 iret 138 139/* 140 * Interrupt priority mechanism 141 * 142 * Two flavors -- imlXX masks relative to ISA noemenclature (for PC compat sw) 143 * -- splXX masks with group mechanism for BSD purposes 144 */ 145 146 .globl _splhigh 147 .globl _splclock 148_splhigh: 149_splclock: 150 cli # disable interrupts 151 movw $0xffff,%ax # set new priority level 152 movw %ax,%dx 153 # orw _imen,%ax # mask off those not enabled yet 154 movw %ax,%cx 155 NOP 156 outb %al,$ IO_ICU1+1 /* update icu's */ 157 NOP 158 movb %ah,%al 159 NOP 160 outb %al,$ IO_ICU2+1 161 NOP 162 movzwl _cpl,%eax # return old priority 163 movw %dx,_cpl # set new priority level 164 sti # enable interrupts 165 ret 166 167 .globl _spltty # block clists 168_spltty: 169 cli # disable interrupts 170 movw _cpl,%ax 171 orw _ttymask,%ax 172 movw %ax,%dx 173 orw _imen,%ax # mask off those not enabled yet 174 movw %ax,%cx 175 NOP 176 outb %al,$ IO_ICU1+1 /* update icu's */ 177 NOP 178 movb %ah,%al 179 NOP 180 outb %al,$ IO_ICU2+1 181 NOP 182 movzwl _cpl,%eax # return old priority 183 movw %dx,_cpl # set new priority level 184 sti # enable interrupts 185 ret 186 187 .globl _splimp 188 .globl _splnet 189_splimp: 190_splnet: 191 cli # disable interrupts 192 movw _cpl,%ax 193 orw _netmask,%ax 194 movw %ax,%dx 195 orw _imen,%ax # mask off those not enabled yet 196 movw %ax,%cx 197 NOP 198 outb %al,$ IO_ICU1+1 /* update icu's */ 199 NOP 200 movb %ah,%al 201 NOP 202 outb %al,$ IO_ICU2+1 203 NOP 204 movzwl _cpl,%eax # return old priority 205 movw %dx,_cpl # set new priority level 206 sti # enable interrupts 207 ret 208 209 .globl _splbio 210_splbio: 211 cli # disable interrupts 212 movw _cpl,%ax 213 orw _biomask,%ax 214 movw %ax,%dx 215 orw _imen,%ax # mask off those not enabled yet 216 movw %ax,%cx 217 NOP 218 outb %al,$ IO_ICU1+1 /* update icu's */ 219 NOP 220 movb %ah,%al 221 NOP 222 outb %al,$ IO_ICU2+1 223 NOP 224 movzwl _cpl,%eax # return old priority 225 movw %dx,_cpl # set new priority level 226 sti # enable interrupts 227 ret 228 229 .globl _splsoftclock 230_splsoftclock: 231 cli # disable interrupts 232 movw _cpl,%ax 233 orw $0x8000,%ax # set new priority level 234 movw %ax,%dx 235 orw _imen,%ax # mask off those not enabled yet 236 movw %ax,%cx 237 NOP 238 outb %al,$ IO_ICU1+1 /* update icu's */ 239 NOP 240 movb %ah,%al 241 NOP 242 outb %al,$ IO_ICU2+1 243 NOP 244 movzwl _cpl,%eax # return old priority 245 movw %dx,_cpl # set new priority level 246 sti # enable interrupts 247 ret 248 249 .globl _splnone 250 .globl _spl0 251_splnone: 252_spl0: 253 cli # disable interrupts 254 pushl _cpl # save old priority 255 movw _cpl,%ax 256 orw _netmask,%ax # mask off those network devices 257 movw %ax,_cpl # set new priority level 258 orw _imen,%ax # mask off those not enabled yet 259 NOP 260 outb %al,$ IO_ICU1+1 /* update icu's */ 261 NOP 262 movb %ah,%al 263 NOP 264 outb %al,$ IO_ICU2+1 265 NOP 266 sti # enable interrupts 267 268 DONET(NETISR_RAW,_rawintr) 269#ifdef INET 270 DONET(NETISR_IP,_ipintr) 271#endif 272 cli # disable interrupts 273 popl _cpl # save old priority 274 movw $0,%ax # set new priority level 275 movw %ax,%dx 276 orw _imen,%ax # mask off those not enabled yet 277 movw %ax,%cx 278 NOP 279 outb %al,$ IO_ICU1+1 /* update icu's */ 280 NOP 281 movb %ah,%al 282 NOP 283 outb %al,$ IO_ICU2+1 284 NOP 285 movzwl _cpl,%eax # return old priority 286 movw %dx,_cpl # set new priority level 287 sti # enable interrupts 288 ret 289 290 .globl _splx 291_splx: 292 cli # disable interrupts 293 movw 4(%esp),%ax # new priority level 294 movw %ax,%dx 295 cmpw $0,%dx 296 je _spl0 # going to "zero level" is special 297 298 orw _imen,%ax # mask off those not enabled yet 299 movw %ax,%cx 300 NOP 301 outb %al,$ IO_ICU1+1 /* update icu's */ 302 NOP 303 movb %ah,%al 304 NOP 305 outb %al,$ IO_ICU2+1 306 NOP 307 movzwl _cpl,%eax # return old priority 308 movw %dx,_cpl # set new priority level 309 sti # enable interrupts 310 ret 311 312#ifdef notyet 313 .globl _iml8 # mask off all but irq0-1 314_iml8: 315 cli # disable interrupts 316 movw $0xfffc,%ax # set new priority level 317 movw %ax,%dx 318 orw _imen,%ax # mask off those not enabled yet 319 movw %ax,%cx 320 NOP 321 outb %al,$ IO_ICU1+1 /* update icu's */ 322 NOP 323 movb %ah,%al 324 NOP 325 outb %al,$ IO_ICU2+1 326 NOP 327 movzwl _cpl,%eax # return old priority 328 movw %dx,_cpl # set new priority level 329 sti # enable interrupts 330 ret 331 332 .globl _iml10 # mask off all but irq0-1,8-9 333_iml10: 334 cli # disable interrupts 335 movw $0xfcf8,%ax # set new priority level 336 movw %ax,%dx 337 orw _imen,%ax # mask off those not enabled yet 338 movw %ax,%cx 339 NOP 340 outb %al,$ IO_ICU1+1 /* update icu's */ 341 NOP 342 movb %ah,%al 343 NOP 344 outb %al,$ IO_ICU2+1 345 NOP 346 movzwl _cpl,%eax # return old priority 347 movw %dx,_cpl # set new priority level 348 sti # enable interrupts 349 ret 350 351 .globl _iml11 # mask off all but irq0-1,8-10 352_iml11: 353 cli # disable interrupts 354 movw $0xf8f8,%ax # set new priority level 355 movw %ax,%dx 356 orw _imen,%ax # mask off those not enabled yet 357 movw %ax,%cx 358 NOP 359 outb %al,$ IO_ICU1+1 /* update icu's */ 360 NOP 361 movb %ah,%al 362 NOP 363 outb %al,$ IO_ICU2+1 364 NOP 365 movzwl _cpl,%eax # return old priority 366 movw %dx,_cpl # set new priority level 367 sti # enable interrupts 368 ret 369 370 .globl _iml12 # mask off all but irq0-1,8-11 371_iml12: 372 cli # disable interrupts 373 movw $0xf0f8,%ax # set new priority level 374 movw %ax,%dx 375 orw _imen,%ax # mask off those not enabled yet 376 movw %ax,%cx 377 NOP 378 outb %al,$ IO_ICU1+1 /* update icu's */ 379 NOP 380 movb %ah,%al 381 NOP 382 outb %al,$ IO_ICU2+1 383 NOP 384 movzwl _cpl,%eax # return old priority 385 movw %dx,_cpl # set new priority level 386 sti # enable interrupts 387 ret 388 389 .globl _iml13 # mask off all but irq0-1,8-12 390_iml13: 391 cli # disable interrupts 392 movw $0xe0f8,%ax # set new priority level 393 movw %ax,%dx 394 orw _imen,%ax # mask off those not enabled yet 395 movw %ax,%cx 396 NOP 397 outb %al,$ IO_ICU1+1 /* update icu's */ 398 NOP 399 movb %ah,%al 400 NOP 401 outb %al,$ IO_ICU2+1 402 NOP 403 movzwl _cpl,%eax # return old priority 404 movw %dx,_cpl # set new priority level 405 sti # enable interrupts 406 ret 407 408 .globl _iml15 # mask off all but irq0-1,8-14 409_iml15: 410 cli # disable interrupts 411 movw $0x80f8,%ax # set new priority level 412 movw %ax,%dx 413 orw _imen,%ax # mask off those not enabled yet 414 movw %ax,%cx 415 NOP 416 outb %al,$ IO_ICU1+1 /* update icu's */ 417 NOP 418 movb %ah,%al 419 NOP 420 outb %al,$ IO_ICU2+1 421 NOP 422 movzwl _cpl,%eax # return old priority 423 movw %dx,_cpl # set new priority level 424 sti # enable interrupts 425 ret 426 427 .globl _iml3 # mask off all but irq0-1,8-15 428_iml3: 429 cli # disable interrupts 430 movw $0x00f8,%ax # set new priority level 431 movw %ax,%dx 432 orw _imen,%ax # mask off those not enabled yet 433 movw %ax,%cx 434 NOP 435 outb %al,$ IO_ICU1+1 /* update icu's */ 436 NOP 437 movb %ah,%al 438 NOP 439 outb %al,$ IO_ICU2+1 440 NOP 441 movzwl _cpl,%eax # return old priority 442 movw %dx,_cpl # set new priority level 443 sti # enable interrupts 444 ret 445 446 .globl _iml4 # mask off all but irq0-1,8-15,3 447_iml4: 448 cli # disable interrupts 449 movw $0x00f0,%ax # set new priority level 450 movw %ax,%dx 451 orw _imen,%ax # mask off those not enabled yet 452 movw %ax,%cx 453 NOP 454 outb %al,$ IO_ICU1+1 /* update icu's */ 455 NOP 456 movb %ah,%al 457 NOP 458 outb %al,$ IO_ICU2+1 459 NOP 460 movzwl _cpl,%eax # return old priority 461 movw %dx,_cpl # set new priority level 462 sti # enable interrupts 463 ret 464 465 .globl _iml5 # mask off all but irq0-1,8-15,3-4 466_iml5: 467 cli # disable interrupts 468 movw $0x00e0,%ax # set new priority level 469 movw %ax,%dx 470 orw _imen,%ax # mask off those not enabled yet 471 movw %ax,%cx 472 NOP 473 outb %al,$ IO_ICU1+1 /* update icu's */ 474 NOP 475 movb %ah,%al 476 NOP 477 outb %al,$ IO_ICU2+1 478 NOP 479 movzwl _cpl,%eax # return old priority 480 movw %dx,_cpl # set new priority level 481 sti # enable interrupts 482 ret 483 484 .globl _iml6 # mask off all but irq0-1,8-15,3-5 485_iml6: 486 cli # disable interrupts 487 movw $0x00c0,%ax # set new priority level 488 movw %ax,%dx 489 orw _imen,%ax # mask off those not enabled yet 490 movw %ax,%cx 491 NOP 492 outb %al,$ IO_ICU1+1 /* update icu's */ 493 NOP 494 movb %ah,%al 495 NOP 496 outb %al,$ IO_ICU2+1 497 NOP 498 movzwl _cpl,%eax # return old priority 499 movw %dx,_cpl # set new priority level 500 sti # enable interrupts 501 ret 502 503#endif notyet 504 505 /* hardware interrupt catcher (IDT 32 - 47) */ 506 .globl _isa_strayintr 507 508IDTVEC(intr0) 509 INTR(0) ; call _isa_strayintr ; INTREXT1 510 511IDTVEC(intr1) 512 INTR(1) ; call _isa_strayintr ; INTREXT1 513 514IDTVEC(intr2) 515 INTR(2) ; call _isa_strayintr ; INTREXT1 516 517IDTVEC(intr3) 518 INTR(3) ; call _isa_strayintr ; INTREXT1 519 520IDTVEC(intr4) 521 INTR(4) ; call _isa_strayintr ; INTREXT1 522 523IDTVEC(intr5) 524 INTR(5) ; call _isa_strayintr ; INTREXT1 525 526IDTVEC(intr6) 527 INTR(6) ; call _isa_strayintr ; INTREXT1 528 529IDTVEC(intr7) 530 INTR(7) ; call _isa_strayintr ; INTREXT1 531 532 533IDTVEC(intr8) 534 INTR(8) ; call _isa_strayintr ; INTREXT2 535 536IDTVEC(intr9) 537 INTR(9) ; call _isa_strayintr ; INTREXT2 538 539IDTVEC(intr10) 540 INTR(10) ; call _isa_strayintr ; INTREXT2 541 542IDTVEC(intr11) 543 INTR(11) ; call _isa_strayintr ; INTREXT2 544 545IDTVEC(intr12) 546 INTR(12) ; call _isa_strayintr ; INTREXT2 547 548IDTVEC(intr13) 549 INTR(13) ; call _isa_strayintr ; INTREXT2 550 551IDTVEC(intr14) 552 INTR(14) ; call _isa_strayintr ; INTREXT2 553 554IDTVEC(intr15) 555 INTR(15) ; call _isa_strayintr ; INTREXT2 556 557