Changes in kernel/arch/amd64/src/asm_utils.S [a1f60f3:a043e39] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/arch/amd64/src/asm_utils.S
ra1f60f3 ra043e39 27 27 # 28 28 29 #define IREGISTER_SPACE 80 30 31 #define IOFFSET_RAX 0x00 32 #define IOFFSET_RCX 0x08 33 #define IOFFSET_RDX 0x10 34 #define IOFFSET_RSI 0x18 35 #define IOFFSET_RDI 0x20 36 #define IOFFSET_R8 0x28 37 #define IOFFSET_R9 0x30 38 #define IOFFSET_R10 0x38 39 #define IOFFSET_R11 0x40 40 #define IOFFSET_RBP 0x48 41 42 # Mask for interrupts 0 - 31 (bits 0 - 31) where 0 means that int 43 # has no error word and 1 means interrupt with error word 44 45 #define ERROR_WORD_INTERRUPT_LIST 0x00027D00 29 #define IREGISTER_SPACE 80 30 31 #define IOFFSET_RAX 0x0 32 #define IOFFSET_RCX 0x8 33 #define IOFFSET_RDX 0x10 34 #define IOFFSET_RSI 0x18 35 #define IOFFSET_RDI 0x20 36 #define IOFFSET_R8 0x28 37 #define IOFFSET_R9 0x30 38 #define IOFFSET_R10 0x38 39 #define IOFFSET_R11 0x40 40 #define IOFFSET_RBP 0x48 41 42 # Mask for interrupts 0 - 31 (bits 0 - 31) where 0 means that int has no error word 43 # and 1 means interrupt with error word 44 #define ERROR_WORD_INTERRUPT_LIST 0x00027D00 46 45 47 46 #include <arch/pm.h> 48 47 #include <arch/mm/page.h> 49 48 50 49 .text 51 50 .global interrupt_handlers 52 51 .global syscall_entry 53 .global panic_printf54 55 panic_printf:56 movabsq $halt, %rax57 movq %rax, (%rsp)58 jmp printf59 52 60 53 .global cpuid … … 78 71 jmp _memsetw 79 72 80 #define MEMCPY_DST 81 #define MEMCPY_SRC 82 #define MEMCPY_SIZE 73 #define MEMCPY_DST %rdi 74 #define MEMCPY_SRC %rsi 75 #define MEMCPY_SIZE %rdx 83 76 84 77 /** … … 91 84 * or copy_to_uspace(). 92 85 * 93 * @param MEMCPY_DST 94 * @param MEMCPY_SRC 95 * @param MEMCPY_SIZE 86 * @param MEMCPY_DST Destination address. 87 * @param MEMCPY_SRC Source address. 88 * @param MEMCPY_SIZE Number of bytes to copy. 96 89 * 97 90 * @retrun MEMCPY_DST on success, 0 on failure. 98 *99 91 */ 100 92 memcpy: … … 102 94 memcpy_to_uspace: 103 95 movq MEMCPY_DST, %rax 104 96 105 97 movq MEMCPY_SIZE, %rcx 106 shrq $3, %rcx 107 108 rep movsq 109 98 shrq $3, %rcx /* size / 8 */ 99 100 rep movsq /* copy as much as possible word by word */ 101 110 102 movq MEMCPY_SIZE, %rcx 111 andq $7, %rcx 103 andq $7, %rcx /* size % 8 */ 112 104 jz 0f 113 105 114 rep movsb 115 116 117 ret/* return MEMCPY_SRC, success */106 rep movsb /* copy the rest byte by byte */ 107 108 0: 109 ret /* return MEMCPY_SRC, success */ 118 110 119 111 memcpy_from_uspace_failover_address: 120 112 memcpy_to_uspace_failover_address: 121 xorq %rax, %rax 113 xorq %rax, %rax /* return 0, failure */ 122 114 ret 123 115 … … 127 119 # 128 120 has_cpuid: 129 pushfq 130 popq %rax 131 movq %rax, %rdx# copy flags132 btcl $21, %edx# swap the ID bit121 pushfq # store flags 122 popq %rax # read flags 123 movq %rax,%rdx # copy flags 124 btcl $21,%edx # swap the ID bit 133 125 pushq %rdx 134 popfq 126 popfq # propagate the change into flags 135 127 pushfq 136 popq %rdx # read flags137 andl $(1 << 21), %eax# interested only in ID bit138 andl $(1 << 21),%edx139 xorl %edx, %eax# 0 if not supported, 1 if supported128 popq %rdx # read flags 129 andl $(1<<21),%eax # interested only in ID bit 130 andl $(1<<21),%edx 131 xorl %edx,%eax # 0 if not supported, 1 if supported 140 132 ret 141 133 142 134 cpuid: 143 movq %rbx, %r10 144 145 movl %edi,%eax 146 147 cpuid 148 movl %eax, 149 movl %ebx, 150 movl %ecx, 151 movl %edx, 152 135 movq %rbx, %r10 # we have to preserve rbx across function calls 136 137 movl %edi,%eax # load the command into %eax 138 139 cpuid 140 movl %eax,0(%rsi) 141 movl %ebx,4(%rsi) 142 movl %ecx,8(%rsi) 143 movl %edx,12(%rsi) 144 153 145 movq %r10, %rbx 154 146 ret … … 160 152 wrmsr 161 153 ret 162 154 163 155 read_efer_flag: 164 156 movq $0xc0000080, %rcx 165 157 rdmsr 166 ret 158 ret 167 159 168 160 # Push all volatile general purpose registers on stack … … 193 185 .endm 194 186 195 #define INTERRUPT_ALIGN 196 187 #define INTERRUPT_ALIGN 128 188 197 189 ## Declare interrupt handlers 198 190 # … … 203 195 # 204 196 .macro handler i n 205 197 206 198 /* 207 199 * Choose between version with error code and version without error … … 212 204 * Therefore we align the interrupt handlers. 213 205 */ 214 206 215 207 .iflt \i-32 216 208 .if (1 << \i) & ERROR_WORD_INTERRUPT_LIST … … 223 215 * Version without error word, 224 216 */ 225 subq $(IREGISTER_SPACE +8), %rsp217 subq $(IREGISTER_SPACE+8), %rsp 226 218 .endif 227 219 .else … … 229 221 * Version without error word, 230 222 */ 231 subq $(IREGISTER_SPACE +8), %rsp232 .endif 233 223 subq $(IREGISTER_SPACE+8), %rsp 224 .endif 225 234 226 save_all_gpr 235 227 cld 236 237 # Stop stack traces here 238 xorq %rbp, %rbp 239 240 movq $(\i), %rdi # %rdi - first parameter 241 movq %rsp, %rsi # %rsi - pointer to istate 242 call exc_dispatch # exc_dispatch(i, istate) 228 229 # 230 # Stop stack traces here if we came from userspace. 231 # 232 movq %cs, %rax 233 xorq %rdx, %rdx 234 cmpq %rax, IREGISTER_SPACE+16(%rsp) 235 cmovneq %rdx, %rbp 236 237 movq $(\i), %rdi # %rdi - first parameter 238 movq %rsp, %rsi # %rsi - pointer to istate 239 call exc_dispatch # exc_dispatch(i, istate) 243 240 244 241 restore_all_gpr 245 242 # $8 = Skip error word 246 addq $(IREGISTER_SPACE +8), %rsp243 addq $(IREGISTER_SPACE+8), %rsp 247 244 iretq 248 245 249 246 .align INTERRUPT_ALIGN 250 .if (\n - \i) -1251 handler "(\i + 1)",\n247 .if (\n-\i)-1 248 handler "(\i+1)",\n 252 249 .endif 253 250 .endm … … 255 252 .align INTERRUPT_ALIGN 256 253 interrupt_handlers: 257 258 259 254 h_start: 255 handler 0 IDT_ITEMS 256 h_end: 260 257 261 258 ## Low-level syscall handler 262 # 259 # 263 260 # Registers on entry: 264 261 # 265 # @param rcx 266 # @param r11 267 # 268 # @param rax 269 # @param rdi 270 # @param rsi 271 # @param rdx 272 # @param r10 4th syscall argument. Used instead of RCX because273 # theSYSCALL instruction clobbers it.274 # @param r8 275 # @param r9 276 # 277 # @return 262 # @param rcx Userspace return address. 263 # @param r11 Userspace RLFAGS. 264 # 265 # @param rax Syscall number. 266 # @param rdi 1st syscall argument. 267 # @param rsi 2nd syscall argument. 268 # @param rdx 3rd syscall argument. 269 # @param r10 4th syscall argument. Used instead of RCX because the 270 # SYSCALL instruction clobbers it. 271 # @param r8 5th syscall argument. 272 # @param r9 6th syscall argument. 273 # 274 # @return Return value is in rax. 278 275 # 279 276 syscall_entry: 280 swapgs # Switch to hidden gs 277 swapgs # Switch to hidden gs 278 # 279 # %gs:0 Scratch space for this thread's user RSP 280 # %gs:8 Address to be used as this thread's kernel RSP 281 281 # 282 # %gs:0 Scratch space for this thread's user RSP 283 # %gs:8 Address to be used as this thread's kernel RSP 284 # 285 movq %rsp, %gs:0 # Save this thread's user RSP 286 movq %gs:8, %rsp # Set this thread's kernel RSP 287 swapgs # Switch back to remain consistent 282 movq %rsp, %gs:0 # Save this thread's user RSP 283 movq %gs:8, %rsp # Set this thread's kernel RSP 284 swapgs # Switch back to remain consistent 288 285 sti 289 286 290 287 pushq %rcx 291 288 pushq %r11 292 293 movq %r10, %rcx # Copy the 4th argument where it is expected 289 pushq %rbp 290 291 xorq %rbp, %rbp # stop the stack traces here 292 293 movq %r10, %rcx # Copy the 4th argument where it is expected 294 294 pushq %rax 295 295 call syscall_handler 296 296 addq $8, %rsp 297 297 298 popq %rbp 298 299 popq %r11 299 300 popq %rcx 300 301 301 302 cli 302 303 swapgs 303 movq %gs:0, %rsp 304 movq %gs:0, %rsp # Restore the user RSP 304 305 swapgs 305 306 306 307 sysretq 307 308 … … 309 310 .global interrupt_handler_size 310 311 311 interrupt_handler_size: .quad (h_end - h_start) /IDT_ITEMS312 interrupt_handler_size: .quad (h_end-h_start)/IDT_ITEMS
Note:
See TracChangeset
for help on using the changeset viewer.