xref: /titanic_50/usr/src/uts/sun4v/ml/mach_proc_init.s (revision c77a61a72b5ecdc507d6cf104142edd371a16c84)
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 */
51void
52mach_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
1150:
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
1401:
141	! install a locked entry
142	mov	MAP_PERM_ADDR, %o5
143	ta	FAST_TRAP
144
1452:
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
1573:
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	 */
194startup_error:
195	ba	startup_error
196	  nop
197
198	/*
199	 * Jump to the generic CPU initialization code.
200	 */
201startup_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
209mach_cpu_startup_end:
210
211#endif	/* lint */
212