annotate usr/src/uts/intel/ia32/os/archdep.c @ 3446:5903aece022d

PSARC 2006/469 EOF and removal of eeprom -I PSARC 2006/568 direct boot (dboot) for x86 6219282 interrupt service routine called twice 6223946 potential infinite loop in fbt.c 6228819 tsc_gethrtimeunscaled resets to 0 on suspend 6342201 hat_unload() and cross call usage are needlessly slow on x86, x64 6378723 ctfconvert can't handle GCC empty struct C extension 6379124 ctfconvert can't handle C99 flexible array members 6401187 merging ip's CTF data into genunix introduces a race 6437553 shmat(2) fails on platforms that don't support large pages 6449286 eeprom -I should be torched 6464072 need support for firmware properties 6465816 need a debug record page 6467491 64-bit processes must point %fs or %gs to null selector to utilize [fs|gs]base 6475880 vestiges of old boot code on i386/amd64 should be purged 6475956 Interrupt handling code on x86 platforms should be easier to understand 6477828 pcplusmp psm module should be rearranged to allow multiple platforms to share the same apic code 6477867 x86 KDI should belong in the kernel 6477871 fix for 6232859 also needed for kmdb 6477872 MDB MMU commands need improvements 6477873 cpr debugging can be improved 6477877 mstate accounting should be reset when gethrtimef() is changed 6477915 32-bit x86 kernel should use interrupt gates for all traps 6477963 _update_sregs should be written in C 6477976 no longer need to capture [fs,gs]base in struct regs on every exception 6478642 Solaris needs to support multiple x86 platforms 6478648 ON could use an new & unencumbered xsvc driver 6478734 kernel lint not in C99 mode 6478826 swrand should have framework to lock individual pages 6480763 if interrupts can't be disabled, re-onlining an offline cpu fails 6481824 /dev/fb is not created if installation is done over tty 6483747 clock-tick processing should re-include threads waiting for I/O 6485872 use PTOU macro to access user area instead of old "u" from user.h 6486263 need way to extend kernel core dumps with pages that don't have page_t's 6486435 eeprom, prtdiag should only be platform specific where necessary 6486436 genunix mdb module makefiles duplicate list of files 6486437 intr_common.c should be common 6486445 /dev/mem needs support for page_t-less pages 6486451 cpu_pause() routine should be mach-specific 6486456 SIMULATOR_SUPPORT should die 6486832 x86 platform will need memlist/memseg locking 6486911 amd64 port not finished 6486972 platform TOD setting code may not have real TOD hdw to set 6492647 Better trap trace support for x-calls 6493613 apic_disable_intr() needs round robin fix 6497633 ctfmerge could allow for no ctf sections 6500637 floating point context switching is needlessly slow 6500656 move floating point configuration to C 6500666 need a means to override the setting of uname -m in the kernel build 6500669 update x86 defines 6502790 Files in the boot archive should be individually compressed 6503792 live upgrade environment + bfu + alternate root == incorrect menu.lst file 6504373 kmdb promif shouldn't needlessly busy-wait 6504374 ::interrupts could show level/edge 6506305 opteron erratum 123 should be enabled 6507629 porting x86 platform code to Xen 6510847 kobj.c is unaware of sparc hole between nucleus text and data (from dtrace)
author mrj
date Fri, 19 Jan 2007 08:10:06 -0800
parents f74a135872bc
children 8cf697a3acff
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1 /*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
2 * CDDL HEADER START
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
3 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
4 * The contents of this file are subject to the terms of the
2712
f74a135872bc PSARC/2005/471 BrandZ: Support for non-native zones
nn35248
parents: 1217
diff changeset
5 * Common Development and Distribution License (the "License").
f74a135872bc PSARC/2005/471 BrandZ: Support for non-native zones
nn35248
parents: 1217
diff changeset
6 * You may not use this file except in compliance with the License.
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
7 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
9 * or http://www.opensolaris.org/os/licensing.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
10 * See the License for the specific language governing permissions
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
11 * and limitations under the License.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
12 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
13 * When distributing Covered Code, include this CDDL HEADER in each
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
15 * If applicable, add the following below this CDDL HEADER, with the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
16 * fields enclosed by brackets "[]" replaced with your own identifying
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
17 * information: Portions Copyright [yyyy] [name of copyright owner]
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
18 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
19 * CDDL HEADER END
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
20 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
21 /*
3446
5903aece022d PSARC 2006/469 EOF and removal of eeprom -I
mrj
parents: 2712
diff changeset
22 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
23 * Use is subject to license terms.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
24 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
25
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
26 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
27 /* All Rights Reserved */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
28
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
29
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
30 #pragma ident "%Z%%M% %I% %E% SMI"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
31
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
32 #include <sys/param.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
33 #include <sys/types.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
34 #include <sys/vmparam.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
35 #include <sys/systm.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
36 #include <sys/signal.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
37 #include <sys/stack.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
38 #include <sys/regset.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
39 #include <sys/privregs.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
40 #include <sys/frame.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
41 #include <sys/proc.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
42 #include <sys/psw.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
43 #include <sys/siginfo.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
44 #include <sys/cpuvar.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
45 #include <sys/asm_linkage.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
46 #include <sys/kmem.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
47 #include <sys/errno.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
48 #include <sys/bootconf.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
49 #include <sys/archsystm.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
50 #include <sys/debug.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
51 #include <sys/elf.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
52 #include <sys/spl.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
53 #include <sys/time.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
54 #include <sys/atomic.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
55 #include <sys/sysmacros.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
56 #include <sys/cmn_err.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
57 #include <sys/modctl.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
58 #include <sys/kobj.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
59 #include <sys/panic.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
60 #include <sys/reboot.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
61 #include <sys/time.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
62 #include <sys/fp.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
63 #include <sys/x86_archext.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
64 #include <sys/auxv.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
65 #include <sys/auxv_386.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
66 #include <sys/dtrace.h>
2712
f74a135872bc PSARC/2005/471 BrandZ: Support for non-native zones
nn35248
parents: 1217
diff changeset
67 #include <sys/brand.h>
f74a135872bc PSARC/2005/471 BrandZ: Support for non-native zones
nn35248
parents: 1217
diff changeset
68 #include <sys/machbrand.h>
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
69
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
70 extern const struct fnsave_state x87_initial;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
71 extern const struct fxsave_state sse_initial;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
72
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
73 /*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
74 * Map an fnsave-formatted save area into an fxsave-formatted save area.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
75 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
76 * Most fields are the same width, content and semantics. However
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
77 * the tag word is compressed.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
78 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
79 static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
80 fnsave_to_fxsave(const struct fnsave_state *fn, struct fxsave_state *fx)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
81 {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
82 uint_t i, tagbits;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
83
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
84 fx->fx_fcw = fn->f_fcw;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
85 fx->fx_fsw = fn->f_fsw;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
86
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
87 /*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
88 * copy element by element (because of holes)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
89 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
90 for (i = 0; i < 8; i++)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
91 bcopy(&fn->f_st[i].fpr_16[0], &fx->fx_st[i].fpr_16[0],
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
92 sizeof (fn->f_st[0].fpr_16)); /* 80-bit x87-style floats */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
93
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
94 /*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
95 * synthesize compressed tag bits
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
96 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
97 fx->fx_fctw = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
98 for (tagbits = fn->f_ftw, i = 0; i < 8; i++, tagbits >>= 2)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
99 if ((tagbits & 3) != 3)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
100 fx->fx_fctw |= (1 << i);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
101
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
102 fx->fx_fop = fn->f_fop;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
103
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
104 #if defined(__amd64)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
105 fx->fx_rip = (uint64_t)fn->f_eip;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
106 fx->fx_rdp = (uint64_t)fn->f_dp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
107 #else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
108 fx->fx_eip = fn->f_eip;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
109 fx->fx_cs = fn->f_cs;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
110 fx->__fx_ign0 = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
111 fx->fx_dp = fn->f_dp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
112 fx->fx_ds = fn->f_ds;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
113 fx->__fx_ign1 = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
114 #endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
115 }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
116
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
117 /*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
118 * Map from an fxsave-format save area to an fnsave-format save area.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
119 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
120 static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
121 fxsave_to_fnsave(const struct fxsave_state *fx, struct fnsave_state *fn)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
122 {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
123 uint_t i, top, tagbits;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
124
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
125 fn->f_fcw = fx->fx_fcw;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
126 fn->__f_ign0 = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
127 fn->f_fsw = fx->fx_fsw;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
128 fn->__f_ign1 = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
129
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
130 top = (fx->fx_fsw & FPS_TOP) >> 11;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
131
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
132 /*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
133 * copy element by element (because of holes)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
134 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
135 for (i = 0; i < 8; i++)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
136 bcopy(&fx->fx_st[i].fpr_16[0], &fn->f_st[i].fpr_16[0],
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
137 sizeof (fn->f_st[0].fpr_16)); /* 80-bit x87-style floats */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
138
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
139 /*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
140 * synthesize uncompressed tag bits
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
141 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
142 fn->f_ftw = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
143 for (tagbits = fx->fx_fctw, i = 0; i < 8; i++, tagbits >>= 1) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
144 uint_t ibit, expo;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
145 const uint16_t *fpp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
146 static const uint16_t zero[5] = { 0, 0, 0, 0, 0 };
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
147
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
148 if ((tagbits & 1) == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
149 fn->f_ftw |= 3 << (i << 1); /* empty */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
150 continue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
151 }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
152
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
153 /*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
154 * (tags refer to *physical* registers)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
155 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
156 fpp = &fx->fx_st[(i - top + 8) & 7].fpr_16[0];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
157 ibit = fpp[3] >> 15;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
158 expo = fpp[4] & 0x7fff;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
159
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
160 if (ibit && expo != 0 && expo != 0x7fff)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
161 continue; /* valid fp number */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
162
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
163 if (bcmp(fpp, &zero, sizeof (zero)))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
164 fn->f_ftw |= 2 << (i << 1); /* NaN */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
165 else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
166 fn->f_ftw |= 1 << (i << 1); /* fp zero */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
167 }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
168
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
169 fn->f_fop = fx->fx_fop;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
170
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
171 fn->__f_ign2 = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
172 #if defined(__amd64)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
173 fn->f_eip = (uint32_t)fx->fx_rip;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
174 fn->f_cs = U32CS_SEL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
175 fn->f_dp = (uint32_t)fx->fx_rdp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
176 fn->f_ds = UDS_SEL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
177 #else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
178 fn->f_eip = fx->fx_eip;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
179 fn->f_cs = fx->fx_cs;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
180 fn->f_dp = fx->fx_dp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
181 fn->f_ds = fx->fx_ds;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
182 #endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
183 fn->__f_ign3 = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
184 }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
185
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
186 /*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
187 * Map from an fpregset_t into an fxsave-format save area
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
188 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
189 static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
190 fpregset_to_fxsave(const fpregset_t *fp, struct fxsave_state *fx)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
191 {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
192 #if defined(__amd64)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
193 bcopy(fp, fx, sizeof (*fx));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
194 #else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
195 const struct fpchip_state *fc = &fp->fp_reg_set.fpchip_state;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
196
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
197 fnsave_to_fxsave((const struct fnsave_state *)fc, fx);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
198 fx->fx_mxcsr = fc->mxcsr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
199 bcopy(&fc->xmm[0], &fx->fx_xmm[0], sizeof (fc->xmm));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
200 #endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
201 /*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
202 * avoid useless #gp exceptions - mask reserved bits
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
203 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
204 fx->fx_mxcsr &= sse_mxcsr_mask;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
205 }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
206
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
207 /*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
208 * Map from an fxsave-format save area into a fpregset_t
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
209 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
210 static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
211 fxsave_to_fpregset(const struct fxsave_state *fx, fpregset_t *fp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
212 {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
213 #if defined(__amd64)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
214 bcopy(fx, fp, sizeof (*fx));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
215 #else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
216 struct fpchip_state *fc = &fp->fp_reg_set.fpchip_state;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
217
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
218 fxsave_to_fnsave(fx, (struct fnsave_state *)fc);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
219 fc->mxcsr = fx->fx_mxcsr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
220 bcopy(&fx->fx_xmm[0], &fc->xmm[0], sizeof (fc->xmm));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
221 #endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
222 }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
223
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
224 #if defined(_SYSCALL32_IMPL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
225 static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
226 fpregset32_to_fxsave(const fpregset32_t *fp, struct fxsave_state *fx)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
227 {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
228 const struct fpchip32_state *fc = &fp->fp_reg_set.fpchip_state;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
229
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
230 fnsave_to_fxsave((const struct fnsave_state *)fc, fx);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
231 /*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
232 * avoid useless #gp exceptions - mask reserved bits
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
233 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
234 fx->fx_mxcsr = sse_mxcsr_mask & fc->mxcsr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
235 bcopy(&fc->xmm[0], &fx->fx_xmm[0], sizeof (fc->xmm));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
236 }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
237
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
238 static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
239 fxsave_to_fpregset32(const struct fxsave_state *fx, fpregset32_t *fp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
240 {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
241 struct fpchip32_state *fc = &fp->fp_reg_set.fpchip_state;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
242
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
243 fxsave_to_fnsave(fx, (struct fnsave_state *)fc);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
244 fc->mxcsr = fx->fx_mxcsr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
245 bcopy(&fx->fx_xmm[0], &fc->xmm[0], sizeof (fc->xmm));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
246 }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
247
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
248 static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
249 fpregset_nto32(const fpregset_t *src, fpregset32_t *dst)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
250 {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
251 fxsave_to_fpregset32((struct fxsave_state *)src, dst);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
252 dst->fp_reg_set.fpchip_state.status =
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
253 src->fp_reg_set.fpchip_state.status;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
254 dst->fp_reg_set.fpchip_state.xstatus =
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
255 src->fp_reg_set.fpchip_state.xstatus;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
256 }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
257
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
258 static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
259 fpregset_32ton(const fpregset32_t *src, fpregset_t *dst)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
260 {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
261 fpregset32_to_fxsave(src, (struct fxsave_state *)dst);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
262 dst->fp_reg_set.fpchip_state.status =
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
263 src->fp_reg_set.fpchip_state.status;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
264 dst->fp_reg_set.fpchip_state.xstatus =
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
265 src->fp_reg_set.fpchip_state.xstatus;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
266 }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
267 #endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
268
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
269 /*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
270 * Set floating-point registers from a native fpregset_t.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
271 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
272 void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
273 setfpregs(klwp_t *lwp, fpregset_t *fp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
274 {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
275 struct fpu_ctx *fpu = &lwp->lwp_pcb.pcb_fpu;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
276
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
277 if (fpu->fpu_flags & FPU_EN) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
278 if (!(fpu->fpu_flags & FPU_VALID)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
279 /*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
280 * FPU context is still active, release the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
281 * ownership.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
282 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
283 fp_free(fpu, 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
284 }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
285 #if !defined(__amd64)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
286 if (fp_kind == __FP_SSE) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
287 #endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
288 fpregset_to_fxsave(fp, &fpu->fpu_regs.kfpu_u.kfpu_fx);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
289 fpu->fpu_regs.kfpu_xstatus =
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
290 fp->fp_reg_set.fpchip_state.xstatus;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
291 #if !defined(__amd64)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
292 } else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
293 bcopy(fp, &fpu->fpu_regs.kfpu_u.kfpu_fn,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
294 sizeof (fpu->fpu_regs.kfpu_u.kfpu_fn));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
295 #endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
296 fpu->fpu_regs.kfpu_status = fp->fp_reg_set.fpchip_state.status;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
297 fpu->fpu_flags |= FPU_VALID;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
298 } else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
299 /*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
300 * If we are trying to change the FPU state of a thread which
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
301 * hasn't yet initialized floating point, store the state in
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
302 * the pcb and indicate that the state is valid. When the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
303 * thread enables floating point, it will use this state instead
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
304 * of the default state.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
305 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
306 #if !defined(__amd64)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
307 if (fp_kind == __FP_SSE) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
308 #endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
309 fpregset_to_fxsave(fp, &fpu->fpu_regs.kfpu_u.kfpu_fx);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
310 fpu->fpu_regs.kfpu_xstatus =
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
311 fp->fp_reg_set.fpchip_state.xstatus;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
312 #if !defined(__amd64)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
313 } else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
314 bcopy(fp, &fpu->fpu_regs.kfpu_u.kfpu_fn,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
315 sizeof (fpu->fpu_regs.kfpu_u.kfpu_fn));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
316 #endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
317 fpu->fpu_regs.kfpu_status = fp->fp_reg_set.fpchip_state.status;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
318 fpu->fpu_flags |= FPU_VALID;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
319 }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
320 }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
321
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
322 /*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
323 * Get floating-point registers into a native fpregset_t.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
324 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
325 void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
326 getfpregs(klwp_t *lwp, fpregset_t *fp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
327 {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
328 struct fpu_ctx *fpu = &lwp->lwp_pcb.pcb_fpu;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
329
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
330 kpreempt_disable();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
331 if (fpu->fpu_flags & FPU_EN) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
332 /*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
333 * If we have FPU hw and the thread's pcb doesn't have
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
334 * a valid FPU state then get the state from the hw.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
335 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
336 if (fpu_exists && ttolwp(curthread) == lwp &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
337 !(fpu->fpu_flags & FPU_VALID))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
338 fp_save(fpu); /* get the current FPU state */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
339 }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
340
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
341 /*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
342 * There are 3 possible cases we have to be aware of here:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
343 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
344 * 1. FPU is enabled. FPU state is stored in the current LWP.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
345 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
346 * 2. FPU is not enabled, and there have been no intervening /proc
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
347 * modifications. Return initial FPU state.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
348 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
349 * 3. FPU is not enabled, but a /proc consumer has modified FPU state.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
350 * FPU state is stored in the current LWP.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
351 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
352 if ((fpu->fpu_flags & FPU_EN) || (fpu->fpu_flags & FPU_VALID)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
353 /*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
354 * Cases 1 and 3.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
355 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
356 #if !defined(__amd64)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
357 if (fp_kind == __FP_SSE) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
358 #endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
359 fxsave_to_fpregset(&fpu->fpu_regs.kfpu_u.kfpu_fx, fp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
360 fp->fp_reg_set.fpchip_state.xstatus =
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
361 fpu->fpu_regs.kfpu_xstatus;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
362 #if !defined(__amd64)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
363 } else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
364 bcopy(&fpu->fpu_regs.kfpu_u.kfpu_fn, fp,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
365 sizeof (fpu->fpu_regs.kfpu_u.kfpu_fn));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
366 #endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
367 fp->fp_reg_set.fpchip_state.status = fpu->fpu_regs.kfpu_status;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
368 } else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
369 /*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
370 * Case 2.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
371 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
372 #if !defined(__amd64)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
373 if (fp_kind == __FP_SSE) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
374 #endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
375 fxsave_to_fpregset(&sse_initial, fp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
376 fp->fp_reg_set.fpchip_state.xstatus =
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
377 fpu->fpu_regs.kfpu_xstatus;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
378 #if !defined(__amd64)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
379 } else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
380 bcopy(&x87_initial, fp, sizeof (x87_initial));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
381 #endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
382 fp->fp_reg_set.fpchip_state.status = fpu->fpu_regs.kfpu_status;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
383 }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
384 kpreempt_enable();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
385 }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
386
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
387 #if defined(_SYSCALL32_IMPL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
388
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
389 /*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
390 * Set floating-point registers from an fpregset32_t.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
391 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
392 void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
393 setfpregs32(klwp_t *lwp, fpregset32_t *fp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
394 {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
395 fpregset_t fpregs;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
396
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
397 fpregset_32ton(fp, &fpregs);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
398 setfpregs(lwp, &fpregs);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
399 }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
400
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
401 /*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
402 * Get floating-point registers into an fpregset32_t.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
403 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
404 void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
405 getfpregs32(klwp_t *lwp, fpregset32_t *fp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
406 {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
407 fpregset_t fpregs;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
408
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
409 getfpregs(lwp, &fpregs);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
410 fpregset_nto32(&fpregs, fp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
411 }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
412
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
413 #endif /* _SYSCALL32_IMPL */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
414
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
415 /*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
416 * Return the general registers
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
417 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
418 void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
419 getgregs(klwp_t *lwp, gregset_t grp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
420 {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
421 struct regs *rp = lwptoregs(lwp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
422 #if defined(__amd64)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
423 struct pcb *pcb = &lwp->lwp_pcb;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
424 int thisthread = lwptot(lwp) == curthread;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
425
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
426 grp[REG_RDI] = rp->r_rdi;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
427 grp[REG_RSI] = rp->r_rsi;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
428 grp[REG_RDX] = rp->r_rdx;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
429 grp[REG_RCX] = rp->r_rcx;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
430 grp[REG_R8] = rp->r_r8;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
431 grp[REG_R9] = rp->r_r9;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
432 grp[REG_RAX] = rp->r_rax;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
433 grp[REG_RBX] = rp->r_rbx;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
434 grp[REG_RBP] = rp->r_rbp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
435 grp[REG_R10] = rp->r_r10;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
436 grp[REG_R11] = rp->r_r11;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
437 grp[REG_R12] = rp->r_r12;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
438 grp[REG_R13] = rp->r_r13;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
439 grp[REG_R14] = rp->r_r14;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
440 grp[REG_R15] = rp->r_r15;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
441 grp[REG_FSBASE] = pcb->pcb_fsbase;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
442 grp[REG_GSBASE] = pcb->pcb_gsbase;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
443 if (thisthread)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
444 kpreempt_disable();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
445 if (pcb->pcb_flags & RUPDATE_PENDING) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
446 grp[REG_DS] = pcb->pcb_ds;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
447 grp[REG_ES] = pcb->pcb_es;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
448 grp[REG_FS] = pcb->pcb_fs;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
449 grp[REG_GS] = pcb->pcb_gs;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
450 } else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
451 grp[REG_DS] = rp->r_ds;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
452 grp[REG_ES] = rp->r_es;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
453 grp[REG_FS] = rp->r_fs;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
454 grp[REG_GS] = rp->r_gs;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
455 }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
456 if (thisthread)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
457 kpreempt_enable();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
458 grp[REG_TRAPNO] = rp->r_trapno;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
459 grp[REG_ERR] = rp->r_err;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
460 grp[REG_RIP] = rp->r_rip;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
461 grp[REG_CS] = rp->r_cs;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
462 grp[REG_SS] = rp->r_ss;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
463 grp[REG_RFL] = rp->r_rfl;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
464 grp[REG_RSP] = rp->r_rsp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
465 #else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
466 bcopy(&rp->r_gs, grp, sizeof (gregset_t));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
467 #endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
468 }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
469
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
470 #if defined(_SYSCALL32_IMPL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
471
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
472 void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
473 getgregs32(klwp_t *lwp, gregset32_t grp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
474 {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
475 struct regs *rp = lwptoregs(lwp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
476 struct pcb *pcb = &lwp->lwp_pcb;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
477 int thisthread = lwptot(lwp) == curthread;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
478
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
479 if (thisthread)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
480 kpreempt_disable();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
481 if (pcb->pcb_flags & RUPDATE_PENDING) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
482 grp[GS] = (uint16_t)pcb->pcb_gs;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
483 grp[FS] = (uint16_t)pcb->pcb_fs;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
484 grp[DS] = (uint16_t)pcb->pcb_ds;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
485 grp[ES] = (uint16_t)pcb->pcb_es;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
486 } else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
487 grp[GS] = (uint16_t)rp->r_gs;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
488 grp[FS] = (uint16_t)rp->r_fs;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
489 grp[DS] = (uint16_t)rp->r_ds;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
490 grp[ES] = (uint16_t)rp->r_es;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
491 }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
492 if (thisthread)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
493 kpreempt_enable();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
494 grp[EDI] = (greg32_t)rp->r_rdi;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
495 grp[ESI] = (greg32_t)rp->r_rsi;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
496 grp[EBP] = (greg32_t)rp->r_rbp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
497 grp[ESP] = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
498 grp[EBX] = (greg32_t)rp->r_rbx;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
499 grp[EDX] = (greg32_t)rp->r_rdx;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
500 grp[ECX] = (greg32_t)rp->r_rcx;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
501 grp[EAX] = (greg32_t)rp->r_rax;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
502 grp[TRAPNO] = (greg32_t)rp->r_trapno;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
503 grp[ERR] = (greg32_t)rp->r_err;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
504 grp[EIP] = (greg32_t)rp->r_rip;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
505 grp[CS] = (uint16_t)rp->r_cs;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
506 grp[EFL] = (greg32_t)rp->r_rfl;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
507 grp[UESP] = (greg32_t)rp->r_rsp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
508 grp[SS] = (uint16_t)rp->r_ss;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
509 }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
510
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
511 void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
512 ucontext_32ton(const ucontext32_t *src, ucontext_t *dst)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
513 {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
514 mcontext_t *dmc = &dst->uc_mcontext;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
515 const mcontext32_t *smc = &src->uc_mcontext;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
516
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
517 bzero(dst, sizeof (*dst));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
518 dst->uc_flags = src->uc_flags;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
519 dst->uc_link = (ucontext_t *)(uintptr_t)src->uc_link;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
520
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
521 bcopy(&src->uc_sigmask, &dst->uc_sigmask, sizeof (dst->uc_sigmask));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
522
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
523 dst->uc_stack.ss_sp = (void *)(uintptr_t)src->uc_stack.ss_sp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
524 dst->uc_stack.ss_size = (size_t)src->uc_stack.ss_size;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
525 dst->uc_stack.ss_flags = src->uc_stack.ss_flags;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
526
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
527 dmc->gregs[REG_GS] = (greg_t)(uint32_t)smc->gregs[GS];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
528 dmc->gregs[REG_FS] = (greg_t)(uint32_t)smc->gregs[FS];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
529 dmc->gregs[REG_ES] = (greg_t)(uint32_t)smc->gregs[ES];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
530 dmc->gregs[REG_DS] = (greg_t)(uint32_t)smc->gregs[DS];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
531 dmc->gregs[REG_RDI] = (greg_t)(uint32_t)smc->gregs[EDI];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
532 dmc->gregs[REG_RSI] = (greg_t)(uint32_t)smc->gregs[ESI];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
533 dmc->gregs[REG_RBP] = (greg_t)(uint32_t)smc->gregs[EBP];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
534 dmc->gregs[REG_RBX] = (greg_t)(uint32_t)smc->gregs[EBX];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
535 dmc->gregs[REG_RDX] = (greg_t)(uint32_t)smc->gregs[EDX];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
536 dmc->gregs[REG_RCX] = (greg_t)(uint32_t)smc->gregs[ECX];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
537 dmc->gregs[REG_RAX] = (greg_t)(uint32_t)smc->gregs[EAX];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
538 dmc->gregs[REG_TRAPNO] = (greg_t)(uint32_t)smc->gregs[TRAPNO];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
539 dmc->gregs[REG_ERR] = (greg_t)(uint32_t)smc->gregs[ERR];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
540 dmc->gregs[REG_RIP] = (greg_t)(uint32_t)smc->gregs[EIP];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
541 dmc->gregs[REG_CS] = (greg_t)(uint32_t)smc->gregs[CS];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
542 dmc->gregs[REG_RFL] = (greg_t)(uint32_t)smc->gregs[EFL];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
543 dmc->gregs[REG_RSP] = (greg_t)(uint32_t)smc->gregs[UESP];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
544 dmc->gregs[REG_SS] = (greg_t)(uint32_t)smc->gregs[SS];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
545
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
546 /*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
547 * A valid fpregs is only copied in if uc.uc_flags has UC_FPU set
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
548 * otherwise there is no guarantee that anything in fpregs is valid.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
549 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
550 if (src->uc_flags & UC_FPU)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
551 fpregset_32ton(&src->uc_mcontext.fpregs,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
552 &dst->uc_mcontext.fpregs);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
553 }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
554
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
555 #endif /* _SYSCALL32_IMPL */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
556
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
557 /*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
558 * Return the user-level PC.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
559 * If in a system call, return the address of the syscall trap.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
560 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
561 greg_t
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
562 getuserpc()
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
563 {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
564 greg_t upc = lwptoregs(ttolwp(curthread))->r_pc;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
565 uint32_t insn;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
566
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
567 if (curthread->t_sysnum == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
568 return (upc);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
569
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
570 /*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
571 * We might've gotten here from sysenter (0xf 0x34),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
572 * syscall (0xf 0x5) or lcall (0x9a 0 0 0 0 0x27 0).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
573 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
574 * Go peek at the binary to figure it out..
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
575 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
576 if (fuword32((void *)(upc - 2), &insn) != -1 &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
577 (insn & 0xffff) == 0x340f || (insn & 0xffff) == 0x050f)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
578 return (upc - 2);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
579 return (upc - 7);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
580 }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
581
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
582 /*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
583 * Protect segment registers from non-user privilege levels and GDT selectors
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
584 * other than USER_CS, USER_DS and lwp FS and GS values. If the segment
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
585 * selector is non-null and not USER_CS/USER_DS, we make sure that the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
586 * TI bit is set to point into the LDT and that the RPL is set to 3.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
587 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
588 * Since struct regs stores each 16-bit segment register as a 32-bit greg_t, we
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
589 * also explicitly zero the top 16 bits since they may be coming from the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
590 * user's address space via setcontext(2) or /proc.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
591 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
592
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
593 /*ARGSUSED*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
594 static greg_t
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
595 fix_segreg(greg_t sr, model_t datamodel)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
596 {
2712
f74a135872bc PSARC/2005/471 BrandZ: Support for non-native zones
nn35248
parents: 1217
diff changeset
597 kthread_t *t = curthread;
f74a135872bc PSARC/2005/471 BrandZ: Support for non-native zones
nn35248
parents: 1217
diff changeset
598
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
599 switch (sr &= 0xffff) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
600 #if defined(__amd64)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
601 /*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
602 * If lwp attempts to switch data model then force their
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
603 * code selector to be null selector.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
604 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
605 case U32CS_SEL:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
606 if (datamodel == DATAMODEL_NATIVE)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
607 return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
608 else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
609 return (sr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
610
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
611 case UCS_SEL:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
612 if (datamodel == DATAMODEL_ILP32)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
613 return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
614 #elif defined(__i386)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
615 case UCS_SEL:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
616 #endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
617 /*FALLTHROUGH*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
618 case UDS_SEL:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
619 case LWPFS_SEL:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
620 case LWPGS_SEL:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
621 case 0:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
622 return (sr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
623 default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
624 break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
625 }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
626
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
627 /*
2712
f74a135872bc PSARC/2005/471 BrandZ: Support for non-native zones
nn35248
parents: 1217
diff changeset
628 * Allow this process's brand to do any necessary segment register
f74a135872bc PSARC/2005/471 BrandZ: Support for non-native zones
nn35248
parents: 1217
diff changeset
629 * manipulation.
f74a135872bc PSARC/2005/471 BrandZ: Support for non-native zones
nn35248
parents: 1217
diff changeset
630 */
f74a135872bc PSARC/2005/471 BrandZ: Support for non-native zones
nn35248
parents: 1217
diff changeset
631 if (PROC_IS_BRANDED(t->t_procp) && BRMOP(t->t_procp)->b_fixsegreg)
f74a135872bc PSARC/2005/471 BrandZ: Support for non-native zones
nn35248
parents: 1217
diff changeset
632 return (BRMOP(t->t_procp)->b_fixsegreg(sr, datamodel));
f74a135872bc PSARC/2005/471 BrandZ: Support for non-native zones
nn35248
parents: 1217
diff changeset
633
f74a135872bc PSARC/2005/471 BrandZ: Support for non-native zones
nn35248
parents: 1217
diff changeset
634 /*
1217
f95ffdc997b7 6219276 need per-process equivalent of device context
rab
parents: 0
diff changeset
635 * Force it into the LDT in ring 3 for 32-bit processes, which by
f95ffdc997b7 6219276 need per-process equivalent of device context
rab
parents: 0
diff changeset
636 * default do not have an LDT, so that any attempt to use an invalid
f95ffdc997b7 6219276 need per-process equivalent of device context
rab
parents: 0
diff changeset
637 * selector will reference the (non-existant) LDT, and cause a #gp fault
f95ffdc997b7 6219276 need per-process equivalent of device context
rab
parents: 0
diff changeset
638 * for the process.
f95ffdc997b7 6219276 need per-process equivalent of device context
rab
parents: 0
diff changeset
639 *
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
640 * 64-bit processes get the null gdt selector since they
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
641 * are not allowed to have a private LDT.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
642 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
643 #if defined(__amd64)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
644 return (datamodel == DATAMODEL_ILP32 ? (sr | SEL_TI_LDT | SEL_UPL) : 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
645 #elif defined(__i386)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
646 return (sr | SEL_TI_LDT | SEL_UPL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
647 #endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
648 }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
649
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
650 /*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
651 * Set general registers.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
652 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
653 void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
654 setgregs(klwp_t *lwp, gregset_t grp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
655 {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
656 struct regs *rp = lwptoregs(lwp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
657 model_t datamodel = lwp_getdatamodel(lwp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
658
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
659 #if defined(__amd64)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
660 struct pcb *pcb = &lwp->lwp_pcb;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
661 int thisthread = lwptot(lwp) == curthread;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
662
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
663 if (datamodel == DATAMODEL_NATIVE) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
664
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
665 if (thisthread)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
666 (void) save_syscall_args(); /* copy the args */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
667
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
668 rp->r_rdi = grp[REG_RDI];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
669 rp->r_rsi = grp[REG_RSI];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
670 rp->r_rdx = grp[REG_RDX];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
671 rp->r_rcx = grp[REG_RCX];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
672 rp->r_r8 = grp[REG_R8];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
673 rp->r_r9 = grp[REG_R9];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
674 rp->r_rax = grp[REG_RAX];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
675 rp->r_rbx = grp[REG_RBX];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
676 rp->r_rbp = grp[REG_RBP];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
677 rp->r_r10 = grp[REG_R10];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
678 rp->r_r11 = grp[REG_R11];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
679 rp->r_r12 = grp[REG_R12];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
680 rp->r_r13 = grp[REG_R13];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
681 rp->r_r14 = grp[REG_R14];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
682 rp->r_r15 = grp[REG_R15];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
683 rp->r_trapno = grp[REG_TRAPNO];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
684 rp->r_err = grp[REG_ERR];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
685 rp->r_rip = grp[REG_RIP];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
686 /*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
687 * Setting %cs or %ss to anything else is quietly but
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
688 * quite definitely forbidden!
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
689 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
690 rp->r_cs = UCS_SEL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
691 rp->r_ss = UDS_SEL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
692 rp->r_rsp = grp[REG_RSP];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
693
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
694 if (thisthread)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
695 kpreempt_disable();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
696
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
697 pcb->pcb_ds = UDS_SEL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
698 pcb->pcb_es = UDS_SEL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
699
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
700 /*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
701 * 64-bit processes -are- allowed to set their fsbase/gsbase
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
702 * values directly, but only if they're using the segment
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
703 * selectors that allow that semantic.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
704 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
705 * (32-bit processes must use lwp_set_private().)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
706 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
707 pcb->pcb_fsbase = grp[REG_FSBASE];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
708 pcb->pcb_gsbase = grp[REG_GSBASE];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
709 pcb->pcb_fs = fix_segreg(grp[REG_FS], datamodel);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
710 pcb->pcb_gs = fix_segreg(grp[REG_GS], datamodel);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
711
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
712 /*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
713 * Ensure that we go out via update_sregs
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
714 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
715 pcb->pcb_flags |= RUPDATE_PENDING;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
716 lwptot(lwp)->t_post_sys = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
717 if (thisthread)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
718 kpreempt_enable();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
719 #if defined(_SYSCALL32_IMPL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
720 } else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
721 rp->r_rdi = (uint32_t)grp[REG_RDI];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
722 rp->r_rsi = (uint32_t)grp[REG_RSI];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
723 rp->r_rdx = (uint32_t)grp[REG_RDX];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
724 rp->r_rcx = (uint32_t)grp[REG_RCX];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
725 rp->r_rax = (uint32_t)grp[REG_RAX];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
726 rp->r_rbx = (uint32_t)grp[REG_RBX];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
727 rp->r_rbp = (uint32_t)grp[REG_RBP];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
728 rp->r_trapno = (uint32_t)grp[REG_TRAPNO];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
729 rp->r_err = (uint32_t)grp[REG_ERR];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
730 rp->r_rip = (uint32_t)grp[REG_RIP];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
731
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
732 /*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
733 * The kernel uses %cs to determine if it is dealing with
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
734 * another part of the kernel or with a userland application.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
735 * Specifically, it tests the privilege bits. For this reason,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
736 * we must prevent user apps from ending up with a NULL selector
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
737 * in %cs. Instead, we'll use index 0 into the GDT but with the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
738 * privilege bits set to usermode.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
739 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
740 rp->r_cs = fix_segreg(grp[REG_CS], datamodel) | SEL_UPL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
741 rp->r_ss = fix_segreg(grp[REG_DS], datamodel);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
742
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
743 rp->r_rsp = (uint32_t)grp[REG_RSP];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
744
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
745 if (thisthread)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
746 kpreempt_disable();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
747
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
748 pcb->pcb_ds = fix_segreg(grp[REG_DS], datamodel);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
749 pcb->pcb_es = fix_segreg(grp[REG_ES], datamodel);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
750
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
751 /*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
752 * (See fsbase/gsbase commentary above)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
753 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
754 pcb->pcb_fs = fix_segreg(grp[REG_FS], datamodel);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
755 pcb->pcb_gs = fix_segreg(grp[REG_GS], datamodel);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
756
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
757 /*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
758 * Ensure that we go out via update_sregs
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
759 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
760 pcb->pcb_flags |= RUPDATE_PENDING;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
761 lwptot(lwp)->t_post_sys = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
762 if (thisthread)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
763 kpreempt_enable();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
764 #endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
765 }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
766
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
767 /*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
768 * Only certain bits of the flags register can be modified.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
769 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
770 rp->r_rfl = (rp->r_rfl & ~PSL_USERMASK) |
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
771 (grp[REG_RFL] & PSL_USERMASK);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
772
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
773 #elif defined(__i386)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
774
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
775 /*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
776 * Only certain bits of the flags register can be modified.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
777 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
778 grp[EFL] = (rp->r_efl & ~PSL_USERMASK) | (grp[EFL] & PSL_USERMASK);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
779
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
780 /*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
781 * Copy saved registers from user stack.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
782 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
783 bcopy(grp, &rp->r_gs, sizeof (gregset_t));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
784
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
785 rp->r_cs = fix_segreg(rp->r_cs, datamodel);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
786 rp->r_ss = fix_segreg(rp->r_ss, datamodel);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
787 rp->r_ds = fix_segreg(rp->r_ds, datamodel);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
788 rp->r_es = fix_segreg(rp->r_es, datamodel);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
789 rp->r_fs = fix_segreg(rp->r_fs, datamodel);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
790 rp->r_gs = fix_segreg(rp->r_gs, datamodel);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
791
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
792 #endif /* __i386 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
793 }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
794
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
795 /*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
796 * Determine whether eip is likely to have an interrupt frame
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
797 * on the stack. We do this by comparing the address to the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
798 * range of addresses spanned by several well-known routines.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
799 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
800 extern void _interrupt();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
801 extern void _allsyscalls();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
802 extern void _cmntrap();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
803 extern void fakesoftint();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
804
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
805 extern size_t _interrupt_size;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
806 extern size_t _allsyscalls_size;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
807 extern size_t _cmntrap_size;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
808 extern size_t _fakesoftint_size;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
809
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
810 /*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
811 * Get a pc-only stacktrace. Used for kmem_alloc() buffer ownership tracking.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
812 * Returns MIN(current stack depth, pcstack_limit).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
813 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
814 int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
815 getpcstack(pc_t *pcstack, int pcstack_limit)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
816 {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
817 struct frame *fp = (struct frame *)getfp();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
818 struct frame *nextfp, *minfp, *stacktop;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
819 int depth = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
820 int on_intr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
821 uintptr_t pc;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
822
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
823 if ((on_intr = CPU_ON_INTR(CPU)) != 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
824 stacktop = (struct frame *)(CPU->cpu_intr_stack + SA(MINFRAME));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
825 else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
826 stacktop = (struct frame *)curthread->t_stk;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
827 minfp = fp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
828
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
829 pc = ((struct regs *)fp)->r_pc;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
830
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
831 while (depth < pcstack_limit) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
832 nextfp = (struct frame *)fp->fr_savfp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
833 pc = fp->fr_savpc;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
834 if (nextfp <= minfp || nextfp >= stacktop) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
835 if (on_intr) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
836 /*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
837 * Hop from interrupt stack to thread stack.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
838 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
839 stacktop = (struct frame *)curthread->t_stk;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
840 minfp = (struct frame *)curthread->t_stkbase;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
841 on_intr = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
842 continue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
843 }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
844 break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
845 }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
846 pcstack[depth++] = (pc_t)pc;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
847 fp = nextfp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
848 minfp = fp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
849 }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
850 return (depth);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
851 }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
852
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
853 /*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
854 * The following ELF header fields are defined as processor-specific
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
855 * in the V8 ABI:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
856 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
857 * e_ident[EI_DATA] encoding of the processor-specific
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
858 * data in the object file
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
859 * e_machine processor identification
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
860 * e_flags processor-specific flags associated
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
861 * with the file
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
862 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
863
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
864 /*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
865 * The value of at_flags reflects a platform's cpu module support.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
866 * at_flags is used to check for allowing a binary to execute and
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
867 * is passed as the value of the AT_FLAGS auxiliary vector.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
868 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
869 int at_flags = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
870
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
871 /*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
872 * Check the processor-specific fields of an ELF header.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
873 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
874 * returns 1 if the fields are valid, 0 otherwise
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
875 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
876 /*ARGSUSED2*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
877 int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
878 elfheadcheck(
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
879 unsigned char e_data,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
880 Elf32_Half e_machine,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
881 Elf32_Word e_flags)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
882 {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
883 if (e_data != ELFDATA2LSB)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
884 return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
885 #if defined(__amd64)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
886 if (e_machine == EM_AMD64)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
887 return (1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
888 #endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
889 return (e_machine == EM_386);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
890 }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
891
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
892 uint_t auxv_hwcap_include = 0; /* patch to enable unrecognized features */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
893 uint_t auxv_hwcap_exclude = 0; /* patch for broken cpus, debugging */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
894 #if defined(_SYSCALL32_IMPL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
895 uint_t auxv_hwcap32_include = 0; /* ditto for 32-bit apps */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
896 uint_t auxv_hwcap32_exclude = 0; /* ditto for 32-bit apps */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
897 #endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
898
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
899 /*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
900 * Gather information about the processor and place it into auxv_hwcap
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
901 * so that it can be exported to the linker via the aux vector.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
902 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
903 * We use this seemingly complicated mechanism so that we can ensure
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
904 * that /etc/system can be used to override what the system can or
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
905 * cannot discover for itself.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
906 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
907 void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
908 bind_hwcap(void)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
909 {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
910 uint_t cpu_hwcap_flags = cpuid_pass4(NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
911
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
912 auxv_hwcap = (auxv_hwcap_include | cpu_hwcap_flags) &
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
913 ~auxv_hwcap_exclude;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
914
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
915 #if defined(__amd64)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
916 /*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
917 * On AMD processors, sysenter just doesn't work at all
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
918 * when the kernel is in long mode. On IA-32e processors
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
919 * it does, but there's no real point in all the alternate
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
920 * mechanism when syscall works on both.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
921 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
922 * Besides, the kernel's sysenter handler is expecting a
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
923 * 32-bit lwp ...
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
924 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
925 auxv_hwcap &= ~AV_386_SEP;
3446
5903aece022d PSARC 2006/469 EOF and removal of eeprom -I
mrj
parents: 2712
diff changeset
926 #else
5903aece022d PSARC 2006/469 EOF and removal of eeprom -I
mrj
parents: 2712
diff changeset
927 /*
5903aece022d PSARC 2006/469 EOF and removal of eeprom -I
mrj
parents: 2712
diff changeset
928 * 32-bit processes can -always- use the lahf/sahf instructions
5903aece022d PSARC 2006/469 EOF and removal of eeprom -I
mrj
parents: 2712
diff changeset
929 */
5903aece022d PSARC 2006/469 EOF and removal of eeprom -I
mrj
parents: 2712
diff changeset
930 auxv_hwcap |= AV_386_AHF;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
931 #endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
932
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
933 if (auxv_hwcap_include || auxv_hwcap_exclude)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
934 cmn_err(CE_CONT, "?user ABI extensions: %b\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
935 auxv_hwcap, FMT_AV_386);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
936
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
937 #if defined(_SYSCALL32_IMPL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
938 auxv_hwcap32 = (auxv_hwcap32_include | cpu_hwcap_flags) &
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
939 ~auxv_hwcap32_exclude;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
940
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
941 #if defined(__amd64)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
942 /*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
943 * If this is an amd64 architecture machine from Intel, then
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
944 * syscall -doesn't- work in compatibility mode, only sysenter does.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
945 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
946 * Sigh.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
947 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
948 if (!cpuid_syscall32_insn(NULL))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
949 auxv_hwcap32 &= ~AV_386_AMD_SYSC;
3446
5903aece022d PSARC 2006/469 EOF and removal of eeprom -I
mrj
parents: 2712
diff changeset
950
5903aece022d PSARC 2006/469 EOF and removal of eeprom -I
mrj
parents: 2712
diff changeset
951 /*
5903aece022d PSARC 2006/469 EOF and removal of eeprom -I
mrj
parents: 2712
diff changeset
952 * 32-bit processes can -always- use the lahf/sahf instructions
5903aece022d PSARC 2006/469 EOF and removal of eeprom -I
mrj
parents: 2712
diff changeset
953 */
5903aece022d PSARC 2006/469 EOF and removal of eeprom -I
mrj
parents: 2712
diff changeset
954 auxv_hwcap32 |= AV_386_AHF;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
955 #endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
956
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
957 if (auxv_hwcap32_include || auxv_hwcap32_exclude)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
958 cmn_err(CE_CONT, "?32-bit user ABI extensions: %b\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
959 auxv_hwcap32, FMT_AV_386);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
960 #endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
961 }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
962
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
963 /*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
964 * sync_icache() - this is called
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
965 * in proc/fs/prusrio.c. x86 has an unified cache and therefore
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
966 * this is a nop.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
967 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
968 /* ARGSUSED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
969 void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
970 sync_icache(caddr_t addr, uint_t len)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
971 {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
972 /* Do nothing for now */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
973 }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
974
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
975 /*ARGSUSED*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
976 void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
977 sync_data_memory(caddr_t va, size_t len)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
978 {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
979 /* Not implemented for this platform */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
980 }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
981
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
982 int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
983 __ipltospl(int ipl)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
984 {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
985 return (ipltospl(ipl));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
986 }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
987
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
988 /*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
989 * The panic code invokes panic_saveregs() to record the contents of a
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
990 * regs structure into the specified panic_data structure for debuggers.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
991 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
992 void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
993 panic_saveregs(panic_data_t *pdp, struct regs *rp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
994 {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
995 panic_nv_t *pnv = PANICNVGET(pdp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
996
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
997 struct cregs creg;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
998
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
999 getcregs(&creg);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1000
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1001 #if defined(__amd64)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1002 PANICNVADD(pnv, "rdi", rp->r_rdi);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1003 PANICNVADD(pnv, "rsi", rp->r_rsi);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1004 PANICNVADD(pnv, "rdx", rp->r_rdx);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1005 PANICNVADD(pnv, "rcx", rp->r_rcx);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1006 PANICNVADD(pnv, "r8", rp->r_r8);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1007 PANICNVADD(pnv, "r9", rp->r_r9);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1008 PANICNVADD(pnv, "rax", rp->r_rax);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1009 PANICNVADD(pnv, "rbx", rp->r_rbx);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1010 PANICNVADD(pnv, "rbp", rp->r_rbp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1011 PANICNVADD(pnv, "r10", rp->r_r10);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1012 PANICNVADD(pnv, "r10", rp->r_r10);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1013 PANICNVADD(pnv, "r11", rp->r_r11);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1014 PANICNVADD(pnv, "r12", rp->r_r12);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1015 PANICNVADD(pnv, "r13", rp->r_r13);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1016 PANICNVADD(pnv, "r14", rp->r_r14);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1017 PANICNVADD(pnv, "r15", rp->r_r15);
3446
5903aece022d PSARC 2006/469 EOF and removal of eeprom -I
mrj
parents: 2712
diff changeset
1018 PANICNVADD(pnv, "fsbase", rdmsr(MSR_AMD_FSBASE));
5903aece022d PSARC 2006/469 EOF and removal of eeprom -I
mrj
parents: 2712
diff changeset
1019 PANICNVADD(pnv, "gsbase", rdmsr(MSR_AMD_GSBASE));
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1020 PANICNVADD(pnv, "ds", rp->r_ds);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1021 PANICNVADD(pnv, "es", rp->r_es);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1022 PANICNVADD(pnv, "fs", rp->r_fs);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1023 PANICNVADD(pnv, "gs", rp->r_gs);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1024 PANICNVADD(pnv, "trapno", rp->r_trapno);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1025 PANICNVADD(pnv, "err", rp->r_err);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1026 PANICNVADD(pnv, "rip", rp->r_rip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1027 PANICNVADD(pnv, "cs", rp->r_cs);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1028 PANICNVADD(pnv, "rflags", rp->r_rfl);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1029 PANICNVADD(pnv, "rsp", rp->r_rsp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1030 PANICNVADD(pnv, "ss", rp->r_ss);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1031 PANICNVADD(pnv, "gdt_hi", (uint64_t)(creg.cr_gdt._l[3]));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1032 PANICNVADD(pnv, "gdt_lo", (uint64_t)(creg.cr_gdt._l[0]));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1033 PANICNVADD(pnv, "idt_hi", (uint64_t)(creg.cr_idt._l[3]));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1034 PANICNVADD(pnv, "idt_lo", (uint64_t)(creg.cr_idt._l[0]));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1035 #elif defined(__i386)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1036 PANICNVADD(pnv, "gs", (uint32_t)rp->r_gs);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1037 PANICNVADD(pnv, "fs", (uint32_t)rp->r_fs);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1038 PANICNVADD(pnv, "es", (uint32_t)rp->r_es);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1039 PANICNVADD(pnv, "ds", (uint32_t)rp->r_ds);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1040 PANICNVADD(pnv, "edi", (uint32_t)rp->r_edi);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1041 PANICNVADD(pnv, "esi", (uint32_t)rp->r_esi);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1042 PANICNVADD(pnv, "ebp", (uint32_t)rp->r_ebp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1043 PANICNVADD(pnv, "esp", (uint32_t)rp->r_esp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1044 PANICNVADD(pnv, "ebx", (uint32_t)rp->r_ebx);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1045 PANICNVADD(pnv, "edx", (uint32_t)rp->r_edx);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1046 PANICNVADD(pnv, "ecx", (uint32_t)rp->r_ecx);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1047 PANICNVADD(pnv, "eax", (uint32_t)rp->r_eax);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1048 PANICNVADD(pnv, "trapno", (uint32_t)rp->r_trapno);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1049 PANICNVADD(pnv, "err", (uint32_t)rp->r_err);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1050 PANICNVADD(pnv, "eip", (uint32_t)rp->r_eip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1051 PANICNVADD(pnv, "cs", (uint32_t)rp->r_cs);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1052 PANICNVADD(pnv, "eflags", (uint32_t)rp->r_efl);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1053 PANICNVADD(pnv, "uesp", (uint32_t)rp->r_uesp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1054 PANICNVADD(pnv, "ss", (uint32_t)rp->r_ss);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1055 PANICNVADD(pnv, "gdt", creg.cr_gdt);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1056 PANICNVADD(pnv, "idt", creg.cr_idt);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1057 #endif /* __i386 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1058
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1059 PANICNVADD(pnv, "ldt", creg.cr_ldt);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1060 PANICNVADD(pnv, "task", creg.cr_task);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1061 PANICNVADD(pnv, "cr0", creg.cr_cr0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1062 PANICNVADD(pnv, "cr2", creg.cr_cr2);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1063 PANICNVADD(pnv, "cr3", creg.cr_cr3);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1064 if (creg.cr_cr4)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1065 PANICNVADD(pnv, "cr4", creg.cr_cr4);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1066
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1067 PANICNVSET(pdp, pnv);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1068 }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1069
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1070 #define TR_ARG_MAX 6 /* Max args to print, same as SPARC */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1071
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1072 #if !defined(__amd64)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1073
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1074 /*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1075 * Given a return address (%eip), determine the likely number of arguments
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1076 * that were pushed on the stack prior to its execution. We do this by
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1077 * expecting that a typical call sequence consists of pushing arguments on
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1078 * the stack, executing a call instruction, and then performing an add
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1079 * on %esp to restore it to the value prior to pushing the arguments for
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1080 * the call. We attempt to detect such an add, and divide the addend
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1081 * by the size of a word to determine the number of pushed arguments.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1082 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1083 * If we do not find such an add, we punt and return TR_ARG_MAX. It is not
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1084 * possible to reliably determine if a function took no arguments (i.e. was
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1085 * void) because assembler routines do not reliably perform an add on %esp
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1086 * immediately upon returning (eg. _sys_call()), so returning TR_ARG_MAX is
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1087 * safer than returning 0.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1088 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1089 static ulong_t
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1090 argcount(uintptr_t eip)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1091 {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1092 const uint8_t *ins = (const uint8_t *)eip;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1093 ulong_t n;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1094
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1095 enum {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1096 M_MODRM_ESP = 0xc4, /* Mod/RM byte indicates %esp */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1097 M_ADD_IMM32 = 0x81, /* ADD imm32 to r/m32 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1098 M_ADD_IMM8 = 0x83 /* ADD imm8 to r/m32 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1099 };
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1100
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1101 if (eip < KERNELBASE || ins[1] != M_MODRM_ESP)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1102 return (TR_ARG_MAX);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1103
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1104 switch (ins[0]) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1105 case M_ADD_IMM32:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1106 n = ins[2] + (ins[3] << 8) + (ins[4] << 16) + (ins[5] << 24);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1107 break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1108
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1109 case M_ADD_IMM8:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1110 n = ins[2];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1111 break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1112
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1113 default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1114 return (TR_ARG_MAX);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1115 }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1116
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1117 n /= sizeof (long);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1118 return (MIN(n, TR_ARG_MAX));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1119 }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1120
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1121 #endif /* !__amd64 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1122
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1123 /*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1124 * Print a stack backtrace using the specified frame pointer. We delay two
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1125 * seconds before continuing, unless this is the panic traceback. Note
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1126 * that the frame for the starting stack pointer value is omitted because
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1127 * the corresponding %eip is not known.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1128 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1129 #if defined(__amd64)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1130
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1131 void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1132 traceback(caddr_t fpreg)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1133 {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1134 struct frame *fp = (struct frame *)fpreg;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1135 struct frame *nextfp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1136 uintptr_t pc, nextpc;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1137 ulong_t off;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1138 char args[TR_ARG_MAX * 2 + 16], *sym;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1139
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1140 if (!panicstr)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1141 printf("traceback: %%fp = %p\n", (void *)fp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1142
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1143 if ((uintptr_t)fp < KERNELBASE)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1144 goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1145
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1146 pc = fp->fr_savpc;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1147 fp = (struct frame *)fp->fr_savfp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1148
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1149 while ((uintptr_t)fp >= KERNELBASE) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1150 /*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1151 * XX64 Until port is complete tolerate 8-byte aligned
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1152 * frame pointers but flag with a warning so they can
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1153 * be fixed.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1154 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1155 if (((uintptr_t)fp & (STACK_ALIGN - 1)) != 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1156 if (((uintptr_t)fp & (8 - 1)) == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1157 printf(" >> warning! 8-byte"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1158 " aligned %%fp = %p\n", (void *)fp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1159 } else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1160 printf(
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1161 " >> mis-aligned %%fp = %p\n", (void *)fp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1162 break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1163 }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1164 }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1165
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1166 args[0] = '\0';
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1167 nextpc = (uintptr_t)fp->fr_savpc;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1168 nextfp = (struct frame *)fp->fr_savfp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1169 if ((sym = kobj_getsymname(pc, &off)) != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1170 printf("%016lx %s:%s+%lx (%s)\n", (uintptr_t)fp,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1171 mod_containing_pc((caddr_t)pc), sym, off, args);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1172 } else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1173 printf("%016lx %lx (%s)\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1174 (uintptr_t)fp, pc, args);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1175 }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1176
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1177 pc = nextpc;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1178 fp = nextfp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1179 }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1180 out:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1181 if (!panicstr) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1182 printf("end of traceback\n");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1183 DELAY(2 * MICROSEC);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1184 }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1185 }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1186
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1187 #elif defined(__i386)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1188
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1189 void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1190 traceback(caddr_t fpreg)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1191 {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1192 struct frame *fp = (struct frame *)fpreg;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1193 struct frame *nextfp, *minfp, *stacktop;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1194 uintptr_t pc, nextpc;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1195
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1196 cpu_t *cpu;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1197
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1198 /*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1199 * args[] holds TR_ARG_MAX hex long args, plus ", " or '\0'.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1200 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1201 char args[TR_ARG_MAX * 2 + 8], *p;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1202
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1203 int on_intr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1204 ulong_t off;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1205 char *sym;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1206
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1207 if (!panicstr)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1208 printf("traceback: %%fp = %p\n", (void *)fp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1209
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1210 /*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1211 * If we are panicking, all high-level interrupt information in
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1212 * CPU was overwritten. panic_cpu has the correct values.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1213 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1214 kpreempt_disable(); /* prevent migration */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1215
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1216 cpu = (panicstr && CPU->cpu_id == panic_cpu.cpu_id)? &panic_cpu : CPU;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1217
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1218 if ((on_intr = CPU_ON_INTR(cpu)) != 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1219 stacktop = (struct frame *)(cpu->cpu_intr_stack + SA(MINFRAME));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1220 else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1221 stacktop = (struct frame *)curthread->t_stk;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1222
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1223 kpreempt_enable();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1224
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1225 if ((uintptr_t)fp < KERNELBASE)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1226 goto out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1227
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1228 minfp = fp; /* Baseline minimum frame pointer */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1229 pc = fp->fr_savpc;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1230 fp = (struct frame *)fp->fr_savfp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1231
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1232 while ((uintptr_t)fp >= KERNELBASE) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1233 ulong_t argc;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1234 long *argv;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1235
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1236 if (fp <= minfp || fp >= stacktop) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1237 if (on_intr) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1238 /*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1239 * Hop from interrupt stack to thread stack.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1240 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1241 stacktop = (struct frame *)curthread->t_stk;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1242 minfp = (struct frame *)curthread->t_stkbase;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1243 on_intr = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1244 continue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1245 }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1246 break; /* we're outside of the expected range */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1247 }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1248
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1249 if ((uintptr_t)fp & (STACK_ALIGN - 1)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1250 printf(" >> mis-aligned %%fp = %p\n", (void *)fp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1251 break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1252 }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1253
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1254 nextpc = fp->fr_savpc;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1255 nextfp = (struct frame *)fp->fr_savfp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1256 argc = argcount(nextpc);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1257 argv = (long *)((char *)fp + sizeof (struct frame));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1258
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1259 args[0] = '\0';
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1260 p = args;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1261 while (argc-- > 0 && argv < (long *)stacktop) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1262 p += snprintf(p, args + sizeof (args) - p,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1263 "%s%lx", (p == args) ? "" : ", ", *argv++);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1264 }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1265
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1266 if ((sym = kobj_getsymname(pc, &off)) != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1267 printf("%08lx %s:%s+%lx (%s)\n", (uintptr_t)fp,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1268 mod_containing_pc((caddr_t)pc), sym, off, args);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1269 } else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1270 printf("%08lx %lx (%s)\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1271 (uintptr_t)fp, pc, args);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1272 }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1273
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1274 minfp = fp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1275 pc = nextpc;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1276 fp = nextfp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1277 }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1278 out:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1279 if (!panicstr) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1280 printf("end of traceback\n");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1281 DELAY(2 * MICROSEC);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1282 }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1283 }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1284
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1285 #endif /* __i386 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1286
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1287 /*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1288 * Generate a stack backtrace from a saved register set.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1289 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1290 void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1291 traceregs(struct regs *rp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1292 {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1293 traceback((caddr_t)rp->r_fp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1294 }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1295
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1296 void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1297 exec_set_sp(size_t stksize)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1298 {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1299 klwp_t *lwp = ttolwp(curthread);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1300
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1301 lwptoregs(lwp)->r_sp = (uintptr_t)curproc->p_usrstack - stksize;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1302 }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1303
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1304 hrtime_t
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1305 gethrtime_waitfree(void)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1306 {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1307 return (dtrace_gethrtime());
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1308 }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1309
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1310 hrtime_t
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1311 gethrtime(void)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1312 {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1313 return (gethrtimef());
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1314 }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1315
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1316 hrtime_t
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1317 gethrtime_unscaled(void)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1318 {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1319 return (gethrtimeunscaledf());
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1320 }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1321
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1322 void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1323 scalehrtime(hrtime_t *hrt)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1324 {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1325 scalehrtimef(hrt);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1326 }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1327
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1328 void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1329 gethrestime(timespec_t *tp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1330 {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1331 gethrestimef(tp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1332 }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1333
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1334 #if defined(__amd64)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1335 /*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1336 * Part of the implementation of hres_tick(); this routine is
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1337 * easier in C than assembler .. called with the hres_lock held.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1338 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1339 * XX64 Many of these timekeeping variables need to be extern'ed in a header
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1340 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1341
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1342 #include <sys/time.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1343 #include <sys/machlock.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1344
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1345 extern int one_sec;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1346 extern timestruc_t hrestime;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1347 extern int max_hres_adj;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1348
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1349 void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1350 __adj_hrestime(void)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1351 {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1352 long long adj;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1353
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1354 if (hrestime_adj == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1355 adj = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1356 else if (hrestime_adj > 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1357 if (hrestime_adj < max_hres_adj)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1358 adj = hrestime_adj;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1359 else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1360 adj = max_hres_adj;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1361 } else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1362 if (hrestime_adj < -max_hres_adj)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1363 adj = -max_hres_adj;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1364 else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1365 adj = hrestime_adj;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1366 }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1367
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1368 timedelta -= adj;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1369 hrestime_adj = timedelta;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1370 hrestime.tv_nsec += adj;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1371
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1372 while (hrestime.tv_nsec >= NANOSEC) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1373 one_sec++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1374 hrestime.tv_sec++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1375 hrestime.tv_nsec -= NANOSEC;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1376 }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1377 }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1378 #endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1379
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1380 /*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1381 * Wrapper functions to maintain backwards compability
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1382 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1383 int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1384 xcopyin(const void *uaddr, void *kaddr, size_t count)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1385 {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1386 return (xcopyin_nta(uaddr, kaddr, count, UIO_COPY_CACHED));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1387 }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1388
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1389 int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1390 xcopyout(const void *kaddr, void *uaddr, size_t count)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1391 {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1392 return (xcopyout_nta(kaddr, uaddr, count, UIO_COPY_CACHED));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
1393 }