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.
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.
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]
22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 #pragma ident "%Z%%M% %I% %E% SMI"
28 #include <sys/types.h>
31 #include <sys/promimpl.h>
32 #include <sys/prom_plat.h>
35 extern void prom_unmap(caddr_t
, uint_t
);
38 static int cpr_show_props
= 0;
41 * Read the config file and pass back the file path, filesystem
45 cpr_read_cprinfo(int fd
, char *file_path
, char *fs_path
)
49 if (cpr_fs_read(fd
, (char *)&cf
, sizeof (cf
)) != sizeof (cf
) ||
50 cf
.cf_magic
!= CPR_CONFIG_MAGIC
)
53 (void) prom_strcpy(file_path
, cf
.cf_path
);
54 (void) prom_strcpy(fs_path
, cf
.cf_dev_prom
);
55 if (cf
.cf_type
== CFT_ZVOL
)
62 * Read the location of the state file from the root filesystem.
63 * Pass back to the caller the full device path of the filesystem
64 * and the filename relative to that fs.
67 cpr_locate_statefile(char *file_path
, char *fs_path
)
72 if ((fd
= cpr_fs_open(CPR_CONFIG
)) != -1) {
73 rc
= cpr_read_cprinfo(fd
, file_path
, fs_path
);
74 (void) cpr_fs_close(fd
);
83 * Open the "defaults" file in the root fs and read the values of the
84 * properties saved during the checkpoint. Restore the values to nvram.
86 * Note: an invalid magic number in the "defaults" file means that the
87 * state file is bad or obsolete so our caller should not proceed with
91 cpr_reset_properties(void)
93 char *str
, *default_path
;
94 int fd
, len
, rc
, prop_errors
;
99 str
= "cpr_reset_properties";
100 default_path
= CPR_DEFAULT
;
102 if ((fd
= cpr_fs_open(default_path
)) == -1) {
103 prom_printf("%s: unable to open %s\n",
109 len
= cpr_fs_read(fd
, (char *)&cdef
, sizeof (cdef
));
110 if (len
!= sizeof (cdef
)) {
111 prom_printf("%s: error reading %s\n", str
, default_path
);
113 } else if (cdef
.mini
.magic
!= CPR_DEFAULT_MAGIC
) {
114 prom_printf("%s: bad magic number in %s\n", str
, default_path
);
118 (void) cpr_fs_close(fd
);
122 node
= prom_optionsnode();
123 if (node
== OBP_NONODE
|| node
== OBP_BADNODE
) {
124 prom_printf("%s: cannot find \"options\" node\n", str
);
129 * reset nvram to the original property values
132 prom_printf("\n\ncpr_show_props:\n");
133 for (prop_errors
= 0, prop
= cdef
.props
, tail
= prop
+ CPR_MAXPROP
;
134 prop
< tail
; prop
++) {
135 if (cpr_show_props
) {
136 prom_printf("mod=%c, name=\"%s\",\tvalue=\"%s\"\n",
137 prop
->mod
, prop
->name
, prop
->value
);
139 if (prop
->mod
!= PROP_MOD
)
142 len
= prom_strlen(prop
->value
);
143 if (prom_setprop(node
, prop
->name
, prop
->value
, len
+ 1) < 0 ||
144 prom_getproplen(node
, prop
->name
) != len
) {
145 prom_printf("%s: error setting \"%s\" to \"%s\"\n",
146 str
, prop
->name
, prop
->value
);
151 return (prop_errors
? -1 : 0);
156 * Read and verify cpr dump descriptor
159 cpr_read_cdump(int fd
, cdd_t
*cdp
, ushort_t mach_type
)
164 str
= "\ncpr_read_cdump:";
165 nread
= cpr_read(fd
, (caddr_t
)cdp
, sizeof (*cdp
));
166 if (nread
!= sizeof (*cdp
)) {
167 prom_printf("%s Error reading cpr dump descriptor\n", str
);
171 if (cdp
->cdd_magic
!= CPR_DUMP_MAGIC
) {
172 prom_printf("%s bad dump magic 0x%x, expected 0x%x\n",
173 str
, cdp
->cdd_magic
, CPR_DUMP_MAGIC
);
177 if (cdp
->cdd_version
!= CPR_VERSION
) {
178 prom_printf("%s bad cpr version %d, expected %d\n",
179 str
, cdp
->cdd_version
, CPR_VERSION
);
183 if (cdp
->cdd_machine
!= mach_type
) {
184 prom_printf("%s bad machine type 0x%x, expected 0x%x\n",
185 str
, cdp
->cdd_machine
, mach_type
);
189 if (cdp
->cdd_bitmaprec
<= 0) {
190 prom_printf("%s bad bitmap %d\n", str
, cdp
->cdd_bitmaprec
);
194 if (cdp
->cdd_dumppgsize
<= 0) {
195 prom_printf("%s Bad pg tot %d\n", str
, cdp
->cdd_dumppgsize
);
199 cpr_debug
= cdp
->cdd_debug
;
206 * update cpr dump terminator
209 cpr_update_terminator(ctrm_t
*file_term
, caddr_t mapva
)
214 * Add the offset to reach the terminator in the kernel so that we
215 * can directly change the restored kernel image.
217 mem_term
= (ctrm_t
*)(mapva
+ (file_term
->va
& MMU_PAGEOFFSET
));
219 mem_term
->real_statef_size
= file_term
->real_statef_size
;
220 mem_term
->tm_shutdown
= file_term
->tm_shutdown
;
221 mem_term
->tm_cprboot_start
.tv_sec
= file_term
->tm_cprboot_start
.tv_sec
;
222 mem_term
->tm_cprboot_end
.tv_sec
= prom_gettime() / 1000;
227 * simple bcopy for cprboot
230 bcopy(const void *s
, void *d
, size_t count
)