xref: /titanic_41/usr/src/uts/sun4/os/mlsetup.c (revision d73ae94e59c019f5cc3221ee0a0012d02091b40e)
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 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 	sigorset(&p0.p_ignore, &ignoredefault);
182 
183 	CPU->cpu_thread = &t0;
184 	CPU->cpu_dispthread = &t0;
185 	bzero(&cpu0_disp, sizeof (disp_t));
186 	CPU->cpu_disp = &cpu0_disp;
187 	CPU->cpu_disp->disp_cpu = CPU;
188 	CPU->cpu_idle_thread = &t0;
189 	CPU->cpu_flags = CPU_RUNNING;
190 	CPU->cpu_id = getprocessorid();
191 	CPU->cpu_dispatch_pri = t0.t_pri;
192 
193 	/*
194 	 * Initialize thread/cpu microstate accounting here
195 	 */
196 	init_mstate(&t0, LMS_SYSTEM);
197 	init_cpu_mstate(CPU, CMS_SYSTEM);
198 
199 	/*
200 	 * Initialize lists of available and active CPUs.
201 	 */
202 	cpu_list_init(CPU);
203 
204 	cpu_vm_data_init(CPU);
205 
206 	prom_init("kernel", cif);
207 	(void) prom_set_preprom(kern_splr_preprom);
208 	(void) prom_set_postprom(kern_splx_postprom);
209 
210 	PRM_INFO("mlsetup: now ok to call prom_printf");
211 
212 	mpcb->mpcb_pa = va_to_pa(t0.t_stk);
213 
214 	/*
215 	 * Claim the physical and virtual resources used by panicbuf,
216 	 * then map panicbuf.  This operation removes the phys and
217 	 * virtual addresses from the free lists.
218 	 */
219 	if (prom_claim_virt(PANICBUFSIZE, panicbuf) != panicbuf)
220 		prom_panic("Can't claim panicbuf virtual address");
221 
222 	if (prom_retain("panicbuf", PANICBUFSIZE, MMU_PAGESIZE, &pa) != 0)
223 		prom_panic("Can't allocate retained panicbuf physical address");
224 
225 	if (prom_map_phys(-1, PANICBUFSIZE, panicbuf, pa) != 0)
226 		prom_panic("Can't map panicbuf");
227 
228 	PRM_DEBUG(panicbuf);
229 	PRM_DEBUG(pa);
230 
231 	/*
232 	 * Negotiate hypervisor services, if any
233 	 */
234 	hsvc_setup();
235 	mach_soft_state_init();
236 
237 #ifdef TRAPTRACE
238 	/*
239 	 * initialize the trap trace buffer for the boot cpu
240 	 * XXX todo, dynamically allocate this buffer too
241 	 */
242 	ctlp = &trap_trace_ctl[CPU->cpu_id];
243 	ctlp->d.vaddr_base = trap_tr0;
244 	ctlp->d.offset = ctlp->d.last_offset = 0;
245 	ctlp->d.limit = TRAP_TSIZE;		/* XXX dynamic someday */
246 	ctlp->d.paddr_base = va_to_pa(trap_tr0);
247 #endif /* TRAPTRACE */
248 
249 	/*
250 	 * Initialize the Machine Description kernel framework
251 	 */
252 
253 	mach_descrip_startup_init();
254 
255 	/*
256 	 * initialize HV trap trace buffer for the boot cpu
257 	 */
258 	mach_htraptrace_setup(CPU->cpu_id);
259 	mach_htraptrace_configure(CPU->cpu_id);
260 
261 	/*
262 	 * lgroup framework initialization. This must be done prior
263 	 * to devices being mapped.
264 	 */
265 	lgrp_init();
266 
267 	cpu_setup();
268 
269 	if (boothowto & RB_HALT) {
270 		prom_printf("unix: kernel halted by -h flag\n");
271 		prom_enter_mon();
272 	}
273 
274 	setcputype();
275 	map_wellknown_devices();
276 	setcpudelay();
277 
278 	/*
279 	 * Associate the boot cpu with a physical processor.
280 	 * This needs to be done after devices are mapped, since
281 	 * we need to know what type of physical processor this is.
282 	 * (CMP for example)
283 	 */
284 	chip_cpu_init(CPU);
285 	chip_cpu_assign(CPU);
286 }
287 
288 /*
289  * These routines are called immediately before and
290  * immediately after calling into the firmware.  The
291  * firmware is significantly confused by preemption -
292  * particularly on MP machines - but also on UP's too.
293  */
294 
295 static int saved_spl;
296 
297 static void
298 kern_splr_preprom(void)
299 {
300 	saved_spl = spl7();
301 }
302 
303 static void
304 kern_splx_postprom(void)
305 {
306 	splx(saved_spl);
307 }
308