Ignore:
File:
1 edited

Legend:

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

    r0c39b96 r96e0748d  
    4545.global userspace_asm
    4646
    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  */
     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
    10954.macro REGISTERS_STORE_AND_EXC_RESET r
    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        
     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
    13773        mflo $at
    138         sw $at, ISTATE_OFFSET_LO(\r)
     74        sw $at, EOFFSET_LO(\r)
    13975        mfhi $at
    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        
     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
    14782        mfc0 $t0, $status
    14883        mfc0 $t1, $epc
    14984       
    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)
     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)
    15991        mtc0 $t0, $status
    16092.endm
    16193
    16294.macro REGISTERS_LOAD r
    163         /*
    164          * Update only UM, EXR, IE from status, the rest
    165          * is controlled by OS and not bound to task.
    166          */
     95        # Update only UM,EXR,IE from status, the rest
     96        # is controlled by OS and not bound to task
    16797        mfc0 $t0, $status
    168         lw $t1, ISTATE_OFFSET_STATUS(\r)
    169        
    170         /* mask UM, EXL, ERL, IE */
    171         li $t2, ~REG_SAVE_MASK
     98        lw $t1,EOFFSET_STATUS(\r)
     99
     100        li $t2, ~REG_SAVE_MASK          # Mask UM,EXL,ERL,IE
    172101        and $t0, $t0, $t2
    173102       
    174         /* copy UM, EXL, ERL, IE from saved status */
    175         or $t0, $t0, $t1
     103        or $t0, $t0, $t1                # Copy UM,EXL, ERL, IE from saved status
    176104        mtc0 $t0, $status
    177105       
    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)
     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)
    200128        mtlo $at
    201         lw $at, ISTATE_OFFSET_HI(\r)
     129        lw $at, EOFFSET_HI(\r)
    202130        mthi $at
    203        
    204         lw $at, ISTATE_OFFSET_EPC(\r)
     131
     132        lw $at, EOFFSET_EPC(\r)
    205133        mtc0 $at, $epc
    206134       
    207         lw $at, ISTATE_OFFSET_AT(\r)
    208         lw $sp, ISTATE_OFFSET_SP(\r)
     135        lw $at, EOFFSET_AT(\r)
     136        lw $sp, EOFFSET_SP(\r)
    209137.endm
    210138
    211 /*
    212  * Move kernel stack pointer address to register $k0.
    213  * If we are in user mode, load the appropriate stack address.
    214  */
     139# Move kernel stack pointer address to register K0
     140# - if we are in user mode, load the appropriate stack
     141# address
    215142.macro KERNEL_STACK_TO_K0
    216         /* if we are in user mode */
     143        # If we are in user mode
    217144        mfc0 $k0, $status
    218145        andi $k0, 0x10
    219146       
    220147        beq $k0, $0, 1f
    221         move $k0, $sp
    222        
    223         /* move $k0 pointer to kernel stack */
     148        add $k0, $sp, 0
     149       
     150        # Move $k0 pointer to kernel stack
    224151        lui $k0, %hi(supervisor_sp)
    225152        ori $k0, $k0, %lo(supervisor_sp)
    226        
    227         /* move $k0 (supervisor_sp) */
    228         lw $k0, ($k0)
    229        
    230         1:
     153        # Move $k0 (superveisor_sp)
     154        lw $k0, 0($k0)
     1551:
    231156.endm
    232157
    233158.org 0x0
    234159kernel_image_start:
    235         /* load temporary stack */
     160        /* Load temporary stack */
    236161        lui $sp, %hi(end_stack)
    237162        ori $sp, $sp, %lo(end_stack)
    238163       
    239         /* not sure about this, but might be needed for PIC code */
     164        /* Not sure about this, but might
     165           be needed for PIC code */
    240166        lui $gp, 0x8000
    241167       
    242168        /* $a1 contains physical address of bootinfo_t */
     169       
    243170        jal arch_pre_main
    244171        nop
     
    247174        nop
    248175
    249 .space TEMP_STACK_SIZE
     176        .space TEMP_STACK_SIZE
    250177end_stack:
    251178
     
    262189        nop
    263190
    264         FAKE_ABI_PROLOGUE
    265191exception_handler:
    266192        KERNEL_STACK_TO_K0
    267        
    268         sub $k0, ISTATE_SOFT_SIZE
    269         sw $sp, ISTATE_OFFSET_SP($k0)
     193        sub $k0, REGISTER_SPACE
     194        sw $sp, EOFFSET_SP($k0)
    270195        move $sp, $k0
    271196       
    272197        mfc0 $k0, $cause
    273198       
    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 */
     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
    277202       
    278203        beqz $k0, syscall_shortcut
    279         add $k0, 8           /* revert $k0 back to correct exc number */
     204        add $k0, 8           # Revert $k0 back to correct exc number
    280205       
    281206        REGISTERS_STORE_AND_EXC_RESET $sp
    282207       
    283208        move $a1, $sp
    284         jal exc_dispatch     /* exc_dispatch(excno, register_space) */
     209        jal exc_dispatch     # exc_dispatch(excno, register_space)
    285210        move $a0, $k0
    286        
     211
    287212        REGISTERS_LOAD $sp
    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  */
     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
    306234syscall_shortcut:
     235        # We have a lot of space on the stack, with free use
    307236        mfc0 $t3, $epc
    308237        mfc0 $t2, $status
    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 */
     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
    313242        li $t5, ~(0x1f)
    314         and $t2, $t2, $t5  /* clear KSU, EXL, ERL */
    315         ori $t2, $t2, 0x1  /* set IE */
    316        
    317         sw $t4, ISTATE_OFFSET_STATUS($sp)
     243        and $t2, $t2, $t5               # Clear KSU, EXL, ERL
     244        ori $t2, $t2, 0x1               # Set IE
     245
     246        sw $t4, SS_STATUS($sp)
    318247        mtc0 $t2, $status
    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 */
     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
    326255        jal syscall_handler
    327         sw $v0, ISTATE_OFFSET_V0($sp)  /* save the syscall number on the stack */
    328        
    329         /* restore status */
     256        sw $v0, STACK_ARG6($sp)         # save the syscall number on the stack
     257
     258        # restore status
    330259        mfc0 $t2, $status
    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 */
     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
    339265        and $t2, $t2, $t4
    340         or $t2, $t2, $t3  /* copy saved UM, EXL, ERL, IE */
     266        or $t2, $t2, $t3                # Copy saved UM, EXL, ERL, IE
    341267        mtc0 $t2, $status
    342        
    343         /* restore epc + 4 */
    344         lw $t2, ISTATE_OFFSET_EPC($sp)
    345         lw $k1, ISTATE_OFFSET_KT1($sp)
     268                       
     269        # restore epc + 4
     270        lw $t2, SS_EPC($sp)
     271        lw $k1, SS_K1($sp)
    346272        addi $t2, $t2, 4
    347273        mtc0 $t2, $epc
    348274       
    349         lw $sp, ISTATE_OFFSET_SP($sp)  /* restore $sp */
    350         eret
    351 
    352         FAKE_ABI_PROLOGUE
     275        lw $sp, SS_SP($sp)              # restore sp
     276       
     277        eret
     278               
    353279tlb_refill_handler:
    354280        KERNEL_STACK_TO_K0
    355         sub $k0, ISTATE_SOFT_SIZE
     281        sub $k0, REGISTER_SPACE
    356282        REGISTERS_STORE_AND_EXC_RESET $k0
    357         sw $sp, ISTATE_OFFSET_SP($k0)
    358         move $sp, $k0
    359        
     283        sw $sp,EOFFSET_SP($k0)
     284        add $sp, $k0, 0
     285
    360286        jal tlb_refill
    361         move $a0, $sp
    362        
     287        add $a0, $sp, 0
     288
    363289        REGISTERS_LOAD $sp
    364         eret
    365 
    366         FAKE_ABI_PROLOGUE
     290
     291        eret
     292
    367293cache_error_handler:
    368294        KERNEL_STACK_TO_K0
    369         sub $k0, ISTATE_SOFT_SIZE
     295        sub $k0, REGISTER_SPACE
    370296        REGISTERS_STORE_AND_EXC_RESET $k0
    371         sw $sp, ISTATE_OFFSET_SP($k0)
    372         move $sp, $k0
    373        
     297        sw $sp,EOFFSET_SP($k0)
     298        add $sp, $k0, 0
     299
    374300        jal cache_error
    375         move $a0, $sp
    376        
     301        add $a0, $sp, 0
     302
    377303        REGISTERS_LOAD $sp
     304
    378305        eret
    379306
    380307userspace_asm:
    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
     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
Note: See TracChangeset for help on using the changeset viewer.