|
|
1.1 root 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: * Redistribution and use in source and binary forms, with or without
10: * modification, are permitted provided that the following conditions
11: * are met:
12: * 1. Redistributions of source code must retain the above copyright
1.1.1.4 ! root 13: * notice, this list of conditions and the following disclaimer.
1.1 root 14: * 2. Redistributions in binary form must reproduce the above copyright
1.1.1.4 ! root 15: * notice, this list of conditions and the following disclaimer in the
! 16: * documentation and/or other materials provided with the distribution.
1.1 root 17: * 3. All advertising materials mentioning features or use of this software
1.1.1.4 ! root 18: * must display the following acknowledgement:
1.1 root 19: * This product includes software developed by the University of
20: * California, Berkeley and its contributors.
21: * 4. Neither the name of the University nor the names of its contributors
1.1.1.4 ! root 22: * may be used to endorse or promote products derived from this software
! 23: * without specific prior written permission.
1.1 root 24: *
25: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35: * SUCH DAMAGE.
36: *
1.1.1.4 ! root 37: * from: @(#)icu.s 7.2 (Berkeley) 5/21/91
! 38: * icu.s,v 1.19 1993/07/11 14:12:40 mycroft Exp
1.1 root 39: */
40:
41: /*
42: * AT/386
43: * Vector interrupt control section
44: */
45:
1.1.1.4 ! root 46: /*
! 47: * XXX - this file is now misnamed. All spls are now soft and the only thing
! 48: * related to the hardware icu is that the bit numbering is the same in the
! 49: * soft priority masks as in the hard ones.
! 50: */
! 51:
! 52: #ifdef notyet
! 53: #include "sio.h"
! 54: #else
! 55: #define NSIO 0
! 56: #endif
! 57:
! 58: #define HIGHMASK 0xffff
! 59: #define SOFTCLOCKMASK 0x8000
! 60:
1.1 root 61: .data
62: .globl _cpl
1.1.1.4 ! root 63: _cpl: .long 0xffff # current priority (all off)
! 64: .globl _imen
1.1 root 65: _imen: .long 0xffff # interrupt mask enable (all off)
66: .globl _highmask
1.1.1.4 ! root 67: _highmask: .long HIGHMASK
1.1 root 68: .globl _ttymask
69: _ttymask: .long 0
70: .globl _biomask
71: _biomask: .long 0
72: .globl _netmask
73: _netmask: .long 0
1.1.1.4 ! root 74: .globl _impmask
! 75: _impmask: .long 0
! 76: .globl _ipending
! 77: _ipending: .long 0
! 78: vec:
! 79: .long INTRLOCAL(vec0), INTRLOCAL(vec1), INTRLOCAL(vec2)
! 80: .long INTRLOCAL(vec3), INTRLOCAL(vec4), INTRLOCAL(vec5)
! 81: .long INTRLOCAL(vec6), INTRLOCAL(vec7), INTRLOCAL(vec8)
! 82: .long INTRLOCAL(vec9), INTRLOCAL(vec10), INTRLOCAL(vec11)
! 83: .long INTRLOCAL(vec12), INTRLOCAL(vec13), INTRLOCAL(vec14)
! 84: .long INTRLOCAL(vec15)
! 85:
! 86: #define GENSPL(name, mask, event) \
! 87: .globl _spl/**/name ; \
! 88: ALIGN_TEXT ; \
! 89: _spl/**/name: ; \
! 90: COUNT_EVENT(_intrcnt_spl, event) ; \
! 91: movl _cpl,%eax ; \
! 92: movl %eax,%edx ; \
! 93: orl mask,%edx ; \
! 94: movl %edx,_cpl ; \
! 95: SHOW_CPL ; \
! 96: ret
! 97:
! 98: #define FASTSPL(mask) \
! 99: movl mask,_cpl ; \
! 100: SHOW_CPL
! 101:
! 102: #define FASTSPL_VARMASK(varmask) \
! 103: movl varmask,%eax ; \
! 104: movl %eax,_cpl ; \
! 105: SHOW_CPL
1.1 root 106:
107: .text
1.1.1.4 ! root 108:
! 109: ALIGN_TEXT
! 110: INTRLOCAL(unpend_v):
! 111: COUNT_EVENT(_intrcnt_spl, 0)
! 112: bsfl %eax,%eax # slow, but not worth optimizing
! 113: btrl %eax,_ipending
! 114: jnc INTRLOCAL(unpend_v_next) # some intr cleared the in-memory bit
! 115: SHOW_IPENDING
! 116: movl Vresume(,%eax,4),%eax
! 117: testl %eax,%eax
! 118: je INTRLOCAL(noresume)
! 119: jmp %eax
! 120:
! 121: ALIGN_TEXT
! 122: /*
! 123: * XXX - must be some fastintr, need to register those too.
! 124: */
! 125: INTRLOCAL(noresume):
! 126: #if NSIO > 0
! 127: call _softsio1
! 128: #endif
! 129: INTRLOCAL(unpend_v_next):
! 130: movl _cpl,%eax
! 131: movl %eax,%edx
! 132: notl %eax
! 133: andl _ipending,%eax
! 134: je INTRLOCAL(none_to_unpend)
! 135: jmp INTRLOCAL(unpend_v)
! 136:
1.1 root 137: /*
138: * Handle return from interrupt after device handler finishes
139: */
1.1.1.4 ! root 140: ALIGN_TEXT
1.1 root 141: doreti:
1.1.1.4 ! root 142: COUNT_EVENT(_intrcnt_spl, 1)
! 143: addl $4,%esp # discard unit arg
! 144: popl %eax # get previous priority
! 145: /*
! 146: * Now interrupt frame is a trap frame!
! 147: *
! 148: * XXX - setting up the interrupt frame to be almost a stack frame is mostly
! 149: * a waste of time.
! 150: */
! 151: movl %eax,_cpl
! 152: SHOW_CPL
! 153: movl %eax,%edx
! 154: notl %eax
! 155: andl _ipending,%eax
! 156: jne INTRLOCAL(unpend_v)
! 157: INTRLOCAL(none_to_unpend):
! 158: testl %edx,%edx # returning to zero priority?
! 159: jne 1f # nope, going to non-zero priority
! 160: movl _netisr,%eax
! 161: testl %eax,%eax # check for softint s/traps
! 162: jne 2f # there are some
! 163: jmp test_resched # XXX - schedule jumps better
! 164: COUNT_EVENT(_intrcnt_spl, 2) # XXX
! 165:
! 166: ALIGN_TEXT # XXX
! 167: 1: # XXX
! 168: COUNT_EVENT(_intrcnt_spl, 3)
! 169: popl %es
! 170: popl %ds
! 171: popal
1.1 root 172: addl $8,%esp
173: iret
174:
175: #include "../net/netisr.h"
176:
1.1.1.4 ! root 177: #define DONET(s, c, event) ; \
! 178: .globl c ; \
! 179: btrl $s,_netisr ; \
! 180: jnc 1f ; \
! 181: COUNT_EVENT(_intrcnt_spl, event) ; \
1.1 root 182: call c ; \
183: 1:
184:
1.1.1.4 ! root 185: ALIGN_TEXT
! 186: 2:
! 187: COUNT_EVENT(_intrcnt_spl, 4)
! 188: /*
! 189: * XXX - might need extra locking while testing reg copy of netisr, but
! 190: * interrupt routines setting it would not cause any new problems (since we
! 191: * don't loop, fresh bits will not be processed until the next doreti or spl0)
! 192: */
! 193: testl $~((1 << NETISR_SCLK) | (1 << NETISR_AST)),%eax
! 194: je test_ASTs # no net stuff, just temporary AST's
! 195: FASTSPL_VARMASK(_netmask)
! 196: DONET(NETISR_RAW, _rawintr, 5)
1.1 root 197: #ifdef INET
1.1.1.4 ! root 198: DONET(NETISR_IP, _ipintr, 6)
1.1 root 199: #endif
200: #ifdef IMP
1.1.1.4 ! root 201: DONET(NETISR_IMP, _impintr, 7)
1.1 root 202: #endif
203: #ifdef NS
1.1.1.4 ! root 204: DONET(NETISR_NS, _nsintr, 8)
1.1 root 205: #endif
1.1.1.4 ! root 206: #ifdef ISO
! 207: DONET(NETISR_ISO, _clnlintr, 25)
1.1.1.2 root 208: #endif
1.1.1.4 ! root 209: FASTSPL($0)
! 210: test_ASTs:
! 211: btrl $NETISR_SCLK,_netisr
! 212: jnc test_resched
! 213: COUNT_EVENT(_intrcnt_spl, 9)
! 214: FASTSPL($SOFTCLOCKMASK)
! 215: /*
! 216: * Back to an interrupt frame for a moment.
! 217: */
! 218: pushl $0 # previous cpl (probably not used)
! 219: pushl $0x7f # dummy unit number
1.1 root 220: call _softclock
1.1.1.4 ! root 221: addl $8,%esp # discard dummies
! 222: FASTSPL($0)
! 223: test_resched:
! 224: #ifdef notused1
! 225: btrl $NETISR_AST,_netisr
! 226: jnc 2f
! 227: #endif
! 228: #ifdef notused2
1.1.1.2 root 229: cmpl $0,_want_resched
230: je 2f
1.1.1.4 ! root 231: #endif
! 232: cmpl $0,_astpending # XXX - put it back in netisr to
! 233: je 2f # reduce the number of tests
! 234: testb $SEL_RPL_MASK,TRAPF_CS_OFF(%esp)
! 235: # to non-kernel (i.e., user)?
! 236: je 2f # nope, leave
! 237: COUNT_EVENT(_intrcnt_spl, 10)
! 238: movl $0,_astpending
1.1 root 239: call _trap
1.1.1.4 ! root 240: 2:
! 241: COUNT_EVENT(_intrcnt_spl, 11)
! 242: popl %es
! 243: popl %ds
1.1 root 244: popal
245: addl $8,%esp
246: iret
247:
248: /*
249: * Interrupt priority mechanism
1.1.1.4 ! root 250: * -- soft splXX masks with group mechanism (cpl)
! 251: * -- h/w masks for currently active or unused interrupts (imen)
! 252: * -- ipending = active interrupts currently masked by cpl
1.1 root 253: */
254:
1.1.1.4 ! root 255: GENSPL(bio, _biomask, 12)
! 256: GENSPL(clock, $HIGHMASK, 13) /* splclock == splhigh ex for count */
! 257: GENSPL(high, $HIGHMASK, 14)
! 258: GENSPL(imp, _impmask, 15)
! 259: GENSPL(net, _netmask, 16)
! 260: GENSPL(softclock, $SOFTCLOCKMASK, 17)
! 261: GENSPL(tty, _ttymask, 18)
1.1 root 262:
263: .globl _splnone
264: .globl _spl0
1.1.1.4 ! root 265: ALIGN_TEXT
1.1 root 266: _splnone:
267: _spl0:
1.1.1.4 ! root 268: COUNT_EVENT(_intrcnt_spl, 19)
! 269: in_spl0:
! 270: movl _cpl,%eax
! 271: pushl %eax # save old priority
! 272: testl $~((1 << NETISR_SCLK) | (1 << NETISR_AST)),_netisr
! 273: jz INTRLOCAL(over_net_stuff_for_spl0)
! 274: movl _netmask,%eax # mask off those network devices
! 275: movl %eax,_cpl # set new priority
! 276: SHOW_CPL
! 277: DONET(NETISR_RAW, _rawintr, 20)
1.1 root 278: #ifdef INET
1.1.1.4 ! root 279: DONET(NETISR_IP, _ipintr, 21)
! 280: #endif
! 281: #ifdef IMP
! 282: DONET(NETISR_IMP, _impintr, 26)
! 283: #endif
! 284: #ifdef NS
! 285: DONET(NETISR_NS, _nsintr, 27)
1.1 root 286: #endif
1.1.1.4 ! root 287: #ifdef ISO
! 288: DONET(NETISR_ISO, _clnlintr, 28)
! 289: #endif
! 290: INTRLOCAL(over_net_stuff_for_spl0):
! 291: movl $0,_cpl # set new priority
! 292: SHOW_CPL
! 293: movl _ipending,%eax
! 294: testl %eax,%eax
! 295: jne INTRLOCAL(unpend_V)
! 296: popl %eax # return old priority
1.1 root 297: ret
1.1.1.4 ! root 298:
1.1 root 299: .globl _splx
1.1.1.4 ! root 300: ALIGN_TEXT
1.1 root 301: _splx:
1.1.1.4 ! root 302: COUNT_EVENT(_intrcnt_spl, 22)
! 303: movl 4(%esp),%eax # new priority
! 304: testl %eax,%eax
! 305: je in_spl0 # going to "zero level" is special
! 306: COUNT_EVENT(_intrcnt_spl, 23)
! 307: movl _cpl,%edx # save old priority
! 308: movl %eax,_cpl # set new priority
! 309: SHOW_CPL
! 310: notl %eax
! 311: andl _ipending,%eax
! 312: jne INTRLOCAL(unpend_V_result_edx)
! 313: movl %edx,%eax # return old priority
1.1 root 314: ret
315:
1.1.1.4 ! root 316: ALIGN_TEXT
! 317: INTRLOCAL(unpend_V_result_edx):
! 318: pushl %edx
! 319: INTRLOCAL(unpend_V):
! 320: COUNT_EVENT(_intrcnt_spl, 24)
! 321: bsfl %eax,%eax
! 322: btrl %eax,_ipending
! 323: jnc INTRLOCAL(unpend_V_next)
! 324: SHOW_IPENDING
! 325: movl Vresume(,%eax,4),%edx
! 326: testl %edx,%edx
! 327: je INTRLOCAL(noresumeV)
! 328: /*
! 329: * We would prefer to call the intr handler directly here but that doesn't
! 330: * work for badly behaved handlers that want the interrupt frame. Also,
! 331: * there's a problem determining the unit number. We should change the
! 332: * interface so that the unit number is not determined at config time.
! 333: */
! 334: jmp *vec(,%eax,4)
1.1 root 335:
1.1.1.4 ! root 336: ALIGN_TEXT
! 337: /*
! 338: * XXX - must be some fastintr, need to register those too.
! 339: */
! 340: INTRLOCAL(noresumeV):
! 341: #if NSIO > 0
! 342: call _softsio1
! 343: #endif
! 344: INTRLOCAL(unpend_V_next):
! 345: movl _cpl,%eax
! 346: notl %eax
! 347: andl _ipending,%eax
! 348: jne INTRLOCAL(unpend_V)
! 349: popl %eax
! 350: ret
1.1 root 351:
1.1.1.4 ! root 352: #define BUILD_VEC(irq_num) \
! 353: ALIGN_TEXT ; \
! 354: INTRLOCAL(vec/**/irq_num): ; \
! 355: int $ICU_OFFSET + (irq_num) ; \
! 356: popl %eax ; \
! 357: ret
1.1 root 358:
1.1.1.4 ! root 359: BUILD_VEC(0)
! 360: BUILD_VEC(1)
! 361: BUILD_VEC(2)
! 362: BUILD_VEC(3)
! 363: BUILD_VEC(4)
! 364: BUILD_VEC(5)
! 365: BUILD_VEC(6)
! 366: BUILD_VEC(7)
! 367: BUILD_VEC(8)
! 368: BUILD_VEC(9)
! 369: BUILD_VEC(10)
! 370: BUILD_VEC(11)
! 371: BUILD_VEC(12)
! 372: BUILD_VEC(13)
! 373: BUILD_VEC(14)
! 374: BUILD_VEC(15)
1.1 root 375:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.