Home | History | Annotate | Download | only in ml
      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 2009 Sun Microsystems, Inc.  All rights reserved.
     23  * Use is subject to license terms.
     24  */
     25 
     26 #if defined(lint)
     27 #include <sys/types.h>
     28 #else	/* lint */
     29 #include "assym.h"
     30 #endif	/* lint */
     31 
     32 #include <sys/asm_linkage.h>
     33 #include <sys/machthread.h>
     34 #include <sys/param.h>
     35 #include <sys/vm_machparam.h>
     36 #include <sys/privregs.h>
     37 #include <sys/intreg.h>
     38 #include <sys/vis.h>
     39 #include <sys/clock.h>
     40 #include <vm/hat_sfmmu.h>
     41 
     42 #if !defined(lint)
     43 	.weak	cpu_feature_init
     44 	.type	cpu_feature_init, #function
     45 #endif	/* lint */
     46 
     47 #if !defined(lint)
     48 	.weak	cpu_early_feature_init
     49 	.type	cpu_early_feature_init, #function
     50 #endif	/* lint */
     51 
     52 /*
     53  * Processor initialization
     54  *
     55  * This is the kernel entry point for other cpus except the first one.
     56  * When the prom jumps to this location we are still executing with the
     57  * prom's trap table.  It expects the cpuid as its first parameter.
     58  */
     59 
     60 #if defined(lint)
     61 
     62 /* ARGSUSED */
     63 void
     64 cpu_startup(int cpuid)
     65 {}
     66 
     67 #else	/* lint */
     68 
     69 	! allocate a temporary stack to run on while we figure who and
     70 	! what we are.
     71 	.seg	".data"
     72 	.align	8
     73 etmpstk:
     74 	.skip	2048
     75 tmpstk:
     76 	.word	0
     77 
     78 	ENTRY_NP(cpu_startup)
     79 	!
     80 	! Initialize CPU state registers
     81 	!
     82 	! The boot cpu and other cpus are different.  The boot cpu has gone
     83 	! through boot, and its state might be affected as a result.  The
     84 	! other cpus' states come directly from the prom.
     85 	!
     86 	wrpr	%g0, PSTATE_KERN, %pstate
     87 	wr	%g0, %g0, %fprs		! clear fprs
     88 	CLEARTICKNPT			! allow user rdtick
     89 
     90 	!
     91 	! Set up temporary stack
     92 	!
     93 	set	tmpstk, %g1
     94 	sub	%g1, SA(KFPUSIZE+GSR_SIZE), %g2
     95 	and	%g2, 0x3F, %g3
     96 	sub	%g2, %g3, %o2
     97 	sub	%o2, SA(MINFRAME) + STACK_BIAS, %sp
     98 
     99 	mov	%o0, %l1		! save cpuid
    100 
    101 	call	sfmmu_mp_startup
    102 	sub	%g0, 1, THREAD_REG	! catch any curthread acceses
    103 
    104 	! On OPL platforms, context page size TLB programming must be enabled in
    105 	! ASI_MEMCNTL.  To avoid Olympus-C and Jupiter sTLB errata (strands with
    106 	! different TLB page size settings), this must be done here before any
    107 	! reference to non-nucleus memory.  An early hook is added to perform
    108 	! cpu specific initialization.
    109 	!
    110 	sethi	%hi(cpu_early_feature_init), %o0
    111 	or	%o0, %lo(cpu_early_feature_init), %o0
    112 	brz	%o0, 0f
    113 	nop
    114 	call	%o0
    115 	nop
    116 
    117 0:
    118 	! SET_KCONTEXTREG(reg0, reg1, reg2, reg3, reg4, label1, label2, label3)
    119 	SET_KCONTEXTREG(%o0, %g1, %g2, %g3, %l3, l1, l2, l3)
    120 
    121 	! We are now running on the kernel's trap table.
    122 	!
    123 	! It is very important to have a thread pointer and a cpu struct
    124 	! *before* calling into C routines .
    125 	! Otherwise, overflow/underflow handlers, etc. can get very upset!
    126 	!
    127 	!
    128 	! We don't want to simply increment
    129 	! ncpus right now because it is in the cache, and
    130 	! we don't have the cache on yet for this CPU.
    131 	!
    132 	set	cpu, %l3
    133 	sll	%l1, CPTRSHIFT, %l2	! offset into CPU vector.
    134 	ldn	[%l3 + %l2], %l3	! pointer to CPU struct
    135 	ldn	[%l3 + CPU_THREAD], THREAD_REG	! set thread pointer (%g7)
    136 
    137 	!
    138 	! Set up any required cpu feature
    139 	!
    140 	sethi	%hi(cpu_feature_init), %o0
    141 	or	%o0, %lo(cpu_feature_init), %o0
    142 	brz	%o0, 1f
    143 	nop
    144 	call	%o0
    145 	nop
    146 
    147 1:
    148 	!
    149 	! Resume the thread allocated for the CPU.
    150 	!
    151  	ldn	[THREAD_REG + T_PC], %i7
    152 	ldn	[THREAD_REG + T_SP], %fp
    153 	ret				! "return" into the thread
    154 	restore				! WILL cause underflow
    155 	SET_SIZE(cpu_startup)
    156 
    157 #endif	/* lint */
    158