xref: /illumos-gate/usr/src/uts/sun4/os/mlsetup.c (revision bbfe764ef179c2f606b093b6ec6bb149cde0e31b)
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 2007 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/machsystm.h>
32 #include <sys/disp.h>
33 #include <sys/autoconf.h>
34 #include <sys/promif.h>
35 #include <sys/prom_plat.h>
36 #include <sys/clock.h>
37 #include <sys/pte.h>
38 #include <sys/scb.h>
39 #include <sys/cpu.h>
40 #include <sys/stack.h>
41 #include <sys/intreg.h>
42 #include <sys/ivintr.h>
43 #include <vm/as.h>
44 #include <vm/hat_sfmmu.h>
45 #include <sys/reboot.h>
46 #include <sys/sysmacros.h>
47 #include <sys/vtrace.h>
48 #include <sys/trap.h>
49 #include <sys/machtrap.h>
50 #include <sys/privregs.h>
51 #include <sys/machpcb.h>
52 #include <sys/proc.h>
53 #include <sys/cpupart.h>
54 #include <sys/pset.h>
55 #include <sys/cpu_module.h>
56 #include <sys/copyops.h>
57 #include <sys/panic.h>
58 #include <sys/bootconf.h>	/* for bootops */
59 #include <sys/pg.h>
60 #include <sys/kdi.h>
61 #include <sys/fpras.h>
62 
63 #include <sys/prom_debug.h>
64 #include <sys/debug.h>
65 
66 #include <sys/sunddi.h>
67 #include <sys/lgrp.h>
68 #include <sys/traptrace.h>
69 /*
70  * External Routines:
71  */
72 extern void map_wellknown_devices(void);
73 extern void hsvc_setup(void);
74 extern void mach_descrip_startup_init(void);
75 extern void mach_soft_state_init(void);
76 
77 int	dcache_size;
78 int	dcache_linesize;
79 int	icache_size;
80 int	icache_linesize;
81 int	ecache_size;
82 int	ecache_alignsize;
83 int	ecache_associativity;
84 int	ecache_setsize;			/* max possible e$ setsize */
85 int	cpu_setsize;			/* max e$ setsize of configured cpus */
86 int	dcache_line_mask;		/* spitfire only */
87 int	vac_size;			/* cache size in bytes */
88 uint_t	vac_mask;			/* VAC alignment consistency mask */
89 int	vac_shift;			/* log2(vac_size) for ppmapout() */
90 int	vac = 0;	/* virtual address cache type (none == 0) */
91 
92 /*
93  * fpRAS.  An individual sun4* machine class (or perhaps subclass,
94  * eg sun4u/cheetah) must set fpras_implemented to indicate that it implements
95  * the fpRAS feature.  The feature can be suppressed by setting fpras_disable
96  * or the mechanism can be disabled for individual copy operations with
97  * fpras_disableids.  All these are checked in post_startup() code so
98  * fpras_disable and fpras_disableids can be set in /etc/system.
99  * If/when fpRAS is implemented on non-sun4 architectures these
100  * definitions will need to move up to the common level.
101  */
102 int	fpras_implemented;
103 int	fpras_disable;
104 int	fpras_disableids;
105 
106 /*
107  * Static Routines:
108  */
109 static void kern_splr_preprom(void);
110 static void kern_splx_postprom(void);
111 
112 /*
113  * Setup routine called right before main(). Interposing this function
114  * before main() allows us to call it in a machine-independent fashion.
115  */
116 
117 void
118 mlsetup(struct regs *rp, void *cif, kfpu_t *fp)
119 {
120 	struct machpcb *mpcb;
121 
122 	extern char t0stack[];
123 	extern struct classfuncs sys_classfuncs;
124 	extern disp_t cpu0_disp;
125 	unsigned long long pa;
126 
127 #ifdef TRAPTRACE
128 	TRAP_TRACE_CTL *ctlp;
129 #endif /* TRAPTRACE */
130 
131 	/*
132 	 * initialize cpu_self
133 	 */
134 	cpu0.cpu_self = &cpu0;
135 
136 	/*
137 	 * initialize t0
138 	 */
139 	t0.t_stk = (caddr_t)rp - REGOFF;
140 	/* Can't use va_to_pa here - wait until prom_ initialized */
141 	t0.t_stkbase = t0stack;
142 	t0.t_pri = maxclsyspri - 3;
143 	t0.t_schedflag = TS_LOAD | TS_DONT_SWAP;
144 	t0.t_procp = &p0;
145 	t0.t_plockp = &p0lock.pl_lock;
146 	t0.t_lwp = &lwp0;
147 	t0.t_forw = &t0;
148 	t0.t_back = &t0;
149 	t0.t_next = &t0;
150 	t0.t_prev = &t0;
151 	t0.t_cpu = &cpu0;			/* loaded by _start */
152 	t0.t_disp_queue = &cpu0_disp;
153 	t0.t_bind_cpu = PBIND_NONE;
154 	t0.t_bind_pset = PS_NONE;
155 	t0.t_cpupart = &cp_default;
156 	t0.t_clfuncs = &sys_classfuncs.thread;
157 	t0.t_copyops = NULL;
158 	THREAD_ONPROC(&t0, CPU);
159 
160 	lwp0.lwp_thread = &t0;
161 	lwp0.lwp_procp = &p0;
162 	lwp0.lwp_regs = (void *)rp;
163 	t0.t_tid = p0.p_lwpcnt = p0.p_lwprcnt = p0.p_lwpid = 1;
164 
165 	mpcb = lwptompcb(&lwp0);
166 	mpcb->mpcb_fpu = fp;
167 	mpcb->mpcb_fpu->fpu_q = mpcb->mpcb_fpu_q;
168 	mpcb->mpcb_thread = &t0;
169 	lwp0.lwp_fpu = (void *)mpcb->mpcb_fpu;
170 
171 	p0.p_exec = NULL;
172 	p0.p_stat = SRUN;
173 	p0.p_flag = SSYS;
174 	p0.p_tlist = &t0;
175 	p0.p_stksize = 2*PAGESIZE;
176 	p0.p_stkpageszc = 0;
177 	p0.p_as = &kas;
178 	p0.p_lockp = &p0lock;
179 	p0.p_utraps = NULL;
180 	p0.p_brkpageszc = 0;
181 	p0.p_t1_lgrpid = LGRP_NONE;
182 	p0.p_tr_lgrpid = LGRP_NONE;
183 	sigorset(&p0.p_ignore, &ignoredefault);
184 
185 	CPU->cpu_thread = &t0;
186 	CPU->cpu_dispthread = &t0;
187 	bzero(&cpu0_disp, sizeof (disp_t));
188 	CPU->cpu_disp = &cpu0_disp;
189 	CPU->cpu_disp->disp_cpu = CPU;
190 	CPU->cpu_idle_thread = &t0;
191 	CPU->cpu_flags = CPU_RUNNING;
192 	CPU->cpu_id = getprocessorid();
193 	CPU->cpu_dispatch_pri = t0.t_pri;
194 
195 	/*
196 	 * Initialize thread/cpu microstate accounting
197 	 */
198 	init_mstate(&t0, LMS_SYSTEM);
199 	init_cpu_mstate(CPU, CMS_SYSTEM);
200 
201 	/*
202 	 * Initialize lists of available and active CPUs.
203 	 */
204 	cpu_list_init(CPU);
205 
206 	cpu_vm_data_init(CPU);
207 
208 	prom_init("kernel", cif);
209 	(void) prom_set_preprom(kern_splr_preprom);
210 	(void) prom_set_postprom(kern_splx_postprom);
211 
212 	PRM_INFO("mlsetup: now ok to call prom_printf");
213 
214 	mpcb->mpcb_pa = va_to_pa(t0.t_stk);
215 
216 	/*
217 	 * Claim the physical and virtual resources used by panicbuf,
218 	 * then map panicbuf.  This operation removes the phys and
219 	 * virtual addresses from the free lists.
220 	 */
221 	if (prom_claim_virt(PANICBUFSIZE, panicbuf) != panicbuf)
222 		prom_panic("Can't claim panicbuf virtual address");
223 
224 	if (prom_retain("panicbuf", PANICBUFSIZE, MMU_PAGESIZE, &pa) != 0)
225 		prom_panic("Can't allocate retained panicbuf physical address");
226 
227 	if (prom_map_phys(-1, PANICBUFSIZE, panicbuf, pa) != 0)
228 		prom_panic("Can't map panicbuf");
229 
230 	PRM_DEBUG(panicbuf);
231 	PRM_DEBUG(pa);
232 
233 	/*
234 	 * Negotiate hypervisor services, if any
235 	 */
236 	hsvc_setup();
237 	mach_soft_state_init();
238 
239 #ifdef TRAPTRACE
240 	/*
241 	 * initialize the trap trace buffer for the boot cpu
242 	 * XXX todo, dynamically allocate this buffer too
243 	 */
244 	ctlp = &trap_trace_ctl[CPU->cpu_id];
245 	ctlp->d.vaddr_base = trap_tr0;
246 	ctlp->d.offset = ctlp->d.last_offset = 0;
247 	ctlp->d.limit = TRAP_TSIZE;		/* XXX dynamic someday */
248 	ctlp->d.paddr_base = va_to_pa(trap_tr0);
249 #endif /* TRAPTRACE */
250 
251 	/*
252 	 * Initialize the Machine Description kernel framework
253 	 */
254 
255 	mach_descrip_startup_init();
256 
257 	/*
258 	 * initialize HV trap trace buffer for the boot cpu
259 	 */
260 	mach_htraptrace_setup(CPU->cpu_id);
261 	mach_htraptrace_configure(CPU->cpu_id);
262 
263 	/*
264 	 * lgroup framework initialization. This must be done prior
265 	 * to devices being mapped.
266 	 */
267 	lgrp_init();
268 
269 	cpu_setup();
270 
271 	if (boothowto & RB_HALT) {
272 		prom_printf("unix: kernel halted by -h flag\n");
273 		prom_enter_mon();
274 	}
275 
276 	setcputype();
277 	map_wellknown_devices();
278 	setcpudelay();
279 }
280 
281 /*
282  * These routines are called immediately before and
283  * immediately after calling into the firmware.  The
284  * firmware is significantly confused by preemption -
285  * particularly on MP machines - but also on UP's too.
286  */
287 
288 static int saved_spl;
289 
290 static void
291 kern_splr_preprom(void)
292 {
293 	saved_spl = spl7();
294 }
295 
296 static void
297 kern_splx_postprom(void)
298 {
299 	splx(saved_spl);
300 }
301