Changes in kernel/arch/amd64/src/asm_utils.S [a1f60f3:1d6c497] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/arch/amd64/src/asm_utils.S
ra1f60f3 r1d6c497 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 … … 54 53 55 54 panic_printf: 56 movabsq $halt, %rax 57 movq %rax, (%rsp) 55 movq $halt, (%rsp) 58 56 jmp printf 59 57 … … 78 76 jmp _memsetw 79 77 80 #define MEMCPY_DST 81 #define MEMCPY_SRC 82 #define MEMCPY_SIZE 78 #define MEMCPY_DST %rdi 79 #define MEMCPY_SRC %rsi 80 #define MEMCPY_SIZE %rdx 83 81 84 82 /** … … 91 89 * or copy_to_uspace(). 92 90 * 93 * @param MEMCPY_DST 94 * @param MEMCPY_SRC 95 * @param MEMCPY_SIZE 91 * @param MEMCPY_DST Destination address. 92 * @param MEMCPY_SRC Source address. 93 * @param MEMCPY_SIZE Number of bytes to copy. 96 94 * 97 95 * @retrun MEMCPY_DST on success, 0 on failure. 98 *99 96 */ 100 97 memcpy: … … 102 99 memcpy_to_uspace: 103 100 movq MEMCPY_DST, %rax 104 101 105 102 movq MEMCPY_SIZE, %rcx 106 shrq $3, %rcx 107 108 rep movsq 109 103 shrq $3, %rcx /* size / 8 */ 104 105 rep movsq /* copy as much as possible word by word */ 106 110 107 movq MEMCPY_SIZE, %rcx 111 andq $7, %rcx 108 andq $7, %rcx /* size % 8 */ 112 109 jz 0f 113 110 114 rep movsb 115 116 117 ret/* return MEMCPY_SRC, success */111 rep movsb /* copy the rest byte by byte */ 112 113 0: 114 ret /* return MEMCPY_SRC, success */ 118 115 119 116 memcpy_from_uspace_failover_address: 120 117 memcpy_to_uspace_failover_address: 121 xorq %rax, %rax 118 xorq %rax, %rax /* return 0, failure */ 122 119 ret 123 120 … … 127 124 # 128 125 has_cpuid: 129 pushfq 130 popq %rax 131 movq %rax, %rdx# copy flags132 btcl $21, %edx# swap the ID bit126 pushfq # store flags 127 popq %rax # read flags 128 movq %rax,%rdx # copy flags 129 btcl $21,%edx # swap the ID bit 133 130 pushq %rdx 134 popfq 131 popfq # propagate the change into flags 135 132 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 supported133 popq %rdx # read flags 134 andl $(1<<21),%eax # interested only in ID bit 135 andl $(1<<21),%edx 136 xorl %edx,%eax # 0 if not supported, 1 if supported 140 137 ret 141 138 142 139 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 140 movq %rbx, %r10 # we have to preserve rbx across function calls 141 142 movl %edi,%eax # load the command into %eax 143 144 cpuid 145 movl %eax,0(%rsi) 146 movl %ebx,4(%rsi) 147 movl %ecx,8(%rsi) 148 movl %edx,12(%rsi) 149 153 150 movq %r10, %rbx 154 151 ret … … 160 157 wrmsr 161 158 ret 162 159 163 160 read_efer_flag: 164 161 movq $0xc0000080, %rcx 165 162 rdmsr 166 ret 163 ret 167 164 168 165 # Push all volatile general purpose registers on stack … … 193 190 .endm 194 191 195 #define INTERRUPT_ALIGN 196 192 #define INTERRUPT_ALIGN 128 193 197 194 ## Declare interrupt handlers 198 195 # … … 203 200 # 204 201 .macro handler i n 205 202 206 203 /* 207 204 * Choose between version with error code and version without error … … 212 209 * Therefore we align the interrupt handlers. 213 210 */ 214 211 215 212 .iflt \i-32 216 213 .if (1 << \i) & ERROR_WORD_INTERRUPT_LIST … … 223 220 * Version without error word, 224 221 */ 225 subq $(IREGISTER_SPACE +8), %rsp222 subq $(IREGISTER_SPACE+8), %rsp 226 223 .endif 227 224 .else … … 229 226 * Version without error word, 230 227 */ 231 subq $(IREGISTER_SPACE +8), %rsp232 .endif 233 228 subq $(IREGISTER_SPACE+8), %rsp 229 .endif 230 234 231 save_all_gpr 235 232 cld 236 233 237 234 # Stop stack traces here 238 235 xorq %rbp, %rbp 239 240 movq $(\i), %rdi 241 movq %rsp, %rsi 242 call exc_dispatch 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 289 290 movq %r10, %rcx # Copy the 4th argument where it is expected 294 291 pushq %rax 295 292 call syscall_handler 296 293 addq $8, %rsp 297 294 298 295 popq %r11 299 296 popq %rcx 300 297 301 298 cli 302 299 swapgs 303 movq %gs:0, %rsp 300 movq %gs:0, %rsp # Restore the user RSP 304 301 swapgs 305 302 306 303 sysretq 307 304 … … 309 306 .global interrupt_handler_size 310 307 311 interrupt_handler_size: .quad (h_end - h_start) /IDT_ITEMS308 interrupt_handler_size: .quad (h_end-h_start)/IDT_ITEMS
Note:
See TracChangeset
for help on using the changeset viewer.