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
1020:
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
1271:
128	! install a locked entry
129	mov	MAP_PERM_ADDR, %o5
130	ta	FAST_TRAP
131
1322:
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
1443:
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	 */
181startup_error:
182	ba	startup_error
183	  nop
184
185	/*
186	 * Jump to the generic CPU initialization code.
187	 */
188startup_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
196mach_cpu_startup_end:
197
198