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 7.4 (Berkeley) 02/28/92 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 nop 43 popl %eax # get previous priority 44 nop 45 # now interrupt frame is a trap frame! 46 movw %ax,%cx 47 movw %ax,_cpl 48 orw _imen,%ax 49 outb %al,$ IO_ICU1+1 # re-enable intr? 50 movb %ah,%al 51 outb %al,$ IO_ICU2+1 52 53 # andw $0xffff,%cx 54 cmpw $0,%cx # returning to zero? 55 je 1f 56 572: popl %es # nope, going to non-zero level 58 nop 59 popl %ds 60 nop 61 popal 62 nop 63 addl $8,%esp 64 iret 65 661: cmpl $0,_netisr # check for softint s/traps 67 je 2b 68 69#include "../net/netisr.h" 70 711: 72 73#define DONET(s, c) ; \ 74 .globl c ; \ 75 btrl $ s ,_netisr ; \ 76 jnb 1f ; \ 77 call c ; \ 781: 79 80 call _splnet 81 pushl %eax 82 83 84 DONET(NETISR_RAW,_rawintr) 85#ifdef INET 86 DONET(NETISR_IP,_ipintr) 87 DONET(NETISR_ARP,_arpintr) 88#endif 89#ifdef IMP 90 DONET(NETISR_IMP,_impintr) 91#endif 92#ifdef NS 93 DONET(NETISR_NS,_nsintr) 94#endif 95#ifdef ISO 96 DONET(NETISR_ISO,_clnlintr) 97#endif 98#ifdef CCITT 99 DONET(NETISR_CCITT,_hdintr) 100#endif 101 102 /* restore interrupt state, but don't turn them on just yet */ 103 cli 104 popl %eax 105 nop 106 movw %ax,_cpl 107 orw _imen,%ax 108 outb %al,$ IO_ICU1+1 # re-enable intr? 109 movb %ah,%al 110 outb %al,$ IO_ICU2+1 111 112 btrl $ NETISR_SCLK,_netisr 113 jnb 1f 114 # back to an interrupt frame for a moment 115 call _splsoftclock 116 pushl %eax 117 pushl $0xff # dummy intr 118 call _softclock 119 popl %eax 120 nop 121 call _splx 122 popl %eax 123 nop 124 125 jmp 2f 126 1271: 128 cmpw $0x1f,13*4(%esp) # to user? 129 jne 2f # nope, leave 130 btrl $ NETISR_AST ,_netisr 131 jnb 2f 132 call _trap 133 1342: pop %es 135 nop 136 pop %ds 137 nop 138 popal 139 nop 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 outb %al,$ IO_ICU1+1 /* update icu's */ 160 movb %ah,%al 161 outb %al,$ IO_ICU2+1 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 outb %al,$ IO_ICU1+1 /* update icu's */ 176 movb %ah,%al 177 outb %al,$ IO_ICU2+1 178 movzwl _cpl,%eax # return old priority 179 movw %dx,_cpl # set new priority level 180 sti # enable interrupts 181 ret 182 183 .globl _splimp 184 .globl _splnet 185_splimp: 186_splnet: 187 cli # disable interrupts 188 movw _cpl,%ax 189 orw _netmask,%ax 190 movw %ax,%dx 191 orw _imen,%ax # mask off those not enabled yet 192 movw %ax,%cx 193 outb %al,$ IO_ICU1+1 /* update icu's */ 194 movb %ah,%al 195 outb %al,$ IO_ICU2+1 196 movzwl _cpl,%eax # return old priority 197 movw %dx,_cpl # set new priority level 198 sti # enable interrupts 199 ret 200 201 .globl _splbio 202_splbio: 203 cli # disable interrupts 204 movw _cpl,%ax 205 orw _biomask,%ax 206 movw %ax,%dx 207 orw _imen,%ax # mask off those not enabled yet 208 movw %ax,%cx 209 outb %al,$ IO_ICU1+1 /* update icu's */ 210 movb %ah,%al 211 outb %al,$ IO_ICU2+1 212 movzwl _cpl,%eax # return old priority 213 movw %dx,_cpl # set new priority level 214 sti # enable interrupts 215 ret 216 217 .globl _splsoftclock 218_splsoftclock: 219 cli # disable interrupts 220 movw _cpl,%ax 221 orw $0x8000,%ax # set new priority level 222 movw %ax,%dx 223 orw _imen,%ax # mask off those not enabled yet 224 movw %ax,%cx 225 outb %al,$ IO_ICU1+1 /* update icu's */ 226 movb %ah,%al 227 outb %al,$ IO_ICU2+1 228 movzwl _cpl,%eax # return old priority 229 movw %dx,_cpl # set new priority level 230 sti # enable interrupts 231 ret 232 233 .globl _splnone 234 .globl _spl0 235_splnone: 236_spl0: 237 cli # disable interrupts 238 pushl _cpl # save old priority 239 movw _cpl,%ax 240 orw _netmask,%ax # mask off those network devices 241 movw %ax,_cpl # set new priority level 242 orw _imen,%ax # mask off those not enabled yet 243 outb %al,$ IO_ICU1+1 /* update icu's */ 244 movb %ah,%al 245 outb %al,$ IO_ICU2+1 246 sti # enable interrupts 247 248 DONET(NETISR_RAW,_rawintr) 249#ifdef INET 250 DONET(NETISR_IP,_ipintr) 251 DONET(NETISR_ARP,_arpintr) 252#endif 253#ifdef IMP 254 DONET(NETISR_IMP,_impintr) 255#endif 256#ifdef NS 257 DONET(NETISR_NS,_nsintr) 258#endif 259#ifdef ISO 260 DONET(NETISR_ISO,_clnlintr) 261#endif 262#ifdef CCITT 263 DONET(NETISR_CCITT,_hdintr) 264#endif 265 266 cli # disable interrupts 267 popl _cpl # save old priority 268 nop 269 270 movw $0,%ax # set new priority level 271 movw %ax,%dx 272 orw _imen,%ax # mask off those not enabled yet 273 movw %ax,%cx 274 outb %al,$ IO_ICU1+1 /* update icu's */ 275 movb %ah,%al 276 outb %al,$ IO_ICU2+1 277 movzwl _cpl,%eax # return old priority 278 movw %dx,_cpl # set new priority level 279 sti # enable interrupts 280 ret 281 282 .globl _splx 283_splx: 284 cli # disable interrupts 285 movw 4(%esp),%ax # new priority level 286 movw %ax,%dx 287 cmpw $0,%dx 288 je _spl0 # going to "zero level" is special 289 290 orw _imen,%ax # mask off those not enabled yet 291 movw %ax,%cx 292 outb %al,$ IO_ICU1+1 /* update icu's */ 293 movb %ah,%al 294 outb %al,$ IO_ICU2+1 295 movzwl _cpl,%eax # return old priority 296 movw %dx,_cpl # set new priority level 297 sti # enable interrupts 298 ret 299 300 /* hardware interrupt catcher (IDT 32 - 47) */ 301 .globl _isa_strayintr 302 303IDTVEC(intr0) 304 INTR(0, _highmask, 0) ; call _isa_strayintr ; INTREXIT1 305 306IDTVEC(intr1) 307 INTR(1, _highmask, 1) ; call _isa_strayintr ; INTREXIT1 308 309IDTVEC(intr2) 310 INTR(2, _highmask, 2) ; call _isa_strayintr ; INTREXIT1 311 312IDTVEC(intr3) 313 INTR(3, _highmask, 3) ; call _isa_strayintr ; INTREXIT1 314 315IDTVEC(intr4) 316 INTR(4, _highmask, 4) ; call _isa_strayintr ; INTREXIT1 317 318IDTVEC(intr5) 319 INTR(5, _highmask, 5) ; call _isa_strayintr ; INTREXIT1 320 321IDTVEC(intr6) 322 INTR(6, _highmask, 6) ; call _isa_strayintr ; INTREXIT1 323 324IDTVEC(intr7) 325 INTR(7, _highmask, 7) ; call _isa_strayintr ; INTREXIT1 326 327 328IDTVEC(intr8) 329 INTR(8, _highmask, 8) ; call _isa_strayintr ; INTREXIT2 330 331IDTVEC(intr9) 332 INTR(9, _highmask, 9) ; call _isa_strayintr ; INTREXIT2 333 334IDTVEC(intr10) 335 INTR(10, _highmask, 10) ; call _isa_strayintr ; INTREXIT2 336 337IDTVEC(intr11) 338 INTR(11, _highmask, 11) ; call _isa_strayintr ; INTREXIT2 339 340IDTVEC(intr12) 341 INTR(12, _highmask, 12) ; call _isa_strayintr ; INTREXIT2 342 343IDTVEC(intr13) 344 INTR(13, _highmask, 13) ; call _isa_strayintr ; INTREXIT2 345 346IDTVEC(intr14) 347 INTR(14, _highmask, 14) ; call _isa_strayintr ; INTREXIT2 348 349IDTVEC(intr15) 350 INTR(15, _highmask, 15) ; call _isa_strayintr ; INTREXIT2 351 352