1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. 24 */ 25 /* 26 * Copyright (c) 2013, Joyent, Inc. All rights reserved. 27 */ 28 29 /* 30 * PSMI 1.1 extensions are supported only in 2.6 and later versions. 31 * PSMI 1.2 extensions are supported only in 2.7 and later versions. 32 * PSMI 1.3 and 1.4 extensions are supported in Solaris 10. 33 * PSMI 1.5 extensions are supported in Solaris Nevada. 34 * PSMI 1.6 extensions are supported in Solaris Nevada. 35 * PSMI 1.7 extensions are supported in Solaris Nevada. 36 */ 37 #define PSMI_1_7 38 39 #include <sys/processor.h> 40 #include <sys/time.h> 41 #include <sys/psm.h> 42 #include <sys/smp_impldefs.h> 43 #include <sys/cram.h> 44 #include <sys/acpi/acpi.h> 45 #include <sys/acpica.h> 46 #include <sys/psm_common.h> 47 #include <sys/apic.h> 48 #include <sys/pit.h> 49 #include <sys/ddi.h> 50 #include <sys/sunddi.h> 51 #include <sys/ddi_impldefs.h> 52 #include <sys/pci.h> 53 #include <sys/promif.h> 54 #include <sys/x86_archext.h> 55 #include <sys/cpc_impl.h> 56 #include <sys/uadmin.h> 57 #include <sys/panic.h> 58 #include <sys/debug.h> 59 #include <sys/archsystm.h> 60 #include <sys/trap.h> 61 #include <sys/machsystm.h> 62 #include <sys/sysmacros.h> 63 #include <sys/cpuvar.h> 64 #include <sys/rm_platter.h> 65 #include <sys/privregs.h> 66 #include <sys/note.h> 67 #include <sys/pci_intr_lib.h> 68 #include <sys/spl.h> 69 #include <sys/clock.h> 70 #include <sys/dditypes.h> 71 #include <sys/sunddi.h> 72 #include <sys/x_call.h> 73 #include <sys/reboot.h> 74 #include <sys/hpet.h> 75 #include <sys/apic_common.h> 76 #include <sys/apic_timer.h> 77 78 static void apic_record_ioapic_rdt(void *intrmap_private, 79 ioapic_rdt_t *irdt); 80 static void apic_record_msi(void *intrmap_private, msi_regs_t *mregs); 81 82 /* 83 * Common routines between pcplusmp & apix (taken from apic.c). 84 */ 85 86 int apic_clkinit(int); 87 hrtime_t apic_gethrtime(void); 88 void apic_send_ipi(int, int); 89 void apic_set_idlecpu(processorid_t); 90 void apic_unset_idlecpu(processorid_t); 91 void apic_shutdown(int, int); 92 void apic_preshutdown(int, int); 93 processorid_t apic_get_next_processorid(processorid_t); 94 95 hrtime_t apic_gettime(); 96 97 enum apic_ioapic_method_type apix_mul_ioapic_method = APIC_MUL_IOAPIC_PCPLUSMP; 98 99 /* Now the ones for Dynamic Interrupt distribution */ 100 int apic_enable_dynamic_migration = 0; 101 102 /* maximum loop count when sending Start IPIs. */ 103 int apic_sipi_max_loop_count = 0x1000; 104 105 /* 106 * These variables are frequently accessed in apic_intr_enter(), 107 * apic_intr_exit and apic_setspl, so group them together 108 */ 109 volatile uint32_t *apicadr = NULL; /* virtual addr of local APIC */ 110 int apic_setspl_delay = 1; /* apic_setspl - delay enable */ 111 int apic_clkvect; 112 113 /* vector at which error interrupts come in */ 114 int apic_errvect; 115 int apic_enable_error_intr = 1; 116 int apic_error_display_delay = 100; 117 118 /* vector at which performance counter overflow interrupts come in */ 119 int apic_cpcovf_vect; 120 int apic_enable_cpcovf_intr = 1; 121 122 /* vector at which CMCI interrupts come in */ 123 int apic_cmci_vect; 124 extern int cmi_enable_cmci; 125 extern void cmi_cmci_trap(void); 126 127 kmutex_t cmci_cpu_setup_lock; /* protects cmci_cpu_setup_registered */ 128 int cmci_cpu_setup_registered; 129 130 /* number of CPUs in power-on transition state */ 131 static int apic_poweron_cnt = 0; 132 lock_t apic_mode_switch_lock; 133 134 /* 135 * Patchable global variables. 136 */ 137 int apic_forceload = 0; 138 139 int apic_coarse_hrtime = 1; /* 0 - use accurate slow gethrtime() */ 140 141 int apic_flat_model = 0; /* 0 - clustered. 1 - flat */ 142 int apic_panic_on_nmi = 0; 143 int apic_panic_on_apic_error = 0; 144 145 int apic_verbose = 0; /* 0x1ff */ 146 147 #ifdef DEBUG 148 int apic_debug = 0; 149 int apic_restrict_vector = 0; 150 151 int apic_debug_msgbuf[APIC_DEBUG_MSGBUFSIZE]; 152 int apic_debug_msgbufindex = 0; 153 154 #endif /* DEBUG */ 155 156 uint_t apic_nticks = 0; 157 uint_t apic_skipped_redistribute = 0; 158 159 uint_t last_count_read = 0; 160 lock_t apic_gethrtime_lock; 161 volatile int apic_hrtime_stamp = 0; 162 volatile hrtime_t apic_nsec_since_boot = 0; 163 164 static hrtime_t apic_last_hrtime = 0; 165 int apic_hrtime_error = 0; 166 int apic_remote_hrterr = 0; 167 int apic_num_nmis = 0; 168 int apic_apic_error = 0; 169 int apic_num_apic_errors = 0; 170 int apic_num_cksum_errors = 0; 171 172 int apic_error = 0; 173 174 static int apic_cmos_ssb_set = 0; 175 176 /* use to make sure only one cpu handles the nmi */ 177 lock_t apic_nmi_lock; 178 /* use to make sure only one cpu handles the error interrupt */ 179 lock_t apic_error_lock; 180 181 static struct { 182 uchar_t cntl; 183 uchar_t data; 184 } aspen_bmc[] = { 185 { CC_SMS_WR_START, 0x18 }, /* NetFn/LUN */ 186 { CC_SMS_WR_NEXT, 0x24 }, /* Cmd SET_WATCHDOG_TIMER */ 187 { CC_SMS_WR_NEXT, 0x84 }, /* DataByte 1: SMS/OS no log */ 188 { CC_SMS_WR_NEXT, 0x2 }, /* DataByte 2: Power Down */ 189 { CC_SMS_WR_NEXT, 0x0 }, /* DataByte 3: no pre-timeout */ 190 { CC_SMS_WR_NEXT, 0x0 }, /* DataByte 4: timer expir. */ 191 { CC_SMS_WR_NEXT, 0xa }, /* DataByte 5: init countdown */ 192 { CC_SMS_WR_END, 0x0 }, /* DataByte 6: init countdown */ 193 194 { CC_SMS_WR_START, 0x18 }, /* NetFn/LUN */ 195 { CC_SMS_WR_END, 0x22 } /* Cmd RESET_WATCHDOG_TIMER */ 196 }; 197 198 static struct { 199 int port; 200 uchar_t data; 201 } sitka_bmc[] = { 202 { SMS_COMMAND_REGISTER, SMS_WRITE_START }, 203 { SMS_DATA_REGISTER, 0x18 }, /* NetFn/LUN */ 204 { SMS_DATA_REGISTER, 0x24 }, /* Cmd SET_WATCHDOG_TIMER */ 205 { SMS_DATA_REGISTER, 0x84 }, /* DataByte 1: SMS/OS no log */ 206 { SMS_DATA_REGISTER, 0x2 }, /* DataByte 2: Power Down */ 207 { SMS_DATA_REGISTER, 0x0 }, /* DataByte 3: no pre-timeout */ 208 { SMS_DATA_REGISTER, 0x0 }, /* DataByte 4: timer expir. */ 209 { SMS_DATA_REGISTER, 0xa }, /* DataByte 5: init countdown */ 210 { SMS_COMMAND_REGISTER, SMS_WRITE_END }, 211 { SMS_DATA_REGISTER, 0x0 }, /* DataByte 6: init countdown */ 212 213 { SMS_COMMAND_REGISTER, SMS_WRITE_START }, 214 { SMS_DATA_REGISTER, 0x18 }, /* NetFn/LUN */ 215 { SMS_COMMAND_REGISTER, SMS_WRITE_END }, 216 { SMS_DATA_REGISTER, 0x22 } /* Cmd RESET_WATCHDOG_TIMER */ 217 }; 218 219 /* Patchable global variables. */ 220 int apic_kmdb_on_nmi = 0; /* 0 - no, 1 - yes enter kmdb */ 221 uint32_t apic_divide_reg_init = 0; /* 0 - divide by 2 */ 222 223 /* default apic ops without interrupt remapping */ 224 static apic_intrmap_ops_t apic_nointrmap_ops = { 225 (int (*)(int))return_instr, 226 (void (*)(int))return_instr, 227 (void (*)(void **, dev_info_t *, uint16_t, int, uchar_t))return_instr, 228 (void (*)(void *, void *, uint16_t, int))return_instr, 229 (void (*)(void **))return_instr, 230 apic_record_ioapic_rdt, 231 apic_record_msi, 232 }; 233 234 apic_intrmap_ops_t *apic_vt_ops = &apic_nointrmap_ops; 235 apic_cpus_info_t *apic_cpus = NULL; 236 cpuset_t apic_cpumask; 237 uint_t apic_picinit_called; 238 239 /* Flag to indicate that we need to shut down all processors */ 240 static uint_t apic_shutdown_processors; 241 242 /* 243 * Probe the ioapic method for apix module. Called in apic_probe_common() 244 */ 245 int 246 apic_ioapic_method_probe() 247 { 248 if (apix_enable == 0) 249 return (PSM_SUCCESS); 250 251 /* 252 * Set IOAPIC EOI handling method. The priority from low to high is: 253 * 1. IOxAPIC: with EOI register 254 * 2. IOMMU interrupt mapping 255 * 3. Mask-Before-EOI method for systems without boot 256 * interrupt routing, such as systems with only one IOAPIC; 257 * NVIDIA CK8-04/MCP55 systems; systems with bridge solution 258 * which disables the boot interrupt routing already. 259 * 4. Directed EOI 260 */ 261 if (apic_io_ver[0] >= 0x20) 262 apix_mul_ioapic_method = APIC_MUL_IOAPIC_IOXAPIC; 263 if ((apic_io_max == 1) || (apic_nvidia_io_max == apic_io_max)) 264 apix_mul_ioapic_method = APIC_MUL_IOAPIC_MASK; 265 if (apic_directed_EOI_supported()) 266 apix_mul_ioapic_method = APIC_MUL_IOAPIC_DEOI; 267 268 /* fall back to pcplusmp */ 269 if (apix_mul_ioapic_method == APIC_MUL_IOAPIC_PCPLUSMP) { 270 /* make sure apix is after pcplusmp in /etc/mach */ 271 apix_enable = 0; /* go ahead with pcplusmp install next */ 272 return (PSM_FAILURE); 273 } 274 275 return (PSM_SUCCESS); 276 } 277 278 /* 279 * handler for APIC Error interrupt. Just print a warning and continue 280 */ 281 int 282 apic_error_intr() 283 { 284 uint_t error0, error1, error; 285 uint_t i; 286 287 /* 288 * We need to write before read as per 7.4.17 of system prog manual. 289 * We do both and or the results to be safe 290 */ 291 error0 = apic_reg_ops->apic_read(APIC_ERROR_STATUS); 292 apic_reg_ops->apic_write(APIC_ERROR_STATUS, 0); 293 error1 = apic_reg_ops->apic_read(APIC_ERROR_STATUS); 294 error = error0 | error1; 295 296 /* 297 * Clear the APIC error status (do this on all cpus that enter here) 298 * (two writes are required due to the semantics of accessing the 299 * error status register.) 300 */ 301 apic_reg_ops->apic_write(APIC_ERROR_STATUS, 0); 302 apic_reg_ops->apic_write(APIC_ERROR_STATUS, 0); 303 304 /* 305 * Prevent more than 1 CPU from handling error interrupt causing 306 * double printing (interleave of characters from multiple 307 * CPU's when using prom_printf) 308 */ 309 if (lock_try(&apic_error_lock) == 0) 310 return (error ? DDI_INTR_CLAIMED : DDI_INTR_UNCLAIMED); 311 if (error) { 312 #if DEBUG 313 if (apic_debug) 314 debug_enter("pcplusmp: APIC Error interrupt received"); 315 #endif /* DEBUG */ 316 if (apic_panic_on_apic_error) 317 cmn_err(CE_PANIC, 318 "APIC Error interrupt on CPU %d. Status = %x", 319 psm_get_cpu_id(), error); 320 else { 321 if ((error & ~APIC_CS_ERRORS) == 0) { 322 /* cksum error only */ 323 apic_error |= APIC_ERR_APIC_ERROR; 324 apic_apic_error |= error; 325 apic_num_apic_errors++; 326 apic_num_cksum_errors++; 327 } else { 328 /* 329 * prom_printf is the best shot we have of 330 * something which is problem free from 331 * high level/NMI type of interrupts 332 */ 333 prom_printf("APIC Error interrupt on CPU %d. " 334 "Status 0 = %x, Status 1 = %x\n", 335 psm_get_cpu_id(), error0, error1); 336 apic_error |= APIC_ERR_APIC_ERROR; 337 apic_apic_error |= error; 338 apic_num_apic_errors++; 339 for (i = 0; i < apic_error_display_delay; i++) { 340 tenmicrosec(); 341 } 342 /* 343 * provide more delay next time limited to 344 * roughly 1 clock tick time 345 */ 346 if (apic_error_display_delay < 500) 347 apic_error_display_delay *= 2; 348 } 349 } 350 lock_clear(&apic_error_lock); 351 return (DDI_INTR_CLAIMED); 352 } else { 353 lock_clear(&apic_error_lock); 354 return (DDI_INTR_UNCLAIMED); 355 } 356 } 357 358 /* 359 * Turn off the mask bit in the performance counter Local Vector Table entry. 360 */ 361 void 362 apic_cpcovf_mask_clear(void) 363 { 364 apic_reg_ops->apic_write(APIC_PCINT_VECT, 365 (apic_reg_ops->apic_read(APIC_PCINT_VECT) & ~APIC_LVT_MASK)); 366 } 367 368 /*ARGSUSED*/ 369 static int 370 apic_cmci_enable(xc_arg_t arg1, xc_arg_t arg2, xc_arg_t arg3) 371 { 372 apic_reg_ops->apic_write(APIC_CMCI_VECT, apic_cmci_vect); 373 return (0); 374 } 375 376 /*ARGSUSED*/ 377 static int 378 apic_cmci_disable(xc_arg_t arg1, xc_arg_t arg2, xc_arg_t arg3) 379 { 380 apic_reg_ops->apic_write(APIC_CMCI_VECT, apic_cmci_vect | AV_MASK); 381 return (0); 382 } 383 384 /*ARGSUSED*/ 385 int 386 cmci_cpu_setup(cpu_setup_t what, int cpuid, void *arg) 387 { 388 cpuset_t cpu_set; 389 390 CPUSET_ONLY(cpu_set, cpuid); 391 392 switch (what) { 393 case CPU_ON: 394 xc_call(NULL, NULL, NULL, CPUSET2BV(cpu_set), 395 (xc_func_t)apic_cmci_enable); 396 break; 397 398 case CPU_OFF: 399 xc_call(NULL, NULL, NULL, CPUSET2BV(cpu_set), 400 (xc_func_t)apic_cmci_disable); 401 break; 402 403 default: 404 break; 405 } 406 407 return (0); 408 } 409 410 static void 411 apic_disable_local_apic(void) 412 { 413 apic_reg_ops->apic_write_task_reg(APIC_MASK_ALL); 414 apic_reg_ops->apic_write(APIC_LOCAL_TIMER, AV_MASK); 415 416 /* local intr reg 0 */ 417 apic_reg_ops->apic_write(APIC_INT_VECT0, AV_MASK); 418 419 /* disable NMI */ 420 apic_reg_ops->apic_write(APIC_INT_VECT1, AV_MASK); 421 422 /* and error interrupt */ 423 apic_reg_ops->apic_write(APIC_ERR_VECT, AV_MASK); 424 425 /* and perf counter intr */ 426 apic_reg_ops->apic_write(APIC_PCINT_VECT, AV_MASK); 427 428 apic_reg_ops->apic_write(APIC_SPUR_INT_REG, APIC_SPUR_INTR); 429 } 430 431 static void 432 apic_cpu_send_SIPI(processorid_t cpun, boolean_t start) 433 { 434 int loop_count; 435 uint32_t vector; 436 uint_t apicid; 437 ulong_t iflag; 438 439 apicid = apic_cpus[cpun].aci_local_id; 440 441 /* 442 * Interrupts on current CPU will be disabled during the 443 * steps in order to avoid unwanted side effects from 444 * executing interrupt handlers on a problematic BIOS. 445 */ 446 iflag = intr_clear(); 447 448 if (start) { 449 outb(CMOS_ADDR, SSB); 450 outb(CMOS_DATA, BIOS_SHUTDOWN); 451 } 452 453 /* 454 * According to X2APIC specification in section '2.3.5.1' of 455 * Interrupt Command Register Semantics, the semantics of 456 * programming the Interrupt Command Register to dispatch an interrupt 457 * is simplified. A single MSR write to the 64-bit ICR is required 458 * for dispatching an interrupt. Specifically, with the 64-bit MSR 459 * interface to ICR, system software is not required to check the 460 * status of the delivery status bit prior to writing to the ICR 461 * to send an IPI. With the removal of the Delivery Status bit, 462 * system software no longer has a reason to read the ICR. It remains 463 * readable only to aid in debugging. 464 */ 465 #ifdef DEBUG 466 APIC_AV_PENDING_SET(); 467 #else 468 if (apic_mode == LOCAL_APIC) { 469 APIC_AV_PENDING_SET(); 470 } 471 #endif /* DEBUG */ 472 473 /* for integrated - make sure there is one INIT IPI in buffer */ 474 /* for external - it will wake up the cpu */ 475 apic_reg_ops->apic_write_int_cmd(apicid, AV_ASSERT | AV_RESET); 476 477 /* If only 1 CPU is installed, PENDING bit will not go low */ 478 for (loop_count = apic_sipi_max_loop_count; loop_count; loop_count--) { 479 if (apic_mode == LOCAL_APIC && 480 apic_reg_ops->apic_read(APIC_INT_CMD1) & AV_PENDING) 481 apic_ret(); 482 else 483 break; 484 } 485 486 apic_reg_ops->apic_write_int_cmd(apicid, AV_DEASSERT | AV_RESET); 487 drv_usecwait(20000); /* 20 milli sec */ 488 489 if (apic_cpus[cpun].aci_local_ver >= APIC_INTEGRATED_VERS) { 490 /* integrated apic */ 491 492 vector = (rm_platter_pa >> MMU_PAGESHIFT) & 493 (APIC_VECTOR_MASK | APIC_IPL_MASK); 494 495 /* to offset the INIT IPI queue up in the buffer */ 496 apic_reg_ops->apic_write_int_cmd(apicid, vector | AV_STARTUP); 497 drv_usecwait(200); /* 20 micro sec */ 498 499 /* 500 * send the second SIPI (Startup IPI) as recommended by Intel 501 * software development manual. 502 */ 503 apic_reg_ops->apic_write_int_cmd(apicid, vector | AV_STARTUP); 504 drv_usecwait(200); /* 20 micro sec */ 505 } 506 507 intr_restore(iflag); 508 } 509 510 /*ARGSUSED1*/ 511 int 512 apic_cpu_start(processorid_t cpun, caddr_t arg) 513 { 514 ASSERT(MUTEX_HELD(&cpu_lock)); 515 516 if (!apic_cpu_in_range(cpun)) { 517 return (EINVAL); 518 } 519 520 /* 521 * Switch to apic_common_send_ipi for safety during starting other CPUs. 522 */ 523 if (apic_mode == LOCAL_X2APIC) { 524 apic_switch_ipi_callback(B_TRUE); 525 } 526 527 apic_cmos_ssb_set = 1; 528 apic_cpu_send_SIPI(cpun, B_TRUE); 529 530 return (0); 531 } 532 533 /* 534 * Put CPU into halted state with interrupts disabled. 535 */ 536 /*ARGSUSED1*/ 537 int 538 apic_cpu_stop(processorid_t cpun, caddr_t arg) 539 { 540 int rc; 541 cpu_t *cp; 542 extern cpuset_t cpu_ready_set; 543 extern void cpu_idle_intercept_cpu(cpu_t *cp); 544 545 ASSERT(MUTEX_HELD(&cpu_lock)); 546 547 if (!apic_cpu_in_range(cpun)) { 548 return (EINVAL); 549 } 550 if (apic_cpus[cpun].aci_local_ver < APIC_INTEGRATED_VERS) { 551 return (ENOTSUP); 552 } 553 554 cp = cpu_get(cpun); 555 ASSERT(cp != NULL); 556 ASSERT((cp->cpu_flags & CPU_OFFLINE) != 0); 557 ASSERT((cp->cpu_flags & CPU_QUIESCED) != 0); 558 ASSERT((cp->cpu_flags & CPU_ENABLE) == 0); 559 560 /* Clear CPU_READY flag to disable cross calls. */ 561 cp->cpu_flags &= ~CPU_READY; 562 CPUSET_ATOMIC_DEL(cpu_ready_set, cpun); 563 rc = xc_flush_cpu(cp); 564 if (rc != 0) { 565 CPUSET_ATOMIC_ADD(cpu_ready_set, cpun); 566 cp->cpu_flags |= CPU_READY; 567 return (rc); 568 } 569 570 /* Intercept target CPU at a safe point before powering it off. */ 571 cpu_idle_intercept_cpu(cp); 572 573 apic_cpu_send_SIPI(cpun, B_FALSE); 574 cp->cpu_flags &= ~CPU_RUNNING; 575 576 return (0); 577 } 578 579 int 580 apic_cpu_ops(psm_cpu_request_t *reqp) 581 { 582 if (reqp == NULL) { 583 return (EINVAL); 584 } 585 586 switch (reqp->pcr_cmd) { 587 case PSM_CPU_ADD: 588 return (apic_cpu_add(reqp)); 589 590 case PSM_CPU_REMOVE: 591 return (apic_cpu_remove(reqp)); 592 593 case PSM_CPU_STOP: 594 return (apic_cpu_stop(reqp->req.cpu_stop.cpuid, 595 reqp->req.cpu_stop.ctx)); 596 597 default: 598 return (ENOTSUP); 599 } 600 } 601 602 #ifdef DEBUG 603 int apic_break_on_cpu = 9; 604 int apic_stretch_interrupts = 0; 605 int apic_stretch_ISR = 1 << 3; /* IPL of 3 matches nothing now */ 606 #endif /* DEBUG */ 607 608 /* 609 * generates an interprocessor interrupt to another CPU. Any changes made to 610 * this routine must be accompanied by similar changes to 611 * apic_common_send_ipi(). 612 */ 613 void 614 apic_send_ipi(int cpun, int ipl) 615 { 616 int vector; 617 ulong_t flag; 618 619 vector = apic_resv_vector[ipl]; 620 621 ASSERT((vector >= APIC_BASE_VECT) && (vector <= APIC_SPUR_INTR)); 622 623 flag = intr_clear(); 624 625 APIC_AV_PENDING_SET(); 626 627 apic_reg_ops->apic_write_int_cmd(apic_cpus[cpun].aci_local_id, 628 vector); 629 630 intr_restore(flag); 631 } 632 633 634 /*ARGSUSED*/ 635 void 636 apic_set_idlecpu(processorid_t cpun) 637 { 638 } 639 640 /*ARGSUSED*/ 641 void 642 apic_unset_idlecpu(processorid_t cpun) 643 { 644 } 645 646 647 void 648 apic_ret() 649 { 650 } 651 652 /* 653 * If apic_coarse_time == 1, then apic_gettime() is used instead of 654 * apic_gethrtime(). This is used for performance instead of accuracy. 655 */ 656 657 hrtime_t 658 apic_gettime() 659 { 660 int old_hrtime_stamp; 661 hrtime_t temp; 662 663 /* 664 * In one-shot mode, we do not keep time, so if anyone 665 * calls psm_gettime() directly, we vector over to 666 * gethrtime(). 667 * one-shot mode MUST NOT be enabled if this psm is the source of 668 * hrtime. 669 */ 670 671 if (apic_oneshot) 672 return (gethrtime()); 673 674 675 gettime_again: 676 while ((old_hrtime_stamp = apic_hrtime_stamp) & 1) 677 apic_ret(); 678 679 temp = apic_nsec_since_boot; 680 681 if (apic_hrtime_stamp != old_hrtime_stamp) { /* got an interrupt */ 682 goto gettime_again; 683 } 684 return (temp); 685 } 686 687 /* 688 * Here we return the number of nanoseconds since booting. Note every 689 * clock interrupt increments apic_nsec_since_boot by the appropriate 690 * amount. 691 */ 692 hrtime_t 693 apic_gethrtime(void) 694 { 695 int curr_timeval, countval, elapsed_ticks; 696 int old_hrtime_stamp, status; 697 hrtime_t temp; 698 uint32_t cpun; 699 ulong_t oflags; 700 701 /* 702 * In one-shot mode, we do not keep time, so if anyone 703 * calls psm_gethrtime() directly, we vector over to 704 * gethrtime(). 705 * one-shot mode MUST NOT be enabled if this psm is the source of 706 * hrtime. 707 */ 708 709 if (apic_oneshot) 710 return (gethrtime()); 711 712 oflags = intr_clear(); /* prevent migration */ 713 714 cpun = apic_reg_ops->apic_read(APIC_LID_REG); 715 if (apic_mode == LOCAL_APIC) 716 cpun >>= APIC_ID_BIT_OFFSET; 717 718 lock_set(&apic_gethrtime_lock); 719 720 gethrtime_again: 721 while ((old_hrtime_stamp = apic_hrtime_stamp) & 1) 722 apic_ret(); 723 724 /* 725 * Check to see which CPU we are on. Note the time is kept on 726 * the local APIC of CPU 0. If on CPU 0, simply read the current 727 * counter. If on another CPU, issue a remote read command to CPU 0. 728 */ 729 if (cpun == apic_cpus[0].aci_local_id) { 730 countval = apic_reg_ops->apic_read(APIC_CURR_COUNT); 731 } else { 732 #ifdef DEBUG 733 APIC_AV_PENDING_SET(); 734 #else 735 if (apic_mode == LOCAL_APIC) 736 APIC_AV_PENDING_SET(); 737 #endif /* DEBUG */ 738 739 apic_reg_ops->apic_write_int_cmd( 740 apic_cpus[0].aci_local_id, APIC_CURR_ADD | AV_REMOTE); 741 742 while ((status = apic_reg_ops->apic_read(APIC_INT_CMD1)) 743 & AV_READ_PENDING) { 744 apic_ret(); 745 } 746 747 if (status & AV_REMOTE_STATUS) /* 1 = valid */ 748 countval = apic_reg_ops->apic_read(APIC_REMOTE_READ); 749 else { /* 0 = invalid */ 750 apic_remote_hrterr++; 751 /* 752 * return last hrtime right now, will need more 753 * testing if change to retry 754 */ 755 temp = apic_last_hrtime; 756 757 lock_clear(&apic_gethrtime_lock); 758 759 intr_restore(oflags); 760 761 return (temp); 762 } 763 } 764 if (countval > last_count_read) 765 countval = 0; 766 else 767 last_count_read = countval; 768 769 elapsed_ticks = apic_hertz_count - countval; 770 771 curr_timeval = APIC_TICKS_TO_NSECS(elapsed_ticks); 772 temp = apic_nsec_since_boot + curr_timeval; 773 774 if (apic_hrtime_stamp != old_hrtime_stamp) { /* got an interrupt */ 775 /* we might have clobbered last_count_read. Restore it */ 776 last_count_read = apic_hertz_count; 777 goto gethrtime_again; 778 } 779 780 if (temp < apic_last_hrtime) { 781 /* return last hrtime if error occurs */ 782 apic_hrtime_error++; 783 temp = apic_last_hrtime; 784 } 785 else 786 apic_last_hrtime = temp; 787 788 lock_clear(&apic_gethrtime_lock); 789 intr_restore(oflags); 790 791 return (temp); 792 } 793 794 /* apic NMI handler */ 795 /*ARGSUSED*/ 796 void 797 apic_nmi_intr(caddr_t arg, struct regs *rp) 798 { 799 if (apic_shutdown_processors) { 800 apic_disable_local_apic(); 801 return; 802 } 803 804 apic_error |= APIC_ERR_NMI; 805 806 if (!lock_try(&apic_nmi_lock)) 807 return; 808 apic_num_nmis++; 809 810 if (apic_kmdb_on_nmi && psm_debugger()) { 811 debug_enter("NMI received: entering kmdb\n"); 812 } else if (apic_panic_on_nmi) { 813 /* Keep panic from entering kmdb. */ 814 nopanicdebug = 1; 815 panic("NMI received\n"); 816 } else { 817 /* 818 * prom_printf is the best shot we have of something which is 819 * problem free from high level/NMI type of interrupts 820 */ 821 prom_printf("NMI received\n"); 822 } 823 824 lock_clear(&apic_nmi_lock); 825 } 826 827 processorid_t 828 apic_get_next_processorid(processorid_t cpu_id) 829 { 830 831 int i; 832 833 if (cpu_id == -1) 834 return ((processorid_t)0); 835 836 for (i = cpu_id + 1; i < NCPU; i++) { 837 if (apic_cpu_in_range(i)) 838 return (i); 839 } 840 841 return ((processorid_t)-1); 842 } 843 844 int 845 apic_cpu_add(psm_cpu_request_t *reqp) 846 { 847 int i, rv = 0; 848 ulong_t iflag; 849 boolean_t first = B_TRUE; 850 uchar_t localver; 851 uint32_t localid, procid; 852 processorid_t cpuid = (processorid_t)-1; 853 mach_cpu_add_arg_t *ap; 854 855 ASSERT(reqp != NULL); 856 reqp->req.cpu_add.cpuid = (processorid_t)-1; 857 858 /* Check whether CPU hotplug is supported. */ 859 if (!plat_dr_support_cpu() || apic_max_nproc == -1) { 860 return (ENOTSUP); 861 } 862 863 ap = (mach_cpu_add_arg_t *)reqp->req.cpu_add.argp; 864 switch (ap->type) { 865 case MACH_CPU_ARG_LOCAL_APIC: 866 localid = ap->arg.apic.apic_id; 867 procid = ap->arg.apic.proc_id; 868 if (localid >= 255 || procid > 255) { 869 cmn_err(CE_WARN, 870 "!apic: apicid(%u) or procid(%u) is invalid.", 871 localid, procid); 872 return (EINVAL); 873 } 874 break; 875 876 case MACH_CPU_ARG_LOCAL_X2APIC: 877 localid = ap->arg.apic.apic_id; 878 procid = ap->arg.apic.proc_id; 879 if (localid >= UINT32_MAX) { 880 cmn_err(CE_WARN, 881 "!apic: x2apicid(%u) is invalid.", localid); 882 return (EINVAL); 883 } else if (localid >= 255 && apic_mode == LOCAL_APIC) { 884 cmn_err(CE_WARN, "!apic: system is in APIC mode, " 885 "can't support x2APIC processor."); 886 return (ENOTSUP); 887 } 888 break; 889 890 default: 891 cmn_err(CE_WARN, 892 "!apic: unknown argument type %d to apic_cpu_add().", 893 ap->type); 894 return (EINVAL); 895 } 896 897 /* Use apic_ioapic_lock to sync with apic_get_next_bind_cpu. */ 898 iflag = intr_clear(); 899 lock_set(&apic_ioapic_lock); 900 901 /* Check whether local APIC id already exists. */ 902 for (i = 0; i < apic_nproc; i++) { 903 if (!CPU_IN_SET(apic_cpumask, i)) 904 continue; 905 if (apic_cpus[i].aci_local_id == localid) { 906 lock_clear(&apic_ioapic_lock); 907 intr_restore(iflag); 908 cmn_err(CE_WARN, 909 "!apic: local apic id %u already exists.", 910 localid); 911 return (EEXIST); 912 } else if (apic_cpus[i].aci_processor_id == procid) { 913 lock_clear(&apic_ioapic_lock); 914 intr_restore(iflag); 915 cmn_err(CE_WARN, 916 "!apic: processor id %u already exists.", 917 (int)procid); 918 return (EEXIST); 919 } 920 921 /* 922 * There's no local APIC version number available in MADT table, 923 * so assume that all CPUs are homogeneous and use local APIC 924 * version number of the first existing CPU. 925 */ 926 if (first) { 927 first = B_FALSE; 928 localver = apic_cpus[i].aci_local_ver; 929 } 930 } 931 ASSERT(first == B_FALSE); 932 933 /* 934 * Try to assign the same cpuid if APIC id exists in the dirty cache. 935 */ 936 for (i = 0; i < apic_max_nproc; i++) { 937 if (CPU_IN_SET(apic_cpumask, i)) { 938 ASSERT((apic_cpus[i].aci_status & APIC_CPU_FREE) == 0); 939 continue; 940 } 941 ASSERT(apic_cpus[i].aci_status & APIC_CPU_FREE); 942 if ((apic_cpus[i].aci_status & APIC_CPU_DIRTY) && 943 apic_cpus[i].aci_local_id == localid && 944 apic_cpus[i].aci_processor_id == procid) { 945 cpuid = i; 946 break; 947 } 948 } 949 950 /* Avoid the dirty cache and allocate fresh slot if possible. */ 951 if (cpuid == (processorid_t)-1) { 952 for (i = 0; i < apic_max_nproc; i++) { 953 if ((apic_cpus[i].aci_status & APIC_CPU_FREE) && 954 (apic_cpus[i].aci_status & APIC_CPU_DIRTY) == 0) { 955 cpuid = i; 956 break; 957 } 958 } 959 } 960 961 /* Try to find any free slot as last resort. */ 962 if (cpuid == (processorid_t)-1) { 963 for (i = 0; i < apic_max_nproc; i++) { 964 if (apic_cpus[i].aci_status & APIC_CPU_FREE) { 965 cpuid = i; 966 break; 967 } 968 } 969 } 970 971 if (cpuid == (processorid_t)-1) { 972 lock_clear(&apic_ioapic_lock); 973 intr_restore(iflag); 974 cmn_err(CE_NOTE, 975 "!apic: failed to allocate cpu id for processor %u.", 976 procid); 977 rv = EAGAIN; 978 } else if (ACPI_FAILURE(acpica_map_cpu(cpuid, procid))) { 979 lock_clear(&apic_ioapic_lock); 980 intr_restore(iflag); 981 cmn_err(CE_NOTE, 982 "!apic: failed to build mapping for processor %u.", 983 procid); 984 rv = EBUSY; 985 } else { 986 ASSERT(cpuid >= 0 && cpuid < NCPU); 987 ASSERT(cpuid < apic_max_nproc && cpuid < max_ncpus); 988 bzero(&apic_cpus[cpuid], sizeof (apic_cpus[0])); 989 apic_cpus[cpuid].aci_processor_id = procid; 990 apic_cpus[cpuid].aci_local_id = localid; 991 apic_cpus[cpuid].aci_local_ver = localver; 992 CPUSET_ATOMIC_ADD(apic_cpumask, cpuid); 993 if (cpuid >= apic_nproc) { 994 apic_nproc = cpuid + 1; 995 } 996 lock_clear(&apic_ioapic_lock); 997 intr_restore(iflag); 998 reqp->req.cpu_add.cpuid = cpuid; 999 } 1000 1001 return (rv); 1002 } 1003 1004 int 1005 apic_cpu_remove(psm_cpu_request_t *reqp) 1006 { 1007 int i; 1008 ulong_t iflag; 1009 processorid_t cpuid; 1010 1011 /* Check whether CPU hotplug is supported. */ 1012 if (!plat_dr_support_cpu() || apic_max_nproc == -1) { 1013 return (ENOTSUP); 1014 } 1015 1016 cpuid = reqp->req.cpu_remove.cpuid; 1017 1018 /* Use apic_ioapic_lock to sync with apic_get_next_bind_cpu. */ 1019 iflag = intr_clear(); 1020 lock_set(&apic_ioapic_lock); 1021 1022 if (!apic_cpu_in_range(cpuid)) { 1023 lock_clear(&apic_ioapic_lock); 1024 intr_restore(iflag); 1025 cmn_err(CE_WARN, 1026 "!apic: cpuid %d doesn't exist in apic_cpus array.", 1027 cpuid); 1028 return (ENODEV); 1029 } 1030 ASSERT((apic_cpus[cpuid].aci_status & APIC_CPU_FREE) == 0); 1031 1032 if (ACPI_FAILURE(acpica_unmap_cpu(cpuid))) { 1033 lock_clear(&apic_ioapic_lock); 1034 intr_restore(iflag); 1035 return (ENOENT); 1036 } 1037 1038 if (cpuid == apic_nproc - 1) { 1039 /* 1040 * We are removing the highest numbered cpuid so we need to 1041 * find the next highest cpuid as the new value for apic_nproc. 1042 */ 1043 for (i = apic_nproc; i > 0; i--) { 1044 if (CPU_IN_SET(apic_cpumask, i - 1)) { 1045 apic_nproc = i; 1046 break; 1047 } 1048 } 1049 /* at least one CPU left */ 1050 ASSERT(i > 0); 1051 } 1052 CPUSET_ATOMIC_DEL(apic_cpumask, cpuid); 1053 /* mark slot as free and keep it in the dirty cache */ 1054 apic_cpus[cpuid].aci_status = APIC_CPU_FREE | APIC_CPU_DIRTY; 1055 1056 lock_clear(&apic_ioapic_lock); 1057 intr_restore(iflag); 1058 1059 return (0); 1060 } 1061 1062 /* 1063 * Return the number of APIC clock ticks elapsed for 8245 to decrement 1064 * (APIC_TIME_COUNT + pit_ticks_adj) ticks. 1065 */ 1066 uint_t 1067 apic_calibrate(volatile uint32_t *addr, uint16_t *pit_ticks_adj) 1068 { 1069 uint8_t pit_tick_lo; 1070 uint16_t pit_tick, target_pit_tick; 1071 uint32_t start_apic_tick, end_apic_tick; 1072 ulong_t iflag; 1073 uint32_t reg; 1074 1075 reg = addr + APIC_CURR_COUNT - apicadr; 1076 1077 iflag = intr_clear(); 1078 1079 do { 1080 pit_tick_lo = inb(PITCTR0_PORT); 1081 pit_tick = (inb(PITCTR0_PORT) << 8) | pit_tick_lo; 1082 } while (pit_tick < APIC_TIME_MIN || 1083 pit_tick_lo <= APIC_LB_MIN || pit_tick_lo >= APIC_LB_MAX); 1084 1085 /* 1086 * Wait for the 8254 to decrement by 5 ticks to ensure 1087 * we didn't start in the middle of a tick. 1088 * Compare with 0x10 for the wrap around case. 1089 */ 1090 target_pit_tick = pit_tick - 5; 1091 do { 1092 pit_tick_lo = inb(PITCTR0_PORT); 1093 pit_tick = (inb(PITCTR0_PORT) << 8) | pit_tick_lo; 1094 } while (pit_tick > target_pit_tick || pit_tick_lo < 0x10); 1095 1096 start_apic_tick = apic_reg_ops->apic_read(reg); 1097 1098 /* 1099 * Wait for the 8254 to decrement by 1100 * (APIC_TIME_COUNT + pit_ticks_adj) ticks 1101 */ 1102 target_pit_tick = pit_tick - APIC_TIME_COUNT; 1103 do { 1104 pit_tick_lo = inb(PITCTR0_PORT); 1105 pit_tick = (inb(PITCTR0_PORT) << 8) | pit_tick_lo; 1106 } while (pit_tick > target_pit_tick || pit_tick_lo < 0x10); 1107 1108 end_apic_tick = apic_reg_ops->apic_read(reg); 1109 1110 *pit_ticks_adj = target_pit_tick - pit_tick; 1111 1112 intr_restore(iflag); 1113 1114 return (start_apic_tick - end_apic_tick); 1115 } 1116 1117 /* 1118 * Initialise the APIC timer on the local APIC of CPU 0 to the desired 1119 * frequency. Note at this stage in the boot sequence, the boot processor 1120 * is the only active processor. 1121 * hertz value of 0 indicates a one-shot mode request. In this case 1122 * the function returns the resolution (in nanoseconds) for the hardware 1123 * timer interrupt. If one-shot mode capability is not available, 1124 * the return value will be 0. apic_enable_oneshot is a global switch 1125 * for disabling the functionality. 1126 * A non-zero positive value for hertz indicates a periodic mode request. 1127 * In this case the hardware will be programmed to generate clock interrupts 1128 * at hertz frequency and returns the resolution of interrupts in 1129 * nanosecond. 1130 */ 1131 1132 int 1133 apic_clkinit(int hertz) 1134 { 1135 int ret; 1136 1137 apic_int_busy_mark = (apic_int_busy_mark * 1138 apic_sample_factor_redistribution) / 100; 1139 apic_int_free_mark = (apic_int_free_mark * 1140 apic_sample_factor_redistribution) / 100; 1141 apic_diff_for_redistribution = (apic_diff_for_redistribution * 1142 apic_sample_factor_redistribution) / 100; 1143 1144 ret = apic_timer_init(hertz); 1145 return (ret); 1146 1147 } 1148 1149 /* 1150 * apic_preshutdown: 1151 * Called early in shutdown whilst we can still access filesystems to do 1152 * things like loading modules which will be required to complete shutdown 1153 * after filesystems are all unmounted. 1154 */ 1155 void 1156 apic_preshutdown(int cmd, int fcn) 1157 { 1158 APIC_VERBOSE_POWEROFF(("apic_preshutdown(%d,%d); m=%d a=%d\n", 1159 cmd, fcn, apic_poweroff_method, apic_enable_acpi)); 1160 } 1161 1162 void 1163 apic_shutdown(int cmd, int fcn) 1164 { 1165 int restarts, attempts; 1166 int i; 1167 uchar_t byte; 1168 ulong_t iflag; 1169 1170 hpet_acpi_fini(); 1171 1172 /* Send NMI to all CPUs except self to do per processor shutdown */ 1173 iflag = intr_clear(); 1174 #ifdef DEBUG 1175 APIC_AV_PENDING_SET(); 1176 #else 1177 if (apic_mode == LOCAL_APIC) 1178 APIC_AV_PENDING_SET(); 1179 #endif /* DEBUG */ 1180 apic_shutdown_processors = 1; 1181 apic_reg_ops->apic_write(APIC_INT_CMD1, 1182 AV_NMI | AV_LEVEL | AV_SH_ALL_EXCSELF); 1183 1184 /* restore cmos shutdown byte before reboot */ 1185 if (apic_cmos_ssb_set) { 1186 outb(CMOS_ADDR, SSB); 1187 outb(CMOS_DATA, 0); 1188 } 1189 1190 ioapic_disable_redirection(); 1191 1192 /* disable apic mode if imcr present */ 1193 if (apic_imcrp) { 1194 outb(APIC_IMCR_P1, (uchar_t)APIC_IMCR_SELECT); 1195 outb(APIC_IMCR_P2, (uchar_t)APIC_IMCR_PIC); 1196 } 1197 1198 apic_disable_local_apic(); 1199 1200 intr_restore(iflag); 1201 1202 /* remainder of function is for shutdown cases only */ 1203 if (cmd != A_SHUTDOWN) 1204 return; 1205 1206 /* 1207 * Switch system back into Legacy-Mode if using ACPI and 1208 * not powering-off. Some BIOSes need to remain in ACPI-mode 1209 * for power-off to succeed (Dell Dimension 4600) 1210 * Do not disable ACPI while doing fastreboot 1211 */ 1212 if (apic_enable_acpi && fcn != AD_POWEROFF && fcn != AD_FASTREBOOT) 1213 (void) AcpiDisable(); 1214 1215 if (fcn == AD_FASTREBOOT) { 1216 apic_reg_ops->apic_write(APIC_INT_CMD1, 1217 AV_ASSERT | AV_RESET | AV_SH_ALL_EXCSELF); 1218 } 1219 1220 /* remainder of function is for shutdown+poweroff case only */ 1221 if (fcn != AD_POWEROFF) 1222 return; 1223 1224 switch (apic_poweroff_method) { 1225 case APIC_POWEROFF_VIA_RTC: 1226 1227 /* select the extended NVRAM bank in the RTC */ 1228 outb(CMOS_ADDR, RTC_REGA); 1229 byte = inb(CMOS_DATA); 1230 outb(CMOS_DATA, (byte | EXT_BANK)); 1231 1232 outb(CMOS_ADDR, PFR_REG); 1233 1234 /* for Predator must toggle the PAB bit */ 1235 byte = inb(CMOS_DATA); 1236 1237 /* 1238 * clear power active bar, wakeup alarm and 1239 * kickstart 1240 */ 1241 byte &= ~(PAB_CBIT | WF_FLAG | KS_FLAG); 1242 outb(CMOS_DATA, byte); 1243 1244 /* delay before next write */ 1245 drv_usecwait(1000); 1246 1247 /* for S40 the following would suffice */ 1248 byte = inb(CMOS_DATA); 1249 1250 /* power active bar control bit */ 1251 byte |= PAB_CBIT; 1252 outb(CMOS_DATA, byte); 1253 1254 break; 1255 1256 case APIC_POWEROFF_VIA_ASPEN_BMC: 1257 restarts = 0; 1258 restart_aspen_bmc: 1259 if (++restarts == 3) 1260 break; 1261 attempts = 0; 1262 do { 1263 byte = inb(MISMIC_FLAG_REGISTER); 1264 byte &= MISMIC_BUSY_MASK; 1265 if (byte != 0) { 1266 drv_usecwait(1000); 1267 if (attempts >= 3) 1268 goto restart_aspen_bmc; 1269 ++attempts; 1270 } 1271 } while (byte != 0); 1272 outb(MISMIC_CNTL_REGISTER, CC_SMS_GET_STATUS); 1273 byte = inb(MISMIC_FLAG_REGISTER); 1274 byte |= 0x1; 1275 outb(MISMIC_FLAG_REGISTER, byte); 1276 i = 0; 1277 for (; i < (sizeof (aspen_bmc)/sizeof (aspen_bmc[0])); 1278 i++) { 1279 attempts = 0; 1280 do { 1281 byte = inb(MISMIC_FLAG_REGISTER); 1282 byte &= MISMIC_BUSY_MASK; 1283 if (byte != 0) { 1284 drv_usecwait(1000); 1285 if (attempts >= 3) 1286 goto restart_aspen_bmc; 1287 ++attempts; 1288 } 1289 } while (byte != 0); 1290 outb(MISMIC_CNTL_REGISTER, aspen_bmc[i].cntl); 1291 outb(MISMIC_DATA_REGISTER, aspen_bmc[i].data); 1292 byte = inb(MISMIC_FLAG_REGISTER); 1293 byte |= 0x1; 1294 outb(MISMIC_FLAG_REGISTER, byte); 1295 } 1296 break; 1297 1298 case APIC_POWEROFF_VIA_SITKA_BMC: 1299 restarts = 0; 1300 restart_sitka_bmc: 1301 if (++restarts == 3) 1302 break; 1303 attempts = 0; 1304 do { 1305 byte = inb(SMS_STATUS_REGISTER); 1306 byte &= SMS_STATE_MASK; 1307 if ((byte == SMS_READ_STATE) || 1308 (byte == SMS_WRITE_STATE)) { 1309 drv_usecwait(1000); 1310 if (attempts >= 3) 1311 goto restart_sitka_bmc; 1312 ++attempts; 1313 } 1314 } while ((byte == SMS_READ_STATE) || 1315 (byte == SMS_WRITE_STATE)); 1316 outb(SMS_COMMAND_REGISTER, SMS_GET_STATUS); 1317 i = 0; 1318 for (; i < (sizeof (sitka_bmc)/sizeof (sitka_bmc[0])); 1319 i++) { 1320 attempts = 0; 1321 do { 1322 byte = inb(SMS_STATUS_REGISTER); 1323 byte &= SMS_IBF_MASK; 1324 if (byte != 0) { 1325 drv_usecwait(1000); 1326 if (attempts >= 3) 1327 goto restart_sitka_bmc; 1328 ++attempts; 1329 } 1330 } while (byte != 0); 1331 outb(sitka_bmc[i].port, sitka_bmc[i].data); 1332 } 1333 break; 1334 1335 case APIC_POWEROFF_NONE: 1336 1337 /* If no APIC direct method, we will try using ACPI */ 1338 if (apic_enable_acpi) { 1339 if (acpi_poweroff() == 1) 1340 return; 1341 } else 1342 return; 1343 1344 break; 1345 } 1346 /* 1347 * Wait a limited time here for power to go off. 1348 * If the power does not go off, then there was a 1349 * problem and we should continue to the halt which 1350 * prints a message for the user to press a key to 1351 * reboot. 1352 */ 1353 drv_usecwait(7000000); /* wait seven seconds */ 1354 1355 } 1356 1357 cyclic_id_t apic_cyclic_id; 1358 1359 /* 1360 * The following functions are in the platform specific file so that they 1361 * can be different functions depending on whether we are running on 1362 * bare metal or a hypervisor. 1363 */ 1364 1365 /* 1366 * map an apic for memory-mapped access 1367 */ 1368 uint32_t * 1369 mapin_apic(uint32_t addr, size_t len, int flags) 1370 { 1371 return ((void *)psm_map_phys(addr, len, flags)); 1372 } 1373 1374 uint32_t * 1375 mapin_ioapic(uint32_t addr, size_t len, int flags) 1376 { 1377 return (mapin_apic(addr, len, flags)); 1378 } 1379 1380 /* 1381 * unmap an apic 1382 */ 1383 void 1384 mapout_apic(caddr_t addr, size_t len) 1385 { 1386 psm_unmap_phys(addr, len); 1387 } 1388 1389 void 1390 mapout_ioapic(caddr_t addr, size_t len) 1391 { 1392 mapout_apic(addr, len); 1393 } 1394 1395 uint32_t 1396 ioapic_read(int ioapic_ix, uint32_t reg) 1397 { 1398 volatile uint32_t *ioapic; 1399 1400 ioapic = apicioadr[ioapic_ix]; 1401 ioapic[APIC_IO_REG] = reg; 1402 return (ioapic[APIC_IO_DATA]); 1403 } 1404 1405 void 1406 ioapic_write(int ioapic_ix, uint32_t reg, uint32_t value) 1407 { 1408 volatile uint32_t *ioapic; 1409 1410 ioapic = apicioadr[ioapic_ix]; 1411 ioapic[APIC_IO_REG] = reg; 1412 ioapic[APIC_IO_DATA] = value; 1413 } 1414 1415 void 1416 ioapic_write_eoi(int ioapic_ix, uint32_t value) 1417 { 1418 volatile uint32_t *ioapic; 1419 1420 ioapic = apicioadr[ioapic_ix]; 1421 ioapic[APIC_IO_EOI] = value; 1422 } 1423 1424 /* 1425 * Round-robin algorithm to find the next CPU with interrupts enabled. 1426 * It can't share the same static variable apic_next_bind_cpu with 1427 * apic_get_next_bind_cpu(), since that will cause all interrupts to be 1428 * bound to CPU1 at boot time. During boot, only CPU0 is online with 1429 * interrupts enabled when apic_get_next_bind_cpu() and apic_find_cpu() 1430 * are called. However, the pcplusmp driver assumes that there will be 1431 * boot_ncpus CPUs configured eventually so it tries to distribute all 1432 * interrupts among CPU0 - CPU[boot_ncpus - 1]. Thus to prevent all 1433 * interrupts being targetted at CPU1, we need to use a dedicated static 1434 * variable for find_next_cpu() instead of sharing apic_next_bind_cpu. 1435 */ 1436 1437 processorid_t 1438 apic_find_cpu(int flag) 1439 { 1440 int i; 1441 static processorid_t acid = 0; 1442 1443 /* Find the first CPU with the passed-in flag set */ 1444 for (i = 0; i < apic_nproc; i++) { 1445 if (++acid >= apic_nproc) { 1446 acid = 0; 1447 } 1448 if (apic_cpu_in_range(acid) && 1449 (apic_cpus[acid].aci_status & flag)) { 1450 break; 1451 } 1452 } 1453 1454 ASSERT((apic_cpus[acid].aci_status & flag) != 0); 1455 return (acid); 1456 } 1457 1458 /* 1459 * Switch between safe and x2APIC IPI sending method. 1460 * CPU may power on in xapic mode or x2apic mode. If CPU needs to send IPI to 1461 * other CPUs before entering x2APIC mode, it still needs to xAPIC method. 1462 * Before sending StartIPI to target CPU, psm_send_ipi will be changed to 1463 * apic_common_send_ipi, which detects current local APIC mode and use right 1464 * method to send IPI. If some CPUs fail to start up, apic_poweron_cnt 1465 * won't return to zero, so apic_common_send_ipi will always be used. 1466 * psm_send_ipi can't be simply changed back to x2apic_send_ipi if some CPUs 1467 * failed to start up because those failed CPUs may recover itself later at 1468 * unpredictable time. 1469 */ 1470 void 1471 apic_switch_ipi_callback(boolean_t enter) 1472 { 1473 ulong_t iflag; 1474 struct psm_ops *pops = psmops; 1475 1476 iflag = intr_clear(); 1477 lock_set(&apic_mode_switch_lock); 1478 if (enter) { 1479 ASSERT(apic_poweron_cnt >= 0); 1480 if (apic_poweron_cnt == 0) { 1481 pops->psm_send_ipi = apic_common_send_ipi; 1482 send_dirintf = pops->psm_send_ipi; 1483 } 1484 apic_poweron_cnt++; 1485 } else { 1486 ASSERT(apic_poweron_cnt > 0); 1487 apic_poweron_cnt--; 1488 if (apic_poweron_cnt == 0) { 1489 pops->psm_send_ipi = x2apic_send_ipi; 1490 send_dirintf = pops->psm_send_ipi; 1491 } 1492 } 1493 lock_clear(&apic_mode_switch_lock); 1494 intr_restore(iflag); 1495 } 1496 1497 void 1498 apic_intrmap_init(int apic_mode) 1499 { 1500 int suppress_brdcst_eoi = 0; 1501 1502 if (psm_vt_ops != NULL) { 1503 /* 1504 * Since X2APIC requires the use of interrupt remapping 1505 * (though this is not documented explicitly in the Intel 1506 * documentation (yet)), initialize interrupt remapping 1507 * support before initializing the X2APIC unit. 1508 */ 1509 if (((apic_intrmap_ops_t *)psm_vt_ops)-> 1510 apic_intrmap_init(apic_mode) == DDI_SUCCESS) { 1511 1512 apic_vt_ops = psm_vt_ops; 1513 1514 /* 1515 * We leverage the interrupt remapping engine to 1516 * suppress broadcast EOI; thus we must send the 1517 * directed EOI with the directed-EOI handler. 1518 */ 1519 if (apic_directed_EOI_supported() == 0) { 1520 suppress_brdcst_eoi = 1; 1521 } 1522 1523 apic_vt_ops->apic_intrmap_enable(suppress_brdcst_eoi); 1524 1525 if (apic_detect_x2apic()) { 1526 apic_enable_x2apic(); 1527 } 1528 1529 if (apic_directed_EOI_supported() == 0) { 1530 apic_set_directed_EOI_handler(); 1531 } 1532 } 1533 } 1534 } 1535 1536 /*ARGSUSED*/ 1537 static void 1538 apic_record_ioapic_rdt(void *intrmap_private, ioapic_rdt_t *irdt) 1539 { 1540 irdt->ir_hi <<= APIC_ID_BIT_OFFSET; 1541 } 1542 1543 /*ARGSUSED*/ 1544 static void 1545 apic_record_msi(void *intrmap_private, msi_regs_t *mregs) 1546 { 1547 mregs->mr_addr = MSI_ADDR_HDR | 1548 (MSI_ADDR_RH_FIXED << MSI_ADDR_RH_SHIFT) | 1549 (MSI_ADDR_DM_PHYSICAL << MSI_ADDR_DM_SHIFT) | 1550 (mregs->mr_addr << MSI_ADDR_DEST_SHIFT); 1551 mregs->mr_data = (MSI_DATA_TM_EDGE << MSI_DATA_TM_SHIFT) | 1552 mregs->mr_data; 1553 } 1554 1555 /* 1556 * Functions from apic_introp.c 1557 * 1558 * Those functions are used by apic_intr_ops(). 1559 */ 1560 1561 /* 1562 * MSI support flag: 1563 * reflects whether MSI is supported at APIC level 1564 * it can also be patched through /etc/system 1565 * 1566 * 0 = default value - don't know and need to call apic_check_msi_support() 1567 * to find out then set it accordingly 1568 * 1 = supported 1569 * -1 = not supported 1570 */ 1571 int apic_support_msi = 0; 1572 1573 /* Multiple vector support for MSI-X */ 1574 int apic_msix_enable = 1; 1575 1576 /* Multiple vector support for MSI */ 1577 int apic_multi_msi_enable = 1; 1578 1579 /* 1580 * check whether the system supports MSI 1581 * 1582 * If PCI-E capability is found, then this must be a PCI-E system. 1583 * Since MSI is required for PCI-E system, it returns PSM_SUCCESS 1584 * to indicate this system supports MSI. 1585 */ 1586 int 1587 apic_check_msi_support() 1588 { 1589 dev_info_t *cdip; 1590 char dev_type[16]; 1591 int dev_len; 1592 1593 DDI_INTR_IMPLDBG((CE_CONT, "apic_check_msi_support:\n")); 1594 1595 /* 1596 * check whether the first level children of root_node have 1597 * PCI-E capability 1598 */ 1599 for (cdip = ddi_get_child(ddi_root_node()); cdip != NULL; 1600 cdip = ddi_get_next_sibling(cdip)) { 1601 1602 DDI_INTR_IMPLDBG((CE_CONT, "apic_check_msi_support: cdip: 0x%p," 1603 " driver: %s, binding: %s, nodename: %s\n", (void *)cdip, 1604 ddi_driver_name(cdip), ddi_binding_name(cdip), 1605 ddi_node_name(cdip))); 1606 dev_len = sizeof (dev_type); 1607 if (ddi_getlongprop_buf(DDI_DEV_T_ANY, cdip, DDI_PROP_DONTPASS, 1608 "device_type", (caddr_t)dev_type, &dev_len) 1609 != DDI_PROP_SUCCESS) 1610 continue; 1611 if (strcmp(dev_type, "pciex") == 0) 1612 return (PSM_SUCCESS); 1613 } 1614 1615 /* MSI is not supported on this system */ 1616 DDI_INTR_IMPLDBG((CE_CONT, "apic_check_msi_support: no 'pciex' " 1617 "device_type found\n")); 1618 return (PSM_FAILURE); 1619 } 1620 1621 /* 1622 * apic_pci_msi_unconfigure: 1623 * 1624 * This and next two interfaces are copied from pci_intr_lib.c 1625 * Do ensure that these two files stay in sync. 1626 * These needed to be copied over here to avoid a deadlock situation on 1627 * certain mp systems that use MSI interrupts. 1628 * 1629 * IMPORTANT regards next three interfaces: 1630 * i) are called only for MSI/X interrupts. 1631 * ii) called with interrupts disabled, and must not block 1632 */ 1633 void 1634 apic_pci_msi_unconfigure(dev_info_t *rdip, int type, int inum) 1635 { 1636 ushort_t msi_ctrl; 1637 int cap_ptr = i_ddi_get_msi_msix_cap_ptr(rdip); 1638 ddi_acc_handle_t handle = i_ddi_get_pci_config_handle(rdip); 1639 1640 ASSERT((handle != NULL) && (cap_ptr != 0)); 1641 1642 if (type == DDI_INTR_TYPE_MSI) { 1643 msi_ctrl = pci_config_get16(handle, cap_ptr + PCI_MSI_CTRL); 1644 msi_ctrl &= (~PCI_MSI_MME_MASK); 1645 pci_config_put16(handle, cap_ptr + PCI_MSI_CTRL, msi_ctrl); 1646 pci_config_put32(handle, cap_ptr + PCI_MSI_ADDR_OFFSET, 0); 1647 1648 if (msi_ctrl & PCI_MSI_64BIT_MASK) { 1649 pci_config_put16(handle, 1650 cap_ptr + PCI_MSI_64BIT_DATA, 0); 1651 pci_config_put32(handle, 1652 cap_ptr + PCI_MSI_ADDR_OFFSET + 4, 0); 1653 } else { 1654 pci_config_put16(handle, 1655 cap_ptr + PCI_MSI_32BIT_DATA, 0); 1656 } 1657 1658 } else if (type == DDI_INTR_TYPE_MSIX) { 1659 uintptr_t off; 1660 uint32_t mask; 1661 ddi_intr_msix_t *msix_p = i_ddi_get_msix(rdip); 1662 1663 ASSERT(msix_p != NULL); 1664 1665 /* Offset into "inum"th entry in the MSI-X table & mask it */ 1666 off = (uintptr_t)msix_p->msix_tbl_addr + (inum * 1667 PCI_MSIX_VECTOR_SIZE) + PCI_MSIX_VECTOR_CTRL_OFFSET; 1668 1669 mask = ddi_get32(msix_p->msix_tbl_hdl, (uint32_t *)off); 1670 1671 ddi_put32(msix_p->msix_tbl_hdl, (uint32_t *)off, (mask | 1)); 1672 1673 /* Offset into the "inum"th entry in the MSI-X table */ 1674 off = (uintptr_t)msix_p->msix_tbl_addr + 1675 (inum * PCI_MSIX_VECTOR_SIZE); 1676 1677 /* Reset the "data" and "addr" bits */ 1678 ddi_put32(msix_p->msix_tbl_hdl, 1679 (uint32_t *)(off + PCI_MSIX_DATA_OFFSET), 0); 1680 ddi_put64(msix_p->msix_tbl_hdl, (uint64_t *)off, 0); 1681 } 1682 } 1683 1684 /* 1685 * apic_pci_msi_disable_mode: 1686 */ 1687 void 1688 apic_pci_msi_disable_mode(dev_info_t *rdip, int type) 1689 { 1690 ushort_t msi_ctrl; 1691 int cap_ptr = i_ddi_get_msi_msix_cap_ptr(rdip); 1692 ddi_acc_handle_t handle = i_ddi_get_pci_config_handle(rdip); 1693 1694 ASSERT((handle != NULL) && (cap_ptr != 0)); 1695 1696 if (type == DDI_INTR_TYPE_MSI) { 1697 msi_ctrl = pci_config_get16(handle, cap_ptr + PCI_MSI_CTRL); 1698 if (!(msi_ctrl & PCI_MSI_ENABLE_BIT)) 1699 return; 1700 1701 msi_ctrl &= ~PCI_MSI_ENABLE_BIT; /* MSI disable */ 1702 pci_config_put16(handle, cap_ptr + PCI_MSI_CTRL, msi_ctrl); 1703 1704 } else if (type == DDI_INTR_TYPE_MSIX) { 1705 msi_ctrl = pci_config_get16(handle, cap_ptr + PCI_MSIX_CTRL); 1706 if (msi_ctrl & PCI_MSIX_ENABLE_BIT) { 1707 msi_ctrl &= ~PCI_MSIX_ENABLE_BIT; 1708 pci_config_put16(handle, cap_ptr + PCI_MSIX_CTRL, 1709 msi_ctrl); 1710 } 1711 } 1712 } 1713 1714 uint32_t 1715 apic_get_localapicid(uint32_t cpuid) 1716 { 1717 ASSERT(cpuid < apic_nproc && apic_cpus != NULL); 1718 1719 return (apic_cpus[cpuid].aci_local_id); 1720 } 1721 1722 uchar_t 1723 apic_get_ioapicid(uchar_t ioapicindex) 1724 { 1725 ASSERT(ioapicindex < MAX_IO_APIC); 1726 1727 return (apic_io_id[ioapicindex]); 1728 }