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