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 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 /* 27 * Platform specific implementation code 28 * Currently only suspend to RAM is supported (ACPI S3) 29 */ 30 31 #define SUNDDI_IMPL 32 33 #include <sys/types.h> 34 #include <sys/promif.h> 35 #include <sys/prom_isa.h> 36 #include <sys/prom_plat.h> 37 #include <sys/cpuvar.h> 38 #include <sys/pte.h> 39 #include <vm/hat.h> 40 #include <vm/page.h> 41 #include <vm/as.h> 42 #include <sys/cpr.h> 43 #include <sys/kmem.h> 44 #include <sys/clock.h> 45 #include <sys/kmem.h> 46 #include <sys/panic.h> 47 #include <vm/seg_kmem.h> 48 #include <sys/cpu_module.h> 49 #include <sys/callb.h> 50 #include <sys/machsystm.h> 51 #include <sys/vmsystm.h> 52 #include <sys/systm.h> 53 #include <sys/archsystm.h> 54 #include <sys/stack.h> 55 #include <sys/fs/ufs_fs.h> 56 #include <sys/memlist.h> 57 #include <sys/bootconf.h> 58 #include <sys/thread.h> 59 #include <sys/x_call.h> 60 #include <sys/smp_impldefs.h> 61 #include <vm/vm_dep.h> 62 #include <sys/psm.h> 63 #include <sys/epm.h> 64 #include <sys/cpr_wakecode.h> 65 #include <sys/x86_archext.h> 66 #include <sys/reboot.h> 67 #include <sys/acpi/acpi.h> 68 #include <sys/acpica.h> 69 70 #define AFMT "%lx" 71 72 extern int flushes_require_xcalls; 73 extern cpuset_t cpu_ready_set; 74 75 #if defined(__amd64) 76 extern void *wc_long_mode_64(void); 77 #endif /* __amd64 */ 78 extern int tsc_gethrtime_enable; 79 extern void i_cpr_start_cpu(void); 80 81 ushort_t cpr_mach_type = CPR_MACHTYPE_X86; 82 void (*cpr_start_cpu_func)(void) = i_cpr_start_cpu; 83 84 static wc_cpu_t *wc_other_cpus = NULL; 85 static cpuset_t procset; 86 87 static void 88 init_real_mode_platter(int cpun, uint32_t offset, uint_t cr4, wc_desctbr_t gdt); 89 90 static int i_cpr_platform_alloc(psm_state_request_t *req); 91 static void i_cpr_platform_free(psm_state_request_t *req); 92 static int i_cpr_save_apic(psm_state_request_t *req); 93 static int i_cpr_restore_apic(psm_state_request_t *req); 94 static int wait_for_set(cpuset_t *set, int who); 95 96 static void i_cpr_save_stack(kthread_t *t, wc_cpu_t *wc_cpu); 97 void i_cpr_restore_stack(kthread_t *t, greg_t *save_stack); 98 99 #ifdef STACK_GROWTH_DOWN 100 #define CPR_GET_STACK_START(t) ((t)->t_stkbase) 101 #define CPR_GET_STACK_END(t) ((t)->t_stk) 102 #else 103 #define CPR_GET_STACK_START(t) ((t)->t_stk) 104 #define CPR_GET_STACK_END(t) ((t)->t_stkbase) 105 #endif /* STACK_GROWTH_DOWN */ 106 107 /* 108 * restart paused slave cpus 109 */ 110 void 111 i_cpr_machdep_setup(void) 112 { 113 if (ncpus > 1) { 114 CPR_DEBUG(CPR_DEBUG1, ("MP restarted...\n")); 115 mutex_enter(&cpu_lock); 116 start_cpus(); 117 mutex_exit(&cpu_lock); 118 } 119 } 120 121 122 /* 123 * Stop all interrupt activities in the system 124 */ 125 void 126 i_cpr_stop_intr(void) 127 { 128 (void) spl7(); 129 } 130 131 /* 132 * Set machine up to take interrupts 133 */ 134 void 135 i_cpr_enable_intr(void) 136 { 137 (void) spl0(); 138 } 139 140 /* 141 * Save miscellaneous information which needs to be written to the 142 * state file. This information is required to re-initialize 143 * kernel/prom handshaking. 144 */ 145 void 146 i_cpr_save_machdep_info(void) 147 { 148 int notcalled = 0; 149 ASSERT(notcalled); 150 } 151 152 153 void 154 i_cpr_set_tbr(void) 155 { 156 } 157 158 159 processorid_t 160 i_cpr_bootcpuid(void) 161 { 162 return (0); 163 } 164 165 /* 166 * cpu0 should contain bootcpu info 167 */ 168 cpu_t * 169 i_cpr_bootcpu(void) 170 { 171 ASSERT(MUTEX_HELD(&cpu_lock)); 172 173 return (cpu_get(i_cpr_bootcpuid())); 174 } 175 176 /* 177 * Save context for the specified CPU 178 */ 179 void * 180 i_cpr_save_context(void *arg) 181 { 182 long index = (long)arg; 183 psm_state_request_t *papic_state; 184 int resuming; 185 int ret; 186 wc_cpu_t *wc_cpu = wc_other_cpus + index; 187 188 PMD(PMD_SX, ("i_cpr_save_context() index = %ld\n", index)) 189 190 ASSERT(index < NCPU); 191 192 papic_state = &(wc_cpu)->wc_apic_state; 193 194 ret = i_cpr_platform_alloc(papic_state); 195 ASSERT(ret == 0); 196 197 ret = i_cpr_save_apic(papic_state); 198 ASSERT(ret == 0); 199 200 i_cpr_save_stack(curthread, wc_cpu); 201 202 /* 203 * wc_save_context returns twice, once when susending and 204 * once when resuming, wc_save_context() returns 0 when 205 * suspending and non-zero upon resume 206 */ 207 resuming = (wc_save_context(wc_cpu) == 0); 208 209 /* 210 * do NOT call any functions after this point, because doing so 211 * will modify the stack that we are running on 212 */ 213 214 if (resuming) { 215 216 ret = i_cpr_restore_apic(papic_state); 217 ASSERT(ret == 0); 218 219 i_cpr_platform_free(papic_state); 220 221 /* 222 * Enable interrupts on this cpu. 223 * Do not bind interrupts to this CPU's local APIC until 224 * the CPU is ready to receive interrupts. 225 */ 226 ASSERT(CPU->cpu_id != i_cpr_bootcpuid()); 227 mutex_enter(&cpu_lock); 228 cpu_enable_intr(CPU); 229 mutex_exit(&cpu_lock); 230 231 /* 232 * Setting the bit in cpu_ready_set must be the last operation 233 * in processor initialization; the boot CPU will continue to 234 * boot once it sees this bit set for all active CPUs. 235 */ 236 CPUSET_ATOMIC_ADD(cpu_ready_set, CPU->cpu_id); 237 238 PMD(PMD_SX, 239 ("i_cpr_save_context() resuming cpu %d in cpu_ready_set\n", 240 CPU->cpu_id)) 241 } else { 242 /* 243 * Disable interrupts on this CPU so that PSM knows not to bind 244 * interrupts here on resume until the CPU has executed 245 * cpu_enable_intr() (above) in the resume path. 246 * We explicitly do not grab cpu_lock here because at this point 247 * in the suspend process, the boot cpu owns cpu_lock and all 248 * other cpus are also executing in the pause thread (only 249 * modifying their respective CPU structure). 250 */ 251 (void) cpu_disable_intr(CPU); 252 } 253 254 PMD(PMD_SX, ("i_cpr_save_context: wc_save_context returns %d\n", 255 resuming)) 256 257 return (NULL); 258 } 259 260 static ushort_t *warm_reset_vector = NULL; 261 262 static ushort_t * 263 map_warm_reset_vector() 264 { 265 /*LINTED*/ 266 if (!(warm_reset_vector = (ushort_t *)psm_map_phys(WARM_RESET_VECTOR, 267 sizeof (ushort_t *), PROT_READ|PROT_WRITE))) 268 return (NULL); 269 270 /* 271 * setup secondary cpu bios boot up vector 272 */ 273 *warm_reset_vector = (ushort_t)((caddr_t) 274 /*LINTED*/ 275 ((struct rm_platter *)rm_platter_va)->rm_code - rm_platter_va 276 + ((ulong_t)rm_platter_va & 0xf)); 277 warm_reset_vector++; 278 *warm_reset_vector = (ushort_t)(rm_platter_pa >> 4); 279 280 --warm_reset_vector; 281 return (warm_reset_vector); 282 } 283 284 void 285 i_cpr_pre_resume_cpus() 286 { 287 /* 288 * this is a cut down version of start_other_cpus() 289 * just do the initialization to wake the other cpus 290 */ 291 unsigned who; 292 int boot_cpuid = i_cpr_bootcpuid(); 293 uint32_t code_length = 0; 294 caddr_t wakevirt = rm_platter_va; 295 /*LINTED*/ 296 wakecode_t *wp = (wakecode_t *)wakevirt; 297 char *str = "i_cpr_pre_resume_cpus"; 298 extern int get_tsc_ready(); 299 int err; 300 301 /*LINTED*/ 302 rm_platter_t *real_mode_platter = (rm_platter_t *)rm_platter_va; 303 304 /* 305 * If startup wasn't able to find a page under 1M, we cannot 306 * proceed. 307 */ 308 if (rm_platter_va == 0) { 309 cmn_err(CE_WARN, "Cannot suspend the system because no " 310 "memory below 1M could be found for processor startup"); 311 return; 312 } 313 314 /* 315 * Copy the real mode code at "real_mode_start" to the 316 * page at rm_platter_va. 317 */ 318 warm_reset_vector = map_warm_reset_vector(); 319 if (warm_reset_vector == NULL) { 320 PMD(PMD_SX, ("i_cpr_pre_resume_cpus() returning #2\n")) 321 return; 322 } 323 324 flushes_require_xcalls = 1; 325 326 /* 327 * We lock our affinity to the master CPU to ensure that all slave CPUs 328 * do their TSC syncs with the same CPU. 329 */ 330 331 affinity_set(CPU_CURRENT); 332 333 /* 334 * Mark the boot cpu as being ready and in the procset, since we are 335 * running on that cpu. 336 */ 337 CPUSET_ONLY(cpu_ready_set, boot_cpuid); 338 CPUSET_ONLY(procset, boot_cpuid); 339 340 for (who = 0; who < max_ncpus; who++) { 341 342 wc_cpu_t *cpup = wc_other_cpus + who; 343 wc_desctbr_t gdt; 344 345 if (who == boot_cpuid) 346 continue; 347 348 if (!CPU_IN_SET(mp_cpus, who)) 349 continue; 350 351 PMD(PMD_SX, ("%s() waking up %d cpu\n", str, who)) 352 353 bcopy(cpup, &(wp->wc_cpu), sizeof (wc_cpu_t)); 354 355 gdt.base = cpup->wc_gdt_base; 356 gdt.limit = cpup->wc_gdt_limit; 357 358 #if defined(__amd64) 359 code_length = (uint32_t)wc_long_mode_64 - (uint32_t)wc_rm_start; 360 #else 361 code_length = 0; 362 #endif 363 364 init_real_mode_platter(who, code_length, cpup->wc_cr4, gdt); 365 366 mutex_enter(&cpu_lock); 367 err = mach_cpuid_start(who, rm_platter_va); 368 mutex_exit(&cpu_lock); 369 if (err != 0) { 370 cmn_err(CE_WARN, "cpu%d: failed to start during " 371 "suspend/resume error %d", who, err); 372 continue; 373 } 374 375 PMD(PMD_SX, ("%s() #1 waiting for %d in procset\n", str, who)) 376 377 if (!wait_for_set(&procset, who)) 378 continue; 379 380 PMD(PMD_SX, ("%s() %d cpu started\n", str, who)) 381 382 PMD(PMD_SX, ("%s() tsc_ready = %d\n", str, get_tsc_ready())) 383 384 if (tsc_gethrtime_enable) { 385 PMD(PMD_SX, ("%s() calling tsc_sync_master\n", str)) 386 tsc_sync_master(who); 387 } 388 389 PMD(PMD_SX, ("%s() waiting for %d in cpu_ready_set\n", str, 390 who)) 391 /* 392 * Wait for cpu to declare that it is ready, we want the 393 * cpus to start serially instead of in parallel, so that 394 * they do not contend with each other in wc_rm_start() 395 */ 396 if (!wait_for_set(&cpu_ready_set, who)) 397 continue; 398 399 /* 400 * do not need to re-initialize dtrace using dtrace_cpu_init 401 * function 402 */ 403 PMD(PMD_SX, ("%s() cpu %d now ready\n", str, who)) 404 } 405 406 affinity_clear(); 407 408 PMD(PMD_SX, ("%s() all cpus now ready\n", str)) 409 410 } 411 412 static void 413 unmap_warm_reset_vector(ushort_t *warm_reset_vector) 414 { 415 psm_unmap_phys((caddr_t)warm_reset_vector, sizeof (ushort_t *)); 416 } 417 418 /* 419 * We need to setup a 1:1 (virtual to physical) mapping for the 420 * page containing the wakeup code. 421 */ 422 static struct as *save_as; /* when switching to kas */ 423 424 static void 425 unmap_wakeaddr_1to1(uint64_t wakephys) 426 { 427 uintptr_t wp = (uintptr_t)wakephys; 428 hat_setup(save_as->a_hat, 0); /* switch back from kernel hat */ 429 hat_unload(kas.a_hat, (caddr_t)wp, PAGESIZE, HAT_UNLOAD); 430 } 431 432 void 433 i_cpr_post_resume_cpus() 434 { 435 uint64_t wakephys = rm_platter_pa; 436 437 if (warm_reset_vector != NULL) 438 unmap_warm_reset_vector(warm_reset_vector); 439 440 hat_unload(kas.a_hat, (caddr_t)(uintptr_t)rm_platter_pa, MMU_PAGESIZE, 441 HAT_UNLOAD); 442 443 /* 444 * cmi_post_mpstartup() is only required upon boot not upon 445 * resume from RAM 446 */ 447 448 PT(PT_UNDO1to1); 449 /* Tear down 1:1 mapping for wakeup code */ 450 unmap_wakeaddr_1to1(wakephys); 451 } 452 453 /* ARGSUSED */ 454 void 455 i_cpr_handle_xc(int flag) 456 { 457 } 458 459 int 460 i_cpr_reusable_supported(void) 461 { 462 return (0); 463 } 464 static void 465 map_wakeaddr_1to1(uint64_t wakephys) 466 { 467 uintptr_t wp = (uintptr_t)wakephys; 468 hat_devload(kas.a_hat, (caddr_t)wp, PAGESIZE, btop(wakephys), 469 (PROT_READ|PROT_WRITE|PROT_EXEC|HAT_STORECACHING_OK|HAT_NOSYNC), 470 HAT_LOAD); 471 save_as = curthread->t_procp->p_as; 472 hat_setup(kas.a_hat, 0); /* switch to kernel-only hat */ 473 } 474 475 476 void 477 prt_other_cpus() 478 { 479 int who; 480 481 if (ncpus == 1) { 482 PMD(PMD_SX, ("prt_other_cpus() other cpu table empty for " 483 "uniprocessor machine\n")) 484 return; 485 } 486 487 for (who = 0; who < max_ncpus; who++) { 488 489 wc_cpu_t *cpup = wc_other_cpus + who; 490 491 if (!CPU_IN_SET(mp_cpus, who)) 492 continue; 493 494 PMD(PMD_SX, ("prt_other_cpus() who = %d, gdt=%p:%x, " 495 "idt=%p:%x, ldt=%lx, tr=%lx, kgsbase=" 496 AFMT ", sp=%lx\n", who, 497 (void *)cpup->wc_gdt_base, cpup->wc_gdt_limit, 498 (void *)cpup->wc_idt_base, cpup->wc_idt_limit, 499 (long)cpup->wc_ldt, (long)cpup->wc_tr, 500 (long)cpup->wc_kgsbase, (long)cpup->wc_rsp)) 501 } 502 } 503 504 /* 505 * Power down the system. 506 */ 507 int 508 i_cpr_power_down(int sleeptype) 509 { 510 caddr_t wakevirt = rm_platter_va; 511 uint64_t wakephys = rm_platter_pa; 512 ulong_t saved_intr; 513 uint32_t code_length = 0; 514 wc_desctbr_t gdt; 515 /*LINTED*/ 516 wakecode_t *wp = (wakecode_t *)wakevirt; 517 /*LINTED*/ 518 rm_platter_t *wcpp = (rm_platter_t *)wakevirt; 519 wc_cpu_t *cpup = &(wp->wc_cpu); 520 dev_info_t *ppm; 521 int ret = 0; 522 power_req_t power_req; 523 char *str = "i_cpr_power_down"; 524 #if defined(__amd64) 525 /*LINTED*/ 526 rm_platter_t *real_mode_platter = (rm_platter_t *)rm_platter_va; 527 #endif 528 extern int cpr_suspend_succeeded; 529 extern void kernel_wc_code(); 530 531 ASSERT(sleeptype == CPR_TORAM); 532 ASSERT(CPU->cpu_id == 0); 533 534 if ((ppm = PPM(ddi_root_node())) == NULL) { 535 PMD(PMD_SX, ("%s: root node not claimed\n", str)) 536 return (ENOTTY); 537 } 538 539 PMD(PMD_SX, ("Entering %s()\n", str)) 540 541 PT(PT_IC); 542 saved_intr = intr_clear(); 543 544 PT(PT_1to1); 545 /* Setup 1:1 mapping for wakeup code */ 546 map_wakeaddr_1to1(wakephys); 547 548 PMD(PMD_SX, ("ncpus=%d\n", ncpus)) 549 550 PMD(PMD_SX, ("wc_rm_end - wc_rm_start=%lx WC_CODESIZE=%x\n", 551 ((size_t)((uint_t)wc_rm_end - (uint_t)wc_rm_start)), WC_CODESIZE)) 552 553 PMD(PMD_SX, ("wakevirt=%p, wakephys=%x\n", 554 (void *)wakevirt, (uint_t)wakephys)) 555 556 ASSERT(((size_t)((uint_t)wc_rm_end - (uint_t)wc_rm_start)) < 557 WC_CODESIZE); 558 559 bzero(wakevirt, PAGESIZE); 560 561 /* Copy code to rm_platter */ 562 bcopy((caddr_t)wc_rm_start, wakevirt, 563 (size_t)((uint_t)wc_rm_end - (uint_t)wc_rm_start)); 564 565 prt_other_cpus(); 566 567 #if defined(__amd64) 568 569 PMD(PMD_SX, ("real_mode_platter->rm_cr4=%lx, getcr4()=%lx\n", 570 (ulong_t)real_mode_platter->rm_cr4, (ulong_t)getcr4())) 571 PMD(PMD_SX, ("real_mode_platter->rm_pdbr=%lx, getcr3()=%lx\n", 572 (ulong_t)real_mode_platter->rm_pdbr, getcr3())) 573 574 real_mode_platter->rm_cr4 = getcr4(); 575 real_mode_platter->rm_pdbr = getcr3(); 576 577 rmp_gdt_init(real_mode_platter); 578 579 /* 580 * Since the CPU needs to jump to protected mode using an identity 581 * mapped address, we need to calculate it here. 582 */ 583 real_mode_platter->rm_longmode64_addr = rm_platter_pa + 584 ((uint32_t)wc_long_mode_64 - (uint32_t)wc_rm_start); 585 586 PMD(PMD_SX, ("real_mode_platter->rm_cr4=%lx, getcr4()=%lx\n", 587 (ulong_t)real_mode_platter->rm_cr4, getcr4())) 588 589 PMD(PMD_SX, ("real_mode_platter->rm_pdbr=%lx, getcr3()=%lx\n", 590 (ulong_t)real_mode_platter->rm_pdbr, getcr3())) 591 592 PMD(PMD_SX, ("real_mode_platter->rm_longmode64_addr=%lx\n", 593 (ulong_t)real_mode_platter->rm_longmode64_addr)) 594 595 #endif 596 597 PT(PT_SC); 598 if (wc_save_context(cpup)) { 599 600 ret = i_cpr_platform_alloc(&(wc_other_cpus->wc_apic_state)); 601 if (ret != 0) 602 return (ret); 603 604 ret = i_cpr_save_apic(&(wc_other_cpus->wc_apic_state)); 605 PMD(PMD_SX, ("%s: i_cpr_save_apic() returned %d\n", str, ret)) 606 if (ret != 0) 607 return (ret); 608 609 PMD(PMD_SX, ("wakephys=%x, kernel_wc_code=%p\n", 610 (uint_t)wakephys, (void *)&kernel_wc_code)) 611 PMD(PMD_SX, ("virtaddr=%lx, retaddr=%lx\n", 612 (long)cpup->wc_virtaddr, (long)cpup->wc_retaddr)) 613 PMD(PMD_SX, ("ebx=%x, edi=%x, esi=%x, ebp=%x, esp=%x\n", 614 cpup->wc_ebx, cpup->wc_edi, cpup->wc_esi, cpup->wc_ebp, 615 cpup->wc_esp)) 616 PMD(PMD_SX, ("cr0=%lx, cr3=%lx, cr4=%lx\n", 617 (long)cpup->wc_cr0, (long)cpup->wc_cr3, 618 (long)cpup->wc_cr4)) 619 PMD(PMD_SX, ("cs=%x, ds=%x, es=%x, ss=%x, fs=%lx, gs=%lx, " 620 "flgs=%lx\n", cpup->wc_cs, cpup->wc_ds, cpup->wc_es, 621 cpup->wc_ss, (long)cpup->wc_fs, (long)cpup->wc_gs, 622 (long)cpup->wc_eflags)) 623 624 PMD(PMD_SX, ("gdt=%p:%x, idt=%p:%x, ldt=%lx, tr=%lx, " 625 "kgbase=%lx\n", (void *)cpup->wc_gdt_base, 626 cpup->wc_gdt_limit, (void *)cpup->wc_idt_base, 627 cpup->wc_idt_limit, (long)cpup->wc_ldt, 628 (long)cpup->wc_tr, (long)cpup->wc_kgsbase)) 629 630 gdt.base = cpup->wc_gdt_base; 631 gdt.limit = cpup->wc_gdt_limit; 632 633 #if defined(__amd64) 634 code_length = (uint32_t)wc_long_mode_64 - 635 (uint32_t)wc_rm_start; 636 #else 637 code_length = 0; 638 #endif 639 640 init_real_mode_platter(0, code_length, cpup->wc_cr4, gdt); 641 642 #if defined(__amd64) 643 PMD(PMD_SX, ("real_mode_platter->rm_cr4=%lx, getcr4()=%lx\n", 644 (ulong_t)wcpp->rm_cr4, getcr4())) 645 646 PMD(PMD_SX, ("real_mode_platter->rm_pdbr=%lx, getcr3()=%lx\n", 647 (ulong_t)wcpp->rm_pdbr, getcr3())) 648 649 PMD(PMD_SX, ("real_mode_platter->rm_longmode64_addr=%lx\n", 650 (ulong_t)wcpp->rm_longmode64_addr)) 651 652 PMD(PMD_SX, 653 ("real_mode_platter->rm_temp_gdt[TEMPGDT_KCODE64]=%lx\n", 654 (ulong_t)wcpp->rm_temp_gdt[TEMPGDT_KCODE64])) 655 #endif 656 657 PMD(PMD_SX, ("gdt=%p:%x, idt=%p:%x, ldt=%lx, tr=%lx, " 658 "kgsbase=%lx\n", (void *)wcpp->rm_gdt_base, 659 wcpp->rm_gdt_lim, (void *)wcpp->rm_idt_base, 660 wcpp->rm_idt_lim, (long)cpup->wc_ldt, (long)cpup->wc_tr, 661 (long)cpup->wc_kgsbase)) 662 663 power_req.request_type = PMR_PPM_ENTER_SX; 664 power_req.req.ppm_power_enter_sx_req.sx_state = S3; 665 power_req.req.ppm_power_enter_sx_req.test_point = 666 cpr_test_point; 667 power_req.req.ppm_power_enter_sx_req.wakephys = wakephys; 668 669 PMD(PMD_SX, ("%s: pm_ctlops PMR_PPM_ENTER_SX\n", str)) 670 PT(PT_PPMCTLOP); 671 (void) pm_ctlops(ppm, ddi_root_node(), DDI_CTLOPS_POWER, 672 &power_req, &ret); 673 PMD(PMD_SX, ("%s: returns %d\n", str, ret)) 674 675 /* 676 * If it works, we get control back to the else branch below 677 * If we get control back here, it didn't work. 678 * XXX return EINVAL here? 679 */ 680 681 unmap_wakeaddr_1to1(wakephys); 682 intr_restore(saved_intr); 683 684 return (ret); 685 } else { 686 cpr_suspend_succeeded = 1; 687 688 power_req.request_type = PMR_PPM_EXIT_SX; 689 power_req.req.ppm_power_enter_sx_req.sx_state = S3; 690 691 PMD(PMD_SX, ("%s: pm_ctlops PMR_PPM_EXIT_SX\n", str)) 692 PT(PT_PPMCTLOP); 693 (void) pm_ctlops(ppm, ddi_root_node(), DDI_CTLOPS_POWER, 694 &power_req, &ret); 695 PMD(PMD_SX, ("%s: returns %d\n", str, ret)) 696 697 ret = i_cpr_restore_apic(&(wc_other_cpus->wc_apic_state)); 698 /* 699 * the restore should never fail, if the saved suceeded 700 */ 701 ASSERT(ret == 0); 702 703 i_cpr_platform_free(&(wc_other_cpus->wc_apic_state)); 704 705 /* 706 * Enable interrupts on boot cpu. 707 */ 708 ASSERT(CPU->cpu_id == i_cpr_bootcpuid()); 709 mutex_enter(&cpu_lock); 710 cpu_enable_intr(CPU); 711 mutex_exit(&cpu_lock); 712 713 PT(PT_INTRRESTORE); 714 intr_restore(saved_intr); 715 PT(PT_CPU); 716 717 return (ret); 718 } 719 } 720 721 /* 722 * Stop all other cpu's before halting or rebooting. We pause the cpu's 723 * instead of sending a cross call. 724 * Stolen from sun4/os/mp_states.c 725 */ 726 727 static int cpu_are_paused; /* sic */ 728 729 void 730 i_cpr_stop_other_cpus(void) 731 { 732 mutex_enter(&cpu_lock); 733 if (cpu_are_paused) { 734 mutex_exit(&cpu_lock); 735 return; 736 } 737 pause_cpus(NULL); 738 cpu_are_paused = 1; 739 740 mutex_exit(&cpu_lock); 741 } 742 743 int 744 i_cpr_is_supported(int sleeptype) 745 { 746 extern int cpr_supported_override; 747 extern int cpr_platform_enable; 748 extern int pm_S3_enabled; 749 750 if (sleeptype != CPR_TORAM) 751 return (0); 752 753 /* 754 * The next statement tests if a specific platform has turned off 755 * cpr support. 756 */ 757 if (cpr_supported_override) 758 return (0); 759 760 /* 761 * If a platform has specifically turned on cpr support ... 762 */ 763 if (cpr_platform_enable) 764 return (1); 765 766 return (pm_S3_enabled); 767 } 768 769 void 770 i_cpr_bitmap_cleanup(void) 771 { 772 } 773 774 void 775 i_cpr_free_memory_resources(void) 776 { 777 } 778 779 /* 780 * Needed only for S3 so far 781 */ 782 static int 783 i_cpr_platform_alloc(psm_state_request_t *req) 784 { 785 #ifdef DEBUG 786 char *str = "i_cpr_platform_alloc"; 787 #endif 788 789 PMD(PMD_SX, ("cpu = %d, %s(%p) \n", CPU->cpu_id, str, (void *)req)) 790 791 if (psm_state == NULL) { 792 PMD(PMD_SX, ("%s() : psm_state == NULL\n", str)) 793 return (0); 794 } 795 796 req->psr_cmd = PSM_STATE_ALLOC; 797 return ((*psm_state)(req)); 798 } 799 800 /* 801 * Needed only for S3 so far 802 */ 803 static void 804 i_cpr_platform_free(psm_state_request_t *req) 805 { 806 #ifdef DEBUG 807 char *str = "i_cpr_platform_free"; 808 #endif 809 810 PMD(PMD_SX, ("cpu = %d, %s(%p) \n", CPU->cpu_id, str, (void *)req)) 811 812 if (psm_state == NULL) { 813 PMD(PMD_SX, ("%s() : psm_state == NULL\n", str)) 814 return; 815 } 816 817 req->psr_cmd = PSM_STATE_FREE; 818 (void) (*psm_state)(req); 819 } 820 821 static int 822 i_cpr_save_apic(psm_state_request_t *req) 823 { 824 #ifdef DEBUG 825 char *str = "i_cpr_save_apic"; 826 #endif 827 828 if (psm_state == NULL) { 829 PMD(PMD_SX, ("%s() : psm_state == NULL\n", str)) 830 return (0); 831 } 832 833 req->psr_cmd = PSM_STATE_SAVE; 834 return ((*psm_state)(req)); 835 } 836 837 static int 838 i_cpr_restore_apic(psm_state_request_t *req) 839 { 840 #ifdef DEBUG 841 char *str = "i_cpr_restore_apic"; 842 #endif 843 844 if (psm_state == NULL) { 845 PMD(PMD_SX, ("%s() : psm_state == NULL\n", str)) 846 return (0); 847 } 848 849 req->psr_cmd = PSM_STATE_RESTORE; 850 return ((*psm_state)(req)); 851 } 852 853 854 /* stop lint complaining about offset not being used in 32bit mode */ 855 #if !defined(__amd64) 856 /*ARGSUSED*/ 857 #endif 858 static void 859 init_real_mode_platter(int cpun, uint32_t offset, uint_t cr4, wc_desctbr_t gdt) 860 { 861 /*LINTED*/ 862 rm_platter_t *real_mode_platter = (rm_platter_t *)rm_platter_va; 863 864 /* 865 * Fill up the real mode platter to make it easy for real mode code to 866 * kick it off. This area should really be one passed by boot to kernel 867 * and guaranteed to be below 1MB and aligned to 16 bytes. Should also 868 * have identical physical and virtual address in paged mode. 869 */ 870 871 real_mode_platter->rm_pdbr = getcr3(); 872 real_mode_platter->rm_cpu = cpun; 873 real_mode_platter->rm_cr4 = cr4; 874 875 real_mode_platter->rm_gdt_base = gdt.base; 876 real_mode_platter->rm_gdt_lim = gdt.limit; 877 878 #if defined(__amd64) 879 real_mode_platter->rm_x86feature = x86_feature; 880 881 if (getcr3() > 0xffffffffUL) 882 panic("Cannot initialize CPUs; kernel's 64-bit page tables\n" 883 "located above 4G in physical memory (@ 0x%llx).", 884 (unsigned long long)getcr3()); 885 886 /* 887 * Setup pseudo-descriptors for temporary GDT and IDT for use ONLY 888 * by code in real_mode_start(): 889 * 890 * GDT[0]: NULL selector 891 * GDT[1]: 64-bit CS: Long = 1, Present = 1, bits 12, 11 = 1 892 * 893 * Clear the IDT as interrupts will be off and a limit of 0 will cause 894 * the CPU to triple fault and reset on an NMI, seemingly as reasonable 895 * a course of action as any other, though it may cause the entire 896 * platform to reset in some cases... 897 */ 898 real_mode_platter->rm_temp_gdt[0] = 0ULL; 899 real_mode_platter->rm_temp_gdt[TEMPGDT_KCODE64] = 0x20980000000000ULL; 900 901 real_mode_platter->rm_temp_gdt_lim = (ushort_t) 902 (sizeof (real_mode_platter->rm_temp_gdt) - 1); 903 real_mode_platter->rm_temp_gdt_base = rm_platter_pa + 904 (uint32_t)(&((rm_platter_t *)0)->rm_temp_gdt); 905 906 real_mode_platter->rm_temp_idt_lim = 0; 907 real_mode_platter->rm_temp_idt_base = 0; 908 909 /* 910 * Since the CPU needs to jump to protected mode using an identity 911 * mapped address, we need to calculate it here. 912 */ 913 real_mode_platter->rm_longmode64_addr = rm_platter_pa + offset; 914 #endif /* __amd64 */ 915 916 /* return; */ 917 } 918 919 void 920 i_cpr_start_cpu(void) 921 { 922 923 struct cpu *cp = CPU; 924 925 char *str = "i_cpr_start_cpu"; 926 extern void init_cpu_syscall(struct cpu *cp); 927 928 PMD(PMD_SX, ("%s() called\n", str)) 929 930 PMD(PMD_SX, ("%s() #0 cp->cpu_base_spl %d\n", str, 931 cp->cpu_base_spl)) 932 933 mutex_enter(&cpu_lock); 934 if (cp == i_cpr_bootcpu()) { 935 mutex_exit(&cpu_lock); 936 PMD(PMD_SX, 937 ("%s() called on bootcpu nothing to do!\n", str)) 938 return; 939 } 940 mutex_exit(&cpu_lock); 941 942 /* 943 * We need to Sync PAT with cpu0's PAT. We have to do 944 * this with interrupts disabled. 945 */ 946 if (x86_feature & X86_PAT) 947 pat_sync(); 948 949 /* 950 * Initialize this CPU's syscall handlers 951 */ 952 init_cpu_syscall(cp); 953 954 PMD(PMD_SX, ("%s() #1 cp->cpu_base_spl %d\n", str, cp->cpu_base_spl)) 955 956 /* 957 * Do not need to call cpuid_pass2(), cpuid_pass3(), cpuid_pass4() or 958 * init_cpu_info(), since the work that they do is only needed to 959 * be done once at boot time 960 */ 961 962 963 mutex_enter(&cpu_lock); 964 CPUSET_ADD(procset, cp->cpu_id); 965 mutex_exit(&cpu_lock); 966 967 PMD(PMD_SX, ("%s() #2 cp->cpu_base_spl %d\n", str, 968 cp->cpu_base_spl)) 969 970 if (tsc_gethrtime_enable) { 971 PMD(PMD_SX, ("%s() calling tsc_sync_slave\n", str)) 972 tsc_sync_slave(); 973 } 974 975 PMD(PMD_SX, ("%s() cp->cpu_id %d, cp->cpu_intr_actv %d\n", str, 976 cp->cpu_id, cp->cpu_intr_actv)) 977 PMD(PMD_SX, ("%s() #3 cp->cpu_base_spl %d\n", str, 978 cp->cpu_base_spl)) 979 980 (void) spl0(); /* enable interrupts */ 981 982 PMD(PMD_SX, ("%s() #4 cp->cpu_base_spl %d\n", str, 983 cp->cpu_base_spl)) 984 985 /* 986 * Set up the CPU module for this CPU. This can't be done before 987 * this CPU is made CPU_READY, because we may (in heterogeneous systems) 988 * need to go load another CPU module. The act of attempting to load 989 * a module may trigger a cross-call, which will ASSERT unless this 990 * cpu is CPU_READY. 991 */ 992 993 /* 994 * cmi already been init'd (during boot), so do not need to do it again 995 */ 996 #ifdef PM_REINITMCAONRESUME 997 if (x86_feature & X86_MCA) 998 cmi_mca_init(); 999 #endif 1000 1001 PMD(PMD_SX, ("%s() returning\n", str)) 1002 1003 /* return; */ 1004 } 1005 1006 void 1007 i_cpr_alloc_cpus(void) 1008 { 1009 char *str = "i_cpr_alloc_cpus"; 1010 1011 PMD(PMD_SX, ("%s() CPU->cpu_id %d\n", str, CPU->cpu_id)) 1012 /* 1013 * we allocate this only when we actually need it to save on 1014 * kernel memory 1015 */ 1016 1017 if (wc_other_cpus == NULL) { 1018 wc_other_cpus = kmem_zalloc(max_ncpus * sizeof (wc_cpu_t), 1019 KM_SLEEP); 1020 } 1021 1022 } 1023 1024 void 1025 i_cpr_free_cpus(void) 1026 { 1027 int index; 1028 wc_cpu_t *wc_cpu; 1029 1030 if (wc_other_cpus != NULL) { 1031 for (index = 0; index < max_ncpus; index++) { 1032 wc_cpu = wc_other_cpus + index; 1033 if (wc_cpu->wc_saved_stack != NULL) { 1034 kmem_free(wc_cpu->wc_saved_stack, 1035 wc_cpu->wc_saved_stack_size); 1036 } 1037 } 1038 1039 kmem_free((void *) wc_other_cpus, 1040 max_ncpus * sizeof (wc_cpu_t)); 1041 wc_other_cpus = NULL; 1042 } 1043 } 1044 1045 /* 1046 * wrapper for acpica_ddi_save_resources() 1047 */ 1048 void 1049 i_cpr_save_configuration(dev_info_t *dip) 1050 { 1051 acpica_ddi_save_resources(dip); 1052 } 1053 1054 /* 1055 * wrapper for acpica_ddi_restore_resources() 1056 */ 1057 void 1058 i_cpr_restore_configuration(dev_info_t *dip) 1059 { 1060 acpica_ddi_restore_resources(dip); 1061 } 1062 1063 static int 1064 wait_for_set(cpuset_t *set, int who) 1065 { 1066 int delays; 1067 char *str = "wait_for_set"; 1068 1069 for (delays = 0; !CPU_IN_SET(*set, who); delays++) { 1070 if (delays == 500) { 1071 /* 1072 * After five seconds, things are probably 1073 * looking a bit bleak - explain the hang. 1074 */ 1075 cmn_err(CE_NOTE, "cpu%d: started, " 1076 "but not running in the kernel yet", who); 1077 PMD(PMD_SX, ("%s() %d cpu started " 1078 "but not running in the kernel yet\n", 1079 str, who)) 1080 } else if (delays > 2000) { 1081 /* 1082 * We waited at least 20 seconds, bail .. 1083 */ 1084 cmn_err(CE_WARN, "cpu%d: timed out", who); 1085 PMD(PMD_SX, ("%s() %d cpu timed out\n", 1086 str, who)) 1087 return (0); 1088 } 1089 1090 /* 1091 * wait at least 10ms, then check again.. 1092 */ 1093 drv_usecwait(10000); 1094 } 1095 1096 return (1); 1097 } 1098 1099 static void 1100 i_cpr_save_stack(kthread_t *t, wc_cpu_t *wc_cpu) 1101 { 1102 size_t stack_size; /* size of stack */ 1103 caddr_t start = CPR_GET_STACK_START(t); /* stack start */ 1104 caddr_t end = CPR_GET_STACK_END(t); /* stack end */ 1105 1106 stack_size = (size_t)end - (size_t)start; 1107 1108 if (wc_cpu->wc_saved_stack_size < stack_size) { 1109 if (wc_cpu->wc_saved_stack != NULL) { 1110 kmem_free(wc_cpu->wc_saved_stack, 1111 wc_cpu->wc_saved_stack_size); 1112 } 1113 wc_cpu->wc_saved_stack = kmem_zalloc(stack_size, KM_SLEEP); 1114 wc_cpu->wc_saved_stack_size = stack_size; 1115 } 1116 1117 bcopy(start, wc_cpu->wc_saved_stack, stack_size); 1118 } 1119 1120 void 1121 i_cpr_restore_stack(kthread_t *t, greg_t *save_stack) 1122 { 1123 size_t stack_size; /* size of stack */ 1124 caddr_t start = CPR_GET_STACK_START(t); /* stack start */ 1125 caddr_t end = CPR_GET_STACK_END(t); /* stack end */ 1126 1127 stack_size = (size_t)end - (size_t)start; 1128 1129 bcopy(save_stack, start, stack_size); 1130 } 1131