Changeset 6473d41 in mainline
- Timestamp:
- 2010-06-29T20:19:09Z (15 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- c9eb31c2
- Parents:
- f56e897f
- Location:
- kernel/arch/ia32
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/arch/ia32/include/interrupt.h
rf56e897f r6473d41 72 72 typedef struct istate { 73 73 uint32_t eax; 74 uint32_t ebx; 74 75 uint32_t ecx; 75 76 uint32_t edx; 77 uint32_t edi; 78 uint32_t esi; 76 79 uint32_t ebp; 80 81 uint32_t ebp_frame; /* imitation of frame pointer linkage */ 82 uint32_t eip_frame; /* imitation of return address linkage */ 77 83 78 84 uint32_t gs; … … 81 87 uint32_t ds; 82 88 83 uint32_t error_word; 89 uint32_t error_word; /* real or fake error word */ 84 90 uint32_t eip; 85 91 uint32_t cs; 86 92 uint32_t eflags; 87 uint32_t stack[]; 93 uint32_t esp; /* only if istate_t is from uspace */ 94 uint32_t ss; /* only if istate_t is from uspace */ 88 95 } istate_t; 89 96 -
kernel/arch/ia32/src/asm.S
rf56e897f r6473d41 190 190 191 191 192 #define ISTATE_OFFSET_EAX 0 193 #define ISTATE_OFFSET_EBX 4 194 #define ISTATE_OFFSET_ECX 8 195 #define ISTATE_OFFSET_EDX 12 196 #define ISTATE_OFFSET_EDI 16 197 #define ISTATE_OFFSET_ESI 20 198 #define ISTATE_OFFSET_EBP 24 199 #define ISTATE_OFFSET_EBP_FRAME 28 200 #define ISTATE_OFFSET_EIP_FRAME 32 201 #define ISTATE_OFFSET_GS 36 202 #define ISTATE_OFFSET_FS 40 203 #define ISTATE_OFFSET_ES 44 204 #define ISTATE_OFFSET_DS 48 205 #define ISTATE_OFFSET_ERROR_WORD 52 206 #define ISTATE_OFFSET_EIP 56 207 #define ISTATE_OFFSET_CS 60 208 #define ISTATE_OFFSET_EFLAGS 64 209 #define ISTATE_OFFSET_ESP 68 210 #define ISTATE_OFFSET_SS 72 211 212 /* 213 * Size of the istate structure without the hardware-saved part and without the 214 * error word. 215 */ 216 #define ISTATE_SOFT_SIZE 52 217 192 218 ## Declare interrupt handlers 193 219 # … … 201 227 .macro handler i n 202 228 203 .ifeq \i - 0x30 # Syscall handler 204 pushl %ds 205 pushl %es 206 pushl %fs 207 pushl %gs 208 209 # 210 # Push syscall arguments onto the stack 211 # 212 # NOTE: The idea behind the order of arguments passed in registers is to 213 # use all scratch registers first and preserved registers next. 214 # An optimized libc syscall wrapper can make use of this setup. 215 # 216 pushl %eax 217 pushl %ebp 218 pushl %edi 219 pushl %esi 220 pushl %ebx 221 pushl %ecx 222 pushl %edx 223 224 # we must fill the data segment registers 225 movw $16, %ax 226 movw %ax, %ds 227 movw %ax, %es 228 229 xorl %ebp, %ebp 230 231 cld 232 sti 233 # syscall_handler(edx, ecx, ebx, esi, edi, ebp, eax) 234 call syscall_handler 235 cli 236 237 movl 20(%esp), %ebp # restore EBP 238 addl $28, %esp # clean-up of parameters 239 240 popl %gs 241 popl %fs 242 popl %es 243 popl %ds 244 245 CLEAR_NT_FLAG 246 iret 247 .else 248 /* 249 * This macro distinguishes between two versions of ia32 exceptions. 250 * One version has error word and the other does not have it. 251 * The latter version fakes the error word on the stack so that the 252 * handlers and istate_t can be the same for both types. 253 */ 254 .iflt \i - 32 255 .if (1 << \i) & ERROR_WORD_INTERRUPT_LIST 256 /* 257 * With error word, do nothing 258 */ 259 .else 260 /* 261 * Version without error word 262 */ 263 subl $4, %esp 264 .endif 265 .else 266 /* 267 * Version without error word 268 */ 269 subl $4, %esp 270 .endif 271 272 pushl %ds 273 pushl %es 274 pushl %fs 275 pushl %gs 276 277 pushl %ebp 278 pushl %edx 279 pushl %ecx 280 pushl %eax 281 282 # we must fill the data segment registers 283 284 movw $16, %ax 285 movw %ax, %ds 286 movw %ax, %es 287 288 # stop stack traces here if we came from userspace 289 cmpl $8, 40(%esp) 290 jz 0f 291 xorl %ebp, %ebp 292 293 0: 294 pushl %esp # *istate 295 pushl $(\i) # intnum 296 call exc_dispatch # exc_dispatch(intnum, *istate) 297 addl $8, %esp # Clear arguments from stack 298 299 CLEAR_NT_FLAG # Modifies %ecx 300 301 popl %eax 302 popl %ecx 303 popl %edx 304 popl %ebp 305 306 popl %gs 307 popl %fs 308 popl %es 309 popl %ds 310 311 # skip error word, no matter whether real or fake 312 addl $4, %esp 313 iret 314 .endif 315 316 .align INTERRUPT_ALIGN 317 .if (\n- \i) - 1 318 handler "(\i + 1)", \n 319 .endif 229 .ifeq \i - 0x30 # Syscall handler 230 pushl %ds 231 pushl %es 232 pushl %fs 233 pushl %gs 234 235 # 236 # Push syscall arguments onto the stack 237 # 238 # NOTE: The idea behind the order of arguments passed in registers is to 239 # use all scratch registers first and preserved registers next. 240 # An optimized libc syscall wrapper can make use of this setup. 241 # 242 pushl %eax 243 pushl %ebp 244 pushl %edi 245 pushl %esi 246 pushl %ebx 247 pushl %ecx 248 pushl %edx 249 250 # we must fill the data segment registers 251 movw $16, %ax 252 movw %ax, %ds 253 movw %ax, %es 254 255 xorl %ebp, %ebp 256 257 cld 258 sti 259 # syscall_handler(edx, ecx, ebx, esi, edi, ebp, eax) 260 call syscall_handler 261 cli 262 263 movl 20(%esp), %ebp # restore EBP 264 addl $28, %esp # clean-up of parameters 265 266 popl %gs 267 popl %fs 268 popl %es 269 popl %ds 270 271 CLEAR_NT_FLAG 272 iret 273 .else 274 /* 275 * This macro distinguishes between two versions of ia32 exceptions. 276 * One version has error word and the other does not have it. 277 * The latter version fakes the error word on the stack so that the 278 * handlers and istate_t can be the same for both types. 279 */ 280 .iflt \i - 32 281 .if (1 << \i) & ERROR_WORD_INTERRUPT_LIST 282 # 283 # Exception with error word: do nothing 284 # 285 .else 286 # 287 # Exception without error word: fake up one 288 # 289 pushl $0 290 .endif 291 .else 292 # 293 # Interrupt: fake up one 294 # 295 pushl $0 296 .endif 297 298 subl $ISTATE_SOFT_SIZE, %esp 299 300 # 301 # Save the general purpose registers. 302 # 303 movl %eax, ISTATE_OFFSET_EAX(%esp) 304 movl %ebx, ISTATE_OFFSET_EBX(%esp) 305 movl %ecx, ISTATE_OFFSET_ECX(%esp) 306 movl %edx, ISTATE_OFFSET_EDX(%esp) 307 movl %edi, ISTATE_OFFSET_EDI(%esp) 308 movl %esi, ISTATE_OFFSET_ESI(%esp) 309 movl %ebp, ISTATE_OFFSET_EBP(%esp) 310 311 # 312 # Save the selector registers. 313 # 314 movl %gs, %eax 315 movl %fs, %ebx 316 movl %es, %ecx 317 movl %ds, %edx 318 319 movl %eax, ISTATE_OFFSET_GS(%esp) 320 movl %ebx, ISTATE_OFFSET_FS(%esp) 321 movl %ecx, ISTATE_OFFSET_ES(%esp) 322 movl %edx, ISTATE_OFFSET_DS(%esp) 323 324 # 325 # Switch to kernel selectors. 326 # 327 movl $16, %eax 328 movl %eax, %ds 329 movl %eax, %es 330 331 # 332 # Imitate a regular stack frame linkage. 333 # Stop stack traces here if we came from userspace. 334 # 335 cmpl $8, ISTATE_OFFSET_CS(%esp) 336 jz 0f 337 xorl %ebp, %ebp 338 0: movl %ebp, ISTATE_OFFSET_EBP_FRAME(%esp) 339 movl ISTATE_OFFSET_EIP(%esp), %eax 340 movl %eax, ISTATE_OFFSET_EIP_FRAME(%esp) 341 leal ISTATE_OFFSET_EBP_FRAME(%esp), %ebp 342 343 pushl %esp # pass istate address 344 pushl $(\i) # pass intnum 345 call exc_dispatch # exc_dispatch(intnum, istate) 346 addl $8, %esp # Clear arguments from the stack 347 348 CLEAR_NT_FLAG 349 350 # 351 # Restore the selector registers. 352 # 353 movl ISTATE_OFFSET_GS(%esp), %eax 354 movl ISTATE_OFFSET_FS(%esp), %ebx 355 movl ISTATE_OFFSET_ES(%esp), %ecx 356 movl ISTATE_OFFSET_DS(%esp), %edx 357 358 movl %eax, %gs 359 movl %ebx, %fs 360 movl %ecx, %es 361 movl %edx, %ds 362 363 # 364 # Restore the scratch registers and the preserved registers the handler 365 # cloberred itself (i.e. EBX and EBP). 366 # 367 movl ISTATE_OFFSET_EAX(%esp), %eax 368 movl ISTATE_OFFSET_EBX(%esp), %ebx 369 movl ISTATE_OFFSET_ECX(%esp), %ecx 370 movl ISTATE_OFFSET_EDX(%esp), %edx 371 movl ISTATE_OFFSET_EBP(%esp), %ebp 372 373 addl $(ISTATE_SOFT_SIZE + 4), %esp 374 iret 375 .endif 376 377 .align INTERRUPT_ALIGN 378 .if (\n- \i) - 1 379 handler "(\i + 1)", \n 380 .endif 320 381 .endm 321 382
Note:
See TracChangeset
for help on using the changeset viewer.