Changeset f56e897f in mainline for kernel/arch/amd64/src/asm_utils.S
- Timestamp:
- 2010-06-29T17:43:38Z (15 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 6473d41
- Parents:
- e4a4b44 (diff), 793cf029 (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. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/arch/amd64/src/asm_utils.S
re4a4b44 rf56e897f 27 27 # 28 28 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 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 45 46 46 47 #include <arch/pm.h> 47 48 #include <arch/mm/page.h> 48 49 49 50 .text 50 51 .global interrupt_handlers 51 52 .global syscall_entry 52 53 53 .global cpuid 54 54 .global has_cpuid … … 71 71 jmp _memsetw 72 72 73 #define MEMCPY_DST 74 #define MEMCPY_SRC 75 #define MEMCPY_SIZE 73 #define MEMCPY_DST %rdi 74 #define MEMCPY_SRC %rsi 75 #define MEMCPY_SIZE %rdx 76 76 77 77 /** … … 84 84 * or copy_to_uspace(). 85 85 * 86 * @param MEMCPY_DST 87 * @param MEMCPY_SRC 88 * @param MEMCPY_SIZE 86 * @param MEMCPY_DST Destination address. 87 * @param MEMCPY_SRC Source address. 88 * @param MEMCPY_SIZE Number of bytes to copy. 89 89 * 90 90 * @retrun MEMCPY_DST on success, 0 on failure. 91 * 91 92 */ 92 93 memcpy: … … 94 95 memcpy_to_uspace: 95 96 movq MEMCPY_DST, %rax 96 97 97 98 movq MEMCPY_SIZE, %rcx 98 shrq $3, %rcx 99 100 rep movsq 101 99 shrq $3, %rcx /* size / 8 */ 100 101 rep movsq /* copy as much as possible word by word */ 102 102 103 movq MEMCPY_SIZE, %rcx 103 andq $7, %rcx 104 andq $7, %rcx /* size % 8 */ 104 105 jz 0f 105 106 106 rep movsb 107 108 0:109 ret/* return MEMCPY_SRC, success */107 rep movsb /* copy the rest byte by byte */ 108 109 0: 110 ret /* return MEMCPY_SRC, success */ 110 111 111 112 memcpy_from_uspace_failover_address: 112 113 memcpy_to_uspace_failover_address: 113 xorq %rax, %rax 114 xorq %rax, %rax /* return 0, failure */ 114 115 ret 115 116 … … 119 120 # 120 121 has_cpuid: 121 pushfq 122 popq %rax 123 movq %rax, %rdx# copy flags124 btcl $21, %edx# swap the ID bit122 pushfq # store flags 123 popq %rax # read flags 124 movq %rax, %rdx # copy flags 125 btcl $21, %edx # swap the ID bit 125 126 pushq %rdx 126 popfq 127 popfq # propagate the change into flags 127 128 pushfq 128 popq %rdx # read flags129 andl $(1 <<21),%eax# interested only in ID bit130 andl $(1 <<21),%edx131 xorl %edx, %eax# 0 if not supported, 1 if supported129 popq %rdx # read flags 130 andl $(1 << 21), %eax # interested only in ID bit 131 andl $(1 << 21), %edx 132 xorl %edx, %eax # 0 if not supported, 1 if supported 132 133 ret 133 134 134 135 cpuid: 135 movq %rbx, %r10 # we have to preserve rbx across function calls136 137 movl %edi,%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 136 movq %rbx, %r10 # we have to preserve rbx across function calls 137 138 movl %edi,%eax # load the command into %eax 139 140 cpuid 141 movl %eax, 0(%rsi) 142 movl %ebx, 4(%rsi) 143 movl %ecx, 8(%rsi) 144 movl %edx, 12(%rsi) 145 145 146 movq %r10, %rbx 146 147 ret … … 152 153 wrmsr 153 154 ret 154 155 155 156 read_efer_flag: 156 157 movq $0xc0000080, %rcx 157 158 rdmsr 158 ret 159 ret 159 160 160 161 # Push all volatile general purpose registers on stack … … 185 186 .endm 186 187 187 #define INTERRUPT_ALIGN 128188 188 #define INTERRUPT_ALIGN 128 189 189 190 ## Declare interrupt handlers 190 191 # … … 195 196 # 196 197 .macro handler i n 197 198 198 199 /* 199 200 * Choose between version with error code and version without error … … 204 205 * Therefore we align the interrupt handlers. 205 206 */ 206 207 207 208 .iflt \i-32 208 209 .if (1 << \i) & ERROR_WORD_INTERRUPT_LIST … … 215 216 * Version without error word, 216 217 */ 217 subq $(IREGISTER_SPACE +8), %rsp218 subq $(IREGISTER_SPACE + 8), %rsp 218 219 .endif 219 220 .else … … 221 222 * Version without error word, 222 223 */ 223 subq $(IREGISTER_SPACE +8), %rsp224 .endif 225 224 subq $(IREGISTER_SPACE + 8), %rsp 225 .endif 226 226 227 save_all_gpr 227 228 cld … … 241 242 restore_all_gpr 242 243 # $8 = Skip error word 243 addq $(IREGISTER_SPACE +8), %rsp244 addq $(IREGISTER_SPACE + 8), %rsp 244 245 iretq 245 246 246 247 .align INTERRUPT_ALIGN 247 .if (\n -\i)-1248 handler "(\i+1)",\n248 .if (\n - \i) - 1 249 handler "(\i + 1)", \n 249 250 .endif 250 251 .endm … … 252 253 .align INTERRUPT_ALIGN 253 254 interrupt_handlers: 254 h_start:255 handler 0 IDT_ITEMS256 h_end:255 h_start: 256 handler 0 IDT_ITEMS 257 h_end: 257 258 258 259 ## Low-level syscall handler 259 # 260 # 260 261 # Registers on entry: 261 262 # 262 # @param rcx 263 # @param r11 264 # 265 # @param rax 266 # @param rdi 267 # @param rsi 268 # @param rdx 269 # @param r10 4th syscall argument. Used instead of RCX because the270 # 271 # @param r8 272 # @param r9 273 # 274 # @return 263 # @param rcx Userspace return address. 264 # @param r11 Userspace RLFAGS. 265 # 266 # @param rax Syscall number. 267 # @param rdi 1st syscall argument. 268 # @param rsi 2nd syscall argument. 269 # @param rdx 3rd syscall argument. 270 # @param r10 4th syscall argument. Used instead of RCX because 271 # the SYSCALL instruction clobbers it. 272 # @param r8 5th syscall argument. 273 # @param r9 6th syscall argument. 274 # 275 # @return Return value is in rax. 275 276 # 276 277 syscall_entry: 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 278 swapgs # Switch to hidden gs 281 279 # 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 280 # %gs:0 Scratch space for this thread's user RSP 281 # %gs:8 Address to be used as this thread's kernel RSP 282 # 283 movq %rsp, %gs:0 # Save this thread's user RSP 284 movq %gs:8, %rsp # Set this thread's kernel RSP 285 swapgs # Switch back to remain consistent 285 286 sti 286 287 … … 299 300 popq %r11 300 301 popq %rcx 301 302 302 303 cli 303 304 swapgs 304 movq %gs:0, %rsp 305 movq %gs:0, %rsp # Restore the user RSP 305 306 swapgs 306 307 307 308 sysretq 308 309 … … 310 311 .global interrupt_handler_size 311 312 312 interrupt_handler_size: .quad (h_end -h_start)/IDT_ITEMS313 interrupt_handler_size: .quad (h_end - h_start) / IDT_ITEMS
Note:
See TracChangeset
for help on using the changeset viewer.