xref: /illumos-gate/usr/src/uts/sun4u/os/cpr_impl.c (revision b1e2e3fb17324e9ddf43db264a0c64da7756d9e6)
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 2010 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 /*
27  * Platform specific implementation code
28  */
29 
30 #define	SUNDDI_IMPL
31 
32 #include <sys/types.h>
33 #include <sys/promif.h>
34 #include <sys/prom_isa.h>
35 #include <sys/prom_plat.h>
36 #include <sys/mmu.h>
37 #include <vm/hat_sfmmu.h>
38 #include <sys/iommu.h>
39 #include <sys/scb.h>
40 #include <sys/cpuvar.h>
41 #include <sys/intreg.h>
42 #include <sys/pte.h>
43 #include <vm/hat.h>
44 #include <vm/page.h>
45 #include <vm/as.h>
46 #include <sys/cpr.h>
47 #include <sys/kmem.h>
48 #include <sys/clock.h>
49 #include <sys/kmem.h>
50 #include <sys/panic.h>
51 #include <vm/seg_kmem.h>
52 #include <sys/cpu_module.h>
53 #include <sys/callb.h>
54 #include <sys/machsystm.h>
55 #include <sys/vmsystm.h>
56 #include <sys/systm.h>
57 #include <sys/archsystm.h>
58 #include <sys/stack.h>
59 #include <sys/fs/ufs_fs.h>
60 #include <sys/memlist.h>
61 #include <sys/bootconf.h>
62 #include <sys/thread.h>
63 #include <vm/vm_dep.h>
64 
65 extern	void cpr_clear_bitmaps(void);
66 extern	int cpr_setbit(pfn_t ppn, int mapflag);
67 extern	int cpr_clrbit(pfn_t ppn, int mapflag);
68 extern	pgcnt_t cpr_scan_kvseg(int mapflag, bitfunc_t bitfunc, struct seg *seg);
69 extern	pgcnt_t cpr_count_seg_pages(int mapflag, bitfunc_t bitfunc);
70 extern	void dtlb_wr_entry(uint_t, tte_t *, uint64_t *);
71 extern	void itlb_wr_entry(uint_t, tte_t *, uint64_t *);
72 
73 static	int i_cpr_storage_desc_alloc(csd_t **, pgcnt_t *, csd_t **, int);
74 static	void i_cpr_storage_desc_init(csd_t *, pgcnt_t, csd_t *);
75 static	caddr_t i_cpr_storage_data_alloc(pgcnt_t, pgcnt_t *, int);
76 static	int cpr_dump_sensitive(vnode_t *, csd_t *);
77 static	void i_cpr_clear_entries(uint64_t, uint64_t);
78 static	void i_cpr_xcall(xcfunc_t);
79 
80 void	i_cpr_storage_free(void);
81 
82 extern void *i_cpr_data_page;
83 extern int cpr_test_mode;
84 extern int cpr_nbitmaps;
85 extern char cpr_default_path[];
86 extern caddr_t textva, datava;
87 
88 static struct cpr_map_info cpr_prom_retain[CPR_PROM_RETAIN_CNT];
89 caddr_t cpr_vaddr = NULL;
90 
91 static	uint_t sensitive_pages_saved;
92 static	uint_t sensitive_size_saved;
93 
94 caddr_t	i_cpr_storage_data_base;
95 caddr_t	i_cpr_storage_data_end;
96 csd_t *i_cpr_storage_desc_base;
97 csd_t *i_cpr_storage_desc_end;		/* one byte beyond last used descp */
98 csd_t *i_cpr_storage_desc_last_used;	/* last used descriptor */
99 caddr_t sensitive_write_ptr;		/* position for next storage write */
100 
101 size_t	i_cpr_sensitive_bytes_dumped;
102 pgcnt_t	i_cpr_sensitive_pgs_dumped;
103 pgcnt_t	i_cpr_storage_data_sz;		/* in pages */
104 pgcnt_t	i_cpr_storage_desc_pgcnt;	/* in pages */
105 
106 ushort_t cpr_mach_type = CPR_MACHTYPE_4U;
107 static	csu_md_t m_info;
108 
109 
110 #define	MAX_STORAGE_RETRY	3
111 #define	MAX_STORAGE_ALLOC_RETRY	3
112 #define	INITIAL_ALLOC_PCNT	40	/* starting allocation percentage */
113 #define	INTEGRAL		100	/* to get 1% precision */
114 
115 #define	EXTRA_RATE		2	/* add EXTRA_RATE% extra space */
116 #define	EXTRA_DESCS		10
117 
118 #define	CPR_NO_STORAGE_DESC	1
119 #define	CPR_NO_STORAGE_DATA	2
120 
121 #define	CIF_SPLICE		0
122 #define	CIF_UNLINK		1
123 
124 
125 /*
126  * CPR miscellaneous support routines
127  */
128 #define	cpr_open(path, mode,  vpp)	(vn_open(path, UIO_SYSSPACE, \
129 		mode, 0600, vpp, CRCREAT, 0))
130 #define	cpr_rdwr(rw, vp, basep, cnt)	(vn_rdwr(rw, vp,  (caddr_t)(basep), \
131 		cnt, 0LL, UIO_SYSSPACE, 0, (rlim64_t)MAXOFF_T, CRED(), \
132 		(ssize_t *)NULL))
133 
134 /*
135  * definitions for saving/restoring prom pages
136  */
137 static void	*ppage_buf;
138 static pgcnt_t	ppage_count;
139 static pfn_t	*pphys_list;
140 static size_t	pphys_list_size;
141 
142 typedef void (*tlb_rw_t)(uint_t, tte_t *, uint64_t *);
143 typedef void (*tlb_filter_t)(int, tte_t *, uint64_t, void *);
144 
145 /*
146  * private struct for tlb handling
147  */
148 struct cpr_trans_info {
149 	sutlb_t		*dst;
150 	sutlb_t		*tail;
151 	tlb_rw_t	reader;
152 	tlb_rw_t	writer;
153 	tlb_filter_t	filter;
154 	int		index;
155 	uint64_t	skip;		/* assumes TLB <= 64 locked entries */
156 };
157 typedef struct cpr_trans_info cti_t;
158 
159 
160 /*
161  * special handling for tlb info
162  */
163 #define	WITHIN_OFW(va) \
164 	(((va) > (uint64_t)OFW_START_ADDR) && ((va) < (uint64_t)OFW_END_ADDR))
165 
166 #define	WITHIN_NUCLEUS(va, base) \
167 	(((va) >= (base)) && \
168 	(((va) + MMU_PAGESIZE) <= ((base) + MMU_PAGESIZE4M)))
169 
170 #define	IS_BIGKTSB(va) \
171 	(enable_bigktsb && \
172 	((va) >= (uint64_t)ktsb_base) && \
173 	((va) < (uint64_t)(ktsb_base + ktsb_sz)))
174 
175 
176 /*
177  * WARNING:
178  * the text from this file is linked to follow cpr_resume_setup.o;
179  * only add text between here and i_cpr_end_jumpback when it needs
180  * to be called during resume before we switch back to the kernel
181  * trap table.  all the text in this range must fit within a page.
182  */
183 
184 
185 /*
186  * each time a machine is reset, the prom uses an inconsistent set of phys
187  * pages and the cif cookie may differ as well.  so prior to restoring the
188  * original prom, we have to use to use the new/tmp prom's translations
189  * when requesting prom services.
190  *
191  * cif_handler starts out as the original prom cookie, and that gets used
192  * by client_handler() to jump into the prom.  here we splice-in a wrapper
193  * routine by writing cif_handler; client_handler() will now jump to the
194  * wrapper which switches the %tba to the new/tmp prom's trap table then
195  * jumps to the new cookie.
196  */
197 void
198 i_cpr_cif_setup(int action)
199 {
200 	extern void *i_cpr_orig_cif, *cif_handler;
201 	extern int i_cpr_cif_wrapper(void *);
202 
203 	/*
204 	 * save the original cookie and change the current cookie to the
205 	 * wrapper routine.  later we just restore the original cookie.
206 	 */
207 	if (action == CIF_SPLICE) {
208 		i_cpr_orig_cif = cif_handler;
209 		cif_handler = (void *)i_cpr_cif_wrapper;
210 	} else if (action == CIF_UNLINK)
211 		cif_handler = i_cpr_orig_cif;
212 }
213 
214 
215 /*
216  * launch slave cpus into kernel text, pause them,
217  * and restore the original prom pages
218  */
219 void
220 i_cpr_mp_setup(void)
221 {
222 	extern void restart_other_cpu(int);
223 	cpu_t *cp;
224 
225 	uint64_t kctx = kcontextreg;
226 
227 	/*
228 	 * Do not allow setting page size codes in MMU primary context
229 	 * register while using cif wrapper. This is needed to work
230 	 * around OBP incorrect handling of this MMU register.
231 	 */
232 	kcontextreg = 0;
233 
234 	/*
235 	 * reset cpu_ready_set so x_calls work properly
236 	 */
237 	CPUSET_ZERO(cpu_ready_set);
238 	CPUSET_ADD(cpu_ready_set, getprocessorid());
239 
240 	/*
241 	 * setup cif to use the cookie from the new/tmp prom
242 	 * and setup tmp handling for calling prom services.
243 	 */
244 	i_cpr_cif_setup(CIF_SPLICE);
245 
246 	/*
247 	 * at this point, only the nucleus and a few cpr pages are
248 	 * mapped in.  once we switch to the kernel trap table,
249 	 * we can access the rest of kernel space.
250 	 */
251 	prom_set_traptable(&trap_table);
252 
253 	if (ncpus > 1) {
254 		sfmmu_init_tsbs();
255 
256 		mutex_enter(&cpu_lock);
257 		/*
258 		 * All of the slave cpus are not ready at this time,
259 		 * yet the cpu structures have various cpu_flags set;
260 		 * clear cpu_flags and mutex_ready.
261 		 * Since we are coming up from a CPU suspend, the slave cpus
262 		 * are frozen.
263 		 */
264 		for (cp = CPU->cpu_next; cp != CPU; cp = cp->cpu_next) {
265 			cp->cpu_flags = CPU_FROZEN;
266 			cp->cpu_m.mutex_ready = 0;
267 		}
268 
269 		for (cp = CPU->cpu_next; cp != CPU; cp = cp->cpu_next)
270 			restart_other_cpu(cp->cpu_id);
271 
272 		pause_cpus(NULL, NULL);
273 		mutex_exit(&cpu_lock);
274 
275 		i_cpr_xcall(i_cpr_clear_entries);
276 	} else
277 		i_cpr_clear_entries(0, 0);
278 
279 	/*
280 	 * now unlink the cif wrapper;  WARNING: do not call any
281 	 * prom_xxx() routines until after prom pages are restored.
282 	 */
283 	i_cpr_cif_setup(CIF_UNLINK);
284 
285 	(void) i_cpr_prom_pages(CPR_PROM_RESTORE);
286 
287 	/* allow setting page size codes in MMU primary context register */
288 	kcontextreg = kctx;
289 }
290 
291 
292 /*
293  * end marker for jumpback page;
294  * this symbol is used to check the size of i_cpr_resume_setup()
295  * and the above text.  For simplicity, the Makefile needs to
296  * link i_cpr_resume_setup.o and cpr_impl.o consecutively.
297  */
298 void
299 i_cpr_end_jumpback(void)
300 {
301 }
302 
303 
304 /*
305  * scan tlb entries with reader; when valid entries are found,
306  * the filter routine will selectively save/clear them
307  */
308 static void
309 i_cpr_scan_tlb(cti_t *ctip)
310 {
311 	uint64_t va_tag;
312 	int tlb_index;
313 	tte_t tte;
314 
315 	for (tlb_index = ctip->index; tlb_index >= 0; tlb_index--) {
316 		(*ctip->reader)((uint_t)tlb_index, &tte, &va_tag);
317 		if (va_tag && TTE_IS_VALID(&tte))
318 			(*ctip->filter)(tlb_index, &tte, va_tag, ctip);
319 	}
320 }
321 
322 
323 /*
324  * filter for locked tlb entries that reference the text/data nucleus
325  * and any bigktsb's; these will be reinstalled by cprboot on all cpus
326  */
327 /* ARGSUSED */
328 static void
329 i_cpr_lnb(int index, tte_t *ttep, uint64_t va_tag, void *ctrans)
330 {
331 	cti_t *ctip;
332 
333 	/*
334 	 * record tlb data at ctip->dst; the target tlb index starts
335 	 * at the highest tlb offset and moves towards 0.  the prom
336 	 * reserves both dtlb and itlb index 0.  any selected entry
337 	 * also gets marked to prevent being flushed during resume
338 	 */
339 	if (TTE_IS_LOCKED(ttep) && (va_tag == (uint64_t)textva ||
340 	    va_tag == (uint64_t)datava || IS_BIGKTSB(va_tag))) {
341 		ctip = ctrans;
342 		while ((1 << ctip->index) & ctip->skip)
343 			ctip->index--;
344 		ASSERT(ctip->index > 0);
345 		ASSERT(ctip->dst < ctip->tail);
346 		ctip->dst->tte.ll = ttep->ll;
347 		ctip->dst->va_tag = va_tag;
348 		ctip->dst->index = ctip->index--;
349 		ctip->dst->tmp = 0;
350 		ctip->dst++;
351 	}
352 }
353 
354 
355 /*
356  * some tlb entries are stale, filter for unlocked entries
357  * within the prom virt range and clear them
358  */
359 static void
360 i_cpr_ufw(int index, tte_t *ttep, uint64_t va_tag, void *ctrans)
361 {
362 	sutlb_t clr;
363 	cti_t *ctip;
364 
365 	if (!TTE_IS_LOCKED(ttep) && WITHIN_OFW(va_tag)) {
366 		ctip = ctrans;
367 		bzero(&clr, sizeof (clr));
368 		(*ctip->writer)((uint_t)index, &clr.tte, &clr.va_tag);
369 	}
370 }
371 
372 
373 /*
374  * some of the entries installed by cprboot are needed only on a
375  * short-term basis and need to be flushed to avoid clogging the tlbs.
376  * scan the dtte/itte arrays for items marked as temporary and clear
377  * dtlb/itlb entries using wrfunc.
378  */
379 static void
380 i_cpr_clear_tmp(sutlb_t *listp, int max, tlb_rw_t wrfunc)
381 {
382 	sutlb_t clr, *tail;
383 
384 	bzero(&clr, sizeof (clr));
385 	for (tail = listp + max; listp < tail && listp->va_tag; listp++) {
386 		if (listp->tmp)
387 			(*wrfunc)((uint_t)listp->index, &clr.tte, &clr.va_tag);
388 	}
389 }
390 
391 
392 /* ARGSUSED */
393 static void
394 i_cpr_clear_entries(uint64_t arg1, uint64_t arg2)
395 {
396 	extern void demap_all(void);
397 	cti_t cti;
398 
399 	i_cpr_clear_tmp(m_info.dtte, CPR_MAX_TLB, dtlb_wr_entry);
400 	i_cpr_clear_tmp(m_info.itte, CPR_MAX_TLB, itlb_wr_entry);
401 
402 	/*
403 	 * for newer cpus that implement DEMAP_ALL_TYPE, demap_all is
404 	 * a second label for vtag_flushall.  the call is made using
405 	 * vtag_flushall() instead of demap_all() due to runtime and
406 	 * krtld results with both older and newer cpu modules.
407 	 */
408 	if (&demap_all != 0) {
409 		vtag_flushall();
410 		return;
411 	}
412 
413 	/*
414 	 * for older V9 cpus, scan tlbs and clear stale entries
415 	 */
416 	bzero(&cti, sizeof (cti));
417 	cti.filter = i_cpr_ufw;
418 
419 	cti.index = cpunodes[CPU->cpu_id].dtlb_size - 1;
420 	cti.reader = dtlb_rd_entry;
421 	cti.writer = dtlb_wr_entry;
422 	i_cpr_scan_tlb(&cti);
423 
424 	cti.index = cpunodes[CPU->cpu_id].itlb_size - 1;
425 	cti.reader = itlb_rd_entry;
426 	cti.writer = itlb_wr_entry;
427 	i_cpr_scan_tlb(&cti);
428 }
429 
430 
431 /*
432  * craft tlb info for tmp use during resume; this data gets used by
433  * cprboot to install tlb entries.  we also mark each struct as tmp
434  * so those tlb entries will get flushed after switching to the kernel
435  * trap table.  no data needs to be recorded for vaddr when it falls
436  * within the nucleus since we've already recorded nucleus ttes and
437  * a 8K tte would conflict with a 4MB tte.  eg: the cpr module
438  * text/data may have been loaded into the text/data nucleus.
439  */
440 static void
441 i_cpr_make_tte(cti_t *ctip, void *vaddr, caddr_t nbase)
442 {
443 	pfn_t ppn;
444 	uint_t rw;
445 
446 	if (WITHIN_NUCLEUS((caddr_t)vaddr, nbase))
447 		return;
448 
449 	while ((1 << ctip->index) & ctip->skip)
450 		ctip->index--;
451 	ASSERT(ctip->index > 0);
452 	ASSERT(ctip->dst < ctip->tail);
453 
454 	/*
455 	 * without any global service available to lookup
456 	 * a tte by vaddr, we craft our own here:
457 	 */
458 	ppn = va_to_pfn(vaddr);
459 	rw = (nbase == datava) ? TTE_HWWR_INT : 0;
460 	ctip->dst->tte.tte_inthi = TTE_VALID_INT | TTE_PFN_INTHI(ppn);
461 	ctip->dst->tte.tte_intlo = TTE_PFN_INTLO(ppn) | TTE_LCK_INT |
462 	    TTE_CP_INT | TTE_PRIV_INT | rw;
463 	ctip->dst->va_tag = ((uintptr_t)vaddr & MMU_PAGEMASK);
464 	ctip->dst->index = ctip->index--;
465 	ctip->dst->tmp = 1;
466 	ctip->dst++;
467 }
468 
469 
470 static void
471 i_cpr_xcall(xcfunc_t func)
472 {
473 	uint_t pil, reset_pil;
474 
475 	pil = getpil();
476 	if (pil < XCALL_PIL)
477 		reset_pil = 0;
478 	else {
479 		reset_pil = 1;
480 		setpil(XCALL_PIL - 1);
481 	}
482 	xc_some(cpu_ready_set, func, 0, 0);
483 	if (reset_pil)
484 		setpil(pil);
485 }
486 
487 
488 /*
489  * restart paused slave cpus
490  */
491 void
492 i_cpr_machdep_setup(void)
493 {
494 	if (ncpus > 1) {
495 		CPR_DEBUG(CPR_DEBUG1, "MP restarted...\n");
496 		mutex_enter(&cpu_lock);
497 		start_cpus();
498 		mutex_exit(&cpu_lock);
499 	}
500 }
501 
502 
503 /*
504  * Stop all interrupt activities in the system
505  */
506 void
507 i_cpr_stop_intr(void)
508 {
509 	(void) spl7();
510 }
511 
512 /*
513  * Set machine up to take interrupts
514  */
515 void
516 i_cpr_enable_intr(void)
517 {
518 	(void) spl0();
519 }
520 
521 
522 /*
523  * record cpu nodes and ids
524  */
525 static void
526 i_cpr_save_cpu_info(void)
527 {
528 	struct sun4u_cpu_info *scip;
529 	cpu_t *cp;
530 
531 	scip = m_info.sci;
532 	cp = CPU;
533 	do {
534 		ASSERT(scip < &m_info.sci[NCPU]);
535 		scip->cpu_id = cp->cpu_id;
536 		scip->node = cpunodes[cp->cpu_id].nodeid;
537 		scip++;
538 	} while ((cp = cp->cpu_next) != CPU);
539 }
540 
541 
542 /*
543  * Write necessary machine dependent information to cpr state file,
544  * eg. sun4u mmu ctx secondary for the current running process (cpr) ...
545  */
546 int
547 i_cpr_write_machdep(vnode_t *vp)
548 {
549 	extern uint_t getpstate(), getwstate();
550 	extern uint_t i_cpr_tstack_size;
551 	const char ustr[] = ": unix-tte 2drop false ;";
552 	uintptr_t tinfo;
553 	label_t *ltp;
554 	cmd_t cmach;
555 	char *fmt;
556 	int rc;
557 
558 	/*
559 	 * ustr[] is used as temporary forth words during
560 	 * slave startup sequence, see sfmmu_mp_startup()
561 	 */
562 
563 	cmach.md_magic = (uint_t)CPR_MACHDEP_MAGIC;
564 	cmach.md_size = sizeof (m_info) + sizeof (ustr);
565 
566 	if (rc = cpr_write(vp, (caddr_t)&cmach, sizeof (cmach))) {
567 		cpr_err(CE_WARN, "Failed to write descriptor.");
568 		return (rc);
569 	}
570 
571 	/*
572 	 * m_info is now cleared in i_cpr_dump_setup()
573 	 */
574 	m_info.ksb = (uint32_t)STACK_BIAS;
575 	m_info.kpstate = (uint16_t)getpstate();
576 	m_info.kwstate = (uint16_t)getwstate();
577 	CPR_DEBUG(CPR_DEBUG1, "stack bias 0x%x, pstate 0x%x, wstate 0x%x\n",
578 	    m_info.ksb, m_info.kpstate, m_info.kwstate);
579 
580 	ltp = &ttolwp(curthread)->lwp_qsav;
581 	m_info.qsav_pc = (cpr_ext)ltp->val[0];
582 	m_info.qsav_sp = (cpr_ext)ltp->val[1];
583 
584 	/*
585 	 * Set secondary context to INVALID_CONTEXT to force the HAT
586 	 * to re-setup the MMU registers and locked TTEs it needs for
587 	 * TLB miss handling.
588 	 */
589 	m_info.mmu_ctx_sec = INVALID_CONTEXT;
590 	m_info.mmu_ctx_pri = KCONTEXT;
591 
592 	tinfo = (uintptr_t)curthread;
593 	m_info.thrp = (cpr_ptr)tinfo;
594 
595 	tinfo = (uintptr_t)i_cpr_resume_setup;
596 	m_info.func = (cpr_ptr)tinfo;
597 
598 	/*
599 	 * i_cpr_data_page is comprised of a 4K stack area and a few
600 	 * trailing data symbols; the page is shared by the prom and
601 	 * kernel during resume.  the stack size is recorded here
602 	 * and used by cprboot to set %sp
603 	 */
604 	tinfo = (uintptr_t)&i_cpr_data_page;
605 	m_info.tmp_stack = (cpr_ptr)tinfo;
606 	m_info.tmp_stacksize = i_cpr_tstack_size;
607 
608 	m_info.test_mode = cpr_test_mode;
609 
610 	i_cpr_save_cpu_info();
611 
612 	if (rc = cpr_write(vp, (caddr_t)&m_info, sizeof (m_info))) {
613 		cpr_err(CE_WARN, "Failed to write machdep info.");
614 		return (rc);
615 	}
616 
617 	fmt = "error writing %s forth info";
618 	if (rc = cpr_write(vp, (caddr_t)ustr, sizeof (ustr)))
619 		cpr_err(CE_WARN, fmt, "unix-tte");
620 
621 	return (rc);
622 }
623 
624 
625 /*
626  * Save miscellaneous information which needs to be written to the
627  * state file.  This information is required to re-initialize
628  * kernel/prom handshaking.
629  */
630 void
631 i_cpr_save_machdep_info(void)
632 {
633 	CPR_DEBUG(CPR_DEBUG5, "jumpback size = 0x%lx\n",
634 	    (uintptr_t)&i_cpr_end_jumpback -
635 	    (uintptr_t)i_cpr_resume_setup);
636 
637 	/*
638 	 * Verify the jumpback code all falls in one page.
639 	 */
640 	if (((uintptr_t)&i_cpr_end_jumpback & MMU_PAGEMASK) !=
641 	    ((uintptr_t)i_cpr_resume_setup & MMU_PAGEMASK))
642 		cpr_err(CE_PANIC, "jumpback code exceeds one page.");
643 }
644 
645 
646 /*
647  * cpu0 should contain bootcpu info
648  */
649 cpu_t *
650 i_cpr_bootcpu(void)
651 {
652 	return (&cpu0);
653 }
654 
655 processorid_t
656 i_cpr_bootcpuid(void)
657 {
658 	return (0);
659 }
660 
661 /*
662  * Return the virtual address of the mapping area
663  */
664 caddr_t
665 i_cpr_map_setup(void)
666 {
667 	/*
668 	 * Allocate a virtual memory range spanned by an hmeblk.
669 	 * This would be 8 hments or 64k bytes.  Starting VA
670 	 * must be 64k (8-page) aligned.
671 	 */
672 	cpr_vaddr = vmem_xalloc(heap_arena,
673 	    mmu_ptob(NHMENTS), mmu_ptob(NHMENTS),
674 	    0, 0, NULL, NULL, VM_NOSLEEP);
675 	return (cpr_vaddr);
676 }
677 
678 /*
679  * create tmp locked tlb entries for a group of phys pages;
680  *
681  * i_cpr_mapin/i_cpr_mapout should always be called in pairs,
682  * otherwise would fill up a tlb with locked entries
683  */
684 void
685 i_cpr_mapin(caddr_t vaddr, uint_t pages, pfn_t ppn)
686 {
687 	tte_t tte;
688 	extern pfn_t curthreadpfn;
689 	extern int curthreadremapped;
690 
691 	curthreadremapped = (ppn <= curthreadpfn && curthreadpfn < ppn + pages);
692 
693 	for (; pages--; ppn++, vaddr += MMU_PAGESIZE) {
694 		tte.tte_inthi = TTE_VALID_INT | TTE_PFN_INTHI(ppn);
695 		tte.tte_intlo = TTE_PFN_INTLO(ppn) | TTE_LCK_INT |
696 		    TTE_CP_INT | TTE_PRIV_INT | TTE_HWWR_INT;
697 		sfmmu_dtlb_ld_kva(vaddr, &tte);
698 	}
699 }
700 
701 void
702 i_cpr_mapout(caddr_t vaddr, uint_t pages)
703 {
704 	extern int curthreadremapped;
705 
706 	if (curthreadremapped && vaddr <= (caddr_t)curthread &&
707 	    (caddr_t)curthread < vaddr + pages * MMU_PAGESIZE)
708 		curthreadremapped = 0;
709 
710 	for (; pages--; vaddr += MMU_PAGESIZE)
711 		vtag_flushpage(vaddr, (uint64_t)ksfmmup);
712 }
713 
714 /*
715  * We're done using the mapping area; release virtual space
716  */
717 void
718 i_cpr_map_destroy(void)
719 {
720 	vmem_free(heap_arena, cpr_vaddr, mmu_ptob(NHMENTS));
721 	cpr_vaddr = NULL;
722 }
723 
724 /* ARGSUSED */
725 void
726 i_cpr_handle_xc(int flag)
727 {
728 }
729 
730 
731 /*
732  * This function takes care of pages which are not in kas or need to be
733  * taken care of in a special way.  For example, panicbuf pages are not
734  * in kas and their pages are allocated via prom_retain().
735  */
736 pgcnt_t
737 i_cpr_count_special_kpages(int mapflag, bitfunc_t bitfunc)
738 {
739 	struct cpr_map_info *pri, *tail;
740 	pgcnt_t pages, total = 0;
741 	pfn_t pfn;
742 
743 	/*
744 	 * Save information about prom retained panicbuf pages
745 	 */
746 	if (bitfunc == cpr_setbit) {
747 		pri = &cpr_prom_retain[CPR_PANICBUF];
748 		pri->virt = (cpr_ptr)panicbuf;
749 		pri->phys = va_to_pa(panicbuf);
750 		pri->size = sizeof (panicbuf);
751 	}
752 
753 	/*
754 	 * Go through the prom_retain array to tag those pages.
755 	 */
756 	tail = &cpr_prom_retain[CPR_PROM_RETAIN_CNT];
757 	for (pri = cpr_prom_retain; pri < tail; pri++) {
758 		pages = mmu_btopr(pri->size);
759 		for (pfn = ADDR_TO_PN(pri->phys); pages--; pfn++) {
760 			if (pf_is_memory(pfn)) {
761 				if (bitfunc == cpr_setbit) {
762 					if ((*bitfunc)(pfn, mapflag) == 0)
763 						total++;
764 				} else
765 					total++;
766 			}
767 		}
768 	}
769 
770 	return (total);
771 }
772 
773 
774 /*
775  * Free up memory-related resources here.  We start by freeing buffers
776  * allocated during suspend initialization.  Also, free up the mapping
777  * resources allocated in cpr_init().
778  */
779 void
780 i_cpr_free_memory_resources(void)
781 {
782 	(void) i_cpr_prom_pages(CPR_PROM_FREE);
783 	i_cpr_map_destroy();
784 	i_cpr_storage_free();
785 }
786 
787 
788 /*
789  * Derived from cpr_write_statefile().
790  * Save the sensitive pages to the storage area and do bookkeeping
791  * using the sensitive descriptors. Each descriptor will contain no more
792  * than CPR_MAXCONTIG amount of contiguous pages to match the max amount
793  * of pages that statefile gets written to disk at each write.
794  * XXX The CPR_MAXCONTIG can be changed to the size of the compression
795  * scratch area.
796  */
797 static int
798 i_cpr_save_to_storage(void)
799 {
800 	sensitive_size_saved = 0;
801 	sensitive_pages_saved = 0;
802 	sensitive_write_ptr = i_cpr_storage_data_base;
803 	return (cpr_contig_pages(NULL, SAVE_TO_STORAGE));
804 }
805 
806 
807 /*
808  * This routine allocates space to save the sensitive kernel pages,
809  * i.e. kernel data nucleus, kvalloc and kvseg segments.
810  * It's assumed that those segments are the only areas that can be
811  * contaminated by memory allocations during statefile dumping.
812  * The space allocated here contains:
813  * 	A list of descriptors describing the saved sensitive pages.
814  * 	The storage area for saving the compressed sensitive kernel pages.
815  * Since storage pages are allocated from segkmem, they need to be
816  * excluded when saving.
817  */
818 int
819 i_cpr_save_sensitive_kpages(void)
820 {
821 	static const char pages_fmt[] = "\n%s %s allocs\n"
822 	    "	spages %ld, vpages %ld, diff %ld\n";
823 	int retry_cnt;
824 	int error = 0;
825 	pgcnt_t pages, spages, vpages;
826 	caddr_t	addr;
827 	char *str;
828 
829 	/*
830 	 * Tag sensitive kpages. Allocate space for storage descriptors
831 	 * and storage data area based on the resulting bitmaps.
832 	 * Note: The storage space will be part of the sensitive
833 	 * segment, so we need to tag kpages here before the storage
834 	 * is actually allocated just so their space won't be accounted
835 	 * for. They will not be part of the statefile although those
836 	 * pages will be claimed by cprboot.
837 	 */
838 	cpr_clear_bitmaps();
839 
840 	spages = i_cpr_count_sensitive_kpages(REGULAR_BITMAP, cpr_setbit);
841 	vpages = cpr_count_volatile_pages(REGULAR_BITMAP, cpr_clrbit);
842 	pages = spages - vpages;
843 
844 	str = "i_cpr_save_sensitive_kpages:";
845 	CPR_DEBUG(CPR_DEBUG7, pages_fmt, "before", str, spages, vpages, pages);
846 
847 	/*
848 	 * Allocate space to save the clean sensitive kpages
849 	 */
850 	for (retry_cnt = 0; retry_cnt < MAX_STORAGE_ALLOC_RETRY; retry_cnt++) {
851 		/*
852 		 * Alloc on first pass or realloc if we are retrying because
853 		 * of insufficient storage for sensitive pages
854 		 */
855 		if (retry_cnt == 0 || error == ENOMEM) {
856 			if (i_cpr_storage_data_base) {
857 				kmem_free(i_cpr_storage_data_base,
858 				    mmu_ptob(i_cpr_storage_data_sz));
859 				i_cpr_storage_data_base = NULL;
860 				i_cpr_storage_data_sz = 0;
861 			}
862 			addr = i_cpr_storage_data_alloc(pages,
863 			    &i_cpr_storage_data_sz, retry_cnt);
864 			if (addr == NULL) {
865 				CPR_DEBUG(CPR_DEBUG7,
866 				    "\n%s can't allocate data storage space!\n",
867 				    str);
868 				return (ENOMEM);
869 			}
870 			i_cpr_storage_data_base = addr;
871 			i_cpr_storage_data_end =
872 			    addr + mmu_ptob(i_cpr_storage_data_sz);
873 		}
874 
875 		/*
876 		 * Allocate on first pass, only realloc if retry is because of
877 		 * insufficient descriptors, but reset contents on each pass
878 		 * (desc_alloc resets contents as well)
879 		 */
880 		if (retry_cnt == 0 || error == -1) {
881 			error = i_cpr_storage_desc_alloc(
882 			    &i_cpr_storage_desc_base, &i_cpr_storage_desc_pgcnt,
883 			    &i_cpr_storage_desc_end, retry_cnt);
884 			if (error != 0)
885 				return (error);
886 		} else {
887 			i_cpr_storage_desc_init(i_cpr_storage_desc_base,
888 			    i_cpr_storage_desc_pgcnt, i_cpr_storage_desc_end);
889 		}
890 
891 		/*
892 		 * We are ready to save the sensitive kpages to storage.
893 		 * We cannot trust what's tagged in the bitmaps anymore
894 		 * after storage allocations.  Clear up the bitmaps and
895 		 * retag the sensitive kpages again.  The storage pages
896 		 * should be untagged.
897 		 */
898 		cpr_clear_bitmaps();
899 
900 		spages =
901 		    i_cpr_count_sensitive_kpages(REGULAR_BITMAP, cpr_setbit);
902 		vpages = cpr_count_volatile_pages(REGULAR_BITMAP, cpr_clrbit);
903 
904 		CPR_DEBUG(CPR_DEBUG7, pages_fmt, "after ", str,
905 		    spages, vpages, spages - vpages);
906 
907 		/*
908 		 * Returns 0 on success, -1 if too few descriptors, and
909 		 * ENOMEM if not enough space to save sensitive pages
910 		 */
911 		CPR_DEBUG(CPR_DEBUG1, "compressing pages to storage...\n");
912 		error = i_cpr_save_to_storage();
913 		if (error == 0) {
914 			/* Saving to storage succeeded */
915 			CPR_DEBUG(CPR_DEBUG1, "compressed %d pages\n",
916 			    sensitive_pages_saved);
917 			break;
918 		} else if (error == -1)
919 			CPR_DEBUG(CPR_DEBUG1, "%s too few descriptors\n", str);
920 	}
921 	if (error == -1)
922 		error = ENOMEM;
923 	return (error);
924 }
925 
926 
927 /*
928  * Estimate how much memory we will need to save
929  * the sensitive pages with compression.
930  */
931 static caddr_t
932 i_cpr_storage_data_alloc(pgcnt_t pages, pgcnt_t *alloc_pages, int retry_cnt)
933 {
934 	pgcnt_t alloc_pcnt, last_pcnt;
935 	caddr_t addr;
936 	char *str;
937 
938 	str = "i_cpr_storage_data_alloc:";
939 	if (retry_cnt == 0) {
940 		/*
941 		 * common compression ratio is about 3:1
942 		 * initial storage allocation is estimated at 40%
943 		 * to cover the majority of cases
944 		 */
945 		alloc_pcnt = INITIAL_ALLOC_PCNT;
946 		*alloc_pages = (pages * alloc_pcnt) / INTEGRAL;
947 		CPR_DEBUG(CPR_DEBUG7, "%s sensitive pages: %ld\n", str, pages);
948 		CPR_DEBUG(CPR_DEBUG7,
949 		    "%s initial est pages: %ld, alloc %ld%%\n",
950 		    str, *alloc_pages, alloc_pcnt);
951 	} else {
952 		/*
953 		 * calculate the prior compression percentage (x100)
954 		 * from the last attempt to save sensitive pages
955 		 */
956 		ASSERT(sensitive_pages_saved != 0);
957 		last_pcnt = (mmu_btopr(sensitive_size_saved) * INTEGRAL) /
958 		    sensitive_pages_saved;
959 		CPR_DEBUG(CPR_DEBUG7, "%s last ratio %ld%%\n", str, last_pcnt);
960 
961 		/*
962 		 * new estimated storage size is based on
963 		 * the larger ratio + 5% for each retry:
964 		 * pages * (last + [5%, 10%])
965 		 */
966 		alloc_pcnt = MAX(last_pcnt, INITIAL_ALLOC_PCNT) +
967 		    (retry_cnt * 5);
968 		*alloc_pages = (pages * alloc_pcnt) / INTEGRAL;
969 		CPR_DEBUG(CPR_DEBUG7, "%s Retry est pages: %ld, alloc %ld%%\n",
970 		    str, *alloc_pages, alloc_pcnt);
971 	}
972 
973 	addr = kmem_alloc(mmu_ptob(*alloc_pages), KM_NOSLEEP);
974 	CPR_DEBUG(CPR_DEBUG7, "%s alloc %ld pages\n", str, *alloc_pages);
975 	return (addr);
976 }
977 
978 
979 void
980 i_cpr_storage_free(void)
981 {
982 	/* Free descriptors */
983 	if (i_cpr_storage_desc_base) {
984 		kmem_free(i_cpr_storage_desc_base,
985 		    mmu_ptob(i_cpr_storage_desc_pgcnt));
986 		i_cpr_storage_desc_base = NULL;
987 		i_cpr_storage_desc_pgcnt = 0;
988 	}
989 
990 
991 	/* Data storage */
992 	if (i_cpr_storage_data_base) {
993 		kmem_free(i_cpr_storage_data_base,
994 		    mmu_ptob(i_cpr_storage_data_sz));
995 		i_cpr_storage_data_base = NULL;
996 		i_cpr_storage_data_sz = 0;
997 	}
998 }
999 
1000 
1001 /*
1002  * This routine is derived from cpr_compress_and_write().
1003  * 1. Do bookkeeping in the descriptor for the contiguous sensitive chunk.
1004  * 2. Compress and save the clean sensitive pages into the storage area.
1005  */
1006 int
1007 i_cpr_compress_and_save(int chunks, pfn_t spfn, pgcnt_t pages)
1008 {
1009 	extern char *cpr_compress_pages(cpd_t *, pgcnt_t, int);
1010 	extern caddr_t i_cpr_storage_data_end;
1011 	uint_t remaining, datalen;
1012 	uint32_t test_usum;
1013 	char *datap;
1014 	csd_t *descp;
1015 	cpd_t cpd;
1016 	int error;
1017 
1018 	/*
1019 	 * Fill next empty storage descriptor
1020 	 */
1021 	descp = i_cpr_storage_desc_base + chunks - 1;
1022 	if (descp >= i_cpr_storage_desc_end) {
1023 		CPR_DEBUG(CPR_DEBUG1, "ran out of descriptors, base 0x%p, "
1024 		    "chunks %d, end 0x%p, descp 0x%p\n",
1025 		    (void *)i_cpr_storage_desc_base, chunks,
1026 		    (void *)i_cpr_storage_desc_end, (void *)descp);
1027 		return (-1);
1028 	}
1029 	ASSERT(descp->csd_dirty_spfn == (uint_t)-1);
1030 	i_cpr_storage_desc_last_used = descp;
1031 
1032 	descp->csd_dirty_spfn = spfn;
1033 	descp->csd_dirty_npages = pages;
1034 
1035 	i_cpr_mapin(CPR->c_mapping_area, pages, spfn);
1036 
1037 	/*
1038 	 * try compressing pages and copy cpd fields
1039 	 * pfn is copied for debug use
1040 	 */
1041 	cpd.cpd_pfn = spfn;
1042 	datap = cpr_compress_pages(&cpd, pages, C_COMPRESSING);
1043 	datalen = cpd.cpd_length;
1044 	descp->csd_clean_compressed = (cpd.cpd_flag & CPD_COMPRESS);
1045 #ifdef DEBUG
1046 	descp->csd_usum = cpd.cpd_usum;
1047 	descp->csd_csum = cpd.cpd_csum;
1048 #endif
1049 
1050 	error = 0;
1051 
1052 	/*
1053 	 * Save the raw or compressed data to the storage area pointed to by
1054 	 * sensitive_write_ptr. Make sure the storage space is big enough to
1055 	 * hold the result. Otherwise roll back to increase the storage space.
1056 	 */
1057 	descp->csd_clean_sva = (cpr_ptr)sensitive_write_ptr;
1058 	descp->csd_clean_sz = datalen;
1059 	if ((sensitive_write_ptr + datalen) < i_cpr_storage_data_end) {
1060 		extern	void cprbcopy(void *, void *, size_t);
1061 
1062 		cprbcopy(datap, sensitive_write_ptr, datalen);
1063 		sensitive_size_saved += datalen;
1064 		sensitive_pages_saved += descp->csd_dirty_npages;
1065 		sensitive_write_ptr += datalen;
1066 	} else {
1067 		remaining = (i_cpr_storage_data_end - sensitive_write_ptr);
1068 		CPR_DEBUG(CPR_DEBUG1, "i_cpr_compress_and_save: The storage "
1069 		    "space is too small!\ngot %d, want %d\n\n",
1070 		    remaining, (remaining + datalen));
1071 #ifdef	DEBUG
1072 		/*
1073 		 * Check to see if the content of the sensitive pages that we
1074 		 * just copied have changed during this small time window.
1075 		 */
1076 		test_usum = checksum32(CPR->c_mapping_area, mmu_ptob(pages));
1077 		descp->csd_usum = cpd.cpd_usum;
1078 		if (test_usum != descp->csd_usum) {
1079 			CPR_DEBUG(CPR_DEBUG1, "\nWARNING: "
1080 			    "i_cpr_compress_and_save: "
1081 			    "Data in the range of pfn 0x%lx to pfn "
1082 			    "0x%lx has changed after they are saved "
1083 			    "into storage.", spfn, (spfn + pages - 1));
1084 		}
1085 #endif
1086 		error = ENOMEM;
1087 	}
1088 
1089 	i_cpr_mapout(CPR->c_mapping_area, pages);
1090 	return (error);
1091 }
1092 
1093 
1094 /*
1095  * This routine is derived from cpr_count_kpages().
1096  * It goes through kernel data nucleus and segkmem segments to select
1097  * pages in use and mark them in the corresponding bitmap.
1098  */
1099 pgcnt_t
1100 i_cpr_count_sensitive_kpages(int mapflag, bitfunc_t bitfunc)
1101 {
1102 	pgcnt_t kdata_cnt = 0, segkmem_cnt = 0;
1103 	extern caddr_t e_moddata;
1104 	extern struct seg kvalloc;
1105 	extern struct seg kmem64;
1106 	size_t size;
1107 
1108 	/*
1109 	 * Kernel data nucleus pages
1110 	 */
1111 	size = e_moddata - s_data;
1112 	kdata_cnt += cpr_count_pages(s_data, size,
1113 	    mapflag, bitfunc, DBG_SHOWRANGE);
1114 
1115 	/*
1116 	 * kvseg and kvalloc pages
1117 	 */
1118 	segkmem_cnt += cpr_scan_kvseg(mapflag, bitfunc, &kvseg);
1119 	segkmem_cnt += cpr_count_pages(kvalloc.s_base, kvalloc.s_size,
1120 	    mapflag, bitfunc, DBG_SHOWRANGE);
1121 
1122 	/* segment to support kernel memory usage above 32-bit space (4GB) */
1123 	if (kmem64.s_base)
1124 		segkmem_cnt += cpr_count_pages(kmem64.s_base, kmem64.s_size,
1125 		    mapflag, bitfunc, DBG_SHOWRANGE);
1126 
1127 	CPR_DEBUG(CPR_DEBUG7, "\ni_cpr_count_sensitive_kpages:\n"
1128 	    "\tkdata_cnt %ld + segkmem_cnt %ld = %ld pages\n",
1129 	    kdata_cnt, segkmem_cnt, kdata_cnt + segkmem_cnt);
1130 
1131 	return (kdata_cnt + segkmem_cnt);
1132 }
1133 
1134 
1135 pgcnt_t
1136 i_cpr_count_storage_pages(int mapflag, bitfunc_t bitfunc)
1137 {
1138 	pgcnt_t count = 0;
1139 
1140 	if (i_cpr_storage_desc_base) {
1141 		count += cpr_count_pages((caddr_t)i_cpr_storage_desc_base,
1142 		    (size_t)mmu_ptob(i_cpr_storage_desc_pgcnt),
1143 		    mapflag, bitfunc, DBG_SHOWRANGE);
1144 	}
1145 	if (i_cpr_storage_data_base) {
1146 		count += cpr_count_pages(i_cpr_storage_data_base,
1147 		    (size_t)mmu_ptob(i_cpr_storage_data_sz),
1148 		    mapflag, bitfunc, DBG_SHOWRANGE);
1149 	}
1150 	return (count);
1151 }
1152 
1153 
1154 /*
1155  * Derived from cpr_write_statefile().
1156  * Allocate (or reallocate after exhausting the supply) descriptors for each
1157  * chunk of contiguous sensitive kpages.
1158  */
1159 static int
1160 i_cpr_storage_desc_alloc(csd_t **basepp, pgcnt_t *pgsp, csd_t **endpp,
1161     int retry)
1162 {
1163 	pgcnt_t npages;
1164 	int chunks;
1165 	csd_t	*descp, *end;
1166 	size_t	len;
1167 	char *str = "i_cpr_storage_desc_alloc:";
1168 
1169 	/*
1170 	 * On initial allocation, add some extra to cover overhead caused
1171 	 * by the allocation for the storage area later.
1172 	 */
1173 	if (retry == 0) {
1174 		chunks = cpr_contig_pages(NULL, STORAGE_DESC_ALLOC) +
1175 		    EXTRA_DESCS;
1176 		npages = mmu_btopr(sizeof (**basepp) * (pgcnt_t)chunks);
1177 		CPR_DEBUG(CPR_DEBUG7, "%s chunks %d, ", str, chunks);
1178 	} else {
1179 		CPR_DEBUG(CPR_DEBUG7, "%s retry %d: ", str, retry);
1180 		npages = *pgsp + 1;
1181 	}
1182 	/* Free old descriptors, if any */
1183 	if (*basepp)
1184 		kmem_free((caddr_t)*basepp, mmu_ptob(*pgsp));
1185 
1186 	descp = *basepp = kmem_alloc(mmu_ptob(npages), KM_NOSLEEP);
1187 	if (descp == NULL) {
1188 		CPR_DEBUG(CPR_DEBUG7, "%s no space for descriptors!\n", str);
1189 		return (ENOMEM);
1190 	}
1191 
1192 	*pgsp = npages;
1193 	len = mmu_ptob(npages);
1194 	end = *endpp = descp + (len / (sizeof (**basepp)));
1195 	CPR_DEBUG(CPR_DEBUG7, "npages 0x%lx, len 0x%lx, items 0x%lx\n\t*basepp "
1196 	    "%p, *endpp %p\n", npages, len, (len / (sizeof (**basepp))),
1197 	    (void *)*basepp, (void *)*endpp);
1198 	i_cpr_storage_desc_init(descp, npages, end);
1199 	return (0);
1200 }
1201 
1202 static void
1203 i_cpr_storage_desc_init(csd_t *descp, pgcnt_t npages, csd_t *end)
1204 {
1205 	size_t	len = mmu_ptob(npages);
1206 
1207 	/* Initialize the descriptors to something impossible. */
1208 	bzero(descp, len);
1209 #ifdef	DEBUG
1210 	/*
1211 	 * This condition is tested by an ASSERT
1212 	 */
1213 	for (; descp < end; descp++)
1214 		descp->csd_dirty_spfn = (uint_t)-1;
1215 #endif
1216 }
1217 
1218 int
1219 i_cpr_dump_sensitive_kpages(vnode_t *vp)
1220 {
1221 	int	error = 0;
1222 	uint_t	spin_cnt = 0;
1223 	csd_t	*descp;
1224 
1225 	/*
1226 	 * These following two variables need to be reinitialized
1227 	 * for each cpr cycle.
1228 	 */
1229 	i_cpr_sensitive_bytes_dumped = 0;
1230 	i_cpr_sensitive_pgs_dumped = 0;
1231 
1232 	if (i_cpr_storage_desc_base) {
1233 		for (descp = i_cpr_storage_desc_base;
1234 		    descp <= i_cpr_storage_desc_last_used; descp++) {
1235 			if (error = cpr_dump_sensitive(vp, descp))
1236 				return (error);
1237 			spin_cnt++;
1238 			if ((spin_cnt & 0x5F) == 1)
1239 				cpr_spinning_bar();
1240 		}
1241 		prom_printf(" \b");
1242 	}
1243 
1244 	CPR_DEBUG(CPR_DEBUG7, "\ni_cpr_dump_sensitive_kpages: dumped %ld\n",
1245 	    i_cpr_sensitive_pgs_dumped);
1246 	return (0);
1247 }
1248 
1249 
1250 /*
1251  * 1. Fill the cpr page descriptor with the info of the dirty pages
1252  *    and
1253  *    write the descriptor out. It will be used at resume.
1254  * 2. Write the clean data in stead of the dirty data out.
1255  *    Note: to save space, the clean data is already compressed.
1256  */
1257 static int
1258 cpr_dump_sensitive(vnode_t *vp, csd_t *descp)
1259 {
1260 	int error = 0;
1261 	caddr_t datap;
1262 	cpd_t cpd;	/* cpr page descriptor */
1263 	pfn_t	dirty_spfn;
1264 	pgcnt_t dirty_npages;
1265 	size_t clean_sz;
1266 	caddr_t	clean_sva;
1267 	int	clean_compressed;
1268 	extern uchar_t cpr_pagecopy[];
1269 
1270 	dirty_spfn = descp->csd_dirty_spfn;
1271 	dirty_npages = descp->csd_dirty_npages;
1272 	clean_sva = (caddr_t)descp->csd_clean_sva;
1273 	clean_sz = descp->csd_clean_sz;
1274 	clean_compressed = descp->csd_clean_compressed;
1275 
1276 	/* Fill cpr page descriptor. */
1277 	cpd.cpd_magic = (uint_t)CPR_PAGE_MAGIC;
1278 	cpd.cpd_pfn = dirty_spfn;
1279 	cpd.cpd_flag = 0;  /* must init to zero */
1280 	cpd.cpd_pages = dirty_npages;
1281 
1282 #ifdef	DEBUG
1283 	if ((cpd.cpd_usum = descp->csd_usum) != 0)
1284 		cpd.cpd_flag |= CPD_USUM;
1285 	if ((cpd.cpd_csum = descp->csd_csum) != 0)
1286 		cpd.cpd_flag |= CPD_CSUM;
1287 #endif
1288 
1289 	STAT->cs_dumped_statefsz += mmu_ptob(dirty_npages);
1290 
1291 	/*
1292 	 * The sensitive kpages are usually saved with compression
1293 	 * unless compression could not reduce the size of the data.
1294 	 * If user choose not to have the statefile compressed,
1295 	 * we need to decompress the data back before dumping it to disk.
1296 	 */
1297 	if (CPR->c_flags & C_COMPRESSING) {
1298 		cpd.cpd_length = clean_sz;
1299 		datap = clean_sva;
1300 		if (clean_compressed)
1301 			cpd.cpd_flag |= CPD_COMPRESS;
1302 	} else {
1303 		if (clean_compressed) {
1304 			cpd.cpd_length = decompress(clean_sva, cpr_pagecopy,
1305 			    clean_sz, mmu_ptob(dirty_npages));
1306 			datap = (caddr_t)cpr_pagecopy;
1307 			ASSERT(cpd.cpd_length == mmu_ptob(dirty_npages));
1308 		} else {
1309 			cpd.cpd_length = clean_sz;
1310 			datap = clean_sva;
1311 		}
1312 		cpd.cpd_csum = 0;
1313 	}
1314 
1315 	/* Write cpr page descriptor */
1316 	error = cpr_write(vp, (caddr_t)&cpd, sizeof (cpd));
1317 	if (error) {
1318 		CPR_DEBUG(CPR_DEBUG7, "descp: %p\n", (void *)descp);
1319 #ifdef DEBUG
1320 		debug_enter("cpr_dump_sensitive: cpr_write() page "
1321 		    "descriptor failed!\n");
1322 #endif
1323 		return (error);
1324 	}
1325 
1326 	i_cpr_sensitive_bytes_dumped += sizeof (cpd_t);
1327 
1328 	/* Write page data */
1329 	error = cpr_write(vp, (caddr_t)datap, cpd.cpd_length);
1330 	if (error) {
1331 		CPR_DEBUG(CPR_DEBUG7, "error: %x\n", error);
1332 		CPR_DEBUG(CPR_DEBUG7, "descp: %p\n", (void *)descp);
1333 		CPR_DEBUG(CPR_DEBUG7, "cpr_write(%p, %p , %lx)\n",
1334 		    (void *)vp, (void *)datap, cpd.cpd_length);
1335 #ifdef DEBUG
1336 		debug_enter("cpr_dump_sensitive: cpr_write() data failed!\n");
1337 #endif
1338 		return (error);
1339 	}
1340 
1341 	i_cpr_sensitive_bytes_dumped += cpd.cpd_length;
1342 	i_cpr_sensitive_pgs_dumped += dirty_npages;
1343 
1344 	return (error);
1345 }
1346 
1347 
1348 /*
1349  * Sanity check to make sure that we have dumped right amount
1350  * of pages from different sources to statefile.
1351  */
1352 int
1353 i_cpr_check_pgs_dumped(uint_t pgs_expected, uint_t regular_pgs_dumped)
1354 {
1355 	uint_t total_pgs_dumped;
1356 
1357 	total_pgs_dumped = regular_pgs_dumped + i_cpr_sensitive_pgs_dumped;
1358 
1359 	CPR_DEBUG(CPR_DEBUG7, "\ncheck_pgs: reg %d + sens %ld = %d, "
1360 	    "expect %d\n\n", regular_pgs_dumped, i_cpr_sensitive_pgs_dumped,
1361 	    total_pgs_dumped, pgs_expected);
1362 
1363 	if (pgs_expected == total_pgs_dumped)
1364 		return (0);
1365 
1366 	return (EINVAL);
1367 }
1368 
1369 
1370 int
1371 i_cpr_reusefini(void)
1372 {
1373 	struct vnode *vp;
1374 	cdef_t *cdef;
1375 	size_t size;
1376 	char *bufp;
1377 	int rc;
1378 
1379 	if (cpr_reusable_mode)
1380 		cpr_reusable_mode = 0;
1381 
1382 	if (rc = cpr_open_deffile(FREAD|FWRITE, &vp)) {
1383 		if (rc == EROFS) {
1384 			cpr_err(CE_CONT, "uadmin A_FREEZE AD_REUSEFINI "
1385 			    "(uadmin %d %d)\nmust be done with / mounted "
1386 			    "writeable.\n", A_FREEZE, AD_REUSEFINI);
1387 		}
1388 		return (rc);
1389 	}
1390 
1391 	cdef = kmem_alloc(sizeof (*cdef), KM_SLEEP);
1392 	rc = cpr_rdwr(UIO_READ, vp, cdef, sizeof (*cdef));
1393 
1394 	if (rc) {
1395 		cpr_err(CE_WARN, "Failed reading %s, errno = %d",
1396 		    cpr_default_path, rc);
1397 	} else if (cdef->mini.magic != CPR_DEFAULT_MAGIC) {
1398 		cpr_err(CE_WARN, "bad magic number in %s, cannot restore "
1399 		    "prom values for %s", cpr_default_path,
1400 		    cpr_enumerate_promprops(&bufp, &size));
1401 		kmem_free(bufp, size);
1402 		rc = EINVAL;
1403 	} else {
1404 		/*
1405 		 * clean up prom properties
1406 		 */
1407 		rc = cpr_update_nvram(cdef->props);
1408 		if (rc == 0) {
1409 			/*
1410 			 * invalidate the disk copy and turn off reusable
1411 			 */
1412 			cdef->mini.magic = 0;
1413 			cdef->mini.reusable = 0;
1414 			if (rc = cpr_rdwr(UIO_WRITE, vp,
1415 			    &cdef->mini, sizeof (cdef->mini))) {
1416 				cpr_err(CE_WARN, "Failed writing %s, errno %d",
1417 				    cpr_default_path, rc);
1418 			}
1419 		}
1420 	}
1421 
1422 	(void) VOP_CLOSE(vp, FREAD|FWRITE, 1, (offset_t)0, CRED(), NULL);
1423 	VN_RELE(vp);
1424 	kmem_free(cdef, sizeof (*cdef));
1425 
1426 	return (rc);
1427 }
1428 
1429 
1430 int
1431 i_cpr_reuseinit(void)
1432 {
1433 	int rc = 0;
1434 
1435 	if (rc = cpr_default_setup(1))
1436 		return (rc);
1437 
1438 	/*
1439 	 * We need to validate default file
1440 	 */
1441 	rc = cpr_validate_definfo(1);
1442 	if (rc == 0)
1443 		cpr_reusable_mode = 1;
1444 	else if (rc == EROFS) {
1445 		cpr_err(CE_NOTE, "reuseinit must be performed "
1446 		    "while / is mounted writeable");
1447 	}
1448 
1449 	(void) cpr_default_setup(0);
1450 
1451 	return (rc);
1452 }
1453 
1454 
1455 int
1456 i_cpr_check_cprinfo(void)
1457 {
1458 	struct vnode *vp;
1459 	cmini_t mini;
1460 	int rc = 0;
1461 
1462 	if (rc = cpr_open_deffile(FREAD, &vp)) {
1463 		if (rc == ENOENT)
1464 			cpr_err(CE_NOTE, "cprinfo file does not "
1465 			    "exist.  You must run 'uadmin %d %d' "
1466 			    "command while / is mounted writeable,\n"
1467 			    "then reboot and run 'uadmin %d %d' "
1468 			    "to create a reusable statefile",
1469 			    A_FREEZE, AD_REUSEINIT, A_FREEZE, AD_REUSABLE);
1470 		return (rc);
1471 	}
1472 
1473 	rc = cpr_rdwr(UIO_READ, vp, &mini, sizeof (mini));
1474 	(void) VOP_CLOSE(vp, FREAD, 1, (offset_t)0, CRED(), NULL);
1475 	VN_RELE(vp);
1476 
1477 	if (rc) {
1478 		cpr_err(CE_WARN, "Failed reading %s, errno = %d",
1479 		    cpr_default_path, rc);
1480 	} else if (mini.magic != CPR_DEFAULT_MAGIC) {
1481 		cpr_err(CE_CONT, "bad magic number in cprinfo file.\n"
1482 		    "You must run 'uadmin %d %d' while / is mounted "
1483 		    "writeable, then reboot and run 'uadmin %d %d' "
1484 		    "to create a reusable statefile\n",
1485 		    A_FREEZE, AD_REUSEINIT, A_FREEZE, AD_REUSABLE);
1486 		rc = EINVAL;
1487 	}
1488 
1489 	return (rc);
1490 }
1491 
1492 
1493 int
1494 i_cpr_reusable_supported(void)
1495 {
1496 	return (1);
1497 }
1498 
1499 
1500 /*
1501  * find prom phys pages and alloc space for a tmp copy
1502  */
1503 static int
1504 i_cpr_find_ppages(void)
1505 {
1506 	struct page *pp;
1507 	struct memlist *pmem;
1508 	pgcnt_t npages, pcnt, scnt, vcnt;
1509 	pfn_t ppn, plast, *dst;
1510 	int mapflag;
1511 
1512 	cpr_clear_bitmaps();
1513 	mapflag = REGULAR_BITMAP;
1514 
1515 	/*
1516 	 * there should be a page_t for each phys page used by the kernel;
1517 	 * set a bit for each phys page not tracked by a page_t
1518 	 */
1519 	pcnt = 0;
1520 	memlist_read_lock();
1521 	for (pmem = phys_install; pmem; pmem = pmem->ml_next) {
1522 		npages = mmu_btop(pmem->ml_size);
1523 		ppn = mmu_btop(pmem->ml_address);
1524 		for (plast = ppn + npages; ppn < plast; ppn++) {
1525 			if (page_numtopp_nolock(ppn))
1526 				continue;
1527 			(void) cpr_setbit(ppn, mapflag);
1528 			pcnt++;
1529 		}
1530 	}
1531 	memlist_read_unlock();
1532 
1533 	/*
1534 	 * clear bits for phys pages in each segment
1535 	 */
1536 	scnt = cpr_count_seg_pages(mapflag, cpr_clrbit);
1537 
1538 	/*
1539 	 * set bits for phys pages referenced by the promvp vnode;
1540 	 * these pages are mostly comprised of forthdebug words
1541 	 */
1542 	vcnt = 0;
1543 	for (pp = promvp.v_pages; pp; ) {
1544 		if (cpr_setbit(pp->p_offset, mapflag) == 0)
1545 			vcnt++;
1546 		pp = pp->p_vpnext;
1547 		if (pp == promvp.v_pages)
1548 			break;
1549 	}
1550 
1551 	/*
1552 	 * total number of prom pages are:
1553 	 * (non-page_t pages - seg pages + vnode pages)
1554 	 */
1555 	ppage_count = pcnt - scnt + vcnt;
1556 	CPR_DEBUG(CPR_DEBUG1,
1557 	    "find_ppages: pcnt %ld - scnt %ld + vcnt %ld = %ld\n",
1558 	    pcnt, scnt, vcnt, ppage_count);
1559 
1560 	/*
1561 	 * alloc array of pfn_t to store phys page list
1562 	 */
1563 	pphys_list_size = ppage_count * sizeof (pfn_t);
1564 	pphys_list = kmem_alloc(pphys_list_size, KM_NOSLEEP);
1565 	if (pphys_list == NULL) {
1566 		cpr_err(CE_WARN, "cannot alloc pphys_list");
1567 		return (ENOMEM);
1568 	}
1569 
1570 	/*
1571 	 * phys pages referenced in the bitmap should be
1572 	 * those used by the prom; scan bitmap and save
1573 	 * a list of prom phys page numbers
1574 	 */
1575 	dst = pphys_list;
1576 	memlist_read_lock();
1577 	for (pmem = phys_install; pmem; pmem = pmem->ml_next) {
1578 		npages = mmu_btop(pmem->ml_size);
1579 		ppn = mmu_btop(pmem->ml_address);
1580 		for (plast = ppn + npages; ppn < plast; ppn++) {
1581 			if (cpr_isset(ppn, mapflag)) {
1582 				ASSERT(dst < (pphys_list + ppage_count));
1583 				*dst++ = ppn;
1584 			}
1585 		}
1586 	}
1587 	memlist_read_unlock();
1588 
1589 	/*
1590 	 * allocate space to store prom pages
1591 	 */
1592 	ppage_buf = kmem_alloc(mmu_ptob(ppage_count), KM_NOSLEEP);
1593 	if (ppage_buf == NULL) {
1594 		kmem_free(pphys_list, pphys_list_size);
1595 		pphys_list = NULL;
1596 		cpr_err(CE_WARN, "cannot alloc ppage_buf");
1597 		return (ENOMEM);
1598 	}
1599 
1600 	return (0);
1601 }
1602 
1603 
1604 /*
1605  * save prom pages to kmem pages
1606  */
1607 static void
1608 i_cpr_save_ppages(void)
1609 {
1610 	pfn_t *pphys, *plast;
1611 	caddr_t dst;
1612 
1613 	/*
1614 	 * map in each prom page and copy to a kmem page
1615 	 */
1616 	dst = ppage_buf;
1617 	plast = pphys_list + ppage_count;
1618 	for (pphys = pphys_list; pphys < plast; pphys++) {
1619 		i_cpr_mapin(cpr_vaddr, 1, *pphys);
1620 		bcopy(cpr_vaddr, dst, MMU_PAGESIZE);
1621 		i_cpr_mapout(cpr_vaddr, 1);
1622 		dst += MMU_PAGESIZE;
1623 	}
1624 
1625 	CPR_DEBUG(CPR_DEBUG1, "saved %ld prom pages\n", ppage_count);
1626 }
1627 
1628 
1629 /*
1630  * restore prom pages from kmem pages
1631  */
1632 static void
1633 i_cpr_restore_ppages(void)
1634 {
1635 	pfn_t *pphys, *plast;
1636 	caddr_t src;
1637 
1638 	dcache_flushall();
1639 
1640 	/*
1641 	 * map in each prom page and copy from a kmem page
1642 	 */
1643 	src = ppage_buf;
1644 	plast = pphys_list + ppage_count;
1645 	for (pphys = pphys_list; pphys < plast; pphys++) {
1646 		i_cpr_mapin(cpr_vaddr, 1, *pphys);
1647 		bcopy(src, cpr_vaddr, MMU_PAGESIZE);
1648 		i_cpr_mapout(cpr_vaddr, 1);
1649 		src += MMU_PAGESIZE;
1650 	}
1651 
1652 	dcache_flushall();
1653 
1654 	CPR_DEBUG(CPR_DEBUG1, "restored %ld prom pages\n", ppage_count);
1655 }
1656 
1657 
1658 /*
1659  * save/restore prom pages or free related allocs
1660  */
1661 int
1662 i_cpr_prom_pages(int action)
1663 {
1664 	int error;
1665 
1666 	if (action == CPR_PROM_SAVE) {
1667 		if (ppage_buf == NULL) {
1668 			ASSERT(pphys_list == NULL);
1669 			if (error = i_cpr_find_ppages())
1670 				return (error);
1671 			i_cpr_save_ppages();
1672 		}
1673 	} else if (action == CPR_PROM_RESTORE) {
1674 		i_cpr_restore_ppages();
1675 	} else if (action == CPR_PROM_FREE) {
1676 		if (pphys_list) {
1677 			ASSERT(pphys_list_size);
1678 			kmem_free(pphys_list, pphys_list_size);
1679 			pphys_list = NULL;
1680 			pphys_list_size = 0;
1681 		}
1682 		if (ppage_buf) {
1683 			ASSERT(ppage_count);
1684 			kmem_free(ppage_buf, mmu_ptob(ppage_count));
1685 			CPR_DEBUG(CPR_DEBUG1, "freed %ld prom pages\n",
1686 			    ppage_count);
1687 			ppage_buf = NULL;
1688 			ppage_count = 0;
1689 		}
1690 	}
1691 	return (0);
1692 }
1693 
1694 
1695 /*
1696  * record tlb data for the nucleus, bigktsb's, and the cpr module;
1697  * this data is later used by cprboot to install dtlb/itlb entries.
1698  * when we jump into the cpr module during the resume phase, those
1699  * mappings are needed until switching to the kernel trap table.
1700  * to make the dtte/itte info available during resume, we need
1701  * the info recorded prior to saving sensitive pages, otherwise
1702  * all the data would appear as NULLs.
1703  */
1704 static void
1705 i_cpr_save_tlbinfo(void)
1706 {
1707 	cti_t cti = {0};
1708 
1709 	/*
1710 	 * during resume - shortly after jumping into the cpr module,
1711 	 * sfmmu_load_mmustate() will overwrite any dtlb entry at any
1712 	 * index used for TSBs; skip is set so that any saved tte will
1713 	 * target other tlb offsets and prevent being lost during
1714 	 * resume.  now scan the dtlb and save locked entries,
1715 	 * then add entries for the tmp stack / data page and the
1716 	 * cpr thread structure.
1717 	 */
1718 	cti.dst = m_info.dtte;
1719 	cti.tail = cti.dst + CPR_MAX_TLB;
1720 	cti.reader = dtlb_rd_entry;
1721 	cti.writer = NULL;
1722 	cti.filter = i_cpr_lnb;
1723 	cti.index = cpunodes[CPU->cpu_id].dtlb_size - 1;
1724 
1725 	if (utsb_dtlb_ttenum != -1)
1726 		cti.skip = (1 << utsb_dtlb_ttenum);
1727 
1728 	if (utsb4m_dtlb_ttenum != -1)
1729 		cti.skip |= (1 << utsb4m_dtlb_ttenum);
1730 
1731 	i_cpr_scan_tlb(&cti);
1732 	i_cpr_make_tte(&cti, &i_cpr_data_page, datava);
1733 	i_cpr_make_tte(&cti, curthread, datava);
1734 
1735 	/*
1736 	 * scan itlb and save locked entries; add an entry for
1737 	 * the first text page of the cpr module; cprboot will
1738 	 * jump to that page after restoring kernel pages.
1739 	 */
1740 	cti.dst = m_info.itte;
1741 	cti.tail = cti.dst + CPR_MAX_TLB;
1742 	cti.reader = itlb_rd_entry;
1743 	cti.index = cpunodes[CPU->cpu_id].itlb_size - 1;
1744 	cti.skip = 0;
1745 	i_cpr_scan_tlb(&cti);
1746 	i_cpr_make_tte(&cti, (void *)i_cpr_resume_setup, textva);
1747 }
1748 
1749 
1750 /* ARGSUSED */
1751 int
1752 i_cpr_dump_setup(vnode_t *vp)
1753 {
1754 	/*
1755 	 * zero out m_info and add info to dtte/itte arrays
1756 	 */
1757 	bzero(&m_info, sizeof (m_info));
1758 	i_cpr_save_tlbinfo();
1759 	return (0);
1760 }
1761 
1762 
1763 int
1764 i_cpr_is_supported(int sleeptype)
1765 {
1766 	char es_prop[] = "energystar-v2";
1767 	pnode_t node;
1768 	int last;
1769 	extern int cpr_supported_override;
1770 	extern int cpr_platform_enable;
1771 
1772 	if (sleeptype != CPR_TODISK)
1773 		return (0);
1774 
1775 	/*
1776 	 * The next statement tests if a specific platform has turned off
1777 	 * cpr support.
1778 	 */
1779 	if (cpr_supported_override)
1780 		return (0);
1781 
1782 	/*
1783 	 * Do not inspect energystar-v* property if a platform has
1784 	 * specifically turned on cpr support
1785 	 */
1786 	if (cpr_platform_enable)
1787 		return (1);
1788 
1789 	node = prom_rootnode();
1790 	if (prom_getproplen(node, es_prop) != -1)
1791 		return (1);
1792 	last = strlen(es_prop) - 1;
1793 	es_prop[last] = '3';
1794 	return (prom_getproplen(node, es_prop) != -1);
1795 }
1796 
1797 
1798 /*
1799  * the actual size of the statefile data isn't known until after all the
1800  * compressed pages are written; even the inode size doesn't reflect the
1801  * data size since there are usually many extra fs blocks.  for recording
1802  * the actual data size, the first sector of the statefile is copied to
1803  * a tmp buf, and the copy is later updated and flushed to disk.
1804  */
1805 int
1806 i_cpr_blockzero(char *base, char **bufpp, int *blkno, vnode_t *vp)
1807 {
1808 	extern int cpr_flush_write(vnode_t *);
1809 	static char cpr_sector[DEV_BSIZE];
1810 	cpr_ext bytes, *dst;
1811 
1812 	/*
1813 	 * this routine is called after cdd_t and csu_md_t are copied
1814 	 * to cpr_buf; mini-hack alert: the save/update method creates
1815 	 * a dependency on the combined struct size being >= one sector
1816 	 * or DEV_BSIZE; since introduction in Sol2.7, csu_md_t size is
1817 	 * over 1K bytes and will probably grow with any changes.
1818 	 *
1819 	 * copy when vp is NULL, flush when non-NULL
1820 	 */
1821 	if (vp == NULL) {
1822 		ASSERT((*bufpp - base) >= DEV_BSIZE);
1823 		bcopy(base, cpr_sector, sizeof (cpr_sector));
1824 		return (0);
1825 	} else {
1826 		bytes = dbtob(*blkno);
1827 		dst = &((cdd_t *)cpr_sector)->cdd_filesize;
1828 		bcopy(&bytes, dst, sizeof (bytes));
1829 		bcopy(cpr_sector, base, sizeof (cpr_sector));
1830 		*bufpp = base + sizeof (cpr_sector);
1831 		*blkno = cpr_statefile_offset();
1832 		CPR_DEBUG(CPR_DEBUG1, "statefile data size: %ld\n\n", bytes);
1833 		return (cpr_flush_write(vp));
1834 	}
1835 }
1836 
1837 
1838 /*
1839  * Allocate bitmaps according to the phys_install list.
1840  */
1841 static int
1842 i_cpr_bitmap_setup(void)
1843 {
1844 	struct memlist *pmem;
1845 	cbd_t *dp, *tail;
1846 	void *space;
1847 	size_t size;
1848 
1849 	/*
1850 	 * The number of bitmap descriptors will be the count of
1851 	 * phys_install ranges plus 1 for a trailing NULL struct.
1852 	 */
1853 	cpr_nbitmaps = 1;
1854 	for (pmem = phys_install; pmem; pmem = pmem->ml_next)
1855 		cpr_nbitmaps++;
1856 
1857 	if (cpr_nbitmaps > (CPR_MAX_BMDESC - 1)) {
1858 		cpr_err(CE_WARN, "too many physical memory ranges %d, max %d",
1859 		    cpr_nbitmaps, CPR_MAX_BMDESC - 1);
1860 		return (EFBIG);
1861 	}
1862 
1863 	/* Alloc an array of bitmap descriptors. */
1864 	dp = kmem_zalloc(cpr_nbitmaps * sizeof (*dp), KM_NOSLEEP);
1865 	if (dp == NULL) {
1866 		cpr_nbitmaps = 0;
1867 		return (ENOMEM);
1868 	}
1869 	tail = dp + cpr_nbitmaps;
1870 
1871 	CPR->c_bmda = dp;
1872 	for (pmem = phys_install; pmem; pmem = pmem->ml_next) {
1873 		size = BITMAP_BYTES(pmem->ml_size);
1874 		space = kmem_zalloc(size * 2, KM_NOSLEEP);
1875 		if (space == NULL)
1876 			return (ENOMEM);
1877 		ASSERT(dp < tail);
1878 		dp->cbd_magic = CPR_BITMAP_MAGIC;
1879 		dp->cbd_spfn = mmu_btop(pmem->ml_address);
1880 		dp->cbd_epfn = mmu_btop(pmem->ml_address + pmem->ml_size) - 1;
1881 		dp->cbd_size = size;
1882 		dp->cbd_reg_bitmap = (cpr_ptr)space;
1883 		dp->cbd_vlt_bitmap = (cpr_ptr)((caddr_t)space + size);
1884 		dp++;
1885 	}
1886 
1887 	/* set magic for the last descriptor */
1888 	ASSERT(dp == (tail - 1));
1889 	dp->cbd_magic = CPR_BITMAP_MAGIC;
1890 
1891 	return (0);
1892 }
1893 
1894 
1895 void
1896 i_cpr_bitmap_cleanup(void)
1897 {
1898 	cbd_t *dp;
1899 
1900 	if (CPR->c_bmda == NULL)
1901 		return;
1902 	for (dp = CPR->c_bmda; dp->cbd_size; dp++)
1903 		kmem_free((void *)dp->cbd_reg_bitmap, dp->cbd_size * 2);
1904 	kmem_free(CPR->c_bmda, cpr_nbitmaps * sizeof (*CPR->c_bmda));
1905 	CPR->c_bmda = NULL;
1906 	cpr_nbitmaps = 0;
1907 }
1908 
1909 
1910 /*
1911  * A "regular" and "volatile" bitmap are created for each range of
1912  * physical memory.  The volatile maps are used to count and track pages
1913  * susceptible to heap corruption - caused by drivers that allocate mem
1914  * during VOP_DUMP(); the regular maps are used for all the other non-
1915  * susceptible pages.  Before writing the bitmaps to the statefile,
1916  * each bitmap pair gets merged to simplify handling within cprboot.
1917  */
1918 int
1919 i_cpr_alloc_bitmaps(void)
1920 {
1921 	int err;
1922 
1923 	memlist_read_lock();
1924 	err = i_cpr_bitmap_setup();
1925 	memlist_read_unlock();
1926 	if (err)
1927 		i_cpr_bitmap_cleanup();
1928 	return (err);
1929 }
1930 
1931 
1932 
1933 /*
1934  * Power down the system.
1935  */
1936 int
1937 i_cpr_power_down(int sleeptype)
1938 {
1939 	int is_defined = 0;
1940 	char *wordexists = "p\" power-off\" find nip swap l! ";
1941 	char *req = "power-off";
1942 
1943 	ASSERT(sleeptype == CPR_TODISK);
1944 
1945 	/*
1946 	 * is_defined has value -1 when defined
1947 	 */
1948 	prom_interpret(wordexists, (uintptr_t)&is_defined, 0, 0, 0, 0);
1949 	if (is_defined) {
1950 		CPR_DEBUG(CPR_DEBUG1, "\ncpr: %s...\n", req);
1951 		prom_interpret(req, 0, 0, 0, 0, 0);
1952 	}
1953 	/*
1954 	 * Only returns if failed
1955 	 */
1956 	return (EIO);
1957 }
1958 
1959 void
1960 i_cpr_stop_other_cpus(void)
1961 {
1962 	stop_other_cpus();
1963 }
1964 
1965 /*
1966  *	Save context for the specified CPU
1967  */
1968 /* ARGSUSED */
1969 void *
1970 i_cpr_save_context(void *arg)
1971 {
1972 	/*
1973 	 * Not yet
1974 	 */
1975 	ASSERT(0);
1976 	return (NULL);
1977 }
1978 
1979 void
1980 i_cpr_pre_resume_cpus(void)
1981 {
1982 	/*
1983 	 * Not yet
1984 	 */
1985 	ASSERT(0);
1986 }
1987 
1988 void
1989 i_cpr_post_resume_cpus(void)
1990 {
1991 	/*
1992 	 * Not yet
1993 	 */
1994 	ASSERT(0);
1995 }
1996 
1997 /*
1998  * nothing to do
1999  */
2000 void
2001 i_cpr_alloc_cpus(void)
2002 {
2003 }
2004 
2005 /*
2006  * nothing to do
2007  */
2008 void
2009 i_cpr_free_cpus(void)
2010 {
2011 }
2012 
2013 /* ARGSUSED */
2014 void
2015 i_cpr_save_configuration(dev_info_t *dip)
2016 {
2017 	/*
2018 	 * this is a no-op on sparc
2019 	 */
2020 }
2021 
2022 /* ARGSUSED */
2023 void
2024 i_cpr_restore_configuration(dev_info_t *dip)
2025 {
2026 	/*
2027 	 * this is a no-op on sparc
2028 	 */
2029 }
2030