17c478bdstevel@tonic-gate/* 27c478bdstevel@tonic-gate * CDDL HEADER START 37c478bdstevel@tonic-gate * 47c478bdstevel@tonic-gate * The contents of this file are subject to the terms of the 525cf1a3jl * Common Development and Distribution License (the "License"). 625cf1a3jl * You may not use this file except in compliance with the License. 77c478bdstevel@tonic-gate * 87c478bdstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bdstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bdstevel@tonic-gate * See the License for the specific language governing permissions 117c478bdstevel@tonic-gate * and limitations under the License. 127c478bdstevel@tonic-gate * 137c478bdstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bdstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bdstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bdstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bdstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bdstevel@tonic-gate * 197c478bdstevel@tonic-gate * CDDL HEADER END 207c478bdstevel@tonic-gate */ 217c478bdstevel@tonic-gate/* 222dd3029jimand * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 237c478bdstevel@tonic-gate * Use is subject to license terms. 247c478bdstevel@tonic-gate */ 252a1fd0fPeter Tribble/* 262a1fd0fPeter Tribble * Copyright 2019 Peter Tribble. 272a1fd0fPeter Tribble */ 287c478bdstevel@tonic-gate 297c478bdstevel@tonic-gate#ifndef _SYS_MACHTHREAD_H 307c478bdstevel@tonic-gate#define _SYS_MACHTHREAD_H 317c478bdstevel@tonic-gate 327c478bdstevel@tonic-gate#include <sys/asi.h> 337c478bdstevel@tonic-gate#include <sys/sun4asi.h> 347c478bdstevel@tonic-gate#include <sys/machasi.h> 357c478bdstevel@tonic-gate#include <sys/bitmap.h> 3625cf1a3jl#include <sys/opl_olympus_regs.h> 377c478bdstevel@tonic-gate 387c478bdstevel@tonic-gate#ifdef __cplusplus 397c478bdstevel@tonic-gateextern "C" { 407c478bdstevel@tonic-gate#endif 417c478bdstevel@tonic-gate 427c478bdstevel@tonic-gate#ifdef _ASM 437c478bdstevel@tonic-gate 447c478bdstevel@tonic-gate#define THREAD_REG %g7 /* pointer to current thread data */ 457c478bdstevel@tonic-gate 467c478bdstevel@tonic-gate/* 477c478bdstevel@tonic-gate * Get the processor implementation from the version register. 487c478bdstevel@tonic-gate */ 497c478bdstevel@tonic-gate#define GET_CPU_IMPL(out) \ 507c478bdstevel@tonic-gate rdpr %ver, out; \ 517c478bdstevel@tonic-gate srlx out, 32, out; \ 527c478bdstevel@tonic-gate sll out, 16, out; \ 537c478bdstevel@tonic-gate srl out, 16, out; 547c478bdstevel@tonic-gate 552a1fd0fPeter Tribble#ifdef _OPL 5625cf1a3jl/* 5725cf1a3jl * For OPL platform, we get CPU_INDEX from ASI_EIDR. 5825cf1a3jl */ 5925cf1a3jl#define CPU_INDEX(r, scr) \ 6025cf1a3jl ldxa [%g0]ASI_EIDR, r; \ 6125cf1a3jl and r, 0xfff, r 6225cf1a3jl 6325cf1a3jl 642a1fd0fPeter Tribble#else /* _OPL */ 657c478bdstevel@tonic-gate 667c478bdstevel@tonic-gate/* 677c478bdstevel@tonic-gate * UPA supports up to 32 devices while Safari supports up to 687c478bdstevel@tonic-gate * 1024 devices (utilizing the SSM protocol). Based upon the 697c478bdstevel@tonic-gate * value of NCPU, a 5- or 10-bit mask will be needed for 707c478bdstevel@tonic-gate * extracting the cpu id. 717c478bdstevel@tonic-gate */ 727c478bdstevel@tonic-gate#if NCPU > 32 737c478bdstevel@tonic-gate#define CPU_MASK 0x3ff 747c478bdstevel@tonic-gate#else 757c478bdstevel@tonic-gate#define CPU_MASK 0x1f 767c478bdstevel@tonic-gate#endif /* NCPU > 32 */ 777c478bdstevel@tonic-gate 787c478bdstevel@tonic-gate/* 797c478bdstevel@tonic-gate * CPU_INDEX(r, scr) 807c478bdstevel@tonic-gate * Returns cpu id in r. 817c478bdstevel@tonic-gate * For UPA based systems, the cpu id corresponds to the mid field in 827c478bdstevel@tonic-gate * the UPA config register. For Safari based machines, the cpu id 837c478bdstevel@tonic-gate * corresponds to the aid field in the Safari config register. 847c478bdstevel@tonic-gate * 857c478bdstevel@tonic-gate * XXX - scr reg is not used here. 867c478bdstevel@tonic-gate */ 877c478bdstevel@tonic-gate#define CPU_INDEX(r, scr) \ 887c478bdstevel@tonic-gate ldxa [%g0]ASI_UPA_CONFIG, r; \ 897c478bdstevel@tonic-gate srlx r, 17, r; \ 907c478bdstevel@tonic-gate and r, CPU_MASK, r 917c478bdstevel@tonic-gate 922a1fd0fPeter Tribble#endif /* _OPL */ 937c478bdstevel@tonic-gate 947c478bdstevel@tonic-gate/* 957c478bdstevel@tonic-gate * Given a cpu id extract the appropriate word 967c478bdstevel@tonic-gate * in the cpuset mask for this cpu id. 977c478bdstevel@tonic-gate */ 987c478bdstevel@tonic-gate#if CPUSET_SIZE > CLONGSIZE 997c478bdstevel@tonic-gate#define CPU_INDEXTOSET(base, index, scr) \ 1007c478bdstevel@tonic-gate srl index, BT_ULSHIFT, scr; \ 1017c478bdstevel@tonic-gate and index, BT_ULMASK, index; \ 1027c478bdstevel@tonic-gate sll scr, CLONGSHIFT, scr; \ 1037c478bdstevel@tonic-gate add base, scr, base 1047c478bdstevel@tonic-gate#else 1057c478bdstevel@tonic-gate#define CPU_INDEXTOSET(base, index, scr) 1067c478bdstevel@tonic-gate#endif /* CPUSET_SIZE */ 1077c478bdstevel@tonic-gate 1087c478bdstevel@tonic-gate 1097c478bdstevel@tonic-gate/* 1107c478bdstevel@tonic-gate * Assembly macro to find address of the current CPU. 1117c478bdstevel@tonic-gate * Used when coming in from a user trap - cannot use THREAD_REG. 1127c478bdstevel@tonic-gate * Args are destination register and one scratch register. 1137c478bdstevel@tonic-gate */ 1147c478bdstevel@tonic-gate#define CPU_ADDR(reg, scr) \ 1157c478bdstevel@tonic-gate .global cpu; \ 1167c478bdstevel@tonic-gate CPU_INDEX(scr, reg); \ 1177c478bdstevel@tonic-gate sll scr, CPTRSHIFT, scr; \ 1187c478bdstevel@tonic-gate set cpu, reg; \ 1197c478bdstevel@tonic-gate ldn [reg + scr], reg 1207c478bdstevel@tonic-gate 1217c478bdstevel@tonic-gate#define CINT64SHIFT 3 1227c478bdstevel@tonic-gate 1237c478bdstevel@tonic-gate/* 1247c478bdstevel@tonic-gate * Assembly macro to find the physical address of the current CPU. 1257c478bdstevel@tonic-gate * All memory references using VA must be limited to nucleus 1267c478bdstevel@tonic-gate * memory to avoid any MMU side effect. 1277c478bdstevel@tonic-gate */ 1287c478bdstevel@tonic-gate#define CPU_PADDR(reg, scr) \ 1297c478bdstevel@tonic-gate .global cpu_pa; \ 1307c478bdstevel@tonic-gate CPU_INDEX(scr, reg); \ 1317c478bdstevel@tonic-gate sll scr, CINT64SHIFT, scr; \ 1327c478bdstevel@tonic-gate set cpu_pa, reg; \ 1337c478bdstevel@tonic-gate ldx [reg + scr], reg 1347c478bdstevel@tonic-gate 1357c478bdstevel@tonic-gate#endif /* _ASM */ 1367c478bdstevel@tonic-gate 1378f230a5bs/* 1388f230a5bs * If a high level trap handler decides to call sys_trap() to execute some 1398f230a5bs * base level code, context and other registers must be set to proper 1408f230a5bs * values to run kernel. This is true for most part of the kernel, except 1418f230a5bs * for user_rtt, a substantial part of which is executed with registers 1428f230a5bs * ready to run user code. The following macro may be used to detect this 1438f230a5bs * condition and handle it. Please note that, in general, we can't restart 1448f230a5bs * arbitrary piece of code running at tl > 0; user_rtt is a special case 1458f230a5bs * that can be handled. 1468f230a5bs * 1478f230a5bs * Entry condition: 1488f230a5bs * 1498f230a5bs * %tl = 2 1508f230a5bs * pstate.ag = 1 1518f230a5bs * 1528f230a5bs * Register usage: 1538f230a5bs * 1548f230a5bs * scr1, scr2 - destroyed 1558f230a5bs * normal %g5 and %g6 - destroyed 1568f230a5bs * 1578f230a5bs */ 1588f230a5bs/* BEGIN CSTYLED */ 1598f230a5bs#define RESET_USER_RTT_REGS(scr1, scr2, label) \ 1608f230a5bs /* \ 1618f230a5bs * do nothing if %tl != 2. this an attempt to stop this \ 1628f230a5bs * piece of code from executing more than once before going \ 1638f230a5bs * back to TL=0. more specifically, the changes we are doing \ 1648f230a5bs * to %wstate, %canrestore and %otherwin can't be done more \ 1658f230a5bs * than once before going to TL=0. note that it is okay to \ 1668f230a5bs * execute this more than once if we restart at user_rtt and \ 1678f230a5bs * come back from there. \ 1688f230a5bs */ \ 1698f230a5bs rdpr %tl, scr1; \ 1708f230a5bs cmp scr1, 2; \ 1718f230a5bs bne,a,pn %xcc, label; \ 1728f230a5bs nop; \ 1738f230a5bs /* \ 1748f230a5bs * read tstate[2].%tpc. do nothing if it is not \ 1758f230a5bs * between rtt_ctx_start and rtt_ctx_end. \ 1768f230a5bs */ \ 1778f230a5bs rdpr %tpc, scr1; \ 1788f230a5bs set rtt_ctx_end, scr2; \ 1798f230a5bs cmp scr1, scr2; \ 1808f230a5bs bgu,a,pt %xcc, label; \ 1818f230a5bs nop; \ 1828f230a5bs set rtt_ctx_start, scr2; \ 1838f230a5bs cmp scr1, scr2; \ 1848f230a5bs blu,a,pt %xcc, label; \ 1858f230a5bs nop; \ 1868f230a5bs /* \ 1878f230a5bs * pickup tstate[2].cwp \ 1888f230a5bs */ \ 1898f230a5bs rdpr %tstate, scr1; \ 1908f230a5bs and scr1, TSTATE_CWP, scr1; \ 1918f230a5bs /* \ 1928f230a5bs * set tstate[1].cwp to tstate[2].cwp. fudge \ 1938f230a5bs * tstate[1].tpc and tstate[1].tnpc to restart \ 1948f230a5bs * user_rtt. \ 1958f230a5bs */ \ 1968f230a5bs wrpr %g0, 1, %tl; \ 1978f230a5bs set TSTATE_KERN | TSTATE_IE, scr2; \ 1988f230a5bs or scr1, scr2, scr2; \ 1998f230a5bs wrpr %g0, scr2, %tstate; \ 2008f230a5bs set user_rtt, scr1; \ 2018f230a5bs wrpr %g0, scr1, %tpc; \ 2028f230a5bs add scr1, 4, scr1; \ 2038f230a5bs wrpr %g0, scr1, %tnpc; \ 2048f230a5bs /* \ 2058f230a5bs * restore %tl \ 2068f230a5bs */ \ 2078f230a5bs wrpr %g0, 2, %tl; \ 2088f230a5bs /* \ 2098f230a5bs * set %wstate \ 2108f230a5bs */ \ 2118f230a5bs rdpr %wstate, scr1; \ 2128f230a5bs sllx scr1, WSTATE_SHIFT, scr1; \ 2138f230a5bs wrpr scr1, WSTATE_K64, %wstate; \ 2148f230a5bs /* \ 2158f230a5bs * setup window registers \ 2168f230a5bs * %cleanwin <-- nwin - 1 \ 2178f230a5bs * %otherwin <-- %canrestore \ 2188f230a5bs * %canrestore <-- 0 \ 2198f230a5bs */ \ 2208f230a5bs sethi %hi(nwin_minus_one), scr1; \ 2218f230a5bs ld [scr1 + %lo(nwin_minus_one)], scr1; \ 2228f230a5bs wrpr %g0, scr1, %cleanwin; \ 2238f230a5bs rdpr %canrestore, scr1; \ 2248f230a5bs wrpr %g0, scr1, %otherwin; \ 2258f230a5bs wrpr %g0, 0, %canrestore; \ 2268f230a5bs /* \ 2278f230a5bs * set THREAD_REG, as we have restored user \ 2288f230a5bs * registers in user_rtt. we trash %g5 and %g6 \ 2298f230a5bs * in the process. \ 2308f230a5bs */ \ 2318f230a5bs rdpr %pstate, scr1; \ 2328f230a5bs wrpr scr1, PSTATE_AG, %pstate; \ 2338f230a5bs /* \ 2348f230a5bs * using normal globals now \ 2358f230a5bs */ \ 2368f230a5bs CPU_ADDR(%g5, %g6); \ 2378f230a5bs ldn [%g5 + CPU_THREAD], %g6; \ 2388f230a5bs mov %g6, THREAD_REG; \ 2398f230a5bs rdpr %pstate, %g5; \ 2408f230a5bs wrpr %g5, PSTATE_AG, %pstate; \ 2418f230a5bs /* \ 2428f230a5bs * back to alternate globals. \ 2438f230a5bs * set PCONTEXT to run kernel. \ 244febcc4ajimand * A demap of I/DTLB is required if the nucleus bits differ \ 245febcc4ajimand * from kcontextreg. \ 2468f230a5bs */ \ 2478f230a5bs mov MMU_PCONTEXT, scr1; \ 2488f230a5bs sethi %hi(kcontextreg), scr2; \ 2498f230a5bs ldx [scr2 + %lo(kcontextreg)], scr2; \ 2502dd3029jimand ldxa [scr1]ASI_MMU_CTX, scr1; \ 2512dd3029jimand xor scr2, scr1, scr1; \ 2522dd3029jimand srlx scr1, CTXREG_NEXT_SHIFT, scr1; \ 253febcc4ajimand /* \ 254febcc4ajimand * If N_pgsz0/1 changed, need to demap. \ 255febcc4ajimand */ \ 2562dd3029jimand brz scr1, label/**/_0; \ 2572dd3029jimand nop; \ 2582dd3029jimand mov DEMAP_ALL_TYPE, scr1; \ 2592dd3029jimand stxa %g0, [scr1]ASI_DTLB_DEMAP; \ 2602dd3029jimand stxa %g0, [scr1]ASI_ITLB_DEMAP; \ 2612dd3029jimandlabel/**/_0: \ 2622dd3029jimand mov MMU_PCONTEXT, scr1; \ 2638f230a5bs stxa scr2, [scr1]ASI_MMU_CTX; \ 2642dd3029jimand sethi %hi(FLUSH_ADDR), scr1; \ 2652dd3029jimand flush scr1 2668f230a5bs 2678f230a5bs/* END CSTYLED */ 2688f230a5bs 2697c478bdstevel@tonic-gate#ifdef __cplusplus 2707c478bdstevel@tonic-gate} 2717c478bdstevel@tonic-gate#endif 2727c478bdstevel@tonic-gate 2737c478bdstevel@tonic-gate#endif /* _SYS_MACHTHREAD_H */ 274