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.redist.c% 9 * 10 * @(#)icu.s 7.1 (Berkeley) 05/09/91 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 .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#endif 94#ifdef IMP 95 DONET(NETISR_IMP,_impintr) 96#endif 97#ifdef NS 98 DONET(NETISR_NS,_nsintr) 99#endif 100 101 popl %eax 102 movw %ax,_cpl 103 orw _imen,%ax 104 NOP 105 outb %al,$ IO_ICU1+1 # re-enable intr? 106 NOP 107 movb %ah,%al 108 NOP 109 outb %al,$ IO_ICU2+1 110 NOP 111 inb $0x84,%al 112 113 # btrl $ NETISR_SCLK,_netisr 114 movl $ NETISR_SCLK,%eax # stupid assembler, as usual 115 btrl %eax,_netisr 116 jnb 1f 117 # back to an interrupt frame for a moment 118 call _splsoftclock 119 pushl %eax 120 pushl $0xff # dummy intr 121 call _softclock 122 popl %eax 123 call _splx 124 popl %eax 125 126 jmp 2f 127 128 /* 1: btrl $NETISR_AST,_netisr*/ 1291: 130 cmpw $0x1f,13*4(%esp) # to user? 131 jne 2f # nope, leave 132 movl $ NETISR_AST,%eax # stupid assembler, as usual 133 btrl %eax,_netisr 134 jnb 2f 135 call _trap 136 1372: pop %es 138 pop %ds 139 popal 140 addl $8,%esp 141 iret 142 143/* 144 * Interrupt priority mechanism 145 * 146 * Two flavors -- imlXX masks relative to ISA noemenclature (for PC compat sw) 147 * -- splXX masks with group mechanism for BSD purposes 148 */ 149 150 .globl _splhigh 151 .globl _splclock 152_splhigh: 153_splclock: 154 cli # disable interrupts 155 movw $0xffff,%ax # set new priority level 156 movw %ax,%dx 157 # orw _imen,%ax # mask off those not enabled yet 158 movw %ax,%cx 159 NOP 160 outb %al,$ IO_ICU1+1 /* update icu's */ 161 NOP 162 movb %ah,%al 163 NOP 164 outb %al,$ IO_ICU2+1 165 NOP 166 inb $0x84,%al 167 movzwl _cpl,%eax # return old priority 168 movw %dx,_cpl # set new priority level 169 sti # enable interrupts 170 ret 171 172 .globl _spltty # block clists 173_spltty: 174 cli # disable interrupts 175 movw _cpl,%ax 176 orw _ttymask,%ax 177 movw %ax,%dx 178 orw _imen,%ax # mask off those not enabled yet 179 movw %ax,%cx 180 NOP 181 outb %al,$ IO_ICU1+1 /* update icu's */ 182 NOP 183 movb %ah,%al 184 NOP 185 outb %al,$ IO_ICU2+1 186 NOP 187 inb $0x84,%al 188 movzwl _cpl,%eax # return old priority 189 movw %dx,_cpl # set new priority level 190 sti # enable interrupts 191 ret 192 193 .globl _splimp 194 .globl _splnet 195_splimp: 196_splnet: 197 cli # disable interrupts 198 movw _cpl,%ax 199 orw _netmask,%ax 200 movw %ax,%dx 201 orw _imen,%ax # mask off those not enabled yet 202 movw %ax,%cx 203 NOP 204 outb %al,$ IO_ICU1+1 /* update icu's */ 205 NOP 206 movb %ah,%al 207 NOP 208 outb %al,$ IO_ICU2+1 209 NOP 210 inb $0x84,%al 211 movzwl _cpl,%eax # return old priority 212 movw %dx,_cpl # set new priority level 213 sti # enable interrupts 214 ret 215 216 .globl _splbio 217_splbio: 218 cli # disable interrupts 219 movw _cpl,%ax 220 orw _biomask,%ax 221 movw %ax,%dx 222 orw _imen,%ax # mask off those not enabled yet 223 movw %ax,%cx 224 NOP 225 outb %al,$ IO_ICU1+1 /* update icu's */ 226 NOP 227 movb %ah,%al 228 NOP 229 outb %al,$ IO_ICU2+1 230 NOP 231 inb $0x84,%al 232 movzwl _cpl,%eax # return old priority 233 movw %dx,_cpl # set new priority level 234 sti # enable interrupts 235 ret 236 237 .globl _splsoftclock 238_splsoftclock: 239 cli # disable interrupts 240 movw _cpl,%ax 241 orw $0x8000,%ax # set new priority level 242 movw %ax,%dx 243 orw _imen,%ax # mask off those not enabled yet 244 movw %ax,%cx 245 NOP 246 outb %al,$ IO_ICU1+1 /* update icu's */ 247 NOP 248 movb %ah,%al 249 NOP 250 outb %al,$ IO_ICU2+1 251 NOP 252 inb $0x84,%al 253 movzwl _cpl,%eax # return old priority 254 movw %dx,_cpl # set new priority level 255 sti # enable interrupts 256 ret 257 258 .globl _splnone 259 .globl _spl0 260_splnone: 261_spl0: 262 cli # disable interrupts 263 pushl _cpl # save old priority 264 movw _cpl,%ax 265 orw _netmask,%ax # mask off those network devices 266 movw %ax,_cpl # set new priority level 267 orw _imen,%ax # mask off those not enabled yet 268 NOP 269 outb %al,$ IO_ICU1+1 /* update icu's */ 270 NOP 271 movb %ah,%al 272 NOP 273 outb %al,$ IO_ICU2+1 274 NOP 275 inb $0x84,%al 276 sti # enable interrupts 277 278 DONET(NETISR_RAW,_rawintr) 279#ifdef INET 280 DONET(NETISR_IP,_ipintr) 281#endif 282 cli # disable interrupts 283 popl _cpl # save old priority 284 movw $0,%ax # set new priority level 285 movw %ax,%dx 286 orw _imen,%ax # mask off those not enabled yet 287 movw %ax,%cx 288 NOP 289 outb %al,$ IO_ICU1+1 /* update icu's */ 290 NOP 291 movb %ah,%al 292 NOP 293 outb %al,$ IO_ICU2+1 294 NOP 295 inb $0x84,%al 296 movzwl _cpl,%eax # return old priority 297 movw %dx,_cpl # set new priority level 298 sti # enable interrupts 299 ret 300 301 .globl _splx 302_splx: 303 cli # disable interrupts 304 movw 4(%esp),%ax # new priority level 305 movw %ax,%dx 306 cmpw $0,%dx 307 je _spl0 # going to "zero level" is special 308 309 orw _imen,%ax # mask off those not enabled yet 310 movw %ax,%cx 311 NOP 312 outb %al,$ IO_ICU1+1 /* update icu's */ 313 NOP 314 movb %ah,%al 315 NOP 316 outb %al,$ IO_ICU2+1 317 NOP 318 inb $0x84,%al 319 movzwl _cpl,%eax # return old priority 320 movw %dx,_cpl # set new priority level 321 sti # enable interrupts 322 ret 323 324#ifdef notyet 325 .globl _iml8 # mask off all but irq0-1 326_iml8: 327 cli # disable interrupts 328 movw $0xfffc,%ax # set new priority level 329 movw %ax,%dx 330 orw _imen,%ax # mask off those not enabled yet 331 movw %ax,%cx 332 NOP 333 outb %al,$ IO_ICU1+1 /* update icu's */ 334 NOP 335 movb %ah,%al 336 NOP 337 outb %al,$ IO_ICU2+1 338 NOP 339 movzwl _cpl,%eax # return old priority 340 movw %dx,_cpl # set new priority level 341 sti # enable interrupts 342 ret 343 344 .globl _iml10 # mask off all but irq0-1,8-9 345_iml10: 346 cli # disable interrupts 347 movw $0xfcf8,%ax # set new priority level 348 movw %ax,%dx 349 orw _imen,%ax # mask off those not enabled yet 350 movw %ax,%cx 351 NOP 352 outb %al,$ IO_ICU1+1 /* update icu's */ 353 NOP 354 movb %ah,%al 355 NOP 356 outb %al,$ IO_ICU2+1 357 NOP 358 movzwl _cpl,%eax # return old priority 359 movw %dx,_cpl # set new priority level 360 sti # enable interrupts 361 ret 362 363 .globl _iml11 # mask off all but irq0-1,8-10 364_iml11: 365 cli # disable interrupts 366 movw $0xf8f8,%ax # set new priority level 367 movw %ax,%dx 368 orw _imen,%ax # mask off those not enabled yet 369 movw %ax,%cx 370 NOP 371 outb %al,$ IO_ICU1+1 /* update icu's */ 372 NOP 373 movb %ah,%al 374 NOP 375 outb %al,$ IO_ICU2+1 376 NOP 377 movzwl _cpl,%eax # return old priority 378 movw %dx,_cpl # set new priority level 379 sti # enable interrupts 380 ret 381 382 .globl _iml12 # mask off all but irq0-1,8-11 383_iml12: 384 cli # disable interrupts 385 movw $0xf0f8,%ax # set new priority level 386 movw %ax,%dx 387 orw _imen,%ax # mask off those not enabled yet 388 movw %ax,%cx 389 NOP 390 outb %al,$ IO_ICU1+1 /* update icu's */ 391 NOP 392 movb %ah,%al 393 NOP 394 outb %al,$ IO_ICU2+1 395 NOP 396 movzwl _cpl,%eax # return old priority 397 movw %dx,_cpl # set new priority level 398 sti # enable interrupts 399 ret 400 401 .globl _iml13 # mask off all but irq0-1,8-12 402_iml13: 403 cli # disable interrupts 404 movw $0xe0f8,%ax # set new priority level 405 movw %ax,%dx 406 orw _imen,%ax # mask off those not enabled yet 407 movw %ax,%cx 408 NOP 409 outb %al,$ IO_ICU1+1 /* update icu's */ 410 NOP 411 movb %ah,%al 412 NOP 413 outb %al,$ IO_ICU2+1 414 NOP 415 movzwl _cpl,%eax # return old priority 416 movw %dx,_cpl # set new priority level 417 sti # enable interrupts 418 ret 419 420 .globl _iml15 # mask off all but irq0-1,8-14 421_iml15: 422 cli # disable interrupts 423 movw $0x80f8,%ax # set new priority level 424 movw %ax,%dx 425 orw _imen,%ax # mask off those not enabled yet 426 movw %ax,%cx 427 NOP 428 outb %al,$ IO_ICU1+1 /* update icu's */ 429 NOP 430 movb %ah,%al 431 NOP 432 outb %al,$ IO_ICU2+1 433 NOP 434 movzwl _cpl,%eax # return old priority 435 movw %dx,_cpl # set new priority level 436 sti # enable interrupts 437 ret 438 439 .globl _iml3 # mask off all but irq0-1,8-15 440_iml3: 441 cli # disable interrupts 442 movw $0x00f8,%ax # set new priority level 443 movw %ax,%dx 444 orw _imen,%ax # mask off those not enabled yet 445 movw %ax,%cx 446 NOP 447 outb %al,$ IO_ICU1+1 /* update icu's */ 448 NOP 449 movb %ah,%al 450 NOP 451 outb %al,$ IO_ICU2+1 452 NOP 453 movzwl _cpl,%eax # return old priority 454 movw %dx,_cpl # set new priority level 455 sti # enable interrupts 456 ret 457 458 .globl _iml4 # mask off all but irq0-1,8-15,3 459_iml4: 460 cli # disable interrupts 461 movw $0x00f0,%ax # set new priority level 462 movw %ax,%dx 463 orw _imen,%ax # mask off those not enabled yet 464 movw %ax,%cx 465 NOP 466 outb %al,$ IO_ICU1+1 /* update icu's */ 467 NOP 468 movb %ah,%al 469 NOP 470 outb %al,$ IO_ICU2+1 471 NOP 472 movzwl _cpl,%eax # return old priority 473 movw %dx,_cpl # set new priority level 474 sti # enable interrupts 475 ret 476 477 .globl _iml5 # mask off all but irq0-1,8-15,3-4 478_iml5: 479 cli # disable interrupts 480 movw $0x00e0,%ax # set new priority level 481 movw %ax,%dx 482 orw _imen,%ax # mask off those not enabled yet 483 movw %ax,%cx 484 NOP 485 outb %al,$ IO_ICU1+1 /* update icu's */ 486 NOP 487 movb %ah,%al 488 NOP 489 outb %al,$ IO_ICU2+1 490 NOP 491 movzwl _cpl,%eax # return old priority 492 movw %dx,_cpl # set new priority level 493 sti # enable interrupts 494 ret 495 496 .globl _iml6 # mask off all but irq0-1,8-15,3-5 497_iml6: 498 cli # disable interrupts 499 movw $0x00c0,%ax # set new priority level 500 movw %ax,%dx 501 orw _imen,%ax # mask off those not enabled yet 502 movw %ax,%cx 503 NOP 504 outb %al,$ IO_ICU1+1 /* update icu's */ 505 NOP 506 movb %ah,%al 507 NOP 508 outb %al,$ IO_ICU2+1 509 NOP 510 movzwl _cpl,%eax # return old priority 511 movw %dx,_cpl # set new priority level 512 sti # enable interrupts 513 ret 514 515#endif notyet 516 517 /* hardware interrupt catcher (IDT 32 - 47) */ 518 .globl _isa_strayintr 519 520IDTVEC(intr0) 521 INTR(0, _highmask, 0) ; call _isa_strayintr ; INTREXIT1 522 523IDTVEC(intr1) 524 INTR(1, _highmask, 1) ; call _isa_strayintr ; INTREXIT1 525 526IDTVEC(intr2) 527 INTR(2, _highmask, 2) ; call _isa_strayintr ; INTREXIT1 528 529IDTVEC(intr3) 530 INTR(3, _highmask, 3) ; call _isa_strayintr ; INTREXIT1 531 532IDTVEC(intr4) 533 INTR(4, _highmask, 4) ; call _isa_strayintr ; INTREXIT1 534 535IDTVEC(intr5) 536 INTR(5, _highmask, 5) ; call _isa_strayintr ; INTREXIT1 537 538IDTVEC(intr6) 539 INTR(6, _highmask, 6) ; call _isa_strayintr ; INTREXIT1 540 541IDTVEC(intr7) 542 INTR(7, _highmask, 7) ; call _isa_strayintr ; INTREXIT1 543 544 545IDTVEC(intr8) 546 INTR(8, _highmask, 8) ; call _isa_strayintr ; INTREXIT2 547 548IDTVEC(intr9) 549 INTR(9, _highmask, 9) ; call _isa_strayintr ; INTREXIT2 550 551IDTVEC(intr10) 552 INTR(10, _highmask, 10) ; call _isa_strayintr ; INTREXIT2 553 554IDTVEC(intr11) 555 INTR(11, _highmask, 11) ; call _isa_strayintr ; INTREXIT2 556 557IDTVEC(intr12) 558 INTR(12, _highmask, 12) ; call _isa_strayintr ; INTREXIT2 559 560IDTVEC(intr13) 561 INTR(13, _highmask, 13) ; call _isa_strayintr ; INTREXIT2 562 563IDTVEC(intr14) 564 INTR(14, _highmask, 14) ; call _isa_strayintr ; INTREXIT2 565 566IDTVEC(intr15) 567 INTR(15, _highmask, 15) ; call _isa_strayintr ; INTREXIT2 568 569