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, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22 /*
23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 #pragma ident "%Z%%M% %I% %E% SMI"
28
29 #include <sys/types.h>
30 #include <sys/cpr.h>
31 #include <sys/promimpl.h>
32 #include <sys/privregs.h>
33 #include <sys/stack.h>
34 #include <sys/cpuvar.h>
35 #include "cprboot.h"
36
37
38 #define TIMEOUT_MSECS 1000
39
40
41 /*
42 * globals
43 */
44 int cpr_test_mode;
45 csu_md_t mdinfo;
46 caddr_t tmp_stack;
47 uint_t cb_mid;
48 uint_t cb_clock_freq;
49 uint_t cpu_delay;
50
51
52 /*
53 * file scope
54 */
55 typedef void (*tlb_func_t)(int, caddr_t, tte_t *);
56 static uint_t mdlen;
57 static cpuset_t slave_set;
58 static int has_scbc;
59
60
61 /*
62 * check machdep desc and cpr_machdep info
63 *
64 * sets globals:
65 * mdinfo
66 * mdlen
67 */
68 int
cb_check_machdep(void)69 cb_check_machdep(void)
70 {
71 uint16_t wst32, wst64;
72 char *fmt, *str;
73 cmd_t cmach;
74
75 str = "cb_check_machdep";
76 CB_VPRINTF((ent_fmt, str, entry));
77
78 /*
79 * get machdep desc and set length of prom words
80 */
81 SF_DCOPY(cmach);
82 if (cmach.md_magic != CPR_MACHDEP_MAGIC) {
83 prom_printf("%s: bad machdep magic 0x%x, expect 0x%x\n",
84 str, cmach.md_magic, CPR_MACHDEP_MAGIC);
85 return (ERR);
86 }
87 mdlen = cmach.md_size - sizeof (csu_md_t);
88
89 /*
90 * get machep info, check for valid stack bias and wstate
91 */
92 SF_DCOPY(mdinfo);
93 fmt = "found bad statefile data: %s (0x%x), expect 0x%x or 0x%x\n";
94 if (mdinfo.ksb != 0x0 && mdinfo.ksb != V9BIAS64) {
95 prom_printf(fmt, "stack bias", mdinfo.ksb, 0, V9BIAS64);
96 return (ERR);
97 }
98 wst32 = WSTATE(WSTATE_U32, WSTATE_K32);
99 wst64 = WSTATE(WSTATE_U32, WSTATE_K64);
100 if (mdinfo.kwstate != wst32 && mdinfo.kwstate != wst64) {
101 prom_printf(fmt, "wstate", mdinfo.kwstate, wst32, wst64);
102 return (ERR);
103 }
104
105 return (0);
106 }
107
108
109 /*
110 * interpret saved prom words
111 */
112 int
cb_interpret(void)113 cb_interpret(void)
114 {
115 int bytes, wlen, s;
116 char minibuf[60];
117 char *words;
118
119 CB_VENTRY(cb_interpret);
120
121 /*
122 * The variable length machdep section for sun4u consists of
123 * a sequence of null-terminated strings stored contiguously.
124 *
125 * The first string defines Forth words which help the prom
126 * handle kernel translations.
127 *
128 * The second string defines Forth words required by kadb to
129 * interface with the prom when a trap is taken.
130 */
131 words = SF_DATA();
132 bytes = mdlen;
133 while (bytes) {
134 wlen = prom_strlen(words) + 1; /* include the null */
135 if (verbose) {
136 s = sizeof (minibuf) - 4;
137 (void) prom_strncpy(minibuf, words, s);
138 if (wlen > s)
139 (void) prom_strcpy(&minibuf[s], "...");
140 prom_printf(" interpret \"%s\"\n", minibuf);
141 }
142 prom_interpret(words, 0, 0, 0, 0, 0);
143 words += wlen;
144 bytes -= wlen;
145 }
146
147 /* advance past prom words */
148 SF_ADV(mdlen);
149
150 return (0);
151 }
152
153
154 /*
155 * write dtlb/itlb entries
156 */
157 static void
restore_tlb(struct sun4u_tlb * utp,int cpu_id)158 restore_tlb(struct sun4u_tlb *utp, int cpu_id)
159 {
160 struct sun4u_tlb *tail;
161 tlb_func_t tfunc;
162 caddr_t virt;
163 char tname;
164
165 if (utp == mdinfo.dtte) {
166 tfunc = set_dtlb_entry;
167 tname = 'd';
168 } else if (utp == mdinfo.itte) {
169 tfunc = set_itlb_entry;
170 tname = 'i';
171 }
172
173 for (tail = utp + CPR_MAX_TLB; utp < tail; utp++) {
174 if (utp->va_tag == NULL)
175 continue;
176 virt = (caddr_t)utp->va_tag;
177 (*tfunc)(utp->index, virt, &utp->tte);
178 if (verbose || CPR_DBG(4)) {
179 prom_printf(" cpu_id %d: write %ctlb "
180 "(index %x, virt 0x%lx, size 0x%x)\n",
181 cpu_id, tname, utp->index, utp->va_tag,
182 TTEBYTES(utp->tte.tte_size));
183 }
184 }
185 }
186
187
188 /*
189 * install locked tlb entries for the kernel and cpr module;
190 * also sets up the tmp stack
191 */
192 int
cb_ksetup(void)193 cb_ksetup(void)
194 {
195 CB_VENTRY(cb_ksetup);
196
197 restore_tlb(mdinfo.dtte, cb_mid);
198 restore_tlb(mdinfo.itte, cb_mid);
199 tmp_stack = (caddr_t)(mdinfo.tmp_stack + mdinfo.tmp_stacksize);
200
201 return (0);
202 }
203
204
205 static void
cb_park_err(int cpu_id)206 cb_park_err(int cpu_id)
207 {
208 prom_printf("\ncpu_id %d did not stop!...\n", cpu_id);
209 cb_exit_to_mon();
210 }
211
212
213 /*
214 * local copy of an older interface for OBP revs < 4.6
215 */
216 static int
cb_prom_stop_self(void)217 cb_prom_stop_self(void)
218 {
219 cell_t ci[3];
220
221 ci[0] = p1275_ptr2cell("SUNW,stop-self"); /* Service name */
222 ci[1] = (cell_t)0; /* #argument cells */
223 ci[2] = (cell_t)0; /* #result cells */
224 (void) p1275_cif_handler(&ci); /* Do NOT lock */
225 return (0);
226 }
227
228
229 /*
230 * install locked tlb entries and spin or park in a prom idle-loop
231 */
232 void
slave_init(int cpu_id)233 slave_init(int cpu_id)
234 {
235 restore_tlb(mdinfo.dtte, cpu_id);
236 restore_tlb(mdinfo.itte, cpu_id);
237 CPUSET_ADD(slave_set, cpu_id);
238 membar_stld();
239 if (has_scbc) {
240 /* just spin, master will park this cpu */
241 /* CONSTCOND */
242 while (1);
243 } else {
244 (void) cb_prom_stop_self();
245 cb_park_err(cpu_id);
246 }
247 }
248
249
250 /*
251 * when any cpu is started, they naturally rely on the prom for all
252 * text/data translations until switching to the kernel trap table.
253 * to jump back into the cpr module and to restart slave cpus, cprboot
254 * needs to reinstall translations for the nucleus and some cpr pages.
255 *
256 * the easy method is creating one set of global translations available
257 * to all cpus with prom_map(); unfortunately, a 4MB "map" request will
258 * allocate and overwrite a few pages, and these are often kernel pages
259 * that were just restored.
260 *
261 * to solve the "map" problem, all cpus install their own set of locked
262 * tlb entries to translate the nucleus and parts of the cpr module;
263 * after all cpus have switched to kernel traps, any of these locked
264 * tlb entries for pages outside the nucleus will be cleared.
265 */
266 int
cb_mpsetup(void)267 cb_mpsetup(void)
268 {
269 struct sun4u_cpu_info *scip, *tail;
270 int timeout, ncpu;
271 char *str, *intf;
272
273 intf = "SUNW,stop-cpu-by-cpuid";
274 has_scbc = (prom_test(intf) == 0);
275 CB_VPRINTF(("\n\"%s\" test %d\n", intf, has_scbc));
276
277 str = "cb_mp_setup";
278 CB_VPRINTF((ent_fmt, str, entry));
279
280 /*
281 * launch any slave cpus from the .sci array into cprboot text
282 * and wait about a second for them to checkin with slave_set
283 */
284 ncpu = 0;
285 CPUSET_ZERO(slave_set);
286 for (scip = mdinfo.sci, tail = scip + NCPU; scip < tail; scip++) {
287 if (scip->node == 0 || scip->cpu_id == cb_mid)
288 continue;
289 (void) prom_startcpu(scip->node,
290 (caddr_t)cpu_launch, scip->cpu_id);
291
292 for (timeout = TIMEOUT_MSECS; timeout; timeout--) {
293 if (CPU_IN_SET(slave_set, scip->cpu_id))
294 break;
295 cb_usec_wait(MILLISEC);
296 }
297
298 if (timeout == 0) {
299 prom_printf("\n%s: cpu did not start, "
300 "cpu_id %d, node 0x%x\n",
301 prog, scip->cpu_id, scip->node);
302 return (ERR);
303 }
304
305 if (has_scbc && prom_stopcpu_bycpuid(scip->cpu_id))
306 cb_park_err(scip->cpu_id);
307
308 ncpu++;
309 }
310
311 if (verbose && ncpu)
312 prom_printf("\n%s: slave cpu count: %d\n", str, ncpu);
313
314 return (0);
315 }
316