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