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