Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • kernel/arch/amd64/src/asm_utils.S

    ra1f60f3 ra043e39  
    2727#
    2828
    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
    4645
    4746#include <arch/pm.h>
    4847#include <arch/mm/page.h>
    49 
     48       
    5049.text
    5150.global interrupt_handlers
    5251.global syscall_entry
    53 .global panic_printf
    54 
    55 panic_printf:
    56         movabsq $halt, %rax
    57         movq %rax, (%rsp)
    58         jmp printf
    5952
    6053.global cpuid
     
    7871        jmp _memsetw
    7972
    80 #define MEMCPY_DST   %rdi
    81 #define MEMCPY_SRC   %rsi
    82 #define MEMCPY_SIZE  %rdx
     73#define MEMCPY_DST      %rdi
     74#define MEMCPY_SRC      %rsi
     75#define MEMCPY_SIZE     %rdx
    8376
    8477/**
     
    9184 * or copy_to_uspace().
    9285 *
    93  * @param MEMCPY_DST  Destination address.
    94  * @param MEMCPY_SRC  Source address.
    95  * @param MEMCPY_SIZE Number of bytes to copy.
     86 * @param MEMCPY_DST    Destination address.
     87 * @param MEMCPY_SRC    Source address.
     88 * @param MEMCPY_SIZE   Number of bytes to copy.
    9689 *
    9790 * @retrun MEMCPY_DST on success, 0 on failure.
    98  *
    9991 */
    10092memcpy:
     
    10294memcpy_to_uspace:
    10395        movq MEMCPY_DST, %rax
    104        
     96
    10597        movq MEMCPY_SIZE, %rcx
    106         shrq $3, %rcx           /* size / 8 */
    107        
    108         rep movsq               /* copy as much as possible word by word */
    109        
     98        shrq $3, %rcx                   /* size / 8 */
     99       
     100        rep movsq                       /* copy as much as possible word by word */
     101
    110102        movq MEMCPY_SIZE, %rcx
    111         andq $7, %rcx           /* size % 8 */
     103        andq $7, %rcx                   /* size % 8 */
    112104        jz 0f
    113105       
    114         rep movsb               /* copy the rest byte by byte */
    115        
    116         0:
    117                 ret                 /* return MEMCPY_SRC, success */
     106        rep movsb                       /* copy the rest byte by byte */
     107       
     1080:
     109        ret                             /* return MEMCPY_SRC, success */
    118110
    119111memcpy_from_uspace_failover_address:
    120112memcpy_to_uspace_failover_address:
    121         xorq %rax, %rax         /* return 0, failure */
     113        xorq %rax, %rax                 /* return 0, failure */
    122114        ret
    123115
     
    127119#
    128120has_cpuid:
    129         pushfq                 # store flags
    130         popq %rax              # read flags
    131         movq %rax, %rdx        # copy flags
    132         btcl $21, %edx         # swap the ID bit
     121        pushfq                  # store flags
     122        popq %rax               # read flags
     123        movq %rax,%rdx          # copy flags
     124        btcl $21,%edx           # swap the ID bit
    133125        pushq %rdx
    134         popfq                  # propagate the change into flags
     126        popfq                   # propagate the change into flags
    135127        pushfq
    136         popq %rdx              # read flags
    137         andl $(1 << 21), %eax  # interested only in ID bit
    138         andl $(1 << 21), %edx
    139         xorl %edx, %eax        # 0 if not supported, 1 if supported
     128        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
    140132        ret
    141133
    142134cpuid:
    143         movq %rbx, %r10        # we have to preserve rbx across function calls
    144        
    145         movl %edi,%eax         # load the command into %eax
    146        
    147         cpuid
    148         movl %eax, 0(%rsi)
    149         movl %ebx, 4(%rsi)
    150         movl %ecx, 8(%rsi)
    151         movl %edx, 12(%rsi)
    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
    153145        movq %r10, %rbx
    154146        ret
     
    160152        wrmsr
    161153        ret
    162 
     154       
    163155read_efer_flag:
    164156        movq $0xc0000080, %rcx
    165157        rdmsr
    166         ret
     158        ret             
    167159
    168160# Push all volatile general purpose registers on stack
     
    193185.endm
    194186
    195 #define INTERRUPT_ALIGN  128
    196 
     187#define INTERRUPT_ALIGN 128
     188       
    197189## Declare interrupt handlers
    198190#
     
    203195#
    204196.macro handler i n
    205        
     197
    206198        /*
    207199         * Choose between version with error code and version without error
     
    212204         * Therefore we align the interrupt handlers.
    213205         */
    214        
     206
    215207        .iflt \i-32
    216208                .if (1 << \i) & ERROR_WORD_INTERRUPT_LIST
     
    223215                         * Version without error word,
    224216                         */
    225                         subq $(IREGISTER_SPACE + 8), %rsp
     217                        subq $(IREGISTER_SPACE+8), %rsp
    226218                .endif
    227219        .else
     
    229221                 * Version without error word,
    230222                 */
    231                 subq $(IREGISTER_SPACE + 8), %rsp
    232         .endif
    233        
     223                subq $(IREGISTER_SPACE+8), %rsp
     224        .endif 
     225
    234226        save_all_gpr
    235227        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)
    243240       
    244241        restore_all_gpr
    245242        # $8 = Skip error word
    246         addq $(IREGISTER_SPACE + 8), %rsp
     243        addq $(IREGISTER_SPACE+8), %rsp
    247244        iretq
    248        
     245
    249246        .align INTERRUPT_ALIGN
    250         .if (\n - \i) - 1
    251                 handler "(\i + 1)", \n
     247        .if (\n-\i)-1
     248        handler "(\i+1)",\n
    252249        .endif
    253250.endm
     
    255252.align INTERRUPT_ALIGN
    256253interrupt_handlers:
    257         h_start:
    258                 handler 0 IDT_ITEMS
    259         h_end:
     254h_start:
     255        handler 0 IDT_ITEMS
     256h_end:
    260257
    261258## Low-level syscall handler
    262 #
     259# 
    263260# Registers on entry:
    264261#
    265 # @param rcx Userspace return address.
    266 # @param r11 Userspace RLFAGS.
    267 #
    268 # @param rax Syscall number.
    269 # @param rdi 1st syscall argument.
    270 # @param rsi 2nd syscall argument.
    271 # @param rdx 3rd syscall argument.
    272 # @param r10 4th syscall argument. Used instead of RCX because
    273 #            the SYSCALL instruction clobbers it.
    274 # @param r8  5th syscall argument.
    275 # @param r9  6th syscall argument.
    276 #
    277 # @return Return value is in rax.
     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.
    278275#
    279276syscall_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
    281281        #
    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
    288285        sti
    289286       
    290287        pushq %rcx
    291288        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
    294294        pushq %rax
    295295        call syscall_handler
    296296        addq $8, %rsp
    297        
     297               
     298        popq %rbp
    298299        popq %r11
    299300        popq %rcx
    300        
     301
    301302        cli
    302303        swapgs
    303         movq %gs:0, %rsp  # Restore the user RSP
     304        movq %gs:0, %rsp        # Restore the user RSP
    304305        swapgs
    305        
     306
    306307        sysretq
    307308
     
    309310.global interrupt_handler_size
    310311
    311 interrupt_handler_size: .quad (h_end - h_start) / IDT_ITEMS
     312interrupt_handler_size: .quad (h_end-h_start)/IDT_ITEMS
Note: See TracChangeset for help on using the changeset viewer.