Changeset 074c9bd in mainline for kernel/arch/amd64/src
- Timestamp:
- 2010-07-15T10:39:23Z (16 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/fix-logger-deadlock, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 5c16ce7
- Parents:
- 41ce4d9 (diff), 4003861 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)links above to see all the changes relative to each parent. - Location:
- kernel/arch/amd64/src
- Files:
-
- 7 edited
-
asm.S (modified) (5 diffs)
-
interrupt.c (modified) (1 diff)
-
mm/page.c (modified) (1 diff)
-
pm.c (modified) (1 diff)
-
proc/scheduler.c (modified) (2 diffs)
-
proc/thread.c (modified) (2 diffs)
-
syscall.c (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
kernel/arch/amd64/src/asm.S
r41ce4d9 r074c9bd 26 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 27 */ 28 29 #define IREGISTER_SPACE 8030 31 #define IOFFSET_RAX 0x0032 #define IOFFSET_RCX 0x0833 #define IOFFSET_RDX 0x1034 #define IOFFSET_RSI 0x1835 #define IOFFSET_RDI 0x2036 #define IOFFSET_R8 0x2837 #define IOFFSET_R9 0x3038 #define IOFFSET_R10 0x3839 #define IOFFSET_R11 0x4040 #define IOFFSET_RBP 0x4841 42 /**43 * Mask for interrupts 0 - 31 (bits 0 - 31) where 0 means that int44 * has no error word and 1 means interrupt with error word45 *46 */47 #define ERROR_WORD_INTERRUPT_LIST 0x00027D0048 28 49 29 #include <arch/pm.h> … … 174 154 ret 175 155 176 /** Push all volatile general purpose registers on stack 177 * 156 #define ISTATE_OFFSET_RAX 0 157 #define ISTATE_OFFSET_RBX 8 158 #define ISTATE_OFFSET_RCX 16 159 #define ISTATE_OFFSET_RDX 24 160 #define ISTATE_OFFSET_RSI 32 161 #define ISTATE_OFFSET_RDI 40 162 #define ISTATE_OFFSET_RBP 48 163 #define ISTATE_OFFSET_R8 56 164 #define ISTATE_OFFSET_R9 64 165 #define ISTATE_OFFSET_R10 72 166 #define ISTATE_OFFSET_R11 80 167 #define ISTATE_OFFSET_R12 88 168 #define ISTATE_OFFSET_R13 96 169 #define ISTATE_OFFSET_R14 104 170 #define ISTATE_OFFSET_R15 112 171 #define ISTATE_OFFSET_ALIGNMENT 120 172 #define ISTATE_OFFSET_RBP_FRAME 128 173 #define ISTATE_OFFSET_RIP_FRAME 136 174 #define ISTATE_OFFSET_ERROR_WORD 144 175 #define ISTATE_OFFSET_RIP 152 176 #define ISTATE_OFFSET_CS 160 177 #define ISTATE_OFFSET_RFLAGS 168 178 #define ISTATE_OFFSET_RSP 176 179 #define ISTATE_OFFSET_SS 184 180 181 /* 182 * Size of the istate structure without the hardware-saved part and without the 183 * error word. 178 184 */ 179 .macro save_all_gpr 180 movq %rax, IOFFSET_RAX(%rsp) 181 movq %rcx, IOFFSET_RCX(%rsp) 182 movq %rdx, IOFFSET_RDX(%rsp) 183 movq %rsi, IOFFSET_RSI(%rsp) 184 movq %rdi, IOFFSET_RDI(%rsp) 185 movq %r8, IOFFSET_R8(%rsp) 186 movq %r9, IOFFSET_R9(%rsp) 187 movq %r10, IOFFSET_R10(%rsp) 188 movq %r11, IOFFSET_R11(%rsp) 189 movq %rbp, IOFFSET_RBP(%rsp) 190 .endm 191 192 .macro restore_all_gpr 193 movq IOFFSET_RAX(%rsp), %rax 194 movq IOFFSET_RCX(%rsp), %rcx 195 movq IOFFSET_RDX(%rsp), %rdx 196 movq IOFFSET_RSI(%rsp), %rsi 197 movq IOFFSET_RDI(%rsp), %rdi 198 movq IOFFSET_R8(%rsp), %r8 199 movq IOFFSET_R9(%rsp), %r9 200 movq IOFFSET_R10(%rsp), %r10 201 movq IOFFSET_R11(%rsp), %r11 202 movq IOFFSET_RBP(%rsp), %rbp 203 .endm 204 205 #define INTERRUPT_ALIGN 128 206 207 /** Declare interrupt handlers 208 * 209 * Declare interrupt handlers for n interrupt 210 * vectors starting at vector i. 211 * 212 * The handlers call exc_dispatch(). 185 #define ISTATE_SOFT_SIZE 144 186 187 /** 188 * Mask for interrupts 0 - 31 (bits 0 - 31) where 0 means that int 189 * has no error word and 1 means interrupt with error word 213 190 * 214 191 */ 215 .macro handler i n 216 192 #define ERROR_WORD_INTERRUPT_LIST 0x00027D00 193 194 .macro handler i 195 .global int_\i 196 int_\i: 197 217 198 /* 218 199 * Choose between version with error code and version without error 219 * code. Both versions have to be of the same size. amd64 assembly is, 220 * however, a little bit tricky. For instance, subq $0x80, %rsp and 221 * subq $0x78, %rsp can result in two instructions with different 222 * op-code lengths. 223 * Therefore we align the interrupt handlers. 200 * code. 224 201 */ 225 202 … … 229 206 * Version with error word. 230 207 */ 231 subq $I REGISTER_SPACE, %rsp208 subq $ISTATE_SOFT_SIZE, %rsp 232 209 .else 233 210 /* 234 * Version without error word ,211 * Version without error word. 235 212 */ 236 subq $(I REGISTER_SPACE + 8), %rsp213 subq $(ISTATE_SOFT_SIZE + 8), %rsp 237 214 .endif 238 215 .else 239 216 /* 240 * Version without error word ,217 * Version without error word. 241 218 */ 242 subq $(I REGISTER_SPACE + 8), %rsp219 subq $(ISTATE_SOFT_SIZE + 8), %rsp 243 220 .endif 244 221 245 save_all_gpr 222 /* 223 * Save the general purpose registers. 224 */ 225 movq %rax, ISTATE_OFFSET_RAX(%rsp) 226 movq %rbx, ISTATE_OFFSET_RBX(%rsp) 227 movq %rcx, ISTATE_OFFSET_RCX(%rsp) 228 movq %rdx, ISTATE_OFFSET_RDX(%rsp) 229 movq %rsi, ISTATE_OFFSET_RSI(%rsp) 230 movq %rdi, ISTATE_OFFSET_RDI(%rsp) 231 movq %rbp, ISTATE_OFFSET_RBP(%rsp) 232 movq %r8, ISTATE_OFFSET_R8(%rsp) 233 movq %r9, ISTATE_OFFSET_R9(%rsp) 234 movq %r10, ISTATE_OFFSET_R10(%rsp) 235 movq %r11, ISTATE_OFFSET_R11(%rsp) 236 movq %r12, ISTATE_OFFSET_R12(%rsp) 237 movq %r13, ISTATE_OFFSET_R13(%rsp) 238 movq %r14, ISTATE_OFFSET_R14(%rsp) 239 movq %r15, ISTATE_OFFSET_R15(%rsp) 240 241 /* 242 * Imitate a regular stack frame linkage. 243 * Stop stack traces here if we came from userspace. 244 */ 245 xorq %rdx, %rdx 246 cmpq $(gdtselector(KTEXT_DES)), ISTATE_OFFSET_CS(%rsp) 247 cmovnzq %rdx, %rbp 248 249 movq %rbp, ISTATE_OFFSET_RBP_FRAME(%rsp) 250 movq ISTATE_OFFSET_RIP(%rsp), %rax 251 movq %rax, ISTATE_OFFSET_RIP_FRAME(%rsp) 252 leaq ISTATE_OFFSET_RBP_FRAME(%rsp), %rbp 253 254 movq $(\i), %rdi /* pass intnum in the first argument */ 255 movq %rsp, %rsi /* pass istate address in the second argument */ 256 246 257 cld 247 248 /* 249 * Stop stack traces here if we came from userspace. 250 */ 251 movq %cs, %rax 252 xorq %rdx, %rdx 253 cmpq %rax, IREGISTER_SPACE+16(%rsp) 254 cmovneq %rdx, %rbp 255 256 movq $(\i), %rdi /* %rdi - first argument */ 257 movq %rsp, %rsi /* %rsi - pointer to istate */ 258 258 259 259 /* Call exc_dispatch(i, istate) */ 260 260 call exc_dispatch 261 262 restore_all_gpr 261 262 /* 263 * Restore all scratch registers and the preserved registers we have 264 * clobbered in this handler (i.e. RBP). 265 */ 266 movq ISTATE_OFFSET_RAX(%rsp), %rax 267 movq ISTATE_OFFSET_RCX(%rsp), %rcx 268 movq ISTATE_OFFSET_RDX(%rsp), %rdx 269 movq ISTATE_OFFSET_RSI(%rsp), %rsi 270 movq ISTATE_OFFSET_RDI(%rsp), %rdi 271 movq ISTATE_OFFSET_RBP(%rsp), %rbp 272 movq ISTATE_OFFSET_R8(%rsp), %r8 273 movq ISTATE_OFFSET_R9(%rsp), %r9 274 movq ISTATE_OFFSET_R10(%rsp), %r10 275 movq ISTATE_OFFSET_R11(%rsp), %r11 263 276 264 277 /* $8 = Skip error word */ 265 addq $(I REGISTER_SPACE + 8), %rsp278 addq $(ISTATE_SOFT_SIZE + 8), %rsp 266 279 iretq 267 268 .align INTERRUPT_ALIGN269 .if (\n - \i) - 1270 handler "(\i + 1)", \n271 .endif272 280 .endm 273 281 274 .align INTERRUPT_ALIGN 282 #define LIST_0_63 \ 283 0, 1, 2, 3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,\ 284 28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,\ 285 53,54,55,56,57,58,59,60,61,62,63 286 275 287 interrupt_handlers: 276 h_start: 277 handler 0 IDT_ITEMS278 h_end: 288 .irp cnt, LIST_0_63 289 handler \cnt 290 .endr 279 291 280 292 /** Low-level syscall handler … … 309 321 movq %gs:8, %rsp /* set this thread's kernel RSP */ 310 322 311 /* Switch back to remain consistent */ 323 /* 324 * Note that the space needed for the imitated istate structure has been 325 * preallocated for us in thread_create_arch() and set in 326 * before_thread_runs_arch(). 327 */ 328 329 /* 330 * Save the general purpose registers and push the 7th argument (syscall 331 * number) onto the stack. Note that the istate structure has a layout 332 * which supports this. 333 */ 334 movq %rax, ISTATE_OFFSET_RAX(%rsp) /* 7th argument, passed on stack */ 335 movq %rbx, ISTATE_OFFSET_RBX(%rsp) /* observability */ 336 movq %rcx, ISTATE_OFFSET_RCX(%rsp) /* userspace RIP */ 337 movq %rdx, ISTATE_OFFSET_RDX(%rsp) /* 3rd argument, observability */ 338 movq %rsi, ISTATE_OFFSET_RSI(%rsp) /* 2nd argument, observability */ 339 movq %rdi, ISTATE_OFFSET_RDI(%rsp) /* 1st argument, observability */ 340 movq %rbp, ISTATE_OFFSET_RBP(%rsp) /* need to preserve userspace RBP */ 341 movq %r8, ISTATE_OFFSET_R8(%rsp) /* 5th argument, observability */ 342 movq %r9, ISTATE_OFFSET_R9(%rsp) /* 6th argument, observability */ 343 movq %r10, ISTATE_OFFSET_R10(%rsp) /* 4th argument, observability */ 344 movq %r11, ISTATE_OFFSET_R11(%rsp) /* low 32 bits userspace RFLAGS */ 345 movq %r12, ISTATE_OFFSET_R12(%rsp) /* observability */ 346 movq %r13, ISTATE_OFFSET_R13(%rsp) /* observability */ 347 movq %r14, ISTATE_OFFSET_R14(%rsp) /* observability */ 348 movq %r15, ISTATE_OFFSET_R15(%rsp) /* observability */ 349 350 /* 351 * Save the return address and the userspace stack on locations that 352 * would normally be taken by them. 353 */ 354 movq %gs:0, %rax 355 movq %rax, ISTATE_OFFSET_RSP(%rsp) 356 movq %rcx, ISTATE_OFFSET_RIP(%rsp) 357 358 /* 359 * Imitate a regular stack frame linkage. 360 */ 361 movq $0, ISTATE_OFFSET_RBP_FRAME(%rsp) 362 movq %rcx, ISTATE_OFFSET_RIP_FRAME(%rsp) 363 leaq ISTATE_OFFSET_RBP_FRAME(%rsp), %rbp 364 365 /* Switch back to normal %gs */ 312 366 swapgs 313 367 sti 314 368 315 pushq %rcx316 pushq %r11317 pushq %rbp318 319 xorq %rbp, %rbp /* stop the stack traces here */320 321 369 /* Copy the 4th argument where it is expected */ 322 370 movq %r10, %rcx 323 pushq %rax 324 371 372 /* 373 * Call syscall_handler() with the 7th argument passed on stack. 374 */ 325 375 call syscall_handler 326 376 327 addq $8, %rsp328 329 popq %rbp330 popq %r11331 popq %rcx332 333 377 cli 334 swapgs 335 336 /* Restore the user RSP */ 337 movq %gs:0, %rsp 338 swapgs 339 378 379 /* 380 * Restore registers needed for return via the SYSRET instruction and 381 * the clobbered preserved registers (i.e. RBP). 382 */ 383 movq ISTATE_OFFSET_RBP(%rsp), %rbp 384 movq ISTATE_OFFSET_RCX(%rsp), %rcx 385 movq ISTATE_OFFSET_R11(%rsp), %r11 386 movq ISTATE_OFFSET_RSP(%rsp), %rsp 387 340 388 sysretq 341 389 … … 484 532 ret 485 533 486 .data487 .global interrupt_handler_size488 489 interrupt_handler_size: .quad (h_end - h_start) / IDT_ITEMS -
kernel/arch/amd64/src/interrupt.c
r41ce4d9 r074c9bd 65 65 void istate_decode(istate_t *istate) 66 66 { 67 printf("error_word=%#llx\n", istate->error_word); 68 printf("cs =%#0.16llx\trflags=%#0.16llx\n", istate->cs, 69 istate->rflags); 70 printf("rax=%#0.16llx\trbx=%#0.16llx\trcx=%#0.16llx\n", istate->rax, 71 istate->rcx, istate->rdx); 72 printf("rsi=%#0.16llx\trdi=%#0.16llx\tr8 =%#0.16llx\n", istate->rsi, 73 istate->rdi, istate->r8); 74 printf("r9 =%#0.16llx\tr10=%#0.16llx\tr11=%#0.16llx\n", istate->r9, 75 istate->r10, istate->r11); 67 printf("cs =%p\trip=%p\trfl=%p\terr=%p\n", 68 istate->cs, istate->rip, istate->rflags, istate->error_word); 69 70 if (istate_from_uspace(istate)) 71 printf("ss =%p\n", istate->ss); 72 73 printf("rax=%p\trbx=%p\trcx=%p\trdx=%p\n", 74 istate->rax, istate->rbx, istate->rcx, istate->rdx); 75 printf("rsi=%p\trdi=%p\trbp=%p\trsp=%p\n", 76 istate->rsi, istate->rdi, istate->rbp, 77 istate_from_uspace(istate) ? istate->rsp : (uintptr_t)&istate->rsp); 78 printf("r8 =%p\tr9 =%p\tr10=%p\tr11=%p\n", 79 istate->r8, istate->r9, istate->r10, istate->r11); 80 printf("r12=%p\tr13=%p\tr14=%p\tr15=%p\n", 81 istate->r12, istate->r13, istate->r14, istate->r15); 76 82 } 77 83 -
kernel/arch/amd64/src/mm/page.c
r41ce4d9 r074c9bd 90 90 if (as_page_fault(page, access, istate) == AS_PF_FAULT) { 91 91 fault_if_from_uspace(istate, "Page fault: %#x.", page); 92 panic_memtrap(istate, access, page, "Page fault.");92 panic_memtrap(istate, access, page, NULL); 93 93 } 94 94 } -
kernel/arch/amd64/src/pm.c
r41ce4d9 r074c9bd 175 175 d->present = 1; 176 176 d->type = AR_INTERRUPT; /* masking interrupt */ 177 178 idt_setoffset(d, ((uintptr_t) interrupt_handlers) +179 i * interrupt_handler_size);180 177 } 178 179 d = &idt[0]; 180 idt_setoffset(d++, (uintptr_t) &int_0); 181 idt_setoffset(d++, (uintptr_t) &int_1); 182 idt_setoffset(d++, (uintptr_t) &int_2); 183 idt_setoffset(d++, (uintptr_t) &int_3); 184 idt_setoffset(d++, (uintptr_t) &int_4); 185 idt_setoffset(d++, (uintptr_t) &int_5); 186 idt_setoffset(d++, (uintptr_t) &int_6); 187 idt_setoffset(d++, (uintptr_t) &int_7); 188 idt_setoffset(d++, (uintptr_t) &int_8); 189 idt_setoffset(d++, (uintptr_t) &int_9); 190 idt_setoffset(d++, (uintptr_t) &int_10); 191 idt_setoffset(d++, (uintptr_t) &int_11); 192 idt_setoffset(d++, (uintptr_t) &int_12); 193 idt_setoffset(d++, (uintptr_t) &int_13); 194 idt_setoffset(d++, (uintptr_t) &int_14); 195 idt_setoffset(d++, (uintptr_t) &int_15); 196 idt_setoffset(d++, (uintptr_t) &int_16); 197 idt_setoffset(d++, (uintptr_t) &int_17); 198 idt_setoffset(d++, (uintptr_t) &int_18); 199 idt_setoffset(d++, (uintptr_t) &int_19); 200 idt_setoffset(d++, (uintptr_t) &int_20); 201 idt_setoffset(d++, (uintptr_t) &int_21); 202 idt_setoffset(d++, (uintptr_t) &int_22); 203 idt_setoffset(d++, (uintptr_t) &int_23); 204 idt_setoffset(d++, (uintptr_t) &int_24); 205 idt_setoffset(d++, (uintptr_t) &int_25); 206 idt_setoffset(d++, (uintptr_t) &int_26); 207 idt_setoffset(d++, (uintptr_t) &int_27); 208 idt_setoffset(d++, (uintptr_t) &int_28); 209 idt_setoffset(d++, (uintptr_t) &int_29); 210 idt_setoffset(d++, (uintptr_t) &int_30); 211 idt_setoffset(d++, (uintptr_t) &int_31); 212 idt_setoffset(d++, (uintptr_t) &int_32); 213 idt_setoffset(d++, (uintptr_t) &int_33); 214 idt_setoffset(d++, (uintptr_t) &int_34); 215 idt_setoffset(d++, (uintptr_t) &int_35); 216 idt_setoffset(d++, (uintptr_t) &int_36); 217 idt_setoffset(d++, (uintptr_t) &int_37); 218 idt_setoffset(d++, (uintptr_t) &int_38); 219 idt_setoffset(d++, (uintptr_t) &int_39); 220 idt_setoffset(d++, (uintptr_t) &int_40); 221 idt_setoffset(d++, (uintptr_t) &int_41); 222 idt_setoffset(d++, (uintptr_t) &int_42); 223 idt_setoffset(d++, (uintptr_t) &int_43); 224 idt_setoffset(d++, (uintptr_t) &int_44); 225 idt_setoffset(d++, (uintptr_t) &int_45); 226 idt_setoffset(d++, (uintptr_t) &int_46); 227 idt_setoffset(d++, (uintptr_t) &int_47); 228 idt_setoffset(d++, (uintptr_t) &int_48); 229 idt_setoffset(d++, (uintptr_t) &int_49); 230 idt_setoffset(d++, (uintptr_t) &int_50); 231 idt_setoffset(d++, (uintptr_t) &int_51); 232 idt_setoffset(d++, (uintptr_t) &int_52); 233 idt_setoffset(d++, (uintptr_t) &int_53); 234 idt_setoffset(d++, (uintptr_t) &int_54); 235 idt_setoffset(d++, (uintptr_t) &int_55); 236 idt_setoffset(d++, (uintptr_t) &int_56); 237 idt_setoffset(d++, (uintptr_t) &int_57); 238 idt_setoffset(d++, (uintptr_t) &int_58); 239 idt_setoffset(d++, (uintptr_t) &int_59); 240 idt_setoffset(d++, (uintptr_t) &int_60); 241 idt_setoffset(d++, (uintptr_t) &int_61); 242 idt_setoffset(d++, (uintptr_t) &int_62); 243 idt_setoffset(d++, (uintptr_t) &int_63); 181 244 } 182 245 -
kernel/arch/amd64/src/proc/scheduler.c
r41ce4d9 r074c9bd 38 38 #include <proc/thread.h> 39 39 #include <arch.h> 40 #include <arch/context.h>41 40 #include <arch/asm.h> 42 41 #include <print.h> … … 57 56 { 58 57 CPU->arch.tss->rsp0 = 59 (uintptr_t) &THREAD->kstack[THREAD_STACK_SIZE - SP_DELTA];58 (uintptr_t) &THREAD->kstack[THREAD_STACK_SIZE]; 60 59 61 60 /* -
kernel/arch/amd64/src/proc/thread.c
r41ce4d9 r074c9bd 34 34 35 35 #include <proc/thread.h> 36 #include <arch/interrupt.h> 36 37 37 38 /** Perform amd64 specific thread initialization. … … 49 50 */ 50 51 thread->arch.syscall_rsp[SYSCALL_KSTACK_RSP] = 51 (uintptr_t) &thread->kstack[PAGE_SIZE - sizeof( uint64_t)];52 (uintptr_t) &thread->kstack[PAGE_SIZE - sizeof(istate_t)]; 52 53 } 53 54 -
kernel/arch/amd64/src/syscall.c
r41ce4d9 r074c9bd 66 66 * - clear DF so that the string instructions operate in 67 67 * the right direction 68 * - clear NT to prevent a #GP should the flag proliferate to an IRET 68 69 */ 69 write_msr(AMD_MSR_SFMASK, RFLAGS_IF | RFLAGS_DF );70 write_msr(AMD_MSR_SFMASK, RFLAGS_IF | RFLAGS_DF | RFLAGS_NT); 70 71 } 71 72
Note:
See TracChangeset
for help on using the changeset viewer.
