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