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