1/*- 2 * Copyright (c) 1989, 1990 William F. Jolitz. 3 * Copyright (c) 1990 The Regents of the University of California. 4 * All rights reserved. 5 * 6 * This code is derived from software contributed to Berkeley by 7 * William Jolitz. 8 * 9 * %sccs.include.redist.c% 10 * 11 * @(#)icu.s 7.3 (Berkeley) 09/03/91 12 */ 13 14/* 15 * AT/386 16 * Vector interrupt control section 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 .globl _isa_intr 33_isa_intr: .space 16*4 34 35 .text 36/* 37 * Handle return from interrupt after device handler finishes 38 */ 39doreti: 40 cli 41 popl %ebx # remove intr number 42 popl %eax # get previous priority 43 # now interrupt frame is a trap frame! 44 movw %ax,%cx 45 movw %ax,_cpl 46 orw _imen,%ax 47 NOP 48 outb %al,$ IO_ICU1+1 # re-enable intr? 49 NOP 50 movb %ah,%al 51 NOP 52 outb %al,$ IO_ICU2+1 53 NOP 54 inb $0x84,%al 55 56 andw $0xffff,%cx 57 cmpw $0,%cx # returning to zero? 58 je 1f 59 60 pop %es # nope, going to non-zero level 61 pop %ds 62 popa 63 addl $8,%esp 64 iret 65 661: cmpl $0,_netisr # check for softint s/traps 67 jne 1f 68 69 pop %es # none, going back to base pri 70 pop %ds 71 popa 72 addl $8,%esp 73 iret 74 75#include "../net/netisr.h" 76 771: 78 79#define DONET(s, c) ; \ 80 .globl c ; \ 81 movl $ s ,%eax ; \ 82 btrl %eax,_netisr ; \ 83 jnb 1f ; \ 84 call c ; \ 851: 86 87 call _splnet 88 pushl %eax 89 90 DONET(NETISR_RAW,_rawintr) 91#ifdef INET 92 DONET(NETISR_IP,_ipintr) 93 DONET(NETISR_ARP,_arpintr) 94#endif 95#ifdef IMP 96 DONET(NETISR_IMP,_impintr) 97#endif 98#ifdef NS 99 DONET(NETISR_NS,_nsintr) 100#endif 101#ifdef ISO 102 DONET(NETISR_ISO,_clnlintr) 103#endif 104#ifdef CCITT 105 DONET(NETISR_CCITT,_hdintr) 106#endif 107 108 popl %eax 109 movw %ax,_cpl 110 orw _imen,%ax 111 NOP 112 outb %al,$ IO_ICU1+1 # re-enable intr? 113 NOP 114 movb %ah,%al 115 NOP 116 outb %al,$ IO_ICU2+1 117 NOP 118 inb $0x84,%al 119 120 # btrl $ NETISR_SCLK,_netisr 121 movl $ NETISR_SCLK,%eax # stupid assembler, as usual 122 btrl %eax,_netisr 123 jnb 1f 124 # back to an interrupt frame for a moment 125 call _splsoftclock 126 pushl %eax 127 pushl $0xff # dummy intr 128 call _softclock 129 popl %eax 130 call _splx 131 popl %eax 132 133 jmp 2f 134 135 /* 1: btrl $NETISR_AST,_netisr*/ 1361: 137 cmpw $0x1f,13*4(%esp) # to user? 138 jne 2f # nope, leave 139 movl $ NETISR_AST,%eax # stupid assembler, as usual 140 btrl %eax,_netisr 141 jnb 2f 142 call _trap 143 1442: pop %es 145 pop %ds 146 popal 147 addl $8,%esp 148 iret 149 150/* 151 * Interrupt priority mechanism 152 * 153 * Two flavors -- imlXX masks relative to ISA noemenclature (for PC compat sw) 154 * -- splXX masks with group mechanism for BSD purposes 155 */ 156 157 .globl _splhigh 158 .globl _splclock 159_splhigh: 160_splclock: 161 cli # disable interrupts 162 movw $0xffff,%ax # set new priority level 163 movw %ax,%dx 164 # orw _imen,%ax # mask off those not enabled yet 165 movw %ax,%cx 166 NOP 167 outb %al,$ IO_ICU1+1 /* update icu's */ 168 NOP 169 movb %ah,%al 170 NOP 171 outb %al,$ IO_ICU2+1 172 NOP 173 inb $0x84,%al 174 movzwl _cpl,%eax # return old priority 175 movw %dx,_cpl # set new priority level 176 sti # enable interrupts 177 ret 178 179 .globl _spltty # block clists 180_spltty: 181 cli # disable interrupts 182 movw _cpl,%ax 183 orw _ttymask,%ax 184 movw %ax,%dx 185 orw _imen,%ax # mask off those not enabled yet 186 movw %ax,%cx 187 NOP 188 outb %al,$ IO_ICU1+1 /* update icu's */ 189 NOP 190 movb %ah,%al 191 NOP 192 outb %al,$ IO_ICU2+1 193 NOP 194 inb $0x84,%al 195 movzwl _cpl,%eax # return old priority 196 movw %dx,_cpl # set new priority level 197 sti # enable interrupts 198 ret 199 200 .globl _splimp 201 .globl _splnet 202_splimp: 203_splnet: 204 cli # disable interrupts 205 movw _cpl,%ax 206 orw _netmask,%ax 207 movw %ax,%dx 208 orw _imen,%ax # mask off those not enabled yet 209 movw %ax,%cx 210 NOP 211 outb %al,$ IO_ICU1+1 /* update icu's */ 212 NOP 213 movb %ah,%al 214 NOP 215 outb %al,$ IO_ICU2+1 216 NOP 217 inb $0x84,%al 218 movzwl _cpl,%eax # return old priority 219 movw %dx,_cpl # set new priority level 220 sti # enable interrupts 221 ret 222 223 .globl _splbio 224_splbio: 225 cli # disable interrupts 226 movw _cpl,%ax 227 orw _biomask,%ax 228 movw %ax,%dx 229 orw _imen,%ax # mask off those not enabled yet 230 movw %ax,%cx 231 NOP 232 outb %al,$ IO_ICU1+1 /* update icu's */ 233 NOP 234 movb %ah,%al 235 NOP 236 outb %al,$ IO_ICU2+1 237 NOP 238 inb $0x84,%al 239 movzwl _cpl,%eax # return old priority 240 movw %dx,_cpl # set new priority level 241 sti # enable interrupts 242 ret 243 244 .globl _splsoftclock 245_splsoftclock: 246 cli # disable interrupts 247 movw _cpl,%ax 248 orw $0x8000,%ax # set new priority level 249 movw %ax,%dx 250 orw _imen,%ax # mask off those not enabled yet 251 movw %ax,%cx 252 NOP 253 outb %al,$ IO_ICU1+1 /* update icu's */ 254 NOP 255 movb %ah,%al 256 NOP 257 outb %al,$ IO_ICU2+1 258 NOP 259 inb $0x84,%al 260 movzwl _cpl,%eax # return old priority 261 movw %dx,_cpl # set new priority level 262 sti # enable interrupts 263 ret 264 265 .globl _splnone 266 .globl _spl0 267_splnone: 268_spl0: 269 cli # disable interrupts 270 pushl _cpl # save old priority 271 movw _cpl,%ax 272 orw _netmask,%ax # mask off those network devices 273 movw %ax,_cpl # set new priority level 274 orw _imen,%ax # mask off those not enabled yet 275 NOP 276 outb %al,$ IO_ICU1+1 /* update icu's */ 277 NOP 278 movb %ah,%al 279 NOP 280 outb %al,$ IO_ICU2+1 281 NOP 282 inb $0x84,%al 283 sti # enable interrupts 284 285 DONET(NETISR_RAW,_rawintr) 286#ifdef INET 287 DONET(NETISR_IP,_ipintr) 288#endif 289 cli # disable interrupts 290 popl _cpl # save old priority 291 movw $0,%ax # set new priority level 292 movw %ax,%dx 293 orw _imen,%ax # mask off those not enabled yet 294 movw %ax,%cx 295 NOP 296 outb %al,$ IO_ICU1+1 /* update icu's */ 297 NOP 298 movb %ah,%al 299 NOP 300 outb %al,$ IO_ICU2+1 301 NOP 302 inb $0x84,%al 303 movzwl _cpl,%eax # return old priority 304 movw %dx,_cpl # set new priority level 305 sti # enable interrupts 306 ret 307 308 .globl _splx 309_splx: 310 cli # disable interrupts 311 movw 4(%esp),%ax # new priority level 312 movw %ax,%dx 313 cmpw $0,%dx 314 je _spl0 # going to "zero level" is special 315 316 orw _imen,%ax # mask off those not enabled yet 317 movw %ax,%cx 318 NOP 319 outb %al,$ IO_ICU1+1 /* update icu's */ 320 NOP 321 movb %ah,%al 322 NOP 323 outb %al,$ IO_ICU2+1 324 NOP 325 inb $0x84,%al 326 movzwl _cpl,%eax # return old priority 327 movw %dx,_cpl # set new priority level 328 sti # enable interrupts 329 ret 330 331#ifdef notyet 332 .globl _iml8 # mask off all but irq0-1 333_iml8: 334 cli # disable interrupts 335 movw $0xfffc,%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 _iml10 # mask off all but irq0-1,8-9 352_iml10: 353 cli # disable interrupts 354 movw $0xfcf8,%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 _iml11 # mask off all but irq0-1,8-10 371_iml11: 372 cli # disable interrupts 373 movw $0xf8f8,%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 _iml12 # mask off all but irq0-1,8-11 390_iml12: 391 cli # disable interrupts 392 movw $0xf0f8,%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 _iml13 # mask off all but irq0-1,8-12 409_iml13: 410 cli # disable interrupts 411 movw $0xe0f8,%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 _iml15 # mask off all but irq0-1,8-14 428_iml15: 429 cli # disable interrupts 430 movw $0x80f8,%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 _iml3 # mask off all but irq0-1,8-15 447_iml3: 448 cli # disable interrupts 449 movw $0x00f8,%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 _iml4 # mask off all but irq0-1,8-15,3 466_iml4: 467 cli # disable interrupts 468 movw $0x00f0,%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 _iml5 # mask off all but irq0-1,8-15,3-4 485_iml5: 486 cli # disable interrupts 487 movw $0x00e0,%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 .globl _iml6 # mask off all but irq0-1,8-15,3-5 504_iml6: 505 cli # disable interrupts 506 movw $0x00c0,%ax # set new priority level 507 movw %ax,%dx 508 orw _imen,%ax # mask off those not enabled yet 509 movw %ax,%cx 510 NOP 511 outb %al,$ IO_ICU1+1 /* update icu's */ 512 NOP 513 movb %ah,%al 514 NOP 515 outb %al,$ IO_ICU2+1 516 NOP 517 movzwl _cpl,%eax # return old priority 518 movw %dx,_cpl # set new priority level 519 sti # enable interrupts 520 ret 521 522#endif notyet 523 524 /* hardware interrupt catcher (IDT 32 - 47) */ 525 .globl _isa_strayintr 526 527IDTVEC(intr0) 528 INTR(0, _highmask, 0) ; call _isa_strayintr ; INTREXIT1 529 530IDTVEC(intr1) 531 INTR(1, _highmask, 1) ; call _isa_strayintr ; INTREXIT1 532 533IDTVEC(intr2) 534 INTR(2, _highmask, 2) ; call _isa_strayintr ; INTREXIT1 535 536IDTVEC(intr3) 537 INTR(3, _highmask, 3) ; call _isa_strayintr ; INTREXIT1 538 539IDTVEC(intr4) 540 INTR(4, _highmask, 4) ; call _isa_strayintr ; INTREXIT1 541 542IDTVEC(intr5) 543 INTR(5, _highmask, 5) ; call _isa_strayintr ; INTREXIT1 544 545IDTVEC(intr6) 546 INTR(6, _highmask, 6) ; call _isa_strayintr ; INTREXIT1 547 548IDTVEC(intr7) 549 INTR(7, _highmask, 7) ; call _isa_strayintr ; INTREXIT1 550 551 552IDTVEC(intr8) 553 INTR(8, _highmask, 8) ; call _isa_strayintr ; INTREXIT2 554 555IDTVEC(intr9) 556 INTR(9, _highmask, 9) ; call _isa_strayintr ; INTREXIT2 557 558IDTVEC(intr10) 559 INTR(10, _highmask, 10) ; call _isa_strayintr ; INTREXIT2 560 561IDTVEC(intr11) 562 INTR(11, _highmask, 11) ; call _isa_strayintr ; INTREXIT2 563 564IDTVEC(intr12) 565 INTR(12, _highmask, 12) ; call _isa_strayintr ; INTREXIT2 566 567IDTVEC(intr13) 568 INTR(13, _highmask, 13) ; call _isa_strayintr ; INTREXIT2 569 570IDTVEC(intr14) 571 INTR(14, _highmask, 14) ; call _isa_strayintr ; INTREXIT2 572 573IDTVEC(intr15) 574 INTR(15, _highmask, 15) ; call _isa_strayintr ; INTREXIT2 575 576