/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 1999-2002 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #pragma ident "%Z%%M% %I% %E% SMI" /* * cb_srt0.s - cprboot startup code */ #include #include #include #include #include #include #if defined(lint) #include void *estack; caddr_t _end[1]; #endif #include "cprboot.h" #if defined(lint) /* ARGSUSED */ void _start(void *a, ...) {} #else /* !lint */ .seg ".bss" .align MMU_PAGESIZE .skip CB_SSS eslave_stack: ! top of slave cpu stack .skip CB_MSS estack: ! top of cprboot stack .global estack .seg ".data" .align 8 local_cif: .xword 0 ! space for prom cookie .seg ".text" .align 8 ! ! regs on entry: ! %o4 = prom cookie ! ENTRY(_start) set estack - STACK_BIAS, %o5 save %o5, -SA(MINFRAME), %sp ! ! clear the bss ! set _edata, %o0 set _end, %g2 call bzero sub %g2, %o0, %o1 ! bss size = (_end - _edata) ! ! Set pstate to a known state: ! enable fp, privilege, interrupt enable ! wrpr %g0, PSTATE_PEF|PSTATE_PRIV|PSTATE_IE, %pstate ! ! first stage ! set local_cif, %g2 stx %i4, [%g2] mov %i4, %o0 ! SPARCV9/CIF call main ! Mcprboot [tag] mov 1, %o1 ! first=true ! ! switch to new stack ! set CB_STACK_VIRT + CB_STACK_SIZE, %o5 sub %o5, STACK_BIAS + SA(MINFRAME), %sp ! ! second stage ! set local_cif, %g2 ldx [%g2], %o0 ! SPARCV9/CIF call main ! Mcprboot [tag] mov 0, %o1 ! first=false call prom_exit_to_mon ! can't happen... :-) nop SET_SIZE(_start) #endif /* lint */ #if defined(lint) /* * args from cprboot main: * %o0 prom cookie * %o1 struct sun4u_machdep *mdp * * Any change to this register assignment requires * changes to uts/sun4u/ml/cpr_resume_setup.s */ /* ARGSUSED */ void exit_to_kernel(void *cookie, csu_md_t *mdp) {} #else /* lint */ ENTRY(exit_to_kernel) ! ! setup temporary stack and adjust ! by the saved kernel stack bias ! set tmp_stack, %g1 ! g1 = &tmp_stack ldx [%g1], %l2 ! l2 = tmp_stack sub %l2, SA(MINFRAME), %l2 ld [%o1 + CPR_MD_KSB], %l4 ! mdp->ksb sub %l2, %l4, %sp ! ! set pstate and wstate from saved values ! lduh [%o1 + CPR_MD_KPSTATE], %l4 ! l4 = mdp->kpstate wrpr %g0, %l4, %pstate lduh [%o1 + CPR_MD_KWSTATE], %l4 ! l4 = mdp->kwstate wrpr %g0, %l4, %wstate ! ! jump to kernel with %o0 and %o1 unchanged ! ldx [%o1 + CPR_MD_FUNC], %l3 ! l3 = mdp->func jmpl %l3, %g0 nop /* there is no return from here */ unimp 0 SET_SIZE(exit_to_kernel) #endif /* lint */ #if defined(lint) /* ARGSUSED */ int client_handler(void *cif_handler, void *arg_array) { return (0); } #else ! ! 64/64 client interface for ieee1275 prom ! ENTRY(client_handler) mov %o7, %g1 mov %o0, %g5 mov %o1, %o0 jmp %g5 mov %g1, %o7 SET_SIZE(client_handler) #endif /* lint */ #if defined(lint) /* ARGSUSED */ void bzero(void *base, size_t len) {} #else ENTRY(bzero) brz,pn %o1, 2f nop mov %o0, %o2 mov %o1, %o3 1: stub %g0, [%o2] dec %o3 brgz,pt %o3, 1b inc %o2 2: retl nop SET_SIZE(bzero) #endif /* lint */ #if defined(lint) /* ARGSUSED */ void phys_xcopy(physaddr_t phys_src, physaddr_t phys_dst, size_t len) {} #else ! ! copy len bytes from src to dst phys addrs; ! requires src/dst/len 8-byte alignment; ! used only for copying phys pages ! ENTRY(phys_xcopy) brz,pn %o2, 2f mov %o0, %o3 ! %o3 = src mov %o1, %o4 ! %o4 = dst 1: ldxa [%o3]ASI_MEM, %o5 ! %o5 = *src stxa %o5, [%o4]ASI_MEM ! *dst = %o5 dec 8, %o2 ! len -= 8 inc 8, %o3 ! src += 8 brgz,pt %o2, 1b ! branch when (len > 0) inc 8, %o4 ! dst += 8 2: retl nop SET_SIZE(phys_xcopy) #endif #if defined(lint) /* ARGSUSED */ void get_dtlb_entry(int index, caddr_t *vaddrp, tte_t *tte) {} #else /* lint */ ENTRY(get_dtlb_entry) sllx %o0, 3, %o0 ldxa [%o0]ASI_DTLB_ACCESS, %o3 stx %o3, [%o2] ldxa [%o0]ASI_DTLB_TAGREAD, %o4 retl stx %o4, [%o1] SET_SIZE(get_dtlb_entry) #endif #if defined(lint) /* ARGSUSED */ void set_itlb_entry(int index, caddr_t vaddr, tte_t *tte) {} /* ARGSUSED */ void set_dtlb_entry(int index, caddr_t vaddr, tte_t *tte) {} #else /* lint */ ENTRY(set_dtlb_entry) sllx %o0, 3, %o0 srlx %o1, MMU_PAGESHIFT, %o1 sllx %o1, MMU_PAGESHIFT, %o1 set MMU_TAG_ACCESS, %o4 ldx [%o2], %o3 stxa %o1, [%o4]ASI_DMMU stxa %o3, [%o0]ASI_DTLB_ACCESS membar #Sync retl nop SET_SIZE(set_dtlb_entry) ENTRY(set_itlb_entry) sllx %o0, 3, %o0 srlx %o1, MMU_PAGESHIFT, %o1 sllx %o1, MMU_PAGESHIFT, %o1 set MMU_TAG_ACCESS, %o4 ldx [%o2], %o3 stxa %o1, [%o4]ASI_IMMU stxa %o3, [%o0]ASI_ITLB_ACCESS membar #Sync retl nop SET_SIZE(set_itlb_entry) #endif #if defined(lint) uint_t getmid(void) { return (0); } #else /* lint */ ENTRY(getmid) CPU_INDEX(%o0, %o1) retl nop SET_SIZE(getmid) #endif #if defined(lint) /* ARGSUSED */ void cpu_launch(int cpuid) { slave_init(cpuid); } #else /* lint */ ENTRY(cpu_launch) set CB_STACK_VIRT + CB_SSS, %o5 sub %o5, STACK_BIAS + SA(MINFRAME), %sp wrpr %g0, PSTATE_PEF|PSTATE_PRIV|PSTATE_IE, %pstate call slave_init nop unimp 0 SET_SIZE(cpu_launch) #endif #if defined(lint) void membar_stld(void) {} #else /* lint */ ENTRY(membar_stld) retl membar #StoreLoad SET_SIZE(membar_stld) #endif #if defined(lint) /* ARGSUSED */ void cb_usec_wait(int usecs) {} #else .align 32 ! cache alignment for next 8 instr ENTRY(cb_usec_wait) sethi %hi(cpu_delay), %o1 ld [%o1 + %lo(cpu_delay)], %o1 mov %o1, %o2 1: brnz,pt %o2, 1b ! usec countdown loop dec %o2 ! 2 instr in loop dec %o0 ! for each usec: brgz,pt %o0, 1b ! run the above loop mov %o1, %o2 retl nop SET_SIZE(cb_usec_wait) #endif