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 /*
  23  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
  24  * Use is subject to license terms.
  25  */
  26 
  27 /*
  28  * sun4v processor initialization
  29  *
  30  * This is the kernel entry point for CPUs that enter Solaris
  31  * directly from the hypervisor. i.e. without going through OBP.
  32  */
  33 
  34 #include "assym.h"
  35 
  36 #include <sys/asm_linkage.h>
  37 #include <sys/hypervisor_api.h>
  38 #include <sys/machasi.h>
  39 #include <sys/machpcb.h>
  40 #include <sys/machlock.h>
  41 #include <sys/mmu.h>
  42 #include <sys/lpad.h>
  43 
  44         /*
  45          * %o0 - hcall specified arg (cpuid)
  46          * %i0 - real memory base
  47          * %i1 - memory size
  48          */
  49         ENTRY_NP(mach_cpu_startup)
  50         /*
  51          * Calculate the data pointer. The landing pad
  52          * data immediately follows the landing pad text.
  53          */
  54         rd      %pc, %l0
  55         add     %l0, LPAD_TEXT_SIZE, %l1        ! %l1 has start of data
  56 
  57         /*
  58          * Setup the initial state of the CPU.
  59          */
  60         wrpr    %g0, 0, %tl
  61         wrpr    %g0, 0, %gl
  62         wrpr    %g0, MAXWIN - 2, %cansave
  63         wrpr    %g0, MAXWIN - 2, %cleanwin
  64         wrpr    %g0, 0, %canrestore
  65         wrpr    %g0, 0, %otherwin
  66         wrpr    %g0, 0, %cwp
  67         wrpr    %g0, 0, %wstate
  68         wr      %g0, %y
  69         wrpr    %g0, PIL_MAX, %pil
  70 
  71         set     trap_table, %g1
  72         wrpr    %g1, %tba
  73 
  74         ! initialize cpuid into scratchpad register
  75         mov     SCRATCHPAD_CPUID, %g1
  76         stxa    %o0, [%g1]ASI_SCRATCHPAD
  77         
  78         ! sanity check the data section
  79         setx    LPAD_MAGIC_VAL, %g2, %g1
  80         ldx     [%l1 + LPAD_MAGIC], %g2
  81         cmp     %g1, %g2
  82         bne     startup_error
  83           nop
  84 
  85         /*
  86          * Loop through the array of TTE's, installing the
  87          * VA to RA mapping for each one.
  88          */
  89         ldx     [%l1 + LPAD_NMAP], %l2          ! %l2 = number of mappings
  90         add     %l1, LPAD_MAP, %l3              ! %l3 = the current mapping
  91 
  92         /*
  93          * Sanity check the number of mappings.
  94          */
  95         mulx    %l2, LPAD_MAP_SIZE, %g1
  96         add     %l3, %g1, %g1                   ! %g1 = end of the array
  97         add     %l1, LPAD_DATA_SIZE, %g2        ! %g2 = end of data section
  98         sub     %g2, %g1, %g2
  99         brlz    %g2, startup_error
 100           nop
 101 
 102 0:
 103         cmp     %l2, %g0
 104         be      3f
 105           nop
 106 
 107         ldx     [%l3 + LPAD_MAP_FLAGS], %l4     ! %l4 = flags
 108 
 109         /*
 110          * Generate args for the HV call
 111          */
 112         ldx     [%l3 + LPAD_MAP_VA], %o0        ! %o0 = virtual address
 113         mov     KCONTEXT, %o1                   ! %o1 = context
 114         ldx     [%l3 + LPAD_MAP_TTE], %o2       ! %o2 = TTE
 115         and     %l4, FLAG_MMUFLAGS_MASK, %o3    ! %o3 = MMU flags
 116 
 117         ! check if this is a locked TTE
 118         and     %l4, FLAG_LOCK_MASK, %l4
 119         cmp     %l4, %g0
 120         bne     1f
 121           nop
 122 
 123         ! install an unlocked entry
 124         ta      MMU_MAP_ADDR
 125         ba      2f
 126           nop
 127 1:
 128         ! install a locked entry
 129         mov     MAP_PERM_ADDR, %o5
 130         ta      FAST_TRAP
 131 
 132 2:
 133         ! check for errors from the hcall
 134         cmp     %o0, %g0
 135         bne     startup_error
 136           nop
 137         
 138         sub     %l2, 1, %l2                     ! decrement counter
 139         add     %l3, LPAD_MAP_SIZE, %l3         ! increment pointer
 140 
 141         ba      0b
 142           nop
 143 
 144 3:
 145         /*
 146          * Set the MMU fault status area
 147          */
 148         ldx     [%l1 + LPAD_MMFSA_RA], %o0
 149 
 150         mov     MMU_SET_INFOPTR, %o5
 151         ta      FAST_TRAP
 152 
 153         ! check for errors from the hcall
 154         cmp     %o0, %g0
 155         bne     startup_error
 156           nop
 157 
 158         /*
 159          * Load remaining arguments before enabling the
 160          * MMU so that the loads can be done using real
 161          * addresses.
 162          */
 163         ldx     [%l1 + LPAD_PC], %l3            ! %l3 = specified entry point
 164         ldx     [%l1 + LPAD_ARG], %l4           ! %l4 = specified argument
 165         ldx     [%l1 + LPAD_INUSE], %l5         ! %l5 = va of inuse mailbox
 166 
 167         /*
 168          * Enable the MMU. On success, it returns to the
 169          * global version of the landing pad text, rather
 170          * than the text copied into the lpad buffer.
 171          */
 172         mov     1, %o0                          ! %o0 = enable flag (1 = enable)
 173         set     startup_complete, %o1           ! VA of return address
 174         mov     MMU_ENABLE, %o5
 175         ta      FAST_TRAP
 176 
 177         /*
 178          * On errors, just enter a spin loop until the
 179          * CPU that initiated the start recovers the CPU.
 180          */
 181 startup_error:
 182         ba      startup_error
 183           nop
 184 
 185         /*
 186          * Jump to the generic CPU initialization code.
 187          */
 188 startup_complete:
 189         mov     %l4, %o0
 190         jmpl    %l3, %g0
 191           stx   %g0, [%l5]                      ! clear the inuse mailbox
 192 
 193         SET_SIZE(mach_cpu_startup)
 194 
 195         .global mach_cpu_startup_end
 196 mach_cpu_startup_end:
 197