xref: /illumos-gate/usr/src/uts/sun4/os/mlsetup.c (revision fe0e7ec4)
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/systm.h>
31 #include <sys/archsystm.h>
32 #include <sys/machsystm.h>
33 #include <sys/disp.h>
34 #include <sys/autoconf.h>
35 #include <sys/promif.h>
36 #include <sys/prom_plat.h>
37 #include <sys/clock.h>
38 #include <sys/pte.h>
39 #include <sys/scb.h>
40 #include <sys/cpu.h>
41 #include <sys/stack.h>
42 #include <sys/intreg.h>
43 #include <sys/ivintr.h>
44 #include <vm/as.h>
45 #include <vm/hat_sfmmu.h>
46 #include <sys/reboot.h>
47 #include <sys/sysmacros.h>
48 #include <sys/vtrace.h>
49 #include <sys/trap.h>
50 #include <sys/machtrap.h>
51 #include <sys/privregs.h>
52 #include <sys/machpcb.h>
53 #include <sys/proc.h>
54 #include <sys/cpupart.h>
55 #include <sys/pset.h>
56 #include <sys/cpu_module.h>
57 #include <sys/copyops.h>
58 #include <sys/panic.h>
59 #include <sys/bootconf.h>	/* for bootops */
60 #include <sys/chip.h>
61 #include <sys/kdi.h>
62 #include <sys/fpras.h>
63 
64 #include <sys/prom_debug.h>
65 #include <sys/debug.h>
66 
67 #include <sys/sunddi.h>
68 #include <sys/lgrp.h>
69 
70 #ifdef TRAPTRACE
71 #include <sys/traptrace.h>
72 #endif /* TRAPTRACE */
73 
74 /*
75  * External Routines:
76  */
77 extern void map_wellknown_devices(void);
78 
79 int	dcache_size;
80 int	dcache_linesize;
81 int	icache_size;
82 int	icache_linesize;
83 int	ecache_size;
84 int	ecache_alignsize;
85 int	ecache_associativity;
86 int	ecache_setsize;			/* max possible e$ setsize */
87 int	cpu_setsize;			/* max e$ setsize of configured cpus */
88 int	dcache_line_mask;		/* spitfire only */
89 int	vac_size;			/* cache size in bytes */
90 uint_t	vac_mask;			/* VAC alignment consistency mask */
91 int	vac_shift;			/* log2(vac_size) for ppmapout() */
92 int	vac = 0;	/* virtual address cache type (none == 0) */
93 
94 /*
95  * fpRAS.  An individual sun4* machine class (or perhaps subclass,
96  * eg sun4u/cheetah) must set fpras_implemented to indicate that it implements
97  * the fpRAS feature.  The feature can be suppressed by setting fpras_disable
98  * or the mechanism can be disabled for individual copy operations with
99  * fpras_disableids.  All these are checked in post_startup() code so
100  * fpras_disable and fpras_disableids can be set in /etc/system.
101  * If/when fpRAS is implemented on non-sun4 architectures these
102  * definitions will need to move up to the common level.
103  */
104 int	fpras_implemented;
105 int	fpras_disable;
106 int	fpras_disableids;
107 
108 /*
109  * Static Routines:
110  */
111 static void kern_splr_preprom(void);
112 static void kern_splx_postprom(void);
113 
114 /*
115  * Setup routine called right before main(). Interposing this function
116  * before main() allows us to call it in a machine-independent fashion.
117  */
118 
119 void
120 mlsetup(struct regs *rp, void *cif, kfpu_t *fp)
121 {
122 	struct machpcb *mpcb;
123 
124 	extern char t0stack[];
125 	extern struct classfuncs sys_classfuncs;
126 	extern disp_t cpu0_disp;
127 	unsigned long long pa;
128 
129 #ifdef TRAPTRACE
130 	TRAP_TRACE_CTL *ctlp;
131 #endif /* TRAPTRACE */
132 
133 	/*
134 	 * initialize cpu_self
135 	 */
136 	cpu0.cpu_self = &cpu0;
137 
138 	/*
139 	 * initialize t0
140 	 */
141 	t0.t_stk = (caddr_t)rp - REGOFF;
142 	/* Can't use va_to_pa here - wait until prom_ initialized */
143 	t0.t_stkbase = t0stack;
144 	t0.t_pri = maxclsyspri - 3;
145 	t0.t_schedflag = TS_LOAD | TS_DONT_SWAP;
146 	t0.t_procp = &p0;
147 	t0.t_plockp = &p0lock.pl_lock;
148 	t0.t_lwp = &lwp0;
149 	t0.t_forw = &t0;
150 	t0.t_back = &t0;
151 	t0.t_next = &t0;
152 	t0.t_prev = &t0;
153 	t0.t_cpu = &cpu0;			/* loaded by _start */
154 	t0.t_disp_queue = &cpu0_disp;
155 	t0.t_bind_cpu = PBIND_NONE;
156 	t0.t_bind_pset = PS_NONE;
157 	t0.t_cpupart = &cp_default;
158 	t0.t_clfuncs = &sys_classfuncs.thread;
159 	t0.t_copyops = NULL;
160 	THREAD_ONPROC(&t0, CPU);
161 
162 	lwp0.lwp_thread = &t0;
163 	lwp0.lwp_procp = &p0;
164 	lwp0.lwp_regs = (void *)rp;
165 	t0.t_tid = p0.p_lwpcnt = p0.p_lwprcnt = p0.p_lwpid = 1;
166 
167 	mpcb = lwptompcb(&lwp0);
168 	mpcb->mpcb_fpu = fp;
169 	mpcb->mpcb_fpu->fpu_q = mpcb->mpcb_fpu_q;
170 	mpcb->mpcb_thread = &t0;
171 	lwp0.lwp_fpu = (void *)mpcb->mpcb_fpu;
172 
173 	p0.p_exec = NULL;
174 	p0.p_stat = SRUN;
175 	p0.p_flag = SSYS;
176 	p0.p_tlist = &t0;
177 	p0.p_stksize = 2*PAGESIZE;
178 	p0.p_stkpageszc = 0;
179 	p0.p_as = &kas;
180 	p0.p_lockp = &p0lock;
181 	p0.p_utraps = NULL;
182 	p0.p_brkpageszc = 0;
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 here
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 #ifdef TRAPTRACE
234 	/*
235 	 * initialize the trap trace buffer for the boot cpu
236 	 * XXX todo, dynamically allocate this buffer too
237 	 */
238 	ctlp = &trap_trace_ctl[CPU->cpu_id];
239 	ctlp->d.vaddr_base = trap_tr0;
240 	ctlp->d.offset = ctlp->d.last_offset = 0;
241 	ctlp->d.limit = TRAP_TSIZE;		/* XXX dynamic someday */
242 	ctlp->d.paddr_base = va_to_pa(trap_tr0);
243 	/*
244 	 * initialize HV trap trace buffer for the boot cpu
245 	 */
246 	htrap_trace_setup((trap_tr0 + TRAP_TSIZE), CPU->cpu_id);
247 	htrap_trace_register(CPU->cpu_id);
248 #endif /* TRAPTRACE */
249 
250 	/*
251 	 * lgroup framework initialization. This must be done prior
252 	 * to devices being mapped.
253 	 */
254 	lgrp_init();
255 
256 	cpu_setup();
257 
258 	if (boothowto & RB_HALT) {
259 		prom_printf("unix: kernel halted by -h flag\n");
260 		prom_enter_mon();
261 	}
262 
263 	setcputype();
264 	map_wellknown_devices();
265 	setcpudelay();
266 
267 	/*
268 	 * Associate the boot cpu with a physical processor.
269 	 * This needs to be done after devices are mapped, since
270 	 * we need to know what type of physical processor this is.
271 	 * (CMP for example)
272 	 */
273 	chip_cpu_init(CPU);
274 	chip_cpu_assign(CPU);
275 }
276 
277 /*
278  * These routines are called immediately before and
279  * immediately after calling into the firmware.  The
280  * firmware is significantly confused by preemption -
281  * particularly on MP machines - but also on UP's too.
282  */
283 
284 static int saved_spl;
285 
286 static void
287 kern_splr_preprom(void)
288 {
289 	saved_spl = spl7();
290 }
291 
292 static void
293 kern_splx_postprom(void)
294 {
295 	splx(saved_spl);
296 }
297