17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 525cf1a30Sjl139090 * Common Development and Distribution License (the "License"). 625cf1a30Sjl139090 * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 217c478bd9Sstevel@tonic-gate /* 22*2dd3029aSjimand * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 237c478bd9Sstevel@tonic-gate * Use is subject to license terms. 247c478bd9Sstevel@tonic-gate */ 257c478bd9Sstevel@tonic-gate 267c478bd9Sstevel@tonic-gate #ifndef _SYS_MACHTHREAD_H 277c478bd9Sstevel@tonic-gate #define _SYS_MACHTHREAD_H 287c478bd9Sstevel@tonic-gate 297c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 307c478bd9Sstevel@tonic-gate 317c478bd9Sstevel@tonic-gate #include <sys/asi.h> 327c478bd9Sstevel@tonic-gate #include <sys/sun4asi.h> 337c478bd9Sstevel@tonic-gate #include <sys/machasi.h> 347c478bd9Sstevel@tonic-gate #include <sys/bitmap.h> 3525cf1a30Sjl139090 #include <sys/opl_olympus_regs.h> 367c478bd9Sstevel@tonic-gate 377c478bd9Sstevel@tonic-gate #ifdef __cplusplus 387c478bd9Sstevel@tonic-gate extern "C" { 397c478bd9Sstevel@tonic-gate #endif 407c478bd9Sstevel@tonic-gate 417c478bd9Sstevel@tonic-gate #ifdef _ASM 427c478bd9Sstevel@tonic-gate 437c478bd9Sstevel@tonic-gate #define THREAD_REG %g7 /* pointer to current thread data */ 447c478bd9Sstevel@tonic-gate 457c478bd9Sstevel@tonic-gate /* 467c478bd9Sstevel@tonic-gate * Get the processor implementation from the version register. 477c478bd9Sstevel@tonic-gate */ 487c478bd9Sstevel@tonic-gate #define GET_CPU_IMPL(out) \ 497c478bd9Sstevel@tonic-gate rdpr %ver, out; \ 507c478bd9Sstevel@tonic-gate srlx out, 32, out; \ 517c478bd9Sstevel@tonic-gate sll out, 16, out; \ 527c478bd9Sstevel@tonic-gate srl out, 16, out; 537c478bd9Sstevel@tonic-gate 547c478bd9Sstevel@tonic-gate #ifdef _STARFIRE 557c478bd9Sstevel@tonic-gate /* 567c478bd9Sstevel@tonic-gate * CPU_INDEX(r, scr) 577c478bd9Sstevel@tonic-gate * Returns cpu id in r. 587c478bd9Sstevel@tonic-gate * On Starfire, this is read from the Port Controller's Port ID 597c478bd9Sstevel@tonic-gate * register in local space. 607c478bd9Sstevel@tonic-gate * 617c478bd9Sstevel@tonic-gate * Need to load the 64 bit address of the PC's PortID reg 627c478bd9Sstevel@tonic-gate * using only one register. Kludge the 41 bits address constant to 637c478bd9Sstevel@tonic-gate * be 32bits by shifting it 12 bits to the right first. 647c478bd9Sstevel@tonic-gate */ 657c478bd9Sstevel@tonic-gate #define LOCAL_PC_PORTID_ADDR_SRL12 0x1FFF4000 667c478bd9Sstevel@tonic-gate #define PC_PORT_ID 0xD0 677c478bd9Sstevel@tonic-gate 687c478bd9Sstevel@tonic-gate #define CPU_INDEX(r, scr) \ 697c478bd9Sstevel@tonic-gate rdpr %pstate, scr; \ 707c478bd9Sstevel@tonic-gate andn scr, PSTATE_IE | PSTATE_AM, r; \ 717c478bd9Sstevel@tonic-gate wrpr r, 0, %pstate; \ 727c478bd9Sstevel@tonic-gate set LOCAL_PC_PORTID_ADDR_SRL12, r; \ 737c478bd9Sstevel@tonic-gate sllx r, 12, r; \ 747c478bd9Sstevel@tonic-gate or r, PC_PORT_ID, r; \ 757c478bd9Sstevel@tonic-gate lduwa [r]ASI_IO, r; \ 767c478bd9Sstevel@tonic-gate wrpr scr, 0, %pstate 777c478bd9Sstevel@tonic-gate 7825cf1a30Sjl139090 #elif defined(_OPL) 7925cf1a30Sjl139090 /* 8025cf1a30Sjl139090 * For OPL platform, we get CPU_INDEX from ASI_EIDR. 8125cf1a30Sjl139090 */ 8225cf1a30Sjl139090 #define CPU_INDEX(r, scr) \ 8325cf1a30Sjl139090 ldxa [%g0]ASI_EIDR, r; \ 8425cf1a30Sjl139090 and r, 0xfff, r 8525cf1a30Sjl139090 8625cf1a30Sjl139090 877c478bd9Sstevel@tonic-gate #else /* _STARFIRE */ 887c478bd9Sstevel@tonic-gate 897c478bd9Sstevel@tonic-gate /* 907c478bd9Sstevel@tonic-gate * UPA supports up to 32 devices while Safari supports up to 917c478bd9Sstevel@tonic-gate * 1024 devices (utilizing the SSM protocol). Based upon the 927c478bd9Sstevel@tonic-gate * value of NCPU, a 5- or 10-bit mask will be needed for 937c478bd9Sstevel@tonic-gate * extracting the cpu id. 947c478bd9Sstevel@tonic-gate */ 957c478bd9Sstevel@tonic-gate #if NCPU > 32 967c478bd9Sstevel@tonic-gate #define CPU_MASK 0x3ff 977c478bd9Sstevel@tonic-gate #else 987c478bd9Sstevel@tonic-gate #define CPU_MASK 0x1f 997c478bd9Sstevel@tonic-gate #endif /* NCPU > 32 */ 1007c478bd9Sstevel@tonic-gate 1017c478bd9Sstevel@tonic-gate /* 1027c478bd9Sstevel@tonic-gate * CPU_INDEX(r, scr) 1037c478bd9Sstevel@tonic-gate * Returns cpu id in r. 1047c478bd9Sstevel@tonic-gate * For UPA based systems, the cpu id corresponds to the mid field in 1057c478bd9Sstevel@tonic-gate * the UPA config register. For Safari based machines, the cpu id 1067c478bd9Sstevel@tonic-gate * corresponds to the aid field in the Safari config register. 1077c478bd9Sstevel@tonic-gate * 1087c478bd9Sstevel@tonic-gate * XXX - scr reg is not used here. 1097c478bd9Sstevel@tonic-gate */ 1107c478bd9Sstevel@tonic-gate #define CPU_INDEX(r, scr) \ 1117c478bd9Sstevel@tonic-gate ldxa [%g0]ASI_UPA_CONFIG, r; \ 1127c478bd9Sstevel@tonic-gate srlx r, 17, r; \ 1137c478bd9Sstevel@tonic-gate and r, CPU_MASK, r 1147c478bd9Sstevel@tonic-gate 1157c478bd9Sstevel@tonic-gate #endif /* _STARFIRE */ 1167c478bd9Sstevel@tonic-gate 1177c478bd9Sstevel@tonic-gate /* 1187c478bd9Sstevel@tonic-gate * Given a cpu id extract the appropriate word 1197c478bd9Sstevel@tonic-gate * in the cpuset mask for this cpu id. 1207c478bd9Sstevel@tonic-gate */ 1217c478bd9Sstevel@tonic-gate #if CPUSET_SIZE > CLONGSIZE 1227c478bd9Sstevel@tonic-gate #define CPU_INDEXTOSET(base, index, scr) \ 1237c478bd9Sstevel@tonic-gate srl index, BT_ULSHIFT, scr; \ 1247c478bd9Sstevel@tonic-gate and index, BT_ULMASK, index; \ 1257c478bd9Sstevel@tonic-gate sll scr, CLONGSHIFT, scr; \ 1267c478bd9Sstevel@tonic-gate add base, scr, base 1277c478bd9Sstevel@tonic-gate #else 1287c478bd9Sstevel@tonic-gate #define CPU_INDEXTOSET(base, index, scr) 1297c478bd9Sstevel@tonic-gate #endif /* CPUSET_SIZE */ 1307c478bd9Sstevel@tonic-gate 1317c478bd9Sstevel@tonic-gate 1327c478bd9Sstevel@tonic-gate /* 1337c478bd9Sstevel@tonic-gate * Assembly macro to find address of the current CPU. 1347c478bd9Sstevel@tonic-gate * Used when coming in from a user trap - cannot use THREAD_REG. 1357c478bd9Sstevel@tonic-gate * Args are destination register and one scratch register. 1367c478bd9Sstevel@tonic-gate */ 1377c478bd9Sstevel@tonic-gate #define CPU_ADDR(reg, scr) \ 1387c478bd9Sstevel@tonic-gate .global cpu; \ 1397c478bd9Sstevel@tonic-gate CPU_INDEX(scr, reg); \ 1407c478bd9Sstevel@tonic-gate sll scr, CPTRSHIFT, scr; \ 1417c478bd9Sstevel@tonic-gate set cpu, reg; \ 1427c478bd9Sstevel@tonic-gate ldn [reg + scr], reg 1437c478bd9Sstevel@tonic-gate 1447c478bd9Sstevel@tonic-gate #define CINT64SHIFT 3 1457c478bd9Sstevel@tonic-gate 1467c478bd9Sstevel@tonic-gate /* 1477c478bd9Sstevel@tonic-gate * Assembly macro to find the physical address of the current CPU. 1487c478bd9Sstevel@tonic-gate * All memory references using VA must be limited to nucleus 1497c478bd9Sstevel@tonic-gate * memory to avoid any MMU side effect. 1507c478bd9Sstevel@tonic-gate */ 1517c478bd9Sstevel@tonic-gate #define CPU_PADDR(reg, scr) \ 1527c478bd9Sstevel@tonic-gate .global cpu_pa; \ 1537c478bd9Sstevel@tonic-gate CPU_INDEX(scr, reg); \ 1547c478bd9Sstevel@tonic-gate sll scr, CINT64SHIFT, scr; \ 1557c478bd9Sstevel@tonic-gate set cpu_pa, reg; \ 1567c478bd9Sstevel@tonic-gate ldx [reg + scr], reg 1577c478bd9Sstevel@tonic-gate 1587c478bd9Sstevel@tonic-gate #endif /* _ASM */ 1597c478bd9Sstevel@tonic-gate 1608f230a59Sbs21162 /* 1618f230a59Sbs21162 * If a high level trap handler decides to call sys_trap() to execute some 1628f230a59Sbs21162 * base level code, context and other registers must be set to proper 1638f230a59Sbs21162 * values to run kernel. This is true for most part of the kernel, except 1648f230a59Sbs21162 * for user_rtt, a substantial part of which is executed with registers 1658f230a59Sbs21162 * ready to run user code. The following macro may be used to detect this 1668f230a59Sbs21162 * condition and handle it. Please note that, in general, we can't restart 1678f230a59Sbs21162 * arbitrary piece of code running at tl > 0; user_rtt is a special case 1688f230a59Sbs21162 * that can be handled. 1698f230a59Sbs21162 * 1708f230a59Sbs21162 * Entry condition: 1718f230a59Sbs21162 * 1728f230a59Sbs21162 * %tl = 2 1738f230a59Sbs21162 * pstate.ag = 1 1748f230a59Sbs21162 * 1758f230a59Sbs21162 * Register usage: 1768f230a59Sbs21162 * 1778f230a59Sbs21162 * scr1, scr2 - destroyed 1788f230a59Sbs21162 * normal %g5 and %g6 - destroyed 1798f230a59Sbs21162 * 1808f230a59Sbs21162 */ 1818f230a59Sbs21162 /* BEGIN CSTYLED */ 1828f230a59Sbs21162 #define RESET_USER_RTT_REGS(scr1, scr2, label) \ 1838f230a59Sbs21162 /* \ 1848f230a59Sbs21162 * do nothing if %tl != 2. this an attempt to stop this \ 1858f230a59Sbs21162 * piece of code from executing more than once before going \ 1868f230a59Sbs21162 * back to TL=0. more specifically, the changes we are doing \ 1878f230a59Sbs21162 * to %wstate, %canrestore and %otherwin can't be done more \ 1888f230a59Sbs21162 * than once before going to TL=0. note that it is okay to \ 1898f230a59Sbs21162 * execute this more than once if we restart at user_rtt and \ 1908f230a59Sbs21162 * come back from there. \ 1918f230a59Sbs21162 */ \ 1928f230a59Sbs21162 rdpr %tl, scr1; \ 1938f230a59Sbs21162 cmp scr1, 2; \ 1948f230a59Sbs21162 bne,a,pn %xcc, label; \ 1958f230a59Sbs21162 nop; \ 1968f230a59Sbs21162 /* \ 1978f230a59Sbs21162 * read tstate[2].%tpc. do nothing if it is not \ 1988f230a59Sbs21162 * between rtt_ctx_start and rtt_ctx_end. \ 1998f230a59Sbs21162 */ \ 2008f230a59Sbs21162 rdpr %tpc, scr1; \ 2018f230a59Sbs21162 set rtt_ctx_end, scr2; \ 2028f230a59Sbs21162 cmp scr1, scr2; \ 2038f230a59Sbs21162 bgu,a,pt %xcc, label; \ 2048f230a59Sbs21162 nop; \ 2058f230a59Sbs21162 set rtt_ctx_start, scr2; \ 2068f230a59Sbs21162 cmp scr1, scr2; \ 2078f230a59Sbs21162 blu,a,pt %xcc, label; \ 2088f230a59Sbs21162 nop; \ 2098f230a59Sbs21162 /* \ 2108f230a59Sbs21162 * pickup tstate[2].cwp \ 2118f230a59Sbs21162 */ \ 2128f230a59Sbs21162 rdpr %tstate, scr1; \ 2138f230a59Sbs21162 and scr1, TSTATE_CWP, scr1; \ 2148f230a59Sbs21162 /* \ 2158f230a59Sbs21162 * set tstate[1].cwp to tstate[2].cwp. fudge \ 2168f230a59Sbs21162 * tstate[1].tpc and tstate[1].tnpc to restart \ 2178f230a59Sbs21162 * user_rtt. \ 2188f230a59Sbs21162 */ \ 2198f230a59Sbs21162 wrpr %g0, 1, %tl; \ 2208f230a59Sbs21162 set TSTATE_KERN | TSTATE_IE, scr2; \ 2218f230a59Sbs21162 or scr1, scr2, scr2; \ 2228f230a59Sbs21162 wrpr %g0, scr2, %tstate; \ 2238f230a59Sbs21162 set user_rtt, scr1; \ 2248f230a59Sbs21162 wrpr %g0, scr1, %tpc; \ 2258f230a59Sbs21162 add scr1, 4, scr1; \ 2268f230a59Sbs21162 wrpr %g0, scr1, %tnpc; \ 2278f230a59Sbs21162 /* \ 2288f230a59Sbs21162 * restore %tl \ 2298f230a59Sbs21162 */ \ 2308f230a59Sbs21162 wrpr %g0, 2, %tl; \ 2318f230a59Sbs21162 /* \ 2328f230a59Sbs21162 * set %wstate \ 2338f230a59Sbs21162 */ \ 2348f230a59Sbs21162 rdpr %wstate, scr1; \ 2358f230a59Sbs21162 sllx scr1, WSTATE_SHIFT, scr1; \ 2368f230a59Sbs21162 wrpr scr1, WSTATE_K64, %wstate; \ 2378f230a59Sbs21162 /* \ 2388f230a59Sbs21162 * setup window registers \ 2398f230a59Sbs21162 * %cleanwin <-- nwin - 1 \ 2408f230a59Sbs21162 * %otherwin <-- %canrestore \ 2418f230a59Sbs21162 * %canrestore <-- 0 \ 2428f230a59Sbs21162 */ \ 2438f230a59Sbs21162 sethi %hi(nwin_minus_one), scr1; \ 2448f230a59Sbs21162 ld [scr1 + %lo(nwin_minus_one)], scr1; \ 2458f230a59Sbs21162 wrpr %g0, scr1, %cleanwin; \ 2468f230a59Sbs21162 rdpr %canrestore, scr1; \ 2478f230a59Sbs21162 wrpr %g0, scr1, %otherwin; \ 2488f230a59Sbs21162 wrpr %g0, 0, %canrestore; \ 2498f230a59Sbs21162 /* \ 2508f230a59Sbs21162 * set THREAD_REG, as we have restored user \ 2518f230a59Sbs21162 * registers in user_rtt. we trash %g5 and %g6 \ 2528f230a59Sbs21162 * in the process. \ 2538f230a59Sbs21162 */ \ 2548f230a59Sbs21162 rdpr %pstate, scr1; \ 2558f230a59Sbs21162 wrpr scr1, PSTATE_AG, %pstate; \ 2568f230a59Sbs21162 /* \ 2578f230a59Sbs21162 * using normal globals now \ 2588f230a59Sbs21162 */ \ 2598f230a59Sbs21162 CPU_ADDR(%g5, %g6); \ 2608f230a59Sbs21162 ldn [%g5 + CPU_THREAD], %g6; \ 2618f230a59Sbs21162 mov %g6, THREAD_REG; \ 2628f230a59Sbs21162 rdpr %pstate, %g5; \ 2638f230a59Sbs21162 wrpr %g5, PSTATE_AG, %pstate; \ 2648f230a59Sbs21162 /* \ 2658f230a59Sbs21162 * back to alternate globals. \ 2668f230a59Sbs21162 * set PCONTEXT to run kernel. \ 267febcc4a5Sjimand * A demap of I/DTLB is required if the nucleus bits differ \ 268febcc4a5Sjimand * from kcontextreg. \ 2698f230a59Sbs21162 */ \ 2708f230a59Sbs21162 mov MMU_PCONTEXT, scr1; \ 2718f230a59Sbs21162 sethi %hi(kcontextreg), scr2; \ 2728f230a59Sbs21162 ldx [scr2 + %lo(kcontextreg)], scr2; \ 273*2dd3029aSjimand ldxa [scr1]ASI_MMU_CTX, scr1; \ 274*2dd3029aSjimand xor scr2, scr1, scr1; \ 275*2dd3029aSjimand srlx scr1, CTXREG_NEXT_SHIFT, scr1; \ 276febcc4a5Sjimand /* \ 277febcc4a5Sjimand * If N_pgsz0/1 changed, need to demap. \ 278febcc4a5Sjimand */ \ 279*2dd3029aSjimand brz scr1, label/**/_0; \ 280*2dd3029aSjimand nop; \ 281*2dd3029aSjimand mov DEMAP_ALL_TYPE, scr1; \ 282*2dd3029aSjimand stxa %g0, [scr1]ASI_DTLB_DEMAP; \ 283*2dd3029aSjimand stxa %g0, [scr1]ASI_ITLB_DEMAP; \ 284*2dd3029aSjimand label/**/_0: \ 285*2dd3029aSjimand mov MMU_PCONTEXT, scr1; \ 2868f230a59Sbs21162 stxa scr2, [scr1]ASI_MMU_CTX; \ 287*2dd3029aSjimand sethi %hi(FLUSH_ADDR), scr1; \ 288*2dd3029aSjimand flush scr1 2898f230a59Sbs21162 2908f230a59Sbs21162 /* END CSTYLED */ 2918f230a59Sbs21162 2927c478bd9Sstevel@tonic-gate #ifdef __cplusplus 2937c478bd9Sstevel@tonic-gate } 2947c478bd9Sstevel@tonic-gate #endif 2957c478bd9Sstevel@tonic-gate 2967c478bd9Sstevel@tonic-gate #endif /* _SYS_MACHTHREAD_H */ 297