xref: /titanic_44/usr/src/uts/sun4v/os/mach_cpu_states.c (revision b81bb599d2182818b41e3bbe6d4d1771b9d484d4)
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 2006 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #pragma ident	"%Z%%M%	%I%	%E% SMI"
27 
28 #include <sys/types.h>
29 #include <sys/systm.h>
30 #include <sys/archsystm.h>
31 #include <sys/t_lock.h>
32 #include <sys/uadmin.h>
33 #include <sys/panic.h>
34 #include <sys/reboot.h>
35 #include <sys/autoconf.h>
36 #include <sys/machsystm.h>
37 #include <sys/promif.h>
38 #include <sys/membar.h>
39 #include <vm/hat_sfmmu.h>
40 #include <sys/cpu_module.h>
41 #include <sys/cpu_sgnblk_defs.h>
42 #include <sys/intreg.h>
43 #include <sys/consdev.h>
44 #include <sys/kdi_impl.h>
45 #include <sys/traptrace.h>
46 #include <sys/hypervisor_api.h>
47 #include <sys/vmsystm.h>
48 #include <sys/dtrace.h>
49 #include <sys/xc_impl.h>
50 #include <sys/callb.h>
51 #include <sys/mdesc.h>
52 #include <sys/mach_descrip.h>
53 #include <sys/wdt.h>
54 
55 /*
56  * hvdump_buf_va is a pointer to the currently-configured hvdump_buf.
57  * A value of NULL indicates that this area is not configured.
58  * hvdump_buf_sz is tunable but will be clamped to HVDUMP_SIZE_MAX.
59  */
60 
61 caddr_t hvdump_buf_va;
62 uint64_t hvdump_buf_sz = HVDUMP_SIZE_DEFAULT;
63 static uint64_t hvdump_buf_pa;
64 
65 u_longlong_t panic_tick;
66 
67 extern u_longlong_t gettick();
68 static void reboot_machine(char *);
69 static void update_hvdump_buffer(void);
70 
71 /*
72  * For xt_sync synchronization.
73  */
74 extern uint64_t xc_tick_limit;
75 extern uint64_t xc_tick_jump_limit;
76 
77 /*
78  * We keep our own copies, used for cache flushing, because we can be called
79  * before cpu_fiximpl().
80  */
81 static int kdi_dcache_size;
82 static int kdi_dcache_linesize;
83 static int kdi_icache_size;
84 static int kdi_icache_linesize;
85 
86 /*
87  * Assembly support for generic modules in sun4v/ml/mach_xc.s
88  */
89 extern void init_mondo_nocheck(xcfunc_t *func, uint64_t arg1, uint64_t arg2);
90 extern void kdi_flush_idcache(int, int, int, int);
91 extern uint64_t get_cpuaddr(uint64_t, uint64_t);
92 
93 /*
94  * Machine dependent code to reboot.
95  * "mdep" is interpreted as a character pointer; if non-null, it is a pointer
96  * to a string to be used as the argument string when rebooting.
97  *
98  * "invoke_cb" is a boolean. It is set to true when mdboot() can safely
99  * invoke CB_CL_MDBOOT callbacks before shutting the system down, i.e. when
100  * we are in a normal shutdown sequence (interrupts are not blocked, the
101  * system is not panic'ing or being suspended).
102  */
103 /*ARGSUSED*/
104 void
105 mdboot(int cmd, int fcn, char *bootstr, boolean_t invoke_cb)
106 {
107 	extern void pm_cfb_check_and_powerup(void);
108 
109 	/*
110 	 * XXX - rconsvp is set to NULL to ensure that output messages
111 	 * are sent to the underlying "hardware" device using the
112 	 * monitor's printf routine since we are in the process of
113 	 * either rebooting or halting the machine.
114 	 */
115 	rconsvp = NULL;
116 
117 	/*
118 	 * At a high interrupt level we can't:
119 	 *	1) bring up the console
120 	 * or
121 	 *	2) wait for pending interrupts prior to redistribution
122 	 *	   to the current CPU
123 	 *
124 	 * so we do them now.
125 	 */
126 	pm_cfb_check_and_powerup();
127 
128 	/* make sure there are no more changes to the device tree */
129 	devtree_freeze();
130 
131 	if (invoke_cb)
132 		(void) callb_execute_class(CB_CL_MDBOOT, NULL);
133 
134 	/*
135 	 * Clear any unresolved UEs from memory.
136 	 */
137 	if (memsegs != NULL)
138 		page_retire_hunt(page_retire_mdboot_cb);
139 
140 	/*
141 	 * stop other cpus which also raise our priority. since there is only
142 	 * one active cpu after this, and our priority will be too high
143 	 * for us to be preempted, we're essentially single threaded
144 	 * from here on out.
145 	 */
146 	stop_other_cpus();
147 
148 	/*
149 	 * try and reset leaf devices.  reset_leaves() should only
150 	 * be called when there are no other threads that could be
151 	 * accessing devices
152 	 */
153 	reset_leaves();
154 
155 	watchdog_clear();
156 
157 	if (fcn == AD_HALT) {
158 		halt((char *)NULL);
159 	} else if (fcn == AD_POWEROFF) {
160 		power_down(NULL);
161 	} else {
162 		if (bootstr == NULL) {
163 			switch (fcn) {
164 
165 			case AD_BOOT:
166 				bootstr = "";
167 				break;
168 
169 			case AD_IBOOT:
170 				bootstr = "-a";
171 				break;
172 
173 			case AD_SBOOT:
174 				bootstr = "-s";
175 				break;
176 
177 			case AD_SIBOOT:
178 				bootstr = "-sa";
179 				break;
180 			default:
181 				cmn_err(CE_WARN,
182 				    "mdboot: invalid function %d", fcn);
183 				bootstr = "";
184 				break;
185 			}
186 		}
187 		reboot_machine(bootstr);
188 	}
189 	/* MAYBE REACHED */
190 }
191 
192 /* mdpreboot - may be called prior to mdboot while root fs still mounted */
193 /*ARGSUSED*/
194 void
195 mdpreboot(int cmd, int fcn, char *bootstr)
196 {
197 }
198 
199 /*
200  * Halt the machine and then reboot with the device
201  * and arguments specified in bootstr.
202  */
203 static void
204 reboot_machine(char *bootstr)
205 {
206 	flush_windows();
207 	stop_other_cpus();		/* send stop signal to other CPUs */
208 	prom_printf("rebooting...\n");
209 	/*
210 	 * For platforms that use CPU signatures, we
211 	 * need to set the signature block to OS and
212 	 * the state to exiting for all the processors.
213 	 */
214 	CPU_SIGNATURE(OS_SIG, SIGST_EXIT, SIGSUBST_REBOOT, -1);
215 	prom_reboot(bootstr);
216 	/*NOTREACHED*/
217 }
218 
219 /*
220  * We use the x-trap mechanism and idle_stop_xcall() to stop the other CPUs.
221  * Once in panic_idle() they raise spl, record their location, and spin.
222  */
223 static void
224 panic_idle(void)
225 {
226 	(void) spl7();
227 
228 	debug_flush_windows();
229 	(void) setjmp(&curthread->t_pcb);
230 
231 	CPU->cpu_m.in_prom = 1;
232 	membar_stld();
233 
234 	for (;;);
235 }
236 
237 /*
238  * Force the other CPUs to trap into panic_idle(), and then remove them
239  * from the cpu_ready_set so they will no longer receive cross-calls.
240  */
241 /*ARGSUSED*/
242 void
243 panic_stopcpus(cpu_t *cp, kthread_t *t, int spl)
244 {
245 	cpuset_t cps;
246 	int i;
247 
248 	(void) splzs();
249 	CPUSET_ALL_BUT(cps, cp->cpu_id);
250 	xt_some(cps, (xcfunc_t *)idle_stop_xcall, (uint64_t)&panic_idle, NULL);
251 
252 	for (i = 0; i < NCPU; i++) {
253 		if (i != cp->cpu_id && CPU_XCALL_READY(i)) {
254 			int ntries = 0x10000;
255 
256 			while (!cpu[i]->cpu_m.in_prom && ntries) {
257 				DELAY(50);
258 				ntries--;
259 			}
260 
261 			if (!cpu[i]->cpu_m.in_prom)
262 				printf("panic: failed to stop cpu%d\n", i);
263 
264 			cpu[i]->cpu_flags &= ~CPU_READY;
265 			cpu[i]->cpu_flags |= CPU_QUIESCED;
266 			CPUSET_DEL(cpu_ready_set, cpu[i]->cpu_id);
267 		}
268 	}
269 }
270 
271 /*
272  * Platform callback following each entry to panicsys().  If we've panicked at
273  * level 14, we examine t_panic_trap to see if a fatal trap occurred.  If so,
274  * we disable further %tick_cmpr interrupts.  If not, an explicit call to panic
275  * was made and so we re-enqueue an interrupt request structure to allow
276  * further level 14 interrupts to be processed once we lower PIL.  This allows
277  * us to handle panics from the deadman() CY_HIGH_LEVEL cyclic.
278  */
279 void
280 panic_enter_hw(int spl)
281 {
282 	if (!panic_tick) {
283 		panic_tick = gettick();
284 		if (mach_htraptrace_enable) {
285 			uint64_t prev_freeze;
286 
287 			/*  there are no possible error codes for this hcall */
288 			(void) hv_ttrace_freeze((uint64_t)TRAP_TFREEZE_ALL,
289 			    &prev_freeze);
290 		}
291 #ifdef TRAPTRACE
292 		TRAPTRACE_FREEZE;
293 #endif
294 	}
295 	if (spl == ipltospl(PIL_14)) {
296 		uint_t opstate = disable_vec_intr();
297 
298 		if (curthread->t_panic_trap != NULL) {
299 			tickcmpr_disable();
300 			intr_dequeue_req(PIL_14, cbe_level14_inum);
301 		} else {
302 			if (!tickcmpr_disabled())
303 				intr_enqueue_req(PIL_14, cbe_level14_inum);
304 			/*
305 			 * Clear SOFTINT<14>, SOFTINT<0> (TICK_INT)
306 			 * and SOFTINT<16> (STICK_INT) to indicate
307 			 * that the current level 14 has been serviced.
308 			 */
309 			wr_clr_softint((1 << PIL_14) |
310 				TICK_INT_MASK | STICK_INT_MASK);
311 		}
312 
313 		enable_vec_intr(opstate);
314 	}
315 }
316 
317 /*
318  * Miscellaneous hardware-specific code to execute after panicstr is set
319  * by the panic code: we also print and record PTL1 panic information here.
320  */
321 /*ARGSUSED*/
322 void
323 panic_quiesce_hw(panic_data_t *pdp)
324 {
325 	extern uint_t getpstate(void);
326 	extern void setpstate(uint_t);
327 
328 	/*
329 	 * Turn off TRAPTRACE and save the current %tick value in panic_tick.
330 	 */
331 	if (!panic_tick) {
332 		panic_tick = gettick();
333 		if (mach_htraptrace_enable) {
334 			uint64_t prev_freeze;
335 
336 			/*  there are no possible error codes for this hcall */
337 			(void) hv_ttrace_freeze((uint64_t)TRAP_TFREEZE_ALL,
338 			    &prev_freeze);
339 		}
340 #ifdef TRAPTRACE
341 		TRAPTRACE_FREEZE;
342 #endif
343 	}
344 	/*
345 	 * For Platforms that use CPU signatures, we
346 	 * need to set the signature block to OS, the state to
347 	 * exiting, and the substate to panic for all the processors.
348 	 */
349 	CPU_SIGNATURE(OS_SIG, SIGST_EXIT, SIGSUBST_PANIC, -1);
350 
351 	update_hvdump_buffer();
352 
353 	/*
354 	 * Disable further ECC errors from the bus nexus.
355 	 */
356 	(void) bus_func_invoke(BF_TYPE_ERRDIS);
357 
358 	/*
359 	 * Redirect all interrupts to the current CPU.
360 	 */
361 	intr_redist_all_cpus_shutdown();
362 
363 	/*
364 	 * This call exists solely to support dumps to network
365 	 * devices after sync from OBP.
366 	 *
367 	 * If we came here via the sync callback, then on some
368 	 * platforms, interrupts may have arrived while we were
369 	 * stopped in OBP.  OBP will arrange for those interrupts to
370 	 * be redelivered if you say "go", but not if you invoke a
371 	 * client callback like 'sync'.	 For some dump devices
372 	 * (network swap devices), we need interrupts to be
373 	 * delivered in order to dump, so we have to call the bus
374 	 * nexus driver to reset the interrupt state machines.
375 	 */
376 	(void) bus_func_invoke(BF_TYPE_RESINTR);
377 
378 	setpstate(getpstate() | PSTATE_IE);
379 }
380 
381 /*
382  * Platforms that use CPU signatures need to set the signature block to OS and
383  * the state to exiting for all CPUs. PANIC_CONT indicates that we're about to
384  * write the crash dump, which tells the SSP/SMS to begin a timeout routine to
385  * reboot the machine if the dump never completes.
386  */
387 /*ARGSUSED*/
388 void
389 panic_dump_hw(int spl)
390 {
391 	CPU_SIGNATURE(OS_SIG, SIGST_EXIT, SIGSUBST_DUMP, -1);
392 }
393 
394 /*
395  * for ptl1_panic
396  */
397 void
398 ptl1_init_cpu(struct cpu *cpu)
399 {
400 	ptl1_state_t *pstate = &cpu->cpu_m.ptl1_state;
401 
402 	/*CONSTCOND*/
403 	if (sizeof (struct cpu) + PTL1_SSIZE > CPU_ALLOC_SIZE) {
404 		panic("ptl1_init_cpu: not enough space left for ptl1_panic "
405 		    "stack, sizeof (struct cpu) = %lu",
406 		    (unsigned long)sizeof (struct cpu));
407 	}
408 
409 	pstate->ptl1_stktop = (uintptr_t)cpu + CPU_ALLOC_SIZE;
410 	cpu_pa[cpu->cpu_id] = va_to_pa(cpu);
411 }
412 
413 void
414 ptl1_panic_handler(ptl1_state_t *pstate)
415 {
416 	static const char *ptl1_reasons[] = {
417 #ifdef	PTL1_PANIC_DEBUG
418 		"trap for debug purpose",	/* PTL1_BAD_DEBUG */
419 #else
420 		"unknown trap",			/* PTL1_BAD_DEBUG */
421 #endif
422 		"register window trap",		/* PTL1_BAD_WTRAP */
423 		"kernel MMU miss",		/* PTL1_BAD_KMISS */
424 		"kernel protection fault",	/* PTL1_BAD_KPROT_FAULT */
425 		"ISM MMU miss",			/* PTL1_BAD_ISM */
426 		"kernel MMU trap",		/* PTL1_BAD_MMUTRAP */
427 		"kernel trap handler state",	/* PTL1_BAD_TRAP */
428 		"floating point trap",		/* PTL1_BAD_FPTRAP */
429 #ifdef	DEBUG
430 		"pointer to intr_req",		/* PTL1_BAD_INTR_REQ */
431 #else
432 		"unknown trap",			/* PTL1_BAD_INTR_REQ */
433 #endif
434 #ifdef	TRAPTRACE
435 		"TRACE_PTR state",		/* PTL1_BAD_TRACE_PTR */
436 #else
437 		"unknown trap",			/* PTL1_BAD_TRACE_PTR */
438 #endif
439 		"stack overflow",		/* PTL1_BAD_STACK */
440 		"DTrace flags",			/* PTL1_BAD_DTRACE_FLAGS */
441 		"attempt to steal locked ctx",  /* PTL1_BAD_CTX_STEAL */
442 		"CPU ECC error loop",		/* PTL1_BAD_ECC */
443 		"unexpected error from hypervisor call", /* PTL1_BAD_HCALL */
444 		"unexpected global level(%gl)", /* PTL1_BAD_GL */
445 		"Watchdog Reset", 		/* PTL1_BAD_WATCHDOG */
446 		"unexpected RED mode trap", 	/* PTL1_BAD_RED */
447 		"return value EINVAL from hcall: "\
448 		    "UNMAP_PERM_ADDR",	/* PTL1_BAD_HCALL_UNMAP_PERM_EINVAL */
449 		"return value ENOMAP from hcall: "\
450 		    "UNMAP_PERM_ADDR", /* PTL1_BAD_HCALL_UNMAP_PERM_ENOMAP */
451 	};
452 
453 	uint_t reason = pstate->ptl1_regs.ptl1_gregs[0].ptl1_g1;
454 	uint_t tl = pstate->ptl1_regs.ptl1_trap_regs[0].ptl1_tl;
455 	struct trap_info ti = { 0 };
456 
457 	/*
458 	 * Use trap_info for a place holder to call panic_savetrap() and
459 	 * panic_showtrap() to save and print out ptl1_panic information.
460 	 */
461 	if (curthread->t_panic_trap == NULL)
462 		curthread->t_panic_trap = &ti;
463 
464 	if (reason < sizeof (ptl1_reasons) / sizeof (ptl1_reasons[0]))
465 		panic("bad %s at TL %u", ptl1_reasons[reason], tl);
466 	else
467 		panic("ptl1_panic reason 0x%x at TL %u", reason, tl);
468 }
469 
470 void
471 clear_watchdog_on_exit(void)
472 {
473 	prom_printf("Debugging requested; hardware watchdog suspended.\n");
474 	(void) watchdog_suspend();
475 }
476 
477 /*
478  * Restore the watchdog timer when returning from a debugger
479  * after a panic or L1-A and resume watchdog pat.
480  */
481 void
482 restore_watchdog_on_entry()
483 {
484 	watchdog_resume();
485 }
486 
487 int
488 kdi_watchdog_disable(void)
489 {
490 	watchdog_suspend();
491 
492 	return (0);
493 }
494 
495 void
496 kdi_watchdog_restore(void)
497 {
498 	watchdog_resume();
499 }
500 
501 void
502 mach_dump_buffer_init(void)
503 {
504 	uint64_t  ret, minsize = 0;
505 
506 	if (hvdump_buf_sz > HVDUMP_SIZE_MAX)
507 		hvdump_buf_sz = HVDUMP_SIZE_MAX;
508 
509 	hvdump_buf_va = contig_mem_alloc_align(hvdump_buf_sz, PAGESIZE);
510 	if (hvdump_buf_va == NULL)
511 		return;
512 
513 	hvdump_buf_pa = va_to_pa(hvdump_buf_va);
514 
515 	ret = hv_dump_buf_update(hvdump_buf_pa, hvdump_buf_sz,
516 	    &minsize);
517 
518 	if (ret != H_EOK) {
519 		contig_mem_free(hvdump_buf_va, hvdump_buf_sz);
520 		hvdump_buf_va = NULL;
521 		cmn_err(CE_NOTE, "!Error in setting up hvstate"
522 		    "dump buffer. Error = 0x%lx, size = 0x%lx,"
523 		    "buf_pa = 0x%lx", ret, hvdump_buf_sz,
524 		    hvdump_buf_pa);
525 
526 		if (ret == H_EINVAL) {
527 			cmn_err(CE_NOTE, "!Buffer size too small."
528 			    "Available buffer size = 0x%lx,"
529 			    "Minimum buffer size required = 0x%lx",
530 			    hvdump_buf_sz, minsize);
531 		}
532 	}
533 }
534 
535 
536 static void
537 update_hvdump_buffer(void)
538 {
539 	uint64_t ret, dummy_val;
540 
541 	if (hvdump_buf_va == NULL)
542 		return;
543 
544 	ret = hv_dump_buf_update(hvdump_buf_pa, hvdump_buf_sz,
545 	    &dummy_val);
546 	if (ret != H_EOK) {
547 		cmn_err(CE_NOTE, "!Cannot update hvstate dump"
548 		    "buffer. Error = 0x%lx", ret);
549 	}
550 }
551 
552 
553 static int
554 getintprop(pnode_t node, char *name, int deflt)
555 {
556 	int	value;
557 
558 	switch (prom_getproplen(node, name)) {
559 	case 0:
560 		value = 1;	/* boolean properties */
561 		break;
562 
563 	case sizeof (int):
564 		(void) prom_getprop(node, name, (caddr_t)&value);
565 		break;
566 
567 	default:
568 		value = deflt;
569 		break;
570 	}
571 
572 	return (value);
573 }
574 
575 /*
576  * Called by setcpudelay
577  */
578 void
579 cpu_init_tick_freq(void)
580 {
581 	md_t *mdp;
582 	mde_cookie_t rootnode;
583 	int		listsz;
584 	mde_cookie_t	*listp = NULL;
585 	int	num_nodes;
586 	uint64_t stick_prop;
587 
588 	if (broken_md_flag) {
589 		sys_tick_freq = cpunodes[CPU->cpu_id].clock_freq;
590 		return;
591 	}
592 
593 	if ((mdp = md_get_handle()) == NULL)
594 		panic("stick_frequency property not found in MD");
595 
596 	rootnode = md_root_node(mdp);
597 	ASSERT(rootnode != MDE_INVAL_ELEM_COOKIE);
598 
599 	num_nodes = md_node_count(mdp);
600 
601 	ASSERT(num_nodes > 0);
602 	listsz = num_nodes * sizeof (mde_cookie_t);
603 	listp = (mde_cookie_t *)prom_alloc((caddr_t)0, listsz, 0);
604 
605 	if (listp == NULL)
606 		panic("cannot allocate list for MD properties");
607 
608 	num_nodes = md_scan_dag(mdp, rootnode, md_find_name(mdp, "platform"),
609 	    md_find_name(mdp, "fwd"), listp);
610 
611 	ASSERT(num_nodes == 1);
612 
613 	if (md_get_prop_val(mdp, *listp, "stick-frequency", &stick_prop) != 0)
614 		panic("stick_frequency property not found in MD");
615 
616 	sys_tick_freq = stick_prop;
617 
618 	prom_free((caddr_t)listp, listsz);
619 	(void) md_fini_handle(mdp);
620 }
621 
622 int shipit(int n, uint64_t cpu_list_ra);
623 extern uint64_t xc_tick_limit;
624 extern uint64_t xc_tick_jump_limit;
625 
626 #ifdef DEBUG
627 #define	SEND_MONDO_STATS	1
628 #endif
629 
630 #ifdef SEND_MONDO_STATS
631 uint32_t x_one_stimes[64];
632 uint32_t x_one_ltimes[16];
633 uint32_t x_set_stimes[64];
634 uint32_t x_set_ltimes[16];
635 uint32_t x_set_cpus[NCPU];
636 #endif
637 
638 void
639 send_one_mondo(int cpuid)
640 {
641 	int retries, stat;
642 	uint64_t starttick, endtick, tick, lasttick;
643 	struct machcpu	*mcpup = &(CPU->cpu_m);
644 
645 	CPU_STATS_ADDQ(CPU, sys, xcalls, 1);
646 	starttick = lasttick = gettick();
647 	mcpup->cpu_list[0] = (uint16_t)cpuid;
648 	stat = shipit(1, mcpup->cpu_list_ra);
649 	endtick = starttick + xc_tick_limit;
650 	retries = 0;
651 	while (stat != H_EOK) {
652 		if (stat != H_EWOULDBLOCK) {
653 			if (panic_quiesce)
654 				return;
655 			if (stat == H_ECPUERROR)
656 				cmn_err(CE_PANIC, "send_one_mondo: "
657 				    "cpuid: 0x%x has been marked in "
658 				    "error", cpuid);
659 			else
660 				cmn_err(CE_PANIC, "send_one_mondo: "
661 				    "unexpected hypervisor error 0x%x "
662 				    "while sending a mondo to cpuid: "
663 				    "0x%x", stat, cpuid);
664 		}
665 		tick = gettick();
666 		/*
667 		 * If there is a big jump between the current tick
668 		 * count and lasttick, we have probably hit a break
669 		 * point.  Adjust endtick accordingly to avoid panic.
670 		 */
671 		if (tick > (lasttick + xc_tick_jump_limit))
672 			endtick += (tick - lasttick);
673 		lasttick = tick;
674 		if (tick > endtick) {
675 			if (panic_quiesce)
676 				return;
677 			cmn_err(CE_PANIC, "send mondo timeout "
678 			    "(target 0x%x) [retries: 0x%x hvstat: 0x%x]",
679 			    cpuid, retries, stat);
680 		}
681 		drv_usecwait(1);
682 		stat = shipit(1, mcpup->cpu_list_ra);
683 		retries++;
684 	}
685 #ifdef SEND_MONDO_STATS
686 	{
687 		uint64_t n = gettick() - starttick;
688 		if (n < 8192)
689 			x_one_stimes[n >> 7]++;
690 		else if (n < 15*8192)
691 			x_one_ltimes[n >> 13]++;
692 		else
693 			x_one_ltimes[0xf]++;
694 	}
695 #endif
696 }
697 
698 void
699 send_mondo_set(cpuset_t set)
700 {
701 	uint64_t starttick, endtick, tick, lasttick;
702 	uint_t largestid, smallestid;
703 	int i, j;
704 	int ncpuids = 0;
705 	int shipped = 0;
706 	int retries = 0;
707 	struct machcpu	*mcpup = &(CPU->cpu_m);
708 
709 	ASSERT(!CPUSET_ISNULL(set));
710 	CPUSET_BOUNDS(set, smallestid, largestid);
711 	if (smallestid == CPUSET_NOTINSET) {
712 		return;
713 	}
714 
715 	starttick = lasttick = gettick();
716 	endtick = starttick + xc_tick_limit;
717 
718 	/*
719 	 * Assemble CPU list for HV argument. We already know
720 	 * smallestid and largestid are members of set.
721 	 */
722 	mcpup->cpu_list[ncpuids++] = (uint16_t)smallestid;
723 	if (largestid != smallestid) {
724 		for (i = smallestid+1; i <= largestid-1; i++) {
725 			if (CPU_IN_SET(set, i)) {
726 				mcpup->cpu_list[ncpuids++] = (uint16_t)i;
727 			}
728 		}
729 		mcpup->cpu_list[ncpuids++] = (uint16_t)largestid;
730 	}
731 
732 	do {
733 		int stat;
734 
735 		stat = shipit(ncpuids, mcpup->cpu_list_ra);
736 		if (stat == H_EOK) {
737 			shipped += ncpuids;
738 			break;
739 		}
740 
741 		/*
742 		 * Either not all CPU mondos were sent, or an
743 		 * error occurred. CPUs that were sent mondos
744 		 * have their CPU IDs overwritten in cpu_list.
745 		 * Reset cpu_list so that it only holds those
746 		 * CPU IDs that still need to be sent.
747 		 */
748 		for (i = 0, j = 0; i < ncpuids; i++) {
749 			if (mcpup->cpu_list[i] == HV_SEND_MONDO_ENTRYDONE) {
750 				shipped++;
751 			} else {
752 				mcpup->cpu_list[j++] = mcpup->cpu_list[i];
753 			}
754 		}
755 		ncpuids = j;
756 
757 		/*
758 		 * Now handle possible errors returned
759 		 * from hypervisor.
760 		 */
761 		if (stat == H_ECPUERROR) {
762 			int errorcpus;
763 
764 			if (!panic_quiesce)
765 				cmn_err(CE_CONT, "send_mondo_set: cpuid(s) ");
766 
767 			/*
768 			 * Remove any CPUs in the error state from
769 			 * cpu_list. At this point cpu_list only
770 			 * contains the CPU IDs for mondos not
771 			 * succesfully sent.
772 			 */
773 			for (i = 0, errorcpus = 0; i < ncpuids; i++) {
774 				uint64_t state = CPU_STATE_INVALID;
775 				uint16_t id = mcpup->cpu_list[i];
776 
777 				(void) hv_cpu_state(id, &state);
778 				if (state == CPU_STATE_ERROR) {
779 					if (!panic_quiesce)
780 						cmn_err(CE_CONT, "0x%x ", id);
781 					errorcpus++;
782 				} else if (errorcpus > 0) {
783 					mcpup->cpu_list[i - errorcpus] =
784 					    mcpup->cpu_list[i];
785 				}
786 			}
787 			ncpuids -= errorcpus;
788 
789 			if (!panic_quiesce) {
790 				if (errorcpus == 0) {
791 					cmn_err(CE_CONT, "<none> have been "
792 					    "marked in error\n");
793 					cmn_err(CE_PANIC, "send_mondo_set: "
794 					    "hypervisor returned "
795 					    "H_ECPUERROR but no CPU in "
796 					    "cpu_list in error state");
797 				} else {
798 					cmn_err(CE_CONT, "have been marked in "
799 					    "error\n");
800 					cmn_err(CE_PANIC, "send_mondo_set: "
801 					    "CPU(s) in error state");
802 				}
803 			}
804 		} else if (stat != H_EWOULDBLOCK) {
805 			if (panic_quiesce)
806 				return;
807 			/*
808 			 * For all other errors, panic.
809 			 */
810 			cmn_err(CE_CONT, "send_mondo_set: unexpected "
811 			    "hypervisor error 0x%x while sending a "
812 			    "mondo to cpuid(s):", stat);
813 			for (i = 0; i < ncpuids; i++) {
814 				cmn_err(CE_CONT, " 0x%x", mcpup->cpu_list[i]);
815 			}
816 			cmn_err(CE_CONT, "\n");
817 			cmn_err(CE_PANIC, "send_mondo_set: unexpected "
818 			    "hypervisor error");
819 		}
820 
821 		tick = gettick();
822 		/*
823 		 * If there is a big jump between the current tick
824 		 * count and lasttick, we have probably hit a break
825 		 * point.  Adjust endtick accordingly to avoid panic.
826 		 */
827 		if (tick > (lasttick + xc_tick_jump_limit))
828 			endtick += (tick - lasttick);
829 		lasttick = tick;
830 		if (tick > endtick) {
831 			if (panic_quiesce)
832 				return;
833 			cmn_err(CE_CONT, "send mondo timeout "
834 			    "[retries: 0x%x]  cpuids: ", retries);
835 			for (i = 0; i < ncpuids; i++)
836 				cmn_err(CE_CONT, " 0x%x", mcpup->cpu_list[i]);
837 			cmn_err(CE_CONT, "\n");
838 			cmn_err(CE_PANIC, "send_mondo_set: timeout");
839 		}
840 
841 		while (gettick() < (tick + sys_clock_mhz))
842 			;
843 		retries++;
844 	} while (ncpuids > 0);
845 
846 	CPU_STATS_ADDQ(CPU, sys, xcalls, shipped);
847 
848 #ifdef SEND_MONDO_STATS
849 	{
850 		uint64_t n = gettick() - starttick;
851 		if (n < 8192)
852 			x_set_stimes[n >> 7]++;
853 		else if (n < 15*8192)
854 			x_set_ltimes[n >> 13]++;
855 		else
856 			x_set_ltimes[0xf]++;
857 	}
858 	x_set_cpus[shipped]++;
859 #endif
860 }
861 
862 void
863 syncfpu(void)
864 {
865 }
866 
867 void
868 cpu_flush_ecache(void)
869 {
870 }
871 
872 void
873 sticksync_slave(void)
874 {}
875 
876 void
877 sticksync_master(void)
878 {}
879 
880 void
881 cpu_init_cache_scrub(void)
882 {}
883 
884 int
885 dtrace_blksuword32_err(uintptr_t addr, uint32_t *data)
886 {
887 	int ret, watched;
888 
889 	watched = watch_disable_addr((void *)addr, 4, S_WRITE);
890 	ret = dtrace_blksuword32(addr, data, 0);
891 	if (watched)
892 		watch_enable_addr((void *)addr, 4, S_WRITE);
893 
894 	return (ret);
895 }
896 
897 int
898 dtrace_blksuword32(uintptr_t addr, uint32_t *data, int tryagain)
899 {
900 	if (suword32((void *)addr, *data) == -1)
901 		return (tryagain ? dtrace_blksuword32_err(addr, data) : -1);
902 	dtrace_flush_sec(addr);
903 
904 	return (0);
905 }
906 
907 /*ARGSUSED*/
908 void
909 cpu_faulted_enter(struct cpu *cp)
910 {
911 }
912 
913 /*ARGSUSED*/
914 void
915 cpu_faulted_exit(struct cpu *cp)
916 {
917 }
918 
919 static int
920 kdi_cpu_ready_iter(int (*cb)(int, void *), void *arg)
921 {
922 	int rc, i;
923 
924 	for (rc = 0, i = 0; i < NCPU; i++) {
925 		if (CPU_IN_SET(cpu_ready_set, i))
926 			rc += cb(i, arg);
927 	}
928 
929 	return (rc);
930 }
931 
932 /*
933  * Sends a cross-call to a specified processor.  The caller assumes
934  * responsibility for repetition of cross-calls, as appropriate (MARSA for
935  * debugging).
936  */
937 static int
938 kdi_xc_one(int cpuid, void (*func)(uintptr_t, uintptr_t), uintptr_t arg1,
939     uintptr_t arg2)
940 {
941 	int stat;
942 	struct machcpu	*mcpup;
943 	uint64_t cpuaddr_reg = 0, cpuaddr_scr = 0;
944 
945 	mcpup = &(((cpu_t *)get_cpuaddr(cpuaddr_reg, cpuaddr_scr))->cpu_m);
946 
947 	/*
948 	 * if (idsr_busy())
949 	 *	return (KDI_XC_RES_ERR);
950 	 */
951 
952 	init_mondo_nocheck((xcfunc_t *)func, arg1, arg2);
953 
954 	mcpup->cpu_list[0] = (uint16_t)cpuid;
955 	stat = shipit(1, mcpup->cpu_list_ra);
956 
957 	if (stat == 0)
958 		return (KDI_XC_RES_OK);
959 	else
960 		return (KDI_XC_RES_NACK);
961 }
962 
963 static void
964 kdi_tickwait(clock_t nticks)
965 {
966 	clock_t endtick = gettick() + nticks;
967 
968 	while (gettick() < endtick);
969 }
970 
971 static void
972 kdi_cpu_init(int dcache_size, int dcache_linesize, int icache_size,
973     int icache_linesize)
974 {
975 	kdi_dcache_size = dcache_size;
976 	kdi_dcache_linesize = dcache_linesize;
977 	kdi_icache_size = icache_size;
978 	kdi_icache_linesize = icache_linesize;
979 }
980 
981 /* used directly by kdi_read/write_phys */
982 void
983 kdi_flush_caches(void)
984 {
985 	/* Not required on sun4v architecture. */
986 }
987 
988 /*ARGSUSED*/
989 int
990 kdi_get_stick(uint64_t *stickp)
991 {
992 	return (-1);
993 }
994 
995 void
996 cpu_kdi_init(kdi_t *kdi)
997 {
998 	kdi->kdi_flush_caches = kdi_flush_caches;
999 	kdi->mkdi_cpu_init = kdi_cpu_init;
1000 	kdi->mkdi_cpu_ready_iter = kdi_cpu_ready_iter;
1001 	kdi->mkdi_xc_one = kdi_xc_one;
1002 	kdi->mkdi_tickwait = kdi_tickwait;
1003 	kdi->mkdi_get_stick = kdi_get_stick;
1004 }
1005 
1006 static void
1007 sun4v_system_claim(void)
1008 {
1009 	watchdog_suspend();
1010 }
1011 
1012 static void
1013 sun4v_system_release(void)
1014 {
1015 	watchdog_resume();
1016 }
1017 
1018 void
1019 plat_kdi_init(kdi_t *kdi)
1020 {
1021 	kdi->pkdi_system_claim = sun4v_system_claim;
1022 	kdi->pkdi_system_release = sun4v_system_release;
1023 }
1024 
1025 /*
1026  * Routine to return memory information associated
1027  * with a physical address and syndrome.
1028  */
1029 /* ARGSUSED */
1030 int
1031 cpu_get_mem_info(uint64_t synd, uint64_t afar,
1032     uint64_t *mem_sizep, uint64_t *seg_sizep, uint64_t *bank_sizep,
1033     int *segsp, int *banksp, int *mcidp)
1034 {
1035 	return (ENOTSUP);
1036 }
1037 
1038 /*
1039  * This routine returns the size of the kernel's FRU name buffer.
1040  */
1041 size_t
1042 cpu_get_name_bufsize()
1043 {
1044 	return (UNUM_NAMLEN);
1045 }
1046 
1047 /*
1048  * This routine is a more generic interface to cpu_get_mem_unum(),
1049  * that may be used by other modules (e.g. mm).
1050  */
1051 /* ARGSUSED */
1052 int
1053 cpu_get_mem_name(uint64_t synd, uint64_t *afsr, uint64_t afar,
1054     char *buf, int buflen, int *lenp)
1055 {
1056 	return (ENOTSUP);
1057 }
1058 
1059 /* ARGSUSED */
1060 int
1061 cpu_get_mem_sid(char *unum, char *buf, int buflen, int *lenp)
1062 {
1063 	return (ENOTSUP);
1064 }
1065 
1066 /* ARGSUSED */
1067 int
1068 cpu_get_mem_addr(char *unum, char *sid, uint64_t offset, uint64_t *addrp)
1069 {
1070 	return (ENOTSUP);
1071 }
1072 
1073 /*
1074  * xt_sync - wait for previous x-traps to finish
1075  */
1076 void
1077 xt_sync(cpuset_t cpuset)
1078 {
1079 	union {
1080 		uint8_t volatile byte[NCPU];
1081 		uint64_t volatile xword[NCPU / 8];
1082 	} cpu_sync;
1083 	uint64_t starttick, endtick, tick, lasttick;
1084 	uint_t largestid, smallestid;
1085 	int i;
1086 
1087 	kpreempt_disable();
1088 	CPUSET_DEL(cpuset, CPU->cpu_id);
1089 	CPUSET_AND(cpuset, cpu_ready_set);
1090 
1091 	CPUSET_BOUNDS(cpuset, smallestid, largestid);
1092 	if (smallestid == CPUSET_NOTINSET)
1093 		goto out;
1094 
1095 	/*
1096 	 * Sun4v uses a queue for receiving mondos. Successful
1097 	 * transmission of a mondo only indicates that the mondo
1098 	 * has been written into the queue.
1099 	 *
1100 	 * We use an array of bytes to let each cpu to signal back
1101 	 * to the cross trap sender that the cross trap has been
1102 	 * executed. Set the byte to 1 before sending the cross trap
1103 	 * and wait until other cpus reset it to 0.
1104 	 */
1105 	bzero((void *)&cpu_sync, NCPU);
1106 	cpu_sync.byte[smallestid] = 1;
1107 	if (largestid != smallestid) {
1108 		for (i = (smallestid + 1); i <= (largestid - 1); i++)
1109 			if (CPU_IN_SET(cpuset, i))
1110 				cpu_sync.byte[i] = 1;
1111 		cpu_sync.byte[largestid] = 1;
1112 	}
1113 
1114 	xt_some(cpuset, (xcfunc_t *)xt_sync_tl1,
1115 	    (uint64_t)cpu_sync.byte, 0);
1116 
1117 	starttick = lasttick = gettick();
1118 	endtick = starttick + xc_tick_limit;
1119 
1120 	for (i = (smallestid / 8); i <= (largestid / 8); i++) {
1121 		while (cpu_sync.xword[i] != 0) {
1122 			tick = gettick();
1123 			/*
1124 			 * If there is a big jump between the current tick
1125 			 * count and lasttick, we have probably hit a break
1126 			 * point. Adjust endtick accordingly to avoid panic.
1127 			 */
1128 			if (tick > (lasttick + xc_tick_jump_limit)) {
1129 				endtick += (tick - lasttick);
1130 			}
1131 			lasttick = tick;
1132 			if (tick > endtick) {
1133 				if (panic_quiesce)
1134 					goto out;
1135 				cmn_err(CE_CONT, "Cross trap sync timeout "
1136 				    "at cpu_sync.xword[%d]: 0x%lx\n",
1137 				    i, cpu_sync.xword[i]);
1138 				cmn_err(CE_PANIC, "xt_sync: timeout");
1139 			}
1140 		}
1141 	}
1142 
1143 out:
1144 	kpreempt_enable();
1145 }
1146