11ae08745Sheppo/*
21ae08745Sheppo * CDDL HEADER START
31ae08745Sheppo *
41ae08745Sheppo * The contents of this file are subject to the terms of the
51ae08745Sheppo * Common Development and Distribution License (the "License").
61ae08745Sheppo * You may not use this file except in compliance with the License.
71ae08745Sheppo *
81ae08745Sheppo * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
91ae08745Sheppo * or http://www.opensolaris.org/os/licensing.
101ae08745Sheppo * See the License for the specific language governing permissions
111ae08745Sheppo * and limitations under the License.
121ae08745Sheppo *
131ae08745Sheppo * When distributing Covered Code, include this CDDL HEADER in each
141ae08745Sheppo * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
151ae08745Sheppo * If applicable, add the following below this CDDL HEADER, with the
161ae08745Sheppo * fields enclosed by brackets "[]" replaced with your own identifying
171ae08745Sheppo * information: Portions Copyright [yyyy] [name of copyright owner]
181ae08745Sheppo *
191ae08745Sheppo * CDDL HEADER END
201ae08745Sheppo */
211ae08745Sheppo
221ae08745Sheppo/*
231ae08745Sheppo * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
241ae08745Sheppo * Use is subject to license terms.
251ae08745Sheppo */
261ae08745Sheppo
271ae08745Sheppo/*
281ae08745Sheppo * sun4v processor initialization
291ae08745Sheppo *
301ae08745Sheppo * This is the kernel entry point for CPUs that enter Solaris
311ae08745Sheppo * directly from the hypervisor. i.e. without going through OBP.
321ae08745Sheppo */
331ae08745Sheppo
341ae08745Sheppo#include "assym.h"
351ae08745Sheppo
361ae08745Sheppo#include <sys/asm_linkage.h>
371ae08745Sheppo#include <sys/hypervisor_api.h>
381ae08745Sheppo#include <sys/machasi.h>
391ae08745Sheppo#include <sys/machpcb.h>
401ae08745Sheppo#include <sys/machlock.h>
411ae08745Sheppo#include <sys/mmu.h>
421ae08745Sheppo#include <sys/lpad.h>
431ae08745Sheppo
441ae08745Sheppo	/*
451ae08745Sheppo	 * %o0 - hcall specified arg (cpuid)
461ae08745Sheppo	 * %i0 - real memory base
471ae08745Sheppo	 * %i1 - memory size
481ae08745Sheppo	 */
491ae08745Sheppo	ENTRY_NP(mach_cpu_startup)
501ae08745Sheppo	/*
511ae08745Sheppo	 * Calculate the data pointer. The landing pad
521ae08745Sheppo	 * data immediately follows the landing pad text.
531ae08745Sheppo	 */
541ae08745Sheppo	rd	%pc, %l0
551ae08745Sheppo	add	%l0, LPAD_TEXT_SIZE, %l1	! %l1 has start of data
561ae08745Sheppo
571ae08745Sheppo	/*
581ae08745Sheppo	 * Setup the initial state of the CPU.
591ae08745Sheppo	 */
601ae08745Sheppo	wrpr	%g0, 0, %tl
611ae08745Sheppo	wrpr	%g0, 0, %gl
621ae08745Sheppo	wrpr	%g0, MAXWIN - 2, %cansave
631ae08745Sheppo	wrpr	%g0, MAXWIN - 2, %cleanwin
641ae08745Sheppo	wrpr	%g0, 0, %canrestore
651ae08745Sheppo	wrpr	%g0, 0, %otherwin
661ae08745Sheppo	wrpr	%g0, 0, %cwp
671ae08745Sheppo	wrpr	%g0, 0, %wstate
681ae08745Sheppo	wr	%g0, %y
691ae08745Sheppo	wrpr	%g0, PIL_MAX, %pil
701ae08745Sheppo
711ae08745Sheppo	set	trap_table, %g1
721ae08745Sheppo	wrpr	%g1, %tba
731ae08745Sheppo
741ae08745Sheppo	! initialize cpuid into scratchpad register
751ae08745Sheppo	mov	SCRATCHPAD_CPUID, %g1
761ae08745Sheppo	stxa	%o0, [%g1]ASI_SCRATCHPAD
77*55fea89dSDan Cross
781ae08745Sheppo	! sanity check the data section
791ae08745Sheppo	setx	LPAD_MAGIC_VAL, %g2, %g1
801ae08745Sheppo	ldx	[%l1 + LPAD_MAGIC], %g2
811ae08745Sheppo	cmp	%g1, %g2
821ae08745Sheppo	bne	startup_error
831ae08745Sheppo	  nop
841ae08745Sheppo
851ae08745Sheppo	/*
861ae08745Sheppo	 * Loop through the array of TTE's, installing the
871ae08745Sheppo	 * VA to RA mapping for each one.
881ae08745Sheppo	 */
891ae08745Sheppo	ldx	[%l1 + LPAD_NMAP], %l2		! %l2 = number of mappings
901ae08745Sheppo	add	%l1, LPAD_MAP, %l3		! %l3 = the current mapping
911ae08745Sheppo
921ae08745Sheppo	/*
931ae08745Sheppo	 * Sanity check the number of mappings.
941ae08745Sheppo	 */
951ae08745Sheppo	mulx	%l2, LPAD_MAP_SIZE, %g1
961ae08745Sheppo	add	%l3, %g1, %g1			! %g1 = end of the array
971ae08745Sheppo	add	%l1, LPAD_DATA_SIZE, %g2	! %g2 = end of data section
981ae08745Sheppo	sub	%g2, %g1, %g2
991ae08745Sheppo	brlz	%g2, startup_error
1001ae08745Sheppo	  nop
1011ae08745Sheppo
1021ae08745Sheppo0:
1031ae08745Sheppo	cmp	%l2, %g0
1041ae08745Sheppo	be	3f
1051ae08745Sheppo	  nop
1061ae08745Sheppo
1071ae08745Sheppo	ldx	[%l3 + LPAD_MAP_FLAGS], %l4	! %l4 = flags
1081ae08745Sheppo
1091ae08745Sheppo	/*
1101ae08745Sheppo	 * Generate args for the HV call
1111ae08745Sheppo	 */
1121ae08745Sheppo	ldx	[%l3 + LPAD_MAP_VA], %o0	! %o0 = virtual address
1131ae08745Sheppo	mov	KCONTEXT, %o1			! %o1 = context
1141ae08745Sheppo	ldx	[%l3 + LPAD_MAP_TTE], %o2	! %o2 = TTE
1151ae08745Sheppo	and	%l4, FLAG_MMUFLAGS_MASK, %o3	! %o3 = MMU flags
1161ae08745Sheppo
1171ae08745Sheppo	! check if this is a locked TTE
1181ae08745Sheppo	and	%l4, FLAG_LOCK_MASK, %l4
1191ae08745Sheppo	cmp	%l4, %g0
1201ae08745Sheppo	bne	1f
1211ae08745Sheppo	  nop
1221ae08745Sheppo
1231ae08745Sheppo	! install an unlocked entry
1241ae08745Sheppo	ta	MMU_MAP_ADDR
1251ae08745Sheppo	ba	2f
1261ae08745Sheppo	  nop
1271ae08745Sheppo1:
1281ae08745Sheppo	! install a locked entry
1291ae08745Sheppo	mov	MAP_PERM_ADDR, %o5
1301ae08745Sheppo	ta	FAST_TRAP
1311ae08745Sheppo
1321ae08745Sheppo2:
1331ae08745Sheppo	! check for errors from the hcall
1341ae08745Sheppo	cmp	%o0, %g0
1351ae08745Sheppo	bne	startup_error
1361ae08745Sheppo	  nop
137*55fea89dSDan Cross
1381ae08745Sheppo	sub	%l2, 1, %l2			! decrement counter
1391ae08745Sheppo	add	%l3, LPAD_MAP_SIZE, %l3		! increment pointer
1401ae08745Sheppo
1411ae08745Sheppo	ba	0b
1421ae08745Sheppo	  nop
1431ae08745Sheppo
1441ae08745Sheppo3:
1451ae08745Sheppo	/*
1461ae08745Sheppo	 * Set the MMU fault status area
1471ae08745Sheppo	 */
1481ae08745Sheppo	ldx	[%l1 + LPAD_MMFSA_RA], %o0
1491ae08745Sheppo
1501ae08745Sheppo	mov	MMU_SET_INFOPTR, %o5
1511ae08745Sheppo	ta	FAST_TRAP
1521ae08745Sheppo
1531ae08745Sheppo	! check for errors from the hcall
1541ae08745Sheppo	cmp	%o0, %g0
1551ae08745Sheppo	bne	startup_error
1561ae08745Sheppo	  nop
1571ae08745Sheppo
1581ae08745Sheppo	/*
1591ae08745Sheppo	 * Load remaining arguments before enabling the
1601ae08745Sheppo	 * MMU so that the loads can be done using real
1611ae08745Sheppo	 * addresses.
1621ae08745Sheppo	 */
1631ae08745Sheppo	ldx	[%l1 + LPAD_PC], %l3		! %l3 = specified entry point
1641ae08745Sheppo	ldx	[%l1 + LPAD_ARG], %l4		! %l4 = specified argument
1651ae08745Sheppo	ldx	[%l1 + LPAD_INUSE], %l5		! %l5 = va of inuse mailbox
1661ae08745Sheppo
1671ae08745Sheppo	/*
1681ae08745Sheppo	 * Enable the MMU. On success, it returns to the
1691ae08745Sheppo	 * global version of the landing pad text, rather
1701ae08745Sheppo	 * than the text copied into the lpad buffer.
1711ae08745Sheppo	 */
1721ae08745Sheppo	mov	1, %o0				! %o0 = enable flag (1 = enable)
1731ae08745Sheppo	set	startup_complete, %o1		! VA of return address
1741ae08745Sheppo	mov	MMU_ENABLE, %o5
1751ae08745Sheppo	ta	FAST_TRAP
1761ae08745Sheppo
1771ae08745Sheppo	/*
1781ae08745Sheppo	 * On errors, just enter a spin loop until the
1791ae08745Sheppo	 * CPU that initiated the start recovers the CPU.
1801ae08745Sheppo	 */
1811ae08745Sheppostartup_error:
1821ae08745Sheppo	ba	startup_error
1831ae08745Sheppo	  nop
1841ae08745Sheppo
1851ae08745Sheppo	/*
1861ae08745Sheppo	 * Jump to the generic CPU initialization code.
1871ae08745Sheppo	 */
1881ae08745Sheppostartup_complete:
1891ae08745Sheppo	mov	%l4, %o0
1901ae08745Sheppo	jmpl	%l3, %g0
1911ae08745Sheppo	  stx	%g0, [%l5]			! clear the inuse mailbox
1921ae08745Sheppo
1931ae08745Sheppo	SET_SIZE(mach_cpu_startup)
1941ae08745Sheppo
1951ae08745Sheppo	.global mach_cpu_startup_end
1961ae08745Sheppomach_cpu_startup_end:
1971ae08745Sheppo
198