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 1999-2002 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/* 30 * cb_srt0.s - cprboot startup code 31 */ 32#include <sys/asm_linkage.h> 33#include <sys/machthread.h> 34#include <sys/privregs.h> 35#include <sys/cpr_impl.h> 36#include <sys/param.h> 37#include <sys/mmu.h> 38 39#if defined(lint) 40#include <sys/cpr.h> 41void *estack; 42caddr_t _end[1]; 43#endif 44 45#include "cprboot.h" 46 47 48#if defined(lint) 49 50/* ARGSUSED */ 51void 52_start(void *a, ...) 53{} 54 55#else /* !lint */ 56 57 .seg ".bss" 58 .align MMU_PAGESIZE 59 .skip CB_SSS 60eslave_stack: ! top of slave cpu stack 61 .skip CB_MSS 62estack: ! top of cprboot stack 63 .global estack 64 65 .seg ".data" 66 .align 8 67local_cif: 68 .xword 0 ! space for prom cookie 69 70 .seg ".text" 71 .align 8 72 73 ! 74 ! regs on entry: 75 ! %o4 = prom cookie 76 ! 77 ENTRY(_start) 78 set estack - STACK_BIAS, %o5 79 save %o5, -SA(MINFRAME), %sp 80 81 ! 82 ! clear the bss 83 ! 84 set _edata, %o0 85 set _end, %g2 86 call bzero 87 sub %g2, %o0, %o1 ! bss size = (_end - _edata) 88 89 ! 90 ! Set pstate to a known state: 91 ! enable fp, privilege, interrupt enable 92 ! 93 wrpr %g0, PSTATE_PEF|PSTATE_PRIV|PSTATE_IE, %pstate 94 95 ! 96 ! first stage 97 ! 98 set local_cif, %g2 99 stx %i4, [%g2] 100 mov %i4, %o0 ! SPARCV9/CIF 101 call main ! Mcprboot [tag] 102 mov 1, %o1 ! first=true 103 104 ! 105 ! switch to new stack 106 ! 107 set CB_STACK_VIRT + CB_STACK_SIZE, %o5 108 sub %o5, STACK_BIAS + SA(MINFRAME), %sp 109 110 ! 111 ! second stage 112 ! 113 set local_cif, %g2 114 ldx [%g2], %o0 ! SPARCV9/CIF 115 call main ! Mcprboot [tag] 116 mov 0, %o1 ! first=false 117 118 call prom_exit_to_mon ! can't happen... :-) 119 nop 120 SET_SIZE(_start) 121 122#endif /* lint */ 123 124 125#if defined(lint) 126 127/* 128 * args from cprboot main: 129 * %o0 prom cookie 130 * %o1 struct sun4u_machdep *mdp 131 * 132 * Any change to this register assignment requires 133 * changes to uts/sun4u/ml/cpr_resume_setup.s 134 */ 135 136/* ARGSUSED */ 137void 138exit_to_kernel(void *cookie, csu_md_t *mdp) 139{} 140 141#else /* lint */ 142 143 ENTRY(exit_to_kernel) 144 ! 145 ! setup temporary stack and adjust 146 ! by the saved kernel stack bias 147 ! 148 set tmp_stack, %g1 ! g1 = &tmp_stack 149 ldx [%g1], %l2 ! l2 = tmp_stack 150 sub %l2, SA(MINFRAME), %l2 151 ld [%o1 + CPR_MD_KSB], %l4 ! mdp->ksb 152 sub %l2, %l4, %sp 153 154 ! 155 ! set pstate and wstate from saved values 156 ! 157 lduh [%o1 + CPR_MD_KPSTATE], %l4 ! l4 = mdp->kpstate 158 wrpr %g0, %l4, %pstate 159 lduh [%o1 + CPR_MD_KWSTATE], %l4 ! l4 = mdp->kwstate 160 wrpr %g0, %l4, %wstate 161 162 ! 163 ! jump to kernel with %o0 and %o1 unchanged 164 ! 165 ldx [%o1 + CPR_MD_FUNC], %l3 ! l3 = mdp->func 166 jmpl %l3, %g0 167 nop 168 169 /* there is no return from here */ 170 unimp 0 171 SET_SIZE(exit_to_kernel) 172 173#endif /* lint */ 174 175 176#if defined(lint) 177 178/* ARGSUSED */ 179int 180client_handler(void *cif_handler, void *arg_array) 181{ return (0); } 182 183#else 184 185 ! 186 ! 64/64 client interface for ieee1275 prom 187 ! 188 ENTRY(client_handler) 189 mov %o7, %g1 190 mov %o0, %g5 191 mov %o1, %o0 192 jmp %g5 193 mov %g1, %o7 194 SET_SIZE(client_handler) 195 196#endif /* lint */ 197 198 199#if defined(lint) 200 201/* ARGSUSED */ 202void 203bzero(void *base, size_t len) 204{} 205 206#else 207 208 ENTRY(bzero) 209 brz,pn %o1, 2f 210 nop 211 mov %o0, %o2 212 mov %o1, %o3 2131: 214 stub %g0, [%o2] 215 dec %o3 216 brgz,pt %o3, 1b 217 inc %o2 2182: 219 retl 220 nop 221 SET_SIZE(bzero) 222 223#endif /* lint */ 224 225 226#if defined(lint) 227 228/* ARGSUSED */ 229void 230phys_xcopy(physaddr_t phys_src, physaddr_t phys_dst, size_t len) 231{} 232 233#else 234 235 ! 236 ! copy len bytes from src to dst phys addrs; 237 ! requires src/dst/len 8-byte alignment; 238 ! used only for copying phys pages 239 ! 240 ENTRY(phys_xcopy) 241 brz,pn %o2, 2f 242 mov %o0, %o3 ! %o3 = src 243 mov %o1, %o4 ! %o4 = dst 2441: 245 ldxa [%o3]ASI_MEM, %o5 ! %o5 = *src 246 stxa %o5, [%o4]ASI_MEM ! *dst = %o5 247 dec 8, %o2 ! len -= 8 248 inc 8, %o3 ! src += 8 249 brgz,pt %o2, 1b ! branch when (len > 0) 250 inc 8, %o4 ! dst += 8 2512: 252 retl 253 nop 254 SET_SIZE(phys_xcopy) 255 256#endif 257 258 259#if defined(lint) 260 261/* ARGSUSED */ 262void 263get_dtlb_entry(int index, caddr_t *vaddrp, tte_t *tte) 264{} 265 266#else /* lint */ 267 268 ENTRY(get_dtlb_entry) 269 sllx %o0, 3, %o0 270 ldxa [%o0]ASI_DTLB_ACCESS, %o3 271 stx %o3, [%o2] 272 ldxa [%o0]ASI_DTLB_TAGREAD, %o4 273 retl 274 stx %o4, [%o1] 275 SET_SIZE(get_dtlb_entry) 276 277#endif 278 279 280#if defined(lint) 281 282/* ARGSUSED */ 283void 284set_itlb_entry(int index, caddr_t vaddr, tte_t *tte) 285{} 286 287/* ARGSUSED */ 288void 289set_dtlb_entry(int index, caddr_t vaddr, tte_t *tte) 290{} 291 292#else /* lint */ 293 294 ENTRY(set_dtlb_entry) 295 sllx %o0, 3, %o0 296 srlx %o1, MMU_PAGESHIFT, %o1 297 sllx %o1, MMU_PAGESHIFT, %o1 298 set MMU_TAG_ACCESS, %o4 299 ldx [%o2], %o3 300 stxa %o1, [%o4]ASI_DMMU 301 stxa %o3, [%o0]ASI_DTLB_ACCESS 302 membar #Sync 303 retl 304 nop 305 SET_SIZE(set_dtlb_entry) 306 307 ENTRY(set_itlb_entry) 308 sllx %o0, 3, %o0 309 srlx %o1, MMU_PAGESHIFT, %o1 310 sllx %o1, MMU_PAGESHIFT, %o1 311 set MMU_TAG_ACCESS, %o4 312 ldx [%o2], %o3 313 stxa %o1, [%o4]ASI_IMMU 314 stxa %o3, [%o0]ASI_ITLB_ACCESS 315 membar #Sync 316 retl 317 nop 318 SET_SIZE(set_itlb_entry) 319 320#endif 321 322 323#if defined(lint) 324 325uint_t 326getmid(void) 327{ return (0); } 328 329#else /* lint */ 330 331 ENTRY(getmid) 332 CPU_INDEX(%o0, %o1) 333 retl 334 nop 335 SET_SIZE(getmid) 336 337#endif 338 339 340#if defined(lint) 341 342/* ARGSUSED */ 343void 344cpu_launch(int cpuid) 345{ 346 slave_init(cpuid); 347} 348 349#else /* lint */ 350 351 ENTRY(cpu_launch) 352 set CB_STACK_VIRT + CB_SSS, %o5 353 sub %o5, STACK_BIAS + SA(MINFRAME), %sp 354 wrpr %g0, PSTATE_PEF|PSTATE_PRIV|PSTATE_IE, %pstate 355 call slave_init 356 nop 357 unimp 0 358 SET_SIZE(cpu_launch) 359 360#endif 361 362 363#if defined(lint) 364 365void 366membar_stld(void) 367{} 368 369#else /* lint */ 370 371 ENTRY(membar_stld) 372 retl 373 membar #StoreLoad 374 SET_SIZE(membar_stld) 375 376#endif 377 378 379#if defined(lint) 380 381/* ARGSUSED */ 382void 383cb_usec_wait(int usecs) 384{} 385 386#else 387 388 .align 32 ! cache alignment for next 8 instr 389 ENTRY(cb_usec_wait) 390 391 sethi %hi(cpu_delay), %o1 392 ld [%o1 + %lo(cpu_delay)], %o1 393 mov %o1, %o2 3941: brnz,pt %o2, 1b ! usec countdown loop 395 dec %o2 ! 2 instr in loop 396 397 dec %o0 ! for each usec: 398 brgz,pt %o0, 1b ! run the above loop 399 mov %o1, %o2 400 401 retl 402 nop 403 SET_SIZE(cb_usec_wait) 404 405#endif 406