1 /* $NetBSD: int.c,v 1.27 2014/06/03 12:15:00 macallan Exp $ */ 2 3 /* 4 * Copyright (c) 2009 Stephen M. Rumble 5 * Copyright (c) 2004 Christopher SEKIYA 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. The name of the author may not be used to endorse or promote products 17 * derived from this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 /* 32 * INT1/INT2/INT3 interrupt controllers (IP6, IP10, IP12, IP20, IP22, IP24...) 33 */ 34 35 #include <sys/cdefs.h> 36 __KERNEL_RCSID(0, "$NetBSD: int.c,v 1.27 2014/06/03 12:15:00 macallan Exp $"); 37 38 #define __INTR_PRIVATE 39 #include "opt_cputype.h" 40 41 #include <sys/param.h> 42 #include <sys/proc.h> 43 #include <sys/systm.h> 44 #include <sys/timetc.h> 45 #include <sys/kernel.h> 46 #include <sys/device.h> 47 #include <sys/malloc.h> 48 49 #include <dev/ic/i8253reg.h> 50 #include <machine/sysconf.h> 51 #include <machine/machtype.h> 52 #include <sys/bus.h> 53 #include <mips/locore.h> 54 55 #include <mips/cache.h> 56 57 #include <sgimips/dev/int1reg.h> 58 #include <sgimips/dev/int2reg.h> 59 #include <sgimips/dev/int2var.h> 60 61 static bus_space_handle_t ioh; 62 static bus_space_tag_t iot; 63 64 static int int_match(device_t, cfdata_t, void *); 65 static void int_attach(device_t, device_t, void *); 66 static void *int1_intr_establish(int, int, int (*)(void *), void *); 67 static void *int2_intr_establish(int, int, int (*)(void *), void *); 68 static void int1_local_intr(vaddr_t, uint32_t, uint32_t); 69 static void int2_local0_intr(vaddr_t, uint32_t, uint32_t); 70 static void int2_local1_intr(vaddr_t, uint32_t, uint32_t); 71 static int int2_mappable_intr(void *); 72 static void int_8254_cal(void); 73 static u_int int_8254_get_timecount(struct timecounter *); 74 static void int_8254_intr0(vaddr_t, uint32_t, uint32_t); 75 static void int_8254_intr1(vaddr_t, uint32_t, uint32_t); 76 77 #ifdef MIPS3 78 static u_long int2_cpu_freq(device_t); 79 static u_long int2_cal_timer(void); 80 #endif 81 82 static struct timecounter int_8254_timecounter = { 83 int_8254_get_timecount, /* get_timecount */ 84 0, /* no poll_pps */ 85 ~0u, /* counter_mask */ 86 0, /* frequency; set in int_8254_cal */ 87 "int i8254", /* name */ 88 100, /* quality */ 89 NULL, /* prev */ 90 NULL, /* next */ 91 }; 92 93 static u_long int_8254_tc_count; 94 95 CFATTACH_DECL_NEW(int, 0, 96 int_match, int_attach, NULL, NULL); 97 98 static int 99 int_match(device_t parent, cfdata_t match, void *aux) 100 { 101 102 switch (mach_type) { 103 case MACH_SGI_IP6 | MACH_SGI_IP10: 104 case MACH_SGI_IP12: 105 case MACH_SGI_IP20: 106 case MACH_SGI_IP22: 107 return 1; 108 } 109 110 return 0; 111 } 112 113 static void 114 int_attach(device_t parent, device_t self, void *aux) 115 { 116 uint32_t address; 117 118 switch (mach_type) { 119 case MACH_SGI_IP6 | MACH_SGI_IP10: 120 address = INT1_IP6_IP10; 121 break; 122 123 case MACH_SGI_IP12: 124 address = INT2_IP12; 125 break; 126 127 case MACH_SGI_IP20: 128 address = INT2_IP20; 129 break; 130 131 case MACH_SGI_IP22: 132 if (mach_subtype == MACH_SGI_IP22_FULLHOUSE) 133 address = INT2_IP22; 134 else 135 address = INT2_IP24; 136 break; 137 138 default: 139 panic("\nint0: passed match, but failed attach?"); 140 } 141 142 printf(" addr 0x%x\n", address); 143 144 bus_space_map(iot, address, 0, 0, &ioh); 145 iot = SGIMIPS_BUS_SPACE_NORMAL; 146 147 switch (mach_type) { 148 case MACH_SGI_IP6 | MACH_SGI_IP10: 149 /* Clean out interrupt masks */ 150 bus_space_write_1(iot, ioh, INT1_LOCAL_MASK, 0); 151 152 /* Turn off timers and clear interrupts */ 153 bus_space_write_1(iot, ioh, INT1_TIMER_CONTROL, 154 (TIMER_SEL0 | TIMER_16BIT | TIMER_SWSTROBE)); 155 bus_space_write_1(iot, ioh, INT1_TIMER_CONTROL, 156 (TIMER_SEL1 | TIMER_16BIT | TIMER_SWSTROBE)); 157 bus_space_write_1(iot, ioh, INT1_TIMER_CONTROL, 158 (TIMER_SEL2 | TIMER_16BIT | TIMER_SWSTROBE)); 159 wbflush(); 160 delay(4); 161 bus_space_read_1(iot, ioh, INT1_TIMER_0_ACK); 162 bus_space_read_1(iot, ioh, INT1_TIMER_1_ACK); 163 164 platform.intr_establish = int1_intr_establish; 165 platform.intr1 = int1_local_intr; 166 platform.intr2 = int_8254_intr0; 167 platform.intr4 = int_8254_intr1; 168 int_8254_cal(); 169 break; 170 171 case MACH_SGI_IP12: 172 case MACH_SGI_IP20: 173 case MACH_SGI_IP22: 174 /* Clean out interrupt masks */ 175 bus_space_write_1(iot, ioh, INT2_LOCAL0_MASK, 0); 176 bus_space_write_1(iot, ioh, INT2_LOCAL1_MASK, 0); 177 bus_space_write_1(iot, ioh, INT2_MAP_MASK0, 0); 178 bus_space_write_1(iot, ioh, INT2_MAP_MASK1, 0); 179 180 /* Reset timer interrupts */ 181 bus_space_write_1(iot, ioh, INT2_TIMER_CONTROL, 182 (TIMER_SEL0 | TIMER_16BIT | TIMER_SWSTROBE)); 183 bus_space_write_1(iot, ioh, INT2_TIMER_CONTROL, 184 (TIMER_SEL1 | TIMER_16BIT | TIMER_SWSTROBE)); 185 bus_space_write_1(iot, ioh, INT2_TIMER_CONTROL, 186 (TIMER_SEL2 | TIMER_16BIT | TIMER_SWSTROBE)); 187 wbflush(); 188 delay(4); 189 bus_space_write_1(iot, ioh, INT2_TIMER_CLEAR, 0x03); 190 191 if (mach_type == MACH_SGI_IP12) { 192 platform.intr_establish = int2_intr_establish; 193 platform.intr1 = int2_local0_intr; 194 platform.intr2 = int2_local1_intr; 195 platform.intr3 = int_8254_intr0; 196 platform.intr4 = int_8254_intr1; 197 int_8254_cal(); 198 } else { 199 platform.intr_establish = int2_intr_establish; 200 platform.intr0 = int2_local0_intr; 201 platform.intr1 = int2_local1_intr; 202 #ifdef MIPS3 203 curcpu()->ci_cpu_freq = int2_cpu_freq(self); 204 #endif 205 } 206 break; 207 208 default: 209 panic("int0: unsupported machine type %i\n", mach_type); 210 } 211 212 curcpu()->ci_cycles_per_hz = curcpu()->ci_cpu_freq / (2 * hz); 213 curcpu()->ci_divisor_delay = curcpu()->ci_cpu_freq / (2 * 1000000); 214 215 if (mach_type == MACH_SGI_IP22) { 216 /* Wire interrupts 7, 11 to mappable interrupt 0,1 handlers */ 217 intrtab[7].ih_fun = int2_mappable_intr; 218 intrtab[7].ih_arg = (void*) 0; 219 220 intrtab[11].ih_fun = int2_mappable_intr; 221 intrtab[11].ih_arg = (void*) 1; 222 } 223 } 224 225 int 226 int2_mappable_intr(void *arg) 227 { 228 int i; 229 int ret; 230 int intnum; 231 uint32_t mstat; 232 uint32_t mmask; 233 int which = (intptr_t)arg; 234 struct sgimips_intrhand *ih; 235 236 ret = 0; 237 mstat = bus_space_read_1(iot, ioh, INT2_MAP_STATUS); 238 mmask = bus_space_read_1(iot, ioh, INT2_MAP_MASK0 + (which << 2)); 239 240 mstat &= mmask; 241 242 for (i = 0; i < 8; i++) { 243 intnum = i + 16 + (which << 3); 244 if (mstat & (1 << i)) { 245 for (ih = &intrtab[intnum]; ih != NULL; 246 ih = ih->ih_next) { 247 if (ih->ih_fun != NULL) 248 ret |= (ih->ih_fun)(ih->ih_arg); 249 else 250 printf("int0: unexpected mapped " 251 "interrupt %d\n", intnum); 252 } 253 } 254 } 255 256 return ret; 257 } 258 259 static void 260 int1_local_intr(vaddr_t pc, uint32_t status, uint32_t ipend) 261 { 262 int i; 263 uint16_t stat; 264 uint8_t mask; 265 struct sgimips_intrhand *ih; 266 267 stat = bus_space_read_2(iot, ioh, INT1_LOCAL_STATUS); 268 mask = bus_space_read_1(iot, ioh, INT1_LOCAL_MASK); 269 270 /* for STATUS, a 0 bit means interrupt is pending */ 271 stat = ~stat & mask; 272 273 for (i = 0; stat != 0; i++, stat >>= 1) { 274 if (stat & 1) { 275 for (ih = &intrtab[i]; ih != NULL; ih = ih->ih_next) { 276 if (ih->ih_fun != NULL) 277 (ih->ih_fun)(ih->ih_arg); 278 else 279 printf("int0: unexpected local " 280 "interrupt %d\n", i); 281 } 282 } 283 } 284 } 285 286 void 287 int2_local0_intr(vaddr_t pc, uint32_t status, uint32_t ipending) 288 { 289 int i; 290 uint32_t l0stat; 291 uint32_t l0mask; 292 struct sgimips_intrhand *ih; 293 294 l0stat = bus_space_read_1(iot, ioh, INT2_LOCAL0_STATUS); 295 l0mask = bus_space_read_1(iot, ioh, INT2_LOCAL0_MASK); 296 297 l0stat &= l0mask; 298 299 for (i = 0; i < 8; i++) { 300 if (l0stat & (1 << i)) { 301 for (ih = &intrtab[i]; ih != NULL; ih = ih->ih_next) { 302 if (ih->ih_fun != NULL) 303 (ih->ih_fun)(ih->ih_arg); 304 else 305 printf("int0: unexpected local0 " 306 "interrupt %d\n", i); 307 } 308 } 309 } 310 } 311 312 void 313 int2_local1_intr(vaddr_t pc, uint32_t status, uint32_t ipending) 314 { 315 int i; 316 uint32_t l1stat; 317 uint32_t l1mask; 318 struct sgimips_intrhand *ih; 319 320 l1stat = bus_space_read_1(iot, ioh, INT2_LOCAL1_STATUS); 321 l1mask = bus_space_read_1(iot, ioh, INT2_LOCAL1_MASK); 322 323 l1stat &= l1mask; 324 325 for (i = 0; i < 8; i++) { 326 if (l1stat & (1 << i)) { 327 for (ih = &intrtab[8+i]; ih != NULL; ih = ih->ih_next) { 328 if (ih->ih_fun != NULL) 329 (ih->ih_fun)(ih->ih_arg); 330 else 331 printf("int0: unexpected local1 " 332 " interrupt %x\n", 8 + i); 333 } 334 } 335 } 336 } 337 338 void * 339 int1_intr_establish(int level, int ipl, int (*handler) (void *), void *arg) 340 { 341 uint8_t mask; 342 343 if (level < 0 || level >= NINTR) 344 panic("invalid interrupt level"); 345 346 if (intrtab[level].ih_fun == NULL) { 347 intrtab[level].ih_fun = handler; 348 intrtab[level].ih_arg = arg; 349 intrtab[level].ih_next = NULL; 350 } else { 351 struct sgimips_intrhand *n, *ih; 352 353 ih = malloc(sizeof *ih, M_DEVBUF, M_NOWAIT); 354 if (ih == NULL) { 355 printf("int0: can't allocate handler\n"); 356 return (void *)NULL; 357 } 358 359 ih->ih_fun = handler; 360 ih->ih_arg = arg; 361 ih->ih_next = NULL; 362 363 for (n = &intrtab[level]; n->ih_next != NULL; n = n->ih_next) 364 ; 365 366 n->ih_next = ih; 367 368 return NULL; /* vector already set */ 369 } 370 371 if (level < 8) { 372 mask = bus_space_read_1(iot, ioh, INT1_LOCAL_MASK); 373 mask |= (1 << level); 374 bus_space_write_1(iot, ioh, INT1_LOCAL_MASK, mask); 375 } else { 376 printf("int0: level >= 16 (%d)\n", level); 377 } 378 379 return NULL; 380 } 381 382 void * 383 int2_intr_establish(int level, int ipl, int (*handler) (void *), void *arg) 384 { 385 uint32_t mask; 386 387 if (level < 0 || level >= NINTR) 388 panic("invalid interrupt level"); 389 390 if (intrtab[level].ih_fun == NULL) { 391 intrtab[level].ih_fun = handler; 392 intrtab[level].ih_arg = arg; 393 intrtab[level].ih_next = NULL; 394 } else { 395 struct sgimips_intrhand *n, *ih; 396 397 ih = malloc(sizeof *ih, M_DEVBUF, M_NOWAIT); 398 if (ih == NULL) { 399 printf("int0: can't allocate handler\n"); 400 return NULL; 401 } 402 403 ih->ih_fun = handler; 404 ih->ih_arg = arg; 405 ih->ih_next = NULL; 406 407 for (n = &intrtab[level]; n->ih_next != NULL; n = n->ih_next) 408 ; 409 410 n->ih_next = ih; 411 412 return NULL; /* vector already set */ 413 } 414 415 if (level < 8) { 416 mask = bus_space_read_1(iot, ioh, INT2_LOCAL0_MASK); 417 mask |= (1 << level); 418 bus_space_write_1(iot, ioh, INT2_LOCAL0_MASK, mask); 419 } else if (level < 16) { 420 mask = bus_space_read_1(iot, ioh, INT2_LOCAL1_MASK); 421 mask |= (1 << (level - 8)); 422 bus_space_write_1(iot, ioh, INT2_LOCAL1_MASK, mask); 423 } else if (level < 24) { 424 /* Map0 interrupt maps to l0 bit 7, so turn that on too */ 425 mask = bus_space_read_1(iot, ioh, INT2_LOCAL0_MASK); 426 mask |= (1 << 7); 427 bus_space_write_1(iot, ioh, INT2_LOCAL0_MASK, mask); 428 429 mask = bus_space_read_1(iot, ioh, INT2_MAP_MASK0); 430 mask |= (1 << (level - 16)); 431 bus_space_write_1(iot, ioh, INT2_MAP_MASK0, mask); 432 } else { 433 /* Map1 interrupt maps to l1 bit 3, so turn that on too */ 434 mask = bus_space_read_1(iot, ioh, INT2_LOCAL1_MASK); 435 mask |= (1 << 3); 436 bus_space_write_1(iot, ioh, INT2_LOCAL1_MASK, mask); 437 438 mask = bus_space_read_1(iot, ioh, INT2_MAP_MASK1); 439 mask |= (1 << (level - 24)); 440 bus_space_write_1(iot, ioh, INT2_MAP_MASK1, mask); 441 } 442 443 return NULL; 444 } 445 446 #ifdef MIPS3 447 static u_long 448 int2_cpu_freq(device_t self) 449 { 450 int i; 451 unsigned long cps; 452 unsigned long ctrdiff[3]; 453 454 /* calibrate timer */ 455 int2_cal_timer(); 456 457 cps = 0; 458 for (i = 0; 459 i < sizeof(ctrdiff) / sizeof(ctrdiff[0]); i++) { 460 do { 461 ctrdiff[i] = int2_cal_timer(); 462 } while (ctrdiff[i] == 0); 463 464 cps += ctrdiff[i]; 465 } 466 467 cps = cps / (sizeof(ctrdiff) / sizeof(ctrdiff[0])); 468 469 printf("%s: bus %luMHz, CPU %luMHz\n", 470 device_xname(self), cps / 10000, cps / 5000); 471 472 /* R4k/R4400/R4600/R5k count at half CPU frequency */ 473 return (2 * cps * hz); 474 } 475 476 static u_long 477 int2_cal_timer(void) 478 { 479 int s; 480 int roundtime; 481 int sampletime; 482 int msb; 483 unsigned long startctr, endctr; 484 485 /* 486 * NOTE: HZ must be greater than 15 for this to work, as otherwise 487 * we'll overflow the counter. We round the answer to nearest 1 488 * MHz of the master (2x) clock. 489 */ 490 roundtime = (1000000 / hz) / 2; 491 sampletime = (1000000 / hz) + 0xff; 492 493 s = splhigh(); 494 495 bus_space_write_1(iot, ioh, INT2_TIMER_CONTROL, 496 (TIMER_SEL2 | TIMER_16BIT | TIMER_RATEGEN)); 497 bus_space_write_1(iot, ioh, INT2_TIMER_2, (sampletime & 0xff)); 498 bus_space_write_1(iot, ioh, INT2_TIMER_2, (sampletime >> 8)); 499 500 startctr = mips3_cp0_count_read(); 501 502 /* Wait for the MSB to count down to zero */ 503 do { 504 bus_space_write_1(iot, ioh, INT2_TIMER_CONTROL, TIMER_SEL2); 505 (void)bus_space_read_1(iot, ioh, INT2_TIMER_2); 506 msb = bus_space_read_1(iot, ioh, INT2_TIMER_2) & 0xff; 507 508 endctr = mips3_cp0_count_read(); 509 } while (msb); 510 511 /* Turn off timer */ 512 bus_space_write_1(iot, ioh, INT2_TIMER_CONTROL, 513 (TIMER_SEL2 | TIMER_16BIT | TIMER_SWSTROBE)); 514 515 splx(s); 516 517 return (endctr - startctr) / roundtime * roundtime; 518 } 519 #endif /* MIPS3 */ 520 521 /* 522 * A master clock is wired to TIMER_2, which in turn clocks the two other 523 * timers. The master frequencies are as follows: 524 * IP6, IP10: 3.6864MHz 525 * IP12, IP20, IP22: 1MHz 526 * IP17: 10MHz 527 * 528 * TIMER_0 and TIMER_1 interrupts are tied to MIPS interrupts as follows: 529 * IP6, IP10: TIMER_0: INT2, TIMER_1: INT4 530 * IP12: TIMER_0: INT3, TIMER_1: INT4 531 * IP17, IP20, IP22: TIMER_0: INT2, TIMER_1: INT3 532 * 533 * NB: Apparently int2 doesn't like counting down from one, but two works. 534 */ 535 void 536 int_8254_cal(void) 537 { 538 bus_size_t timer_control, timer_0, timer_1, timer_2; 539 int s; 540 541 switch (mach_type) { 542 case MACH_SGI_IP6 | MACH_SGI_IP10: 543 int_8254_timecounter.tc_frequency = 3686400 / 8; 544 timer_control = INT1_TIMER_CONTROL; 545 timer_0 = INT1_TIMER_0; 546 timer_1 = INT1_TIMER_1; 547 timer_2 = INT1_TIMER_2; 548 break; 549 550 case MACH_SGI_IP12: 551 int_8254_timecounter.tc_frequency = 1000000 / 8; 552 timer_control = INT2_TIMER_CONTROL; 553 timer_0 = INT2_TIMER_0; 554 timer_1 = INT2_TIMER_1; 555 timer_2 = INT2_TIMER_2; 556 break; 557 558 default: 559 panic("int_8254_cal"); 560 } 561 562 s = splhigh(); 563 564 /* Timer0 is our hz. */ 565 bus_space_write_1(iot, ioh, timer_control, 566 TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT); 567 bus_space_write_1(iot, ioh, timer_0, 568 (int_8254_timecounter.tc_frequency / hz) % 256); 569 wbflush(); 570 delay(4); 571 bus_space_write_1(iot, ioh, timer_0, 572 (int_8254_timecounter.tc_frequency / hz) / 256); 573 574 /* Timer1 is for timecounting. */ 575 bus_space_write_1(iot, ioh, timer_control, 576 TIMER_SEL1 | TIMER_RATEGEN | TIMER_16BIT); 577 bus_space_write_1(iot, ioh, timer_1, 0xff); 578 wbflush(); 579 delay(4); 580 bus_space_write_1(iot, ioh, timer_1, 0xff); 581 582 /* Timer2 clocks timer0 and timer1. */ 583 bus_space_write_1(iot, ioh, timer_control, 584 TIMER_SEL2 | TIMER_RATEGEN | TIMER_16BIT); 585 bus_space_write_1(iot, ioh, timer_2, 8); 586 wbflush(); 587 delay(4); 588 bus_space_write_1(iot, ioh, timer_2, 0); 589 590 splx(s); 591 592 tc_init(&int_8254_timecounter); 593 } 594 595 static u_int 596 int_8254_get_timecount(struct timecounter *tc) 597 { 598 int s; 599 u_int count; 600 u_char lo, hi; 601 602 s = splhigh(); 603 604 switch (mach_type) { 605 case MACH_SGI_IP6 | MACH_SGI_IP10: 606 bus_space_write_1(iot, ioh, INT1_TIMER_CONTROL, 607 TIMER_SEL1 | TIMER_LATCH); 608 lo = bus_space_read_1(iot, ioh, INT1_TIMER_1); 609 hi = bus_space_read_1(iot, ioh, INT1_TIMER_1); 610 break; 611 612 case MACH_SGI_IP12: 613 bus_space_write_1(iot, ioh, INT2_TIMER_CONTROL, 614 TIMER_SEL1 | TIMER_LATCH); 615 lo = bus_space_read_1(iot, ioh, INT2_TIMER_1); 616 hi = bus_space_read_1(iot, ioh, INT2_TIMER_1); 617 break; 618 619 default: 620 panic("int_8254_get_timecount"); 621 } 622 623 count = 0xffff - ((hi << 8) | lo); 624 splx(s); 625 626 return (int_8254_tc_count + count); 627 } 628 629 static void 630 int_8254_intr0(vaddr_t pc, uint32_t status, uint32_t ipending) 631 { 632 struct clockframe cf; 633 634 cf.pc = pc; 635 cf.sr = status; 636 cf.intr = (curcpu()->ci_idepth > 1); 637 638 hardclock(&cf); 639 640 switch (mach_type) { 641 case MACH_SGI_IP6 | MACH_SGI_IP10: 642 bus_space_read_1(iot, ioh, INT1_TIMER_0_ACK); 643 break; 644 645 case MACH_SGI_IP12: 646 bus_space_write_1(iot, ioh, INT2_TIMER_CLEAR, 0x01); 647 break; 648 649 default: 650 panic("int_8254_intr0"); 651 } 652 } 653 654 static void 655 int_8254_intr1(vaddr_t pc, uint32_t status, uint32_t ipending) 656 { 657 int s; 658 659 s = splhigh(); 660 661 int_8254_tc_count += 0xffff; 662 switch (mach_type) { 663 case MACH_SGI_IP6 | MACH_SGI_IP10: 664 bus_space_read_1(iot, ioh, INT1_TIMER_1_ACK); 665 break; 666 667 case MACH_SGI_IP12: 668 bus_space_write_1(iot, ioh, INT2_TIMER_CLEAR, 0x02); 669 break; 670 671 default: 672 panic("int_8254_intr1"); 673 } 674 675 splx(s); 676 } 677 678 void 679 int2_wait_fifo(uint32_t flag) 680 { 681 682 if (ioh == 0) 683 delay(5000); 684 else 685 while (bus_space_read_1(iot, ioh, INT2_LOCAL0_STATUS) & flag) 686 ; 687 } 688