Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • kernel/arch/mips32/src/start.S

    r96e0748d r0c39b96  
    4545.global userspace_asm
    4646
    47 # Which status bits should are thread-local
    48 #define REG_SAVE_MASK 0x1f # KSU(UM), EXL, ERL, IE
    49        
    50 # Save registers to space defined by \r
    51 # We will change status: Disable ERL,EXL,UM,IE
    52 # These changes will be automatically reversed in REGISTER_LOAD
    53 # SP is NOT saved as part of these registers
     47/*
     48 * Which status bits are thread-local:
     49 * KSU(UM), EXL, ERL, IE
     50 */
     51#define REG_SAVE_MASK 0x1f
     52
     53#define ISTATE_OFFSET_A0        0
     54#define ISTATE_OFFSET_A1        4
     55#define ISTATE_OFFSET_A2        8
     56#define ISTATE_OFFSET_A3        12
     57#define ISTATE_OFFSET_T0        16
     58#define ISTATE_OFFSET_T1        20
     59#define ISTATE_OFFSET_V0        24
     60#define ISTATE_OFFSET_V1        28
     61#define ISTATE_OFFSET_AT        32
     62#define ISTATE_OFFSET_T2        36
     63#define ISTATE_OFFSET_T3        40
     64#define ISTATE_OFFSET_T4        44
     65#define ISTATE_OFFSET_T5        48
     66#define ISTATE_OFFSET_T6        52
     67#define ISTATE_OFFSET_T7        56
     68#define ISTATE_OFFSET_S0        60
     69#define ISTATE_OFFSET_S1        64
     70#define ISTATE_OFFSET_S2        68
     71#define ISTATE_OFFSET_S3        72
     72#define ISTATE_OFFSET_S4        76
     73#define ISTATE_OFFSET_S5        80
     74#define ISTATE_OFFSET_S6        84
     75#define ISTATE_OFFSET_S7        88
     76#define ISTATE_OFFSET_T8        92
     77#define ISTATE_OFFSET_T9        96
     78#define ISTATE_OFFSET_KT0       100
     79#define ISTATE_OFFSET_KT1       104
     80#define ISTATE_OFFSET_GP        108
     81#define ISTATE_OFFSET_SP        112
     82#define ISTATE_OFFSET_S8        116
     83#define ISTATE_OFFSET_RA        120
     84#define ISTATE_OFFSET_LO        124
     85#define ISTATE_OFFSET_HI        128
     86#define ISTATE_OFFSET_STATUS    132
     87#define ISTATE_OFFSET_EPC       136
     88#define ISTATE_OFFSET_ALIGNMENT 140
     89
     90#define ISTATE_SOFT_SIZE        144
     91
     92/*
     93 * The fake ABI prologue is never executed and may not be part of the
     94 * procedure's body. Instead, it should be immediately preceding the procedure's
     95 * body. Its only purpose is to trick the stack trace walker into thinking that
     96 * the exception is more or less just a normal function call.
     97 */
     98.macro FAKE_ABI_PROLOGUE
     99        sub $sp, ISTATE_SOFT_SIZE
     100        sw $ra, ISTATE_OFFSET_EPC($sp)
     101.endm
     102
     103/*
     104 * Save registers to space defined by \r
     105 * We will change status: Disable ERL, EXL, UM, IE
     106 * These changes will be automatically reversed in REGISTER_LOAD
     107 * %sp is NOT saved as part of these registers
     108 */
    54109.macro REGISTERS_STORE_AND_EXC_RESET r
    55         sw $at, EOFFSET_AT(\r)
    56         sw $v0, EOFFSET_V0(\r)
    57         sw $v1, EOFFSET_V1(\r)
    58         sw $a0, EOFFSET_A0(\r)
    59         sw $a1, EOFFSET_A1(\r)
    60         sw $a2, EOFFSET_A2(\r)
    61         sw $a3, EOFFSET_A3(\r)
    62         sw $t0, EOFFSET_T0(\r)
    63         sw $t1, EOFFSET_T1(\r)
    64         sw $t2, EOFFSET_T2(\r)
    65         sw $t3, EOFFSET_T3(\r)
    66         sw $t4, EOFFSET_T4(\r)
    67         sw $t5, EOFFSET_T5(\r)
    68         sw $t6, EOFFSET_T6(\r)
    69         sw $t7, EOFFSET_T7(\r)
    70         sw $t8, EOFFSET_T8(\r)
    71         sw $t9, EOFFSET_T9(\r)
    72 
     110        sw $at, ISTATE_OFFSET_AT(\r)
     111        sw $v0, ISTATE_OFFSET_V0(\r)
     112        sw $v1, ISTATE_OFFSET_V1(\r)
     113        sw $a0, ISTATE_OFFSET_A0(\r)
     114        sw $a1, ISTATE_OFFSET_A1(\r)
     115        sw $a2, ISTATE_OFFSET_A2(\r)
     116        sw $a3, ISTATE_OFFSET_A3(\r)
     117        sw $t0, ISTATE_OFFSET_T0(\r)
     118        sw $t1, ISTATE_OFFSET_T1(\r)
     119        sw $t2, ISTATE_OFFSET_T2(\r)
     120        sw $t3, ISTATE_OFFSET_T3(\r)
     121        sw $t4, ISTATE_OFFSET_T4(\r)
     122        sw $t5, ISTATE_OFFSET_T5(\r)
     123        sw $t6, ISTATE_OFFSET_T6(\r)
     124        sw $t7, ISTATE_OFFSET_T7(\r)
     125        sw $t8, ISTATE_OFFSET_T8(\r)
     126        sw $t9, ISTATE_OFFSET_T9(\r)
     127        sw $s0, ISTATE_OFFSET_S0(\r)
     128        sw $s1, ISTATE_OFFSET_S1(\r)
     129        sw $s2, ISTATE_OFFSET_S2(\r)
     130        sw $s3, ISTATE_OFFSET_S3(\r)
     131        sw $s4, ISTATE_OFFSET_S4(\r)
     132        sw $s5, ISTATE_OFFSET_S5(\r)
     133        sw $s6, ISTATE_OFFSET_S6(\r)
     134        sw $s7, ISTATE_OFFSET_S7(\r)
     135        sw $s8, ISTATE_OFFSET_S8(\r)
     136       
    73137        mflo $at
    74         sw $at, EOFFSET_LO(\r)
     138        sw $at, ISTATE_OFFSET_LO(\r)
    75139        mfhi $at
    76         sw $at, EOFFSET_HI(\r)
    77        
    78         sw $gp, EOFFSET_GP(\r)
    79         sw $ra, EOFFSET_RA(\r)
    80         sw $k1, EOFFSET_K1(\r)
    81 
     140        sw $at, ISTATE_OFFSET_HI(\r)
     141       
     142        sw $gp, ISTATE_OFFSET_GP(\r)
     143        sw $ra, ISTATE_OFFSET_RA(\r)
     144        sw $k0, ISTATE_OFFSET_KT0(\r)
     145        sw $k1, ISTATE_OFFSET_KT1(\r)
     146       
    82147        mfc0 $t0, $status
    83148        mfc0 $t1, $epc
    84149       
    85         and $t2, $t0, REG_SAVE_MASK     # Save only KSU,EXL,ERL,IE
    86         li $t3, ~(0x1f)
    87         and $t0, $t0, $t3               # Clear KSU,EXL,ERL,IE
    88        
    89         sw $t2,EOFFSET_STATUS(\r)
    90         sw $t1,EOFFSET_EPC(\r)
     150        /* save only KSU, EXL, ERL, IE */
     151        and $t2, $t0, REG_SAVE_MASK
     152       
     153        /* clear KSU, EXL, ERL, IE */
     154        li $t3, ~(REG_SAVE_MASK)
     155        and $t0, $t0, $t3
     156       
     157        sw $t2, ISTATE_OFFSET_STATUS(\r)
     158        sw $t1, ISTATE_OFFSET_EPC(\r)
    91159        mtc0 $t0, $status
    92160.endm
    93161
    94162.macro REGISTERS_LOAD r
    95         # Update only UM,EXR,IE from status, the rest
    96         # is controlled by OS and not bound to task
     163        /*
     164         * Update only UM, EXR, IE from status, the rest
     165         * is controlled by OS and not bound to task.
     166         */
    97167        mfc0 $t0, $status
    98         lw $t1,EOFFSET_STATUS(\r)
    99 
    100         li $t2, ~REG_SAVE_MASK          # Mask UM,EXL,ERL,IE
     168        lw $t1, ISTATE_OFFSET_STATUS(\r)
     169       
     170        /* mask UM, EXL, ERL, IE */
     171        li $t2, ~REG_SAVE_MASK
    101172        and $t0, $t0, $t2
    102173       
    103         or $t0, $t0, $t1                # Copy UM,EXL, ERL, IE from saved status
     174        /* copy UM, EXL, ERL, IE from saved status */
     175        or $t0, $t0, $t1
    104176        mtc0 $t0, $status
    105177       
    106         lw $v0, EOFFSET_V0(\r)
    107         lw $v1, EOFFSET_V1(\r)
    108         lw $a0, EOFFSET_A0(\r)
    109         lw $a1, EOFFSET_A1(\r)
    110         lw $a2, EOFFSET_A2(\r)
    111         lw $a3, EOFFSET_A3(\r)
    112         lw $t0, EOFFSET_T0(\r)
    113         lw $t1, EOFFSET_T1(\r)
    114         lw $t2, EOFFSET_T2(\r)
    115         lw $t3, EOFFSET_T3(\r)
    116         lw $t4, EOFFSET_T4(\r)
    117         lw $t5, EOFFSET_T5(\r)
    118         lw $t6, EOFFSET_T6(\r)
    119         lw $t7, EOFFSET_T7(\r)
    120         lw $t8, EOFFSET_T8(\r)
    121         lw $t9, EOFFSET_T9(\r)
    122        
    123         lw $gp, EOFFSET_GP(\r)
    124         lw $ra, EOFFSET_RA(\r)
    125         lw $k1, EOFFSET_K1(\r)
    126        
    127         lw $at, EOFFSET_LO(\r)
     178        lw $v0, ISTATE_OFFSET_V0(\r)
     179        lw $v1, ISTATE_OFFSET_V1(\r)
     180        lw $a0, ISTATE_OFFSET_A0(\r)
     181        lw $a1, ISTATE_OFFSET_A1(\r)
     182        lw $a2, ISTATE_OFFSET_A2(\r)
     183        lw $a3, ISTATE_OFFSET_A3(\r)
     184        lw $t0, ISTATE_OFFSET_T0(\r)
     185        lw $t1, ISTATE_OFFSET_T1(\r)
     186        lw $t2, ISTATE_OFFSET_T2(\r)
     187        lw $t3, ISTATE_OFFSET_T3(\r)
     188        lw $t4, ISTATE_OFFSET_T4(\r)
     189        lw $t5, ISTATE_OFFSET_T5(\r)
     190        lw $t6, ISTATE_OFFSET_T6(\r)
     191        lw $t7, ISTATE_OFFSET_T7(\r)
     192        lw $t8, ISTATE_OFFSET_T8(\r)
     193        lw $t9, ISTATE_OFFSET_T9(\r)
     194       
     195        lw $gp, ISTATE_OFFSET_GP(\r)
     196        lw $ra, ISTATE_OFFSET_RA(\r)
     197        lw $k1, ISTATE_OFFSET_KT1(\r)
     198       
     199        lw $at, ISTATE_OFFSET_LO(\r)
    128200        mtlo $at
    129         lw $at, EOFFSET_HI(\r)
     201        lw $at, ISTATE_OFFSET_HI(\r)
    130202        mthi $at
    131 
    132         lw $at, EOFFSET_EPC(\r)
     203       
     204        lw $at, ISTATE_OFFSET_EPC(\r)
    133205        mtc0 $at, $epc
    134206       
    135         lw $at, EOFFSET_AT(\r)
    136         lw $sp, EOFFSET_SP(\r)
     207        lw $at, ISTATE_OFFSET_AT(\r)
     208        lw $sp, ISTATE_OFFSET_SP(\r)
    137209.endm
    138210
    139 # Move kernel stack pointer address to register K0
    140 # - if we are in user mode, load the appropriate stack
    141 # address
     211/*
     212 * Move kernel stack pointer address to register $k0.
     213 * If we are in user mode, load the appropriate stack address.
     214 */
    142215.macro KERNEL_STACK_TO_K0
    143         # If we are in user mode
     216        /* if we are in user mode */
    144217        mfc0 $k0, $status
    145218        andi $k0, 0x10
    146219       
    147220        beq $k0, $0, 1f
    148         add $k0, $sp, 0
    149        
    150         # Move $k0 pointer to kernel stack
     221        move $k0, $sp
     222       
     223        /* move $k0 pointer to kernel stack */
    151224        lui $k0, %hi(supervisor_sp)
    152225        ori $k0, $k0, %lo(supervisor_sp)
    153         # Move $k0 (superveisor_sp)
    154         lw $k0, 0($k0)
    155 1:
     226       
     227        /* move $k0 (supervisor_sp) */
     228        lw $k0, ($k0)
     229       
     230        1:
    156231.endm
    157232
    158233.org 0x0
    159234kernel_image_start:
    160         /* Load temporary stack */
     235        /* load temporary stack */
    161236        lui $sp, %hi(end_stack)
    162237        ori $sp, $sp, %lo(end_stack)
    163238       
    164         /* Not sure about this, but might
    165            be needed for PIC code */
     239        /* not sure about this, but might be needed for PIC code */
    166240        lui $gp, 0x8000
    167241       
    168242        /* $a1 contains physical address of bootinfo_t */
    169        
    170243        jal arch_pre_main
    171244        nop
     
    174247        nop
    175248
    176         .space TEMP_STACK_SIZE
     249.space TEMP_STACK_SIZE
    177250end_stack:
    178251
     
    189262        nop
    190263
     264        FAKE_ABI_PROLOGUE
    191265exception_handler:
    192266        KERNEL_STACK_TO_K0
    193         sub $k0, REGISTER_SPACE
    194         sw $sp, EOFFSET_SP($k0)
     267       
     268        sub $k0, ISTATE_SOFT_SIZE
     269        sw $sp, ISTATE_OFFSET_SP($k0)
    195270        move $sp, $k0
    196271       
    197272        mfc0 $k0, $cause
    198273       
    199         sra $k0, $k0, 0x2    # cp0_exc_cause() part 1
    200         andi $k0, $k0, 0x1f  # cp0_exc_cause() part 2
    201         sub $k0, 8           # 8 = SYSCALL
     274        sra $k0, $k0, 0x2    /* cp0_exc_cause() part 1 */
     275        andi $k0, $k0, 0x1f  /* cp0_exc_cause() part 2 */
     276        sub $k0, 8           /* 8 = SYSCALL */
    202277       
    203278        beqz $k0, syscall_shortcut
    204         add $k0, 8           # Revert $k0 back to correct exc number
     279        add $k0, 8           /* revert $k0 back to correct exc number */
    205280       
    206281        REGISTERS_STORE_AND_EXC_RESET $sp
    207282       
    208283        move $a1, $sp
    209         jal exc_dispatch     # exc_dispatch(excno, register_space)
     284        jal exc_dispatch     /* exc_dispatch(excno, register_space) */
    210285        move $a0, $k0
    211 
     286       
    212287        REGISTERS_LOAD $sp
    213         # The $sp is automatically restored to former value
    214         eret
    215 
    216 ## Syscall entry
    217 #
    218 # Registers:
    219 #
    220 # @param v0             Syscall number.
    221 # @param a0             1st argument.
    222 # @param a1             2nd argument.
    223 # @param a2             3rd argument.
    224 # @param a3             4th argument.
    225 # @param t0             5th argument.
    226 # @param t1             6th argument.
    227 #
    228 # @return               The return value will be stored in v0.
    229 #
    230 #define SS_SP           EOFFSET_SP
    231 #define SS_STATUS       EOFFSET_STATUS
    232 #define SS_EPC          EOFFSET_EPC
    233 #define SS_K1           EOFFSET_K1
     288        /* the $sp is automatically restored to former value */
     289        eret
     290
     291/** Syscall entry
     292 *
     293 * Registers:
     294 *
     295 * @param $v0 Syscall number.
     296 * @param $a0 1st argument.
     297 * @param $a1 2nd argument.
     298 * @param $a2 3rd argument.
     299 * @param $a3 4th argument.
     300 * @param $t0 5th argument.
     301 * @param $t1 6th argument.
     302 *
     303 * @return The return value will be stored in $v0.
     304 *
     305 */
    234306syscall_shortcut:
    235         # We have a lot of space on the stack, with free use
    236307        mfc0 $t3, $epc
    237308        mfc0 $t2, $status
    238         sw $t3, SS_EPC($sp)             # Save EPC
    239         sw $k1, SS_K1($sp)              # Save k1 not saved on context switch
    240        
    241         and $t4, $t2, REG_SAVE_MASK     # Save only KSU, EXL, ERL, IE
     309        sw $t3, ISTATE_OFFSET_EPC($sp)  /* save EPC */
     310        sw $k1, ISTATE_OFFSET_KT1($sp)  /* save $k1 not saved on context switch */
     311       
     312        and $t4, $t2, REG_SAVE_MASK  /* save only KSU, EXL, ERL, IE */
    242313        li $t5, ~(0x1f)
    243         and $t2, $t2, $t5               # Clear KSU, EXL, ERL
    244         ori $t2, $t2, 0x1               # Set IE
    245 
    246         sw $t4, SS_STATUS($sp)
     314        and $t2, $t2, $t5  /* clear KSU, EXL, ERL */
     315        ori $t2, $t2, 0x1  /* set IE */
     316       
     317        sw $t4, ISTATE_OFFSET_STATUS($sp)
    247318        mtc0 $t2, $status
    248 
    249         #
    250         # Call the higher level system call handler
    251         # We are going to reuse part of the unused exception stack frame
    252         #
    253         sw $t0, STACK_ARG4($sp)         # save the 5th argument on the stack
    254         sw $t1, STACK_ARG5($sp)         # save the 6th argument on the stack
     319       
     320        /*
     321         * Call the higher level system call handler.
     322         *
     323         */
     324        sw $t0, ISTATE_OFFSET_T0($sp)  /* save the 5th argument on the stack */
     325        sw $t1, ISTATE_OFFSET_T1($sp)  /* save the 6th argument on the stack */
    255326        jal syscall_handler
    256         sw $v0, STACK_ARG6($sp)         # save the syscall number on the stack
    257 
    258         # restore status
     327        sw $v0, ISTATE_OFFSET_V0($sp)  /* save the syscall number on the stack */
     328       
     329        /* restore status */
    259330        mfc0 $t2, $status
    260         lw $t3, SS_STATUS($sp)
    261 
    262         # Change back to EXL = 1 (from last exception), otherwise
    263         # an interrupt could rewrite the CP0 - EPC
    264         li $t4, ~REG_SAVE_MASK          # Mask UM, EXL, ERL, IE
     331        lw $t3, ISTATE_OFFSET_STATUS($sp)
     332       
     333        /*
     334         * Change back to EXL = 1 (from last exception), otherwise
     335         * an interrupt could rewrite the CP0 - EPC.
     336         *
     337         */
     338        li $t4, ~REG_SAVE_MASK  /* mask UM, EXL, ERL, IE */
    265339        and $t2, $t2, $t4
    266         or $t2, $t2, $t3                # Copy saved UM, EXL, ERL, IE
     340        or $t2, $t2, $t3  /* copy saved UM, EXL, ERL, IE */
    267341        mtc0 $t2, $status
    268                        
    269         # restore epc + 4
    270         lw $t2, SS_EPC($sp)
    271         lw $k1, SS_K1($sp)
     342       
     343        /* restore epc + 4 */
     344        lw $t2, ISTATE_OFFSET_EPC($sp)
     345        lw $k1, ISTATE_OFFSET_KT1($sp)
    272346        addi $t2, $t2, 4
    273347        mtc0 $t2, $epc
    274348       
    275         lw $sp, SS_SP($sp)              # restore sp
    276        
    277         eret
    278                
     349        lw $sp, ISTATE_OFFSET_SP($sp)  /* restore $sp */
     350        eret
     351
     352        FAKE_ABI_PROLOGUE
    279353tlb_refill_handler:
    280354        KERNEL_STACK_TO_K0
    281         sub $k0, REGISTER_SPACE
     355        sub $k0, ISTATE_SOFT_SIZE
    282356        REGISTERS_STORE_AND_EXC_RESET $k0
    283         sw $sp,EOFFSET_SP($k0)
    284         add $sp, $k0, 0
    285 
     357        sw $sp, ISTATE_OFFSET_SP($k0)
     358        move $sp, $k0
     359       
    286360        jal tlb_refill
    287         add $a0, $sp, 0
    288 
     361        move $a0, $sp
     362       
    289363        REGISTERS_LOAD $sp
    290 
    291         eret
    292 
     364        eret
     365
     366        FAKE_ABI_PROLOGUE
    293367cache_error_handler:
    294368        KERNEL_STACK_TO_K0
    295         sub $k0, REGISTER_SPACE
     369        sub $k0, ISTATE_SOFT_SIZE
    296370        REGISTERS_STORE_AND_EXC_RESET $k0
    297         sw $sp,EOFFSET_SP($k0)
    298         add $sp, $k0, 0
    299 
     371        sw $sp, ISTATE_OFFSET_SP($k0)
     372        move $sp, $k0
     373       
    300374        jal cache_error
    301         add $a0, $sp, 0
    302 
     375        move $a0, $sp
     376       
    303377        REGISTERS_LOAD $sp
    304 
    305378        eret
    306379
    307380userspace_asm:
    308         add $sp, $a0, 0
    309         add $v0, $a1, 0
    310         add $t9, $a2, 0                 # Set up correct entry into PIC code
    311         xor $a0, $a0, $a0               # $a0 is defined to hold pcb_ptr
    312                                         # set it to 0
    313         eret
     381        move $sp, $a0
     382        move $v0, $a1
     383        move $t9, $a2      /* set up correct entry into PIC code */
     384        xor $a0, $a0, $a0  /* $a0 is defined to hold pcb_ptr */
     385                           /* set it to 0 */
     386        eret
Note: See TracChangeset for help on using the changeset viewer.