Merge remote-tracking branch 'origin/master'
[unleashed/lotheac.git] / usr / src / uts / intel / brand / common / brand_solaris.s
blobaa1e222f2d8288cada1a11950c432c44992f30d1
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
19 * CDDL HEADER END
22 * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
26 * This is an assembly file that gets #include-ed into the brand-specific
27 * assembly files (e.g. sn1_brand_asm.s) for Solaris-derived brands.
28 * We can't make these into functions since in the trap context there's
29 * no easy place to save the extra parameters that would be required, so
30 * each brand module needs its own copy of this code. We #include this and
31 * use brand-specific #defines to replace the XXX_brand_... definitions.
32 */
35 #include <sys/asm_linkage.h>
36 #include <sys/privregs.h>
37 #include <sys/segments.h>
38 #include "assym.h"
39 #include "brand_asm.h"
43 #ifdef _ASM /* The remainder of this file is only for assembly files */
45 #if defined(__amd64)
48 * syscall handler for 32-bit user processes:
49 * See "64-BIT INTERPOSITION STACK" in brand_asm.h.
50 * To 'return' to our user-space handler, we just need to place its address
51 * into %rcx. The original return address is passed back in SYSCALL_REG.
53 ENTRY(XXX_brand_syscall32_callback)
54 CALLBACK_PROLOGUE(XXX_emulation_table, SPD_HANDLER, SYSCALL_REG,
55 SCR_REG, SCR_REGB);
56 CALC_TABLE_ADDR(SCR_REG, SPD_HANDLER);
57 mov %rcx, SYSCALL_REG; /* save orig return addr in syscall_reg */
58 mov SCR_REG, %rcx; /* place new return addr in %rcx */
59 mov %gs:CPU_RTMP_R15, SCR_REG; /* restore scratch register */
60 mov V_SSP(SP_REG), SP_REG /* restore user stack pointer */
61 jmp nopop_sys_syscall32_swapgs_sysretl
63 retq
64 SET_SIZE(XXX_brand_syscall32_callback)
67 * syscall handler for 64-bit user processes:
68 * See "64-BIT INTERPOSITION STACK" in brand_asm.h.
69 * To 'return' to our user-space handler, we just need to place its address
70 * into %rcx. The original return address is passed back in SYSCALL_REG.
72 ENTRY(XXX_brand_syscall_callback)
73 CALLBACK_PROLOGUE(XXX_emulation_table, SPD_HANDLER, SYSCALL_REG,
74 SCR_REG, SCR_REGB);
75 CALC_TABLE_ADDR(SCR_REG, SPD_HANDLER);
76 mov %rcx, SYSCALL_REG; /* save orig return addr in syscall_reg */
77 mov SCR_REG, %rcx; /* place new return addr in %rcx */
78 mov %gs:CPU_RTMP_R15, SCR_REG; /* restore scratch register */
79 mov V_SSP(SP_REG), SP_REG /* restore user stack pointer */
80 jmp nopop_sys_syscall_swapgs_sysretq
82 retq
83 SET_SIZE(XXX_brand_syscall_callback)
86 * See "64-BIT INTERPOSITION STACK" in brand_asm.h.
87 * To 'return' to our user-space handler, we just need to place its address
88 * into %rdx. The original return address is passed back in SYSCALL_REG.
90 ENTRY(XXX_brand_sysenter_callback)
91 CALLBACK_PROLOGUE(XXX_emulation_table, SPD_HANDLER, SYSCALL_REG,
92 SCR_REG, SCR_REGB);
93 CALC_TABLE_ADDR(SCR_REG, SPD_HANDLER);
94 mov %rdx, SYSCALL_REG; /* save orig return addr in syscall_reg */
95 mov SCR_REG, %rdx; /* place new return addr in %rdx */
96 mov %gs:CPU_RTMP_R15, SCR_REG; /* restore scratch register */
97 mov V_SSP(SP_REG), SP_REG /* restore user stack pointer */
98 jmp sys_sysenter_swapgs_sysexit
101 SET_SIZE(XXX_brand_sysenter_callback)
104 * To 'return' to our user-space handler we need to update the user's %eip
105 * pointer in the saved interrupt state on the stack. The interrupt state was
106 * pushed onto our stack automatically when the interrupt occured; see the
107 * comments above. The original return address is passed back in SYSCALL_REG.
108 * See "64-BIT INTERPOSITION STACK" and "64-BIT INT STACK" in brand_asm.h.
110 ENTRY(XXX_brand_int91_callback)
111 CALLBACK_PROLOGUE(XXX_emulation_table, SPD_HANDLER, SYSCALL_REG,
112 SCR_REG, SCR_REGB);
113 CALC_TABLE_ADDR(SCR_REG, SPD_HANDLER); /* new ret addr is in scratch */
114 mov SCR_REG, SYSCALL_REG; /* place new ret addr in syscallreg */
115 mov %gs:CPU_RTMP_R15, SCR_REG; /* restore scratch register */
116 mov V_SSP(SP_REG), SP_REG; /* restore intr stack pointer */
117 /*CSTYLED*/
118 xchg (SP_REG), SYSCALL_REG /* swap new and orig. return addrs */
119 jmp sys_sysint_swapgs_iret
121 retq
122 SET_SIZE(XXX_brand_int91_callback)
124 #else /* !__amd64 */
127 * To 'return' to our user-space handler, we need to replace the iret target
128 * address. The original return address is passed back in %eax.
129 * See "32-BIT INTERPOSITION STACK" and "32-BIT INT STACK" in brand_asm.h.
131 ENTRY(XXX_brand_syscall_callback)
132 CALLBACK_PROLOGUE(XXX_emulation_table, SPD_HANDLER, SYSCALL_REG,
133 SCR_REG, SCR_REGB);
134 CALC_TABLE_ADDR(SCR_REG, SPD_HANDLER); /* new ret addr is in scratch */
135 mov SCR_REG, SYSCALL_REG; /* place new ret addr in syscallreg */
136 GET_V(SP_REG, 0, V_U_EBX, SCR_REG); /* restore scratch register */
137 add $V_END, SP_REG; /* restore intr stack pointer */
138 /*CSTYLED*/
139 xchg (SP_REG), SYSCALL_REG /* swap new and orig. return addrs */
140 jmp nopop_sys_rtt_syscall
143 SET_SIZE(XXX_brand_syscall_callback)
146 * To 'return' to our user-space handler, we just need to place its address
147 * into %edx. The original return address is passed back in SYSCALL_REG.
148 * See "32-BIT INTERPOSITION STACK" in brand_asm.h.
150 ENTRY(XXX_brand_sysenter_callback)
151 CALLBACK_PROLOGUE(XXX_emulation_table, SPD_HANDLER, SYSCALL_REG,
152 SCR_REG, SCR_REGB);
153 mov %edx, SCR_REG; /* save orig return addr in scr reg */
154 CALC_TABLE_ADDR(%edx, SPD_HANDLER); /* new return addr is in %edx */
155 mov SCR_REG, SYSCALL_REG; /* save orig return addr in %eax */
156 GET_V(SP_REG, 0, V_U_EBX, SCR_REG) /* restore scratch register */
157 sysexit
160 SET_SIZE(XXX_brand_sysenter_callback)
162 #endif /* !__amd64 */
163 #endif /* _ASM */