Ignore:
File:
1 edited

Legend:

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

    ra043e39 ra1f60f3  
    2727#
    2828
    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
    4546
    4647#include <arch/pm.h>
    4748#include <arch/mm/page.h>
    48        
     49
    4950.text
    5051.global interrupt_handlers
    5152.global syscall_entry
     53.global panic_printf
     54
     55panic_printf:
     56        movabsq $halt, %rax
     57        movq %rax, (%rsp)
     58        jmp printf
    5259
    5360.global cpuid
     
    7178        jmp _memsetw
    7279
    73 #define MEMCPY_DST      %rdi
    74 #define MEMCPY_SRC      %rsi
    75 #define MEMCPY_SIZE     %rdx
     80#define MEMCPY_DST   %rdi
     81#define MEMCPY_SRC   %rsi
     82#define MEMCPY_SIZE  %rdx
    7683
    7784/**
     
    8491 * or copy_to_uspace().
    8592 *
    86  * @param MEMCPY_DST    Destination address.
    87  * @param MEMCPY_SRC    Source address.
    88  * @param MEMCPY_SIZE   Number of bytes to copy.
     93 * @param MEMCPY_DST  Destination address.
     94 * @param MEMCPY_SRC  Source address.
     95 * @param MEMCPY_SIZE Number of bytes to copy.
    8996 *
    9097 * @retrun MEMCPY_DST on success, 0 on failure.
     98 *
    9199 */
    92100memcpy:
     
    94102memcpy_to_uspace:
    95103        movq MEMCPY_DST, %rax
    96 
     104       
    97105        movq MEMCPY_SIZE, %rcx
    98         shrq $3, %rcx                   /* size / 8 */
    99        
    100         rep movsq                       /* copy as much as possible word by word */
    101 
     106        shrq $3, %rcx           /* size / 8 */
     107       
     108        rep movsq               /* copy as much as possible word by word */
     109       
    102110        movq MEMCPY_SIZE, %rcx
    103         andq $7, %rcx                   /* size % 8 */
     111        andq $7, %rcx           /* size % 8 */
    104112        jz 0f
    105113       
    106         rep movsb                       /* copy the rest byte by byte */
    107        
    108 0:
    109         ret                             /* return MEMCPY_SRC, success */
     114        rep movsb               /* copy the rest byte by byte */
     115       
     116        0:
     117                ret                 /* return MEMCPY_SRC, success */
    110118
    111119memcpy_from_uspace_failover_address:
    112120memcpy_to_uspace_failover_address:
    113         xorq %rax, %rax                 /* return 0, failure */
     121        xorq %rax, %rax         /* return 0, failure */
    114122        ret
    115123
     
    119127#
    120128has_cpuid:
    121         pushfq                  # store flags
    122         popq %rax               # read flags
    123         movq %rax,%rdx          # copy flags
    124         btcl $21,%edx           # swap the ID bit
     129        pushfq                 # store flags
     130        popq %rax              # read flags
     131        movq %rax, %rdx        # copy flags
     132        btcl $21, %edx         # swap the ID bit
    125133        pushq %rdx
    126         popfq                   # propagate the change into flags
     134        popfq                  # propagate the change into flags
    127135        pushfq
    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
     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
    132140        ret
    133141
    134142cpuid:
    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 
     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       
    145153        movq %r10, %rbx
    146154        ret
     
    152160        wrmsr
    153161        ret
    154        
     162
    155163read_efer_flag:
    156164        movq $0xc0000080, %rcx
    157165        rdmsr
    158         ret             
     166        ret
    159167
    160168# Push all volatile general purpose registers on stack
     
    185193.endm
    186194
    187 #define INTERRUPT_ALIGN 128
    188        
     195#define INTERRUPT_ALIGN  128
     196
    189197## Declare interrupt handlers
    190198#
     
    195203#
    196204.macro handler i n
    197 
     205       
    198206        /*
    199207         * Choose between version with error code and version without error
     
    204212         * Therefore we align the interrupt handlers.
    205213         */
    206 
     214       
    207215        .iflt \i-32
    208216                .if (1 << \i) & ERROR_WORD_INTERRUPT_LIST
     
    215223                         * Version without error word,
    216224                         */
    217                         subq $(IREGISTER_SPACE+8), %rsp
     225                        subq $(IREGISTER_SPACE + 8), %rsp
    218226                .endif
    219227        .else
     
    221229                 * Version without error word,
    222230                 */
    223                 subq $(IREGISTER_SPACE+8), %rsp
    224         .endif 
    225 
     231                subq $(IREGISTER_SPACE + 8), %rsp
     232        .endif
     233       
    226234        save_all_gpr
    227235        cld
    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)
     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)
    240243       
    241244        restore_all_gpr
    242245        # $8 = Skip error word
    243         addq $(IREGISTER_SPACE+8), %rsp
     246        addq $(IREGISTER_SPACE + 8), %rsp
    244247        iretq
    245 
     248       
    246249        .align INTERRUPT_ALIGN
    247         .if (\n-\i)-1
    248         handler "(\i+1)",\n
     250        .if (\n - \i) - 1
     251                handler "(\i + 1)", \n
    249252        .endif
    250253.endm
     
    252255.align INTERRUPT_ALIGN
    253256interrupt_handlers:
    254 h_start:
    255         handler 0 IDT_ITEMS
    256 h_end:
     257        h_start:
     258                handler 0 IDT_ITEMS
     259        h_end:
    257260
    258261## Low-level syscall handler
    259 # 
     262#
    260263# Registers on entry:
    261264#
    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.
     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.
    275278#
    276279syscall_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
     280        swapgs            # Switch to hidden gs
    281281        #
    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
     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
    285288        sti
    286289       
    287290        pushq %rcx
    288291        pushq %r11
    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
     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                
    298         popq %rbp
     297       
    299298        popq %r11
    300299        popq %rcx
    301 
     300       
    302301        cli
    303302        swapgs
    304         movq %gs:0, %rsp        # Restore the user RSP
     303        movq %gs:0, %rsp  # Restore the user RSP
    305304        swapgs
    306 
     305       
    307306        sysretq
    308307
     
    310309.global interrupt_handler_size
    311310
    312 interrupt_handler_size: .quad (h_end-h_start)/IDT_ITEMS
     311interrupt_handler_size: .quad (h_end - h_start) / IDT_ITEMS
Note: See TracChangeset for help on using the changeset viewer.