Changes in kernel/arch/ia32/src/asm.S [ed7998b:22c3444] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/arch/ia32/src/asm.S
red7998b r22c3444 164 164 .endm 165 165 166 #define ISTATE_OFFSET_EDX 0 167 #define ISTATE_OFFSET_ECX 4 168 #define ISTATE_OFFSET_EBX 8 169 #define ISTATE_OFFSET_ESI 12 170 #define ISTATE_OFFSET_EDI 16 171 #define ISTATE_OFFSET_EBP 20 172 #define ISTATE_OFFSET_EAX 24 166 /* 167 * The SYSENTER syscall mechanism can be used for syscalls with 168 * four or fewer arguments. To pass these four arguments, we 169 * use four registers: EDX, ECX, EBX, ESI. The syscall number 170 * is passed in EAX. We use EDI to remember the return address 171 * and EBP to remember the stack. The INT-based syscall mechanism 172 * can actually handle six arguments plus the syscall number 173 * entirely in registers. 174 */ 175 .global sysenter_handler 176 sysenter_handler: 177 sti 178 pushl %ebp /* remember user stack */ 179 pushl %edi /* remember return user address */ 180 181 xorl %ebp, %ebp /* stop stack traces here */ 182 183 pushl %gs /* remember TLS */ 184 185 pushl %eax /* syscall number */ 186 subl $8, %esp /* unused sixth and fifth argument */ 187 pushl %esi /* fourth argument */ 188 pushl %ebx /* third argument */ 189 pushl %ecx /* second argument */ 190 pushl %edx /* first argument */ 191 192 movw $16, %ax 193 movw %ax, %ds 194 movw %ax, %es 195 196 cld 197 call syscall_handler 198 addl $28, %esp /* remove arguments from stack */ 199 200 pop %gs /* restore TLS */ 201 202 pop %edx /* prepare return EIP for SYSEXIT */ 203 pop %ecx /* prepare userspace ESP for SYSEXIT */ 204 205 sysexit /* return to userspace */ 206 207 #define ISTATE_OFFSET_EAX 0 208 #define ISTATE_OFFSET_EBX 4 209 #define ISTATE_OFFSET_ECX 8 210 #define ISTATE_OFFSET_EDX 12 211 #define ISTATE_OFFSET_EDI 16 212 #define ISTATE_OFFSET_ESI 20 213 #define ISTATE_OFFSET_EBP 24 173 214 #define ISTATE_OFFSET_EBP_FRAME 28 174 215 #define ISTATE_OFFSET_EIP_FRAME 32 … … 190 231 #define ISTATE_SOFT_SIZE 52 191 232 192 /*193 * Size of the entire istate structure including the error word and the194 * hardware-saved part.195 */196 #define ISTATE_REAL_SIZE (ISTATE_SOFT_SIZE + 24)197 198 /*199 * The SYSENTER syscall mechanism can be used for syscalls with200 * four or fewer arguments. To pass these four arguments, we201 * use four registers: EDX, ECX, EBX, ESI. The syscall number202 * is passed in EAX. We use EDI to remember the return address203 * and EBP to remember the stack. The INT-based syscall mechanism204 * can actually handle six arguments plus the syscall number205 * entirely in registers.206 */207 .global sysenter_handler208 sysenter_handler:209 sti210 subl $(ISTATE_REAL_SIZE), %esp211 212 /*213 * Save the return address and the userspace stack in the istate214 * structure on locations that would normally be taken by them.215 */216 movl %ebp, ISTATE_OFFSET_ESP(%esp)217 movl %edi, ISTATE_OFFSET_EIP(%esp)218 219 /*220 * Push syscall arguments onto the stack221 */222 movl %eax, ISTATE_OFFSET_EAX(%esp)223 movl %ebx, ISTATE_OFFSET_EBX(%esp)224 movl %ecx, ISTATE_OFFSET_ECX(%esp)225 movl %edx, ISTATE_OFFSET_EDX(%esp)226 movl %esi, ISTATE_OFFSET_ESI(%esp)227 movl %edi, ISTATE_OFFSET_EDI(%esp) /* observability; not needed */228 movl %ebp, ISTATE_OFFSET_EBP(%esp) /* observability; not needed */229 230 /*231 * Fake up the stack trace linkage.232 */233 movl %edi, ISTATE_OFFSET_EIP_FRAME(%esp)234 movl $0, ISTATE_OFFSET_EBP_FRAME(%esp)235 leal ISTATE_OFFSET_EBP_FRAME(%esp), %ebp236 237 /*238 * Save TLS.239 */240 movl %gs, %edx241 movl %edx, ISTATE_OFFSET_GS(%esp)242 243 /*244 * Switch to kernel selectors.245 */246 movw $16, %ax247 movw %ax, %ds248 movw %ax, %es249 250 cld251 call syscall_handler252 253 /*254 * Restore TLS.255 */256 movl ISTATE_OFFSET_GS(%esp), %edx257 movl %edx, %gs258 259 /*260 * Prepare return address and userspace stack for SYSEXIT.261 */262 movl ISTATE_OFFSET_EIP(%esp), %edx263 movl ISTATE_OFFSET_ESP(%esp), %ecx264 265 addl $(ISTATE_REAL_SIZE), %esp266 267 sysexit /* return to userspace */268 269 233 /** Declare interrupt handlers 270 234 * … … 281 245 .ifeq \i - 0x30 282 246 /* Syscall handler */ 283 subl $(ISTATE_SOFT_SIZE + 4), %esp 284 247 pushl %ds 248 pushl %es 249 pushl %fs 250 pushl %gs 251 285 252 /* 286 253 * Push syscall arguments onto the stack … … 290 257 * first and preserved registers next. An optimized 291 258 * libc syscall wrapper can make use of this setup. 292 * The istate structure is arranged in the way to support293 * this idea.294 259 * 295 260 */ 296 movl %eax, ISTATE_OFFSET_EAX(%esp) 297 movl %ebx, ISTATE_OFFSET_EBX(%esp) 298 movl %ecx, ISTATE_OFFSET_ECX(%esp) 299 movl %edx, ISTATE_OFFSET_EDX(%esp) 300 movl %edi, ISTATE_OFFSET_EDI(%esp) 301 movl %esi, ISTATE_OFFSET_ESI(%esp) 302 movl %ebp, ISTATE_OFFSET_EBP(%esp) 303 304 /* 305 * Save the selector registers. 306 */ 307 movl %gs, %ecx 308 movl %fs, %edx 309 310 movl %ecx, ISTATE_OFFSET_GS(%esp) 311 movl %edx, ISTATE_OFFSET_FS(%esp) 312 313 movl %es, %ecx 314 movl %ds, %edx 315 316 movl %ecx, ISTATE_OFFSET_ES(%esp) 317 movl %edx, ISTATE_OFFSET_DS(%esp) 318 319 /* 320 * Switch to kernel selectors. 321 */ 322 movl $16, %eax 323 movl %eax, %ds 324 movl %eax, %es 325 326 movl $0, ISTATE_OFFSET_EBP_FRAME(%esp) 327 movl ISTATE_OFFSET_EIP(%esp), %eax 328 movl %eax, ISTATE_OFFSET_EIP_FRAME(%esp) 329 leal ISTATE_OFFSET_EBP_FRAME(%esp), %ebp 261 pushl %eax 262 pushl %ebp 263 pushl %edi 264 pushl %esi 265 pushl %ebx 266 pushl %ecx 267 pushl %edx 268 269 /* We must fill the data segment registers */ 270 movw $16, %ax 271 movw %ax, %ds 272 movw %ax, %es 273 274 xorl %ebp, %ebp 330 275 331 276 cld … … 334 279 /* Call syscall_handler(edx, ecx, ebx, esi, edi, ebp, eax) */ 335 280 call syscall_handler 336 281 cli 282 283 movl 20(%esp), %ebp /* restore EBP */ 284 addl $28, %esp /* clean-up of parameters */ 285 286 popl %gs 287 popl %fs 288 popl %es 289 popl %ds 290 337 291 CLEAR_NT_FLAG 338 339 /*340 * Restore the selector registers.341 */342 movl ISTATE_OFFSET_GS(%esp), %ecx343 movl ISTATE_OFFSET_FS(%esp), %edx344 345 movl %ecx, %gs346 movl %edx, %fs347 348 movl ISTATE_OFFSET_ES(%esp), %ecx349 movl ISTATE_OFFSET_DS(%esp), %edx350 351 movl %ecx, %es352 movl %edx, %ds353 354 /*355 * Restore the preserved registers the handler cloberred itself356 * (i.e. EBP).357 */358 movl ISTATE_OFFSET_EBP(%esp), %ebp359 360 addl $(ISTATE_SOFT_SIZE + 4), %esp361 292 iret 362 363 293 .else 364 294 /*
Note:
See TracChangeset
for help on using the changeset viewer.