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