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 */