1 /* 2 * Copyright (c) 1991 The Regents of the University of California. 3 * Copyright (c) 1996, by Steve Passe. All rights reserved. 4 * Copyright (c) 2005,2008 The DragonFly Project. All rights reserved. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The DragonFly Project 8 * by Matthew Dillon <dillon@backplane.com> 9 * 10 * This code is derived from software contributed to Berkeley by 11 * William Jolitz. 12 * 13 * Redistribution and use in source and binary forms, with or without 14 * modification, are permitted provided that the following conditions 15 * are met: 16 * 17 * 1. Redistributions of source code must retain the above copyright 18 * notice, this list of conditions and the following disclaimer. 19 * 2. Redistributions in binary form must reproduce the above copyright 20 * notice, this list of conditions and the following disclaimer in 21 * the documentation and/or other materials provided with the 22 * distribution. 23 * 3. Neither the name of The DragonFly Project nor the names of its 24 * contributors may be used to endorse or promote products derived 25 * from this software without specific, prior written permission. 26 * 27 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 28 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 29 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 30 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 31 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 32 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, 33 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 34 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 35 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 36 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 37 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 38 * SUCH DAMAGE. 39 * 40 * $DragonFly: src/sys/platform/pc64/apic/apic_abi.c,v 1.1 2008/08/29 17:07:12 dillon Exp $ 41 */ 42 43 #include <sys/param.h> 44 #include <sys/systm.h> 45 #include <sys/kernel.h> 46 #include <sys/machintr.h> 47 #include <sys/interrupt.h> 48 #include <sys/bus.h> 49 50 #include <machine/smp.h> 51 #include <machine/segments.h> 52 #include <machine/md_var.h> 53 #include <machine/intr_machdep.h> 54 #include <machine_base/icu/icu.h> 55 #include <machine/globaldata.h> 56 57 #include <sys/thread2.h> 58 59 #include <machine_base/apic/ioapic_ipl.h> 60 61 #ifdef SMP /* APIC-IO */ 62 63 extern inthand_t 64 IDTVEC(ioapic_intr0), 65 IDTVEC(ioapic_intr1), 66 IDTVEC(ioapic_intr2), 67 IDTVEC(ioapic_intr3), 68 IDTVEC(ioapic_intr4), 69 IDTVEC(ioapic_intr5), 70 IDTVEC(ioapic_intr6), 71 IDTVEC(ioapic_intr7), 72 IDTVEC(ioapic_intr8), 73 IDTVEC(ioapic_intr9), 74 IDTVEC(ioapic_intr10), 75 IDTVEC(ioapic_intr11), 76 IDTVEC(ioapic_intr12), 77 IDTVEC(ioapic_intr13), 78 IDTVEC(ioapic_intr14), 79 IDTVEC(ioapic_intr15), 80 IDTVEC(ioapic_intr16), 81 IDTVEC(ioapic_intr17), 82 IDTVEC(ioapic_intr18), 83 IDTVEC(ioapic_intr19), 84 IDTVEC(ioapic_intr20), 85 IDTVEC(ioapic_intr21), 86 IDTVEC(ioapic_intr22), 87 IDTVEC(ioapic_intr23), 88 IDTVEC(ioapic_intr24), 89 IDTVEC(ioapic_intr25), 90 IDTVEC(ioapic_intr26), 91 IDTVEC(ioapic_intr27), 92 IDTVEC(ioapic_intr28), 93 IDTVEC(ioapic_intr29), 94 IDTVEC(ioapic_intr30), 95 IDTVEC(ioapic_intr31), 96 IDTVEC(ioapic_intr32), 97 IDTVEC(ioapic_intr33), 98 IDTVEC(ioapic_intr34), 99 IDTVEC(ioapic_intr35), 100 IDTVEC(ioapic_intr36), 101 IDTVEC(ioapic_intr37), 102 IDTVEC(ioapic_intr38), 103 IDTVEC(ioapic_intr39), 104 IDTVEC(ioapic_intr40), 105 IDTVEC(ioapic_intr41), 106 IDTVEC(ioapic_intr42), 107 IDTVEC(ioapic_intr43), 108 IDTVEC(ioapic_intr44), 109 IDTVEC(ioapic_intr45), 110 IDTVEC(ioapic_intr46), 111 IDTVEC(ioapic_intr47), 112 IDTVEC(ioapic_intr48), 113 IDTVEC(ioapic_intr49), 114 IDTVEC(ioapic_intr50), 115 IDTVEC(ioapic_intr51), 116 IDTVEC(ioapic_intr52), 117 IDTVEC(ioapic_intr53), 118 IDTVEC(ioapic_intr54), 119 IDTVEC(ioapic_intr55), 120 IDTVEC(ioapic_intr56), 121 IDTVEC(ioapic_intr57), 122 IDTVEC(ioapic_intr58), 123 IDTVEC(ioapic_intr59), 124 IDTVEC(ioapic_intr60), 125 IDTVEC(ioapic_intr61), 126 IDTVEC(ioapic_intr62), 127 IDTVEC(ioapic_intr63), 128 IDTVEC(ioapic_intr64), 129 IDTVEC(ioapic_intr65), 130 IDTVEC(ioapic_intr66), 131 IDTVEC(ioapic_intr67), 132 IDTVEC(ioapic_intr68), 133 IDTVEC(ioapic_intr69), 134 IDTVEC(ioapic_intr70), 135 IDTVEC(ioapic_intr71), 136 IDTVEC(ioapic_intr72), 137 IDTVEC(ioapic_intr73), 138 IDTVEC(ioapic_intr74), 139 IDTVEC(ioapic_intr75), 140 IDTVEC(ioapic_intr76), 141 IDTVEC(ioapic_intr77), 142 IDTVEC(ioapic_intr78), 143 IDTVEC(ioapic_intr79), 144 IDTVEC(ioapic_intr80), 145 IDTVEC(ioapic_intr81), 146 IDTVEC(ioapic_intr82), 147 IDTVEC(ioapic_intr83), 148 IDTVEC(ioapic_intr84), 149 IDTVEC(ioapic_intr85), 150 IDTVEC(ioapic_intr86), 151 IDTVEC(ioapic_intr87), 152 IDTVEC(ioapic_intr88), 153 IDTVEC(ioapic_intr89), 154 IDTVEC(ioapic_intr90), 155 IDTVEC(ioapic_intr91), 156 IDTVEC(ioapic_intr92), 157 IDTVEC(ioapic_intr93), 158 IDTVEC(ioapic_intr94), 159 IDTVEC(ioapic_intr95), 160 IDTVEC(ioapic_intr96), 161 IDTVEC(ioapic_intr97), 162 IDTVEC(ioapic_intr98), 163 IDTVEC(ioapic_intr99), 164 IDTVEC(ioapic_intr100), 165 IDTVEC(ioapic_intr101), 166 IDTVEC(ioapic_intr102), 167 IDTVEC(ioapic_intr103), 168 IDTVEC(ioapic_intr104), 169 IDTVEC(ioapic_intr105), 170 IDTVEC(ioapic_intr106), 171 IDTVEC(ioapic_intr107), 172 IDTVEC(ioapic_intr108), 173 IDTVEC(ioapic_intr109), 174 IDTVEC(ioapic_intr110), 175 IDTVEC(ioapic_intr111), 176 IDTVEC(ioapic_intr112), 177 IDTVEC(ioapic_intr113), 178 IDTVEC(ioapic_intr114), 179 IDTVEC(ioapic_intr115), 180 IDTVEC(ioapic_intr116), 181 IDTVEC(ioapic_intr117), 182 IDTVEC(ioapic_intr118), 183 IDTVEC(ioapic_intr119), 184 IDTVEC(ioapic_intr120), 185 IDTVEC(ioapic_intr121), 186 IDTVEC(ioapic_intr122), 187 IDTVEC(ioapic_intr123), 188 IDTVEC(ioapic_intr124), 189 IDTVEC(ioapic_intr125), 190 IDTVEC(ioapic_intr126), 191 IDTVEC(ioapic_intr127), 192 IDTVEC(ioapic_intr128), 193 IDTVEC(ioapic_intr129), 194 IDTVEC(ioapic_intr130), 195 IDTVEC(ioapic_intr131), 196 IDTVEC(ioapic_intr132), 197 IDTVEC(ioapic_intr133), 198 IDTVEC(ioapic_intr134), 199 IDTVEC(ioapic_intr135), 200 IDTVEC(ioapic_intr136), 201 IDTVEC(ioapic_intr137), 202 IDTVEC(ioapic_intr138), 203 IDTVEC(ioapic_intr139), 204 IDTVEC(ioapic_intr140), 205 IDTVEC(ioapic_intr141), 206 IDTVEC(ioapic_intr142), 207 IDTVEC(ioapic_intr143), 208 IDTVEC(ioapic_intr144), 209 IDTVEC(ioapic_intr145), 210 IDTVEC(ioapic_intr146), 211 IDTVEC(ioapic_intr147), 212 IDTVEC(ioapic_intr148), 213 IDTVEC(ioapic_intr149), 214 IDTVEC(ioapic_intr150), 215 IDTVEC(ioapic_intr151), 216 IDTVEC(ioapic_intr152), 217 IDTVEC(ioapic_intr153), 218 IDTVEC(ioapic_intr154), 219 IDTVEC(ioapic_intr155), 220 IDTVEC(ioapic_intr156), 221 IDTVEC(ioapic_intr157), 222 IDTVEC(ioapic_intr158), 223 IDTVEC(ioapic_intr159), 224 IDTVEC(ioapic_intr160), 225 IDTVEC(ioapic_intr161), 226 IDTVEC(ioapic_intr162), 227 IDTVEC(ioapic_intr163), 228 IDTVEC(ioapic_intr164), 229 IDTVEC(ioapic_intr165), 230 IDTVEC(ioapic_intr166), 231 IDTVEC(ioapic_intr167), 232 IDTVEC(ioapic_intr168), 233 IDTVEC(ioapic_intr169), 234 IDTVEC(ioapic_intr170), 235 IDTVEC(ioapic_intr171), 236 IDTVEC(ioapic_intr172), 237 IDTVEC(ioapic_intr173), 238 IDTVEC(ioapic_intr174), 239 IDTVEC(ioapic_intr175), 240 IDTVEC(ioapic_intr176), 241 IDTVEC(ioapic_intr177), 242 IDTVEC(ioapic_intr178), 243 IDTVEC(ioapic_intr179), 244 IDTVEC(ioapic_intr180), 245 IDTVEC(ioapic_intr181), 246 IDTVEC(ioapic_intr182), 247 IDTVEC(ioapic_intr183), 248 IDTVEC(ioapic_intr184), 249 IDTVEC(ioapic_intr185), 250 IDTVEC(ioapic_intr186), 251 IDTVEC(ioapic_intr187), 252 IDTVEC(ioapic_intr188), 253 IDTVEC(ioapic_intr189), 254 IDTVEC(ioapic_intr190), 255 IDTVEC(ioapic_intr191); 256 257 static inthand_t *ioapic_intr[IOAPIC_HWI_VECTORS] = { 258 &IDTVEC(ioapic_intr0), 259 &IDTVEC(ioapic_intr1), 260 &IDTVEC(ioapic_intr2), 261 &IDTVEC(ioapic_intr3), 262 &IDTVEC(ioapic_intr4), 263 &IDTVEC(ioapic_intr5), 264 &IDTVEC(ioapic_intr6), 265 &IDTVEC(ioapic_intr7), 266 &IDTVEC(ioapic_intr8), 267 &IDTVEC(ioapic_intr9), 268 &IDTVEC(ioapic_intr10), 269 &IDTVEC(ioapic_intr11), 270 &IDTVEC(ioapic_intr12), 271 &IDTVEC(ioapic_intr13), 272 &IDTVEC(ioapic_intr14), 273 &IDTVEC(ioapic_intr15), 274 &IDTVEC(ioapic_intr16), 275 &IDTVEC(ioapic_intr17), 276 &IDTVEC(ioapic_intr18), 277 &IDTVEC(ioapic_intr19), 278 &IDTVEC(ioapic_intr20), 279 &IDTVEC(ioapic_intr21), 280 &IDTVEC(ioapic_intr22), 281 &IDTVEC(ioapic_intr23), 282 &IDTVEC(ioapic_intr24), 283 &IDTVEC(ioapic_intr25), 284 &IDTVEC(ioapic_intr26), 285 &IDTVEC(ioapic_intr27), 286 &IDTVEC(ioapic_intr28), 287 &IDTVEC(ioapic_intr29), 288 &IDTVEC(ioapic_intr30), 289 &IDTVEC(ioapic_intr31), 290 &IDTVEC(ioapic_intr32), 291 &IDTVEC(ioapic_intr33), 292 &IDTVEC(ioapic_intr34), 293 &IDTVEC(ioapic_intr35), 294 &IDTVEC(ioapic_intr36), 295 &IDTVEC(ioapic_intr37), 296 &IDTVEC(ioapic_intr38), 297 &IDTVEC(ioapic_intr39), 298 &IDTVEC(ioapic_intr40), 299 &IDTVEC(ioapic_intr41), 300 &IDTVEC(ioapic_intr42), 301 &IDTVEC(ioapic_intr43), 302 &IDTVEC(ioapic_intr44), 303 &IDTVEC(ioapic_intr45), 304 &IDTVEC(ioapic_intr46), 305 &IDTVEC(ioapic_intr47), 306 &IDTVEC(ioapic_intr48), 307 &IDTVEC(ioapic_intr49), 308 &IDTVEC(ioapic_intr50), 309 &IDTVEC(ioapic_intr51), 310 &IDTVEC(ioapic_intr52), 311 &IDTVEC(ioapic_intr53), 312 &IDTVEC(ioapic_intr54), 313 &IDTVEC(ioapic_intr55), 314 &IDTVEC(ioapic_intr56), 315 &IDTVEC(ioapic_intr57), 316 &IDTVEC(ioapic_intr58), 317 &IDTVEC(ioapic_intr59), 318 &IDTVEC(ioapic_intr60), 319 &IDTVEC(ioapic_intr61), 320 &IDTVEC(ioapic_intr62), 321 &IDTVEC(ioapic_intr63), 322 &IDTVEC(ioapic_intr64), 323 &IDTVEC(ioapic_intr65), 324 &IDTVEC(ioapic_intr66), 325 &IDTVEC(ioapic_intr67), 326 &IDTVEC(ioapic_intr68), 327 &IDTVEC(ioapic_intr69), 328 &IDTVEC(ioapic_intr70), 329 &IDTVEC(ioapic_intr71), 330 &IDTVEC(ioapic_intr72), 331 &IDTVEC(ioapic_intr73), 332 &IDTVEC(ioapic_intr74), 333 &IDTVEC(ioapic_intr75), 334 &IDTVEC(ioapic_intr76), 335 &IDTVEC(ioapic_intr77), 336 &IDTVEC(ioapic_intr78), 337 &IDTVEC(ioapic_intr79), 338 &IDTVEC(ioapic_intr80), 339 &IDTVEC(ioapic_intr81), 340 &IDTVEC(ioapic_intr82), 341 &IDTVEC(ioapic_intr83), 342 &IDTVEC(ioapic_intr84), 343 &IDTVEC(ioapic_intr85), 344 &IDTVEC(ioapic_intr86), 345 &IDTVEC(ioapic_intr87), 346 &IDTVEC(ioapic_intr88), 347 &IDTVEC(ioapic_intr89), 348 &IDTVEC(ioapic_intr90), 349 &IDTVEC(ioapic_intr91), 350 &IDTVEC(ioapic_intr92), 351 &IDTVEC(ioapic_intr93), 352 &IDTVEC(ioapic_intr94), 353 &IDTVEC(ioapic_intr95), 354 &IDTVEC(ioapic_intr96), 355 &IDTVEC(ioapic_intr97), 356 &IDTVEC(ioapic_intr98), 357 &IDTVEC(ioapic_intr99), 358 &IDTVEC(ioapic_intr100), 359 &IDTVEC(ioapic_intr101), 360 &IDTVEC(ioapic_intr102), 361 &IDTVEC(ioapic_intr103), 362 &IDTVEC(ioapic_intr104), 363 &IDTVEC(ioapic_intr105), 364 &IDTVEC(ioapic_intr106), 365 &IDTVEC(ioapic_intr107), 366 &IDTVEC(ioapic_intr108), 367 &IDTVEC(ioapic_intr109), 368 &IDTVEC(ioapic_intr110), 369 &IDTVEC(ioapic_intr111), 370 &IDTVEC(ioapic_intr112), 371 &IDTVEC(ioapic_intr113), 372 &IDTVEC(ioapic_intr114), 373 &IDTVEC(ioapic_intr115), 374 &IDTVEC(ioapic_intr116), 375 &IDTVEC(ioapic_intr117), 376 &IDTVEC(ioapic_intr118), 377 &IDTVEC(ioapic_intr119), 378 &IDTVEC(ioapic_intr120), 379 &IDTVEC(ioapic_intr121), 380 &IDTVEC(ioapic_intr122), 381 &IDTVEC(ioapic_intr123), 382 &IDTVEC(ioapic_intr124), 383 &IDTVEC(ioapic_intr125), 384 &IDTVEC(ioapic_intr126), 385 &IDTVEC(ioapic_intr127), 386 &IDTVEC(ioapic_intr128), 387 &IDTVEC(ioapic_intr129), 388 &IDTVEC(ioapic_intr130), 389 &IDTVEC(ioapic_intr131), 390 &IDTVEC(ioapic_intr132), 391 &IDTVEC(ioapic_intr133), 392 &IDTVEC(ioapic_intr134), 393 &IDTVEC(ioapic_intr135), 394 &IDTVEC(ioapic_intr136), 395 &IDTVEC(ioapic_intr137), 396 &IDTVEC(ioapic_intr138), 397 &IDTVEC(ioapic_intr139), 398 &IDTVEC(ioapic_intr140), 399 &IDTVEC(ioapic_intr141), 400 &IDTVEC(ioapic_intr142), 401 &IDTVEC(ioapic_intr143), 402 &IDTVEC(ioapic_intr144), 403 &IDTVEC(ioapic_intr145), 404 &IDTVEC(ioapic_intr146), 405 &IDTVEC(ioapic_intr147), 406 &IDTVEC(ioapic_intr148), 407 &IDTVEC(ioapic_intr149), 408 &IDTVEC(ioapic_intr150), 409 &IDTVEC(ioapic_intr151), 410 &IDTVEC(ioapic_intr152), 411 &IDTVEC(ioapic_intr153), 412 &IDTVEC(ioapic_intr154), 413 &IDTVEC(ioapic_intr155), 414 &IDTVEC(ioapic_intr156), 415 &IDTVEC(ioapic_intr157), 416 &IDTVEC(ioapic_intr158), 417 &IDTVEC(ioapic_intr159), 418 &IDTVEC(ioapic_intr160), 419 &IDTVEC(ioapic_intr161), 420 &IDTVEC(ioapic_intr162), 421 &IDTVEC(ioapic_intr163), 422 &IDTVEC(ioapic_intr164), 423 &IDTVEC(ioapic_intr165), 424 &IDTVEC(ioapic_intr166), 425 &IDTVEC(ioapic_intr167), 426 &IDTVEC(ioapic_intr168), 427 &IDTVEC(ioapic_intr169), 428 &IDTVEC(ioapic_intr170), 429 &IDTVEC(ioapic_intr171), 430 &IDTVEC(ioapic_intr172), 431 &IDTVEC(ioapic_intr173), 432 &IDTVEC(ioapic_intr174), 433 &IDTVEC(ioapic_intr175), 434 &IDTVEC(ioapic_intr176), 435 &IDTVEC(ioapic_intr177), 436 &IDTVEC(ioapic_intr178), 437 &IDTVEC(ioapic_intr179), 438 &IDTVEC(ioapic_intr180), 439 &IDTVEC(ioapic_intr181), 440 &IDTVEC(ioapic_intr182), 441 &IDTVEC(ioapic_intr183), 442 &IDTVEC(ioapic_intr184), 443 &IDTVEC(ioapic_intr185), 444 &IDTVEC(ioapic_intr186), 445 &IDTVEC(ioapic_intr187), 446 &IDTVEC(ioapic_intr188), 447 &IDTVEC(ioapic_intr189), 448 &IDTVEC(ioapic_intr190), 449 &IDTVEC(ioapic_intr191) 450 }; 451 452 #define IOAPIC_HWI_SYSCALL (IDT_OFFSET_SYSCALL - IDT_OFFSET) 453 454 static struct ioapic_irqmap { 455 int im_type; /* IOAPIC_IMT_ */ 456 enum intr_trigger im_trig; 457 int im_gsi; 458 } ioapic_irqmaps[MAX_HARDINTS]; /* XXX MAX_HARDINTS may not be correct */ 459 460 #define IOAPIC_IMT_UNUSED 0 461 #define IOAPIC_IMT_RESERVED 1 462 #define IOAPIC_IMT_LINE 2 463 #define IOAPIC_IMT_SYSCALL 3 464 465 extern void IOAPIC_INTREN(int); 466 extern void IOAPIC_INTRDIS(int); 467 468 static int ioapic_setvar(int, const void *); 469 static int ioapic_getvar(int, void *); 470 static int ioapic_vectorctl(int, int, int); 471 static void ioapic_finalize(void); 472 static void ioapic_cleanup(void); 473 static void ioapic_setdefault(void); 474 static void ioapic_stabilize(void); 475 static void ioapic_initmap(void); 476 477 static int ioapic_imcr_present; 478 479 struct machintr_abi MachIntrABI_IOAPIC = { 480 MACHINTR_IOAPIC, 481 .intrdis = IOAPIC_INTRDIS, 482 .intren = IOAPIC_INTREN, 483 .vectorctl = ioapic_vectorctl, 484 .setvar = ioapic_setvar, 485 .getvar = ioapic_getvar, 486 .finalize = ioapic_finalize, 487 .cleanup = ioapic_cleanup, 488 .setdefault = ioapic_setdefault, 489 .stabilize = ioapic_stabilize, 490 .initmap = ioapic_initmap 491 }; 492 493 static int 494 ioapic_setvar(int varid, const void *buf) 495 { 496 int error = 0; 497 498 switch(varid) { 499 case MACHINTR_VAR_IMCR_PRESENT: 500 ioapic_imcr_present = *(const int *)buf; 501 break; 502 503 default: 504 error = ENOENT; 505 break; 506 } 507 return error; 508 } 509 510 static int 511 ioapic_getvar(int varid, void *buf) 512 { 513 int error = 0; 514 515 switch(varid) { 516 case MACHINTR_VAR_IMCR_PRESENT: 517 *(int *)buf = ioapic_imcr_present; 518 break; 519 520 default: 521 error = ENOENT; 522 break; 523 } 524 return error; 525 } 526 527 /* 528 * Called from ICU's finalize if I/O APIC is enabled, after BSP's LAPIC 529 * is initialized; some of the BSP's LAPIC configuration are adjusted. 530 * 531 * - disable 'pic mode'. 532 * - disable 'virtual wire mode'. 533 * - switch MachIntrABI 534 * - enable NMI. 535 */ 536 static void 537 ioapic_finalize(void) 538 { 539 register_t ef; 540 uint32_t temp; 541 542 KKASSERT(MachIntrABI.type == MACHINTR_ICU); 543 KKASSERT(apic_io_enable); 544 545 /* 546 * If an IMCR is present, program bit 0 to disconnect the 8259 547 * from the BSP. The 8259 may still be connected to LINT0 on 548 * the BSP's LAPIC. 549 */ 550 if (ioapic_imcr_present) { 551 outb(0x22, 0x70); /* select IMCR */ 552 outb(0x23, 0x01); /* disconnect 8259 */ 553 } 554 555 /* 556 * Setup LINT0 (the 8259 'virtual wire' connection). We 557 * mask the interrupt, completing the disconnection of the 558 * 8259. 559 */ 560 temp = lapic->lvt_lint0; 561 temp |= APIC_LVT_MASKED; 562 lapic->lvt_lint0 = temp; 563 564 crit_enter(); 565 566 ef = read_rflags(); 567 cpu_disable_intr(); 568 569 /* 570 * 8259 is completely disconnected; switch to IOAPIC MachIntrABI 571 * and reconfigure the default IDT entries. 572 */ 573 MachIntrABI = MachIntrABI_IOAPIC; 574 MachIntrABI.setdefault(); 575 576 write_rflags(ef); 577 578 MachIntrABI.cleanup(); 579 580 crit_exit(); 581 582 /* 583 * Setup LINT1 to handle an NMI 584 */ 585 temp = lapic->lvt_lint1; 586 temp &= ~APIC_LVT_MASKED; 587 lapic->lvt_lint1 = temp; 588 589 if (bootverbose) 590 apic_dump("ioapic_finalize()"); 591 } 592 593 /* 594 * This routine is called after physical interrupts are enabled but before 595 * the critical section is released. We need to clean out any interrupts 596 * that had already been posted to the cpu. 597 */ 598 static void 599 ioapic_cleanup(void) 600 { 601 bzero(mdcpu->gd_ipending, sizeof(mdcpu->gd_ipending)); 602 } 603 604 /* Must never be called */ 605 static void 606 ioapic_stabilize(void) 607 { 608 panic("ioapic_stabilize is called\n"); 609 } 610 611 static int 612 ioapic_vectorctl(int op, int intr, int flags) 613 { 614 int error; 615 int vector; 616 int select; 617 uint32_t value; 618 register_t ef; 619 620 if (intr < 0 || intr >= IOAPIC_HWI_VECTORS || 621 intr == IOAPIC_HWI_SYSCALL) 622 return EINVAL; 623 624 ef = read_rflags(); 625 cpu_disable_intr(); 626 error = 0; 627 628 switch(op) { 629 case MACHINTR_VECTOR_SETUP: 630 vector = IDT_OFFSET + intr; 631 setidt(vector, ioapic_intr[intr], SDT_SYSIGT, SEL_KPL, 0); 632 633 /* 634 * Now reprogram the vector in the IO APIC. In order to avoid 635 * losing an EOI for a level interrupt, which is vector based, 636 * make sure that the IO APIC is programmed for edge-triggering 637 * first, then reprogrammed with the new vector. This should 638 * clear the IRR bit. 639 */ 640 if (int_to_apicintpin[intr].ioapic >= 0) { 641 imen_lock(); 642 643 select = int_to_apicintpin[intr].redirindex; 644 value = ioapic_read(int_to_apicintpin[intr].apic_address, 645 select); 646 value |= IOART_INTMSET; 647 648 ioapic_write(int_to_apicintpin[intr].apic_address, 649 select, (value & ~APIC_TRIGMOD_MASK)); 650 ioapic_write(int_to_apicintpin[intr].apic_address, 651 select, (value & ~IOART_INTVEC) | vector); 652 653 imen_unlock(); 654 } 655 656 machintr_intren(intr); 657 break; 658 659 case MACHINTR_VECTOR_TEARDOWN: 660 /* 661 * Teardown an interrupt vector. The vector should already be 662 * installed in the cpu's IDT, but make sure. 663 */ 664 machintr_intrdis(intr); 665 666 vector = IDT_OFFSET + intr; 667 setidt(vector, ioapic_intr[intr], SDT_SYSIGT, SEL_KPL, 0); 668 669 /* 670 * In order to avoid losing an EOI for a level interrupt, which 671 * is vector based, make sure that the IO APIC is programmed for 672 * edge-triggering first, then reprogrammed with the new vector. 673 * This should clear the IRR bit. 674 */ 675 if (int_to_apicintpin[intr].ioapic >= 0) { 676 imen_lock(); 677 678 select = int_to_apicintpin[intr].redirindex; 679 value = ioapic_read(int_to_apicintpin[intr].apic_address, 680 select); 681 682 ioapic_write(int_to_apicintpin[intr].apic_address, 683 select, (value & ~APIC_TRIGMOD_MASK)); 684 ioapic_write(int_to_apicintpin[intr].apic_address, 685 select, (value & ~IOART_INTVEC) | vector); 686 687 imen_unlock(); 688 } 689 break; 690 691 default: 692 error = EOPNOTSUPP; 693 break; 694 } 695 696 write_rflags(ef); 697 return error; 698 } 699 700 static void 701 ioapic_setdefault(void) 702 { 703 int intr; 704 705 for (intr = 0; intr < IOAPIC_HWI_VECTORS; ++intr) { 706 if (intr == IOAPIC_HWI_SYSCALL) 707 continue; 708 setidt(IDT_OFFSET + intr, ioapic_intr[intr], SDT_SYSIGT, 709 SEL_KPL, 0); 710 } 711 } 712 713 /* XXX magic number */ 714 static void 715 ioapic_initmap(void) 716 { 717 int i; 718 719 for (i = 0; i < 16; ++i) { 720 struct ioapic_irqmap *map = &ioapic_irqmaps[i]; 721 722 map->im_type = IOAPIC_IMT_LINE; 723 map->im_trig = INTR_TRIGGER_EDGE; 724 map->im_gsi = i; 725 } 726 ioapic_irqmaps[IOAPIC_HWI_SYSCALL].im_type = IOAPIC_IMT_SYSCALL; 727 } 728 729 #endif /* SMP */ 730