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