Ignore:
Timestamp:
Dec 5, 2017, 4:20:07 PM (6 years ago)
Author:
alain
Message:

Fix several bugs in the fork() syscall.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/hal/tsar_mips32/core/hal_kentry.S

    r407 r408  
    4040#define      UZ_T6           14
    4141#define      UZ_T7           15
    42 #define      UZ_T8           16
    43 #define      UZ_T9           17
    44 #define      UZ_S0           18
    45 #define      UZ_S1           19
    46 #define      UZ_S2           20
    47 #define      UZ_S3           21
    48 #define      UZ_S4           22
    49 #define      UZ_S5           23
    50 #define      UZ_S6           24
    51 #define      UZ_S7           25
    52 #define      UZ_S8           26
    53 #define      UZ_GP           27
    54 #define      UZ_RA           28
    55 #define      UZ_EPC          29
    56 #define      UZ_CR           30
    57 #define      UZ_SP           31
    58 #define      UZ_SR           32
    59 #define      UZ_LO           33
    60 #define      UZ_HI           34
    61 
    62 #define      UZ_REGS         35
     42#define      UZ_S0           16
     43#define      UZ_S1           17
     44#define      UZ_S2           18
     45#define      UZ_S3           19
     46#define      UZ_S4           20
     47#define      UZ_S5           21
     48#define      UZ_S6           22
     49#define      UZ_S7           23
     50#define      UZ_T8           24
     51#define      UZ_T9           25
     52
     53#define      UZ_LO           26
     54#define      UZ_HI           27
     55
     56#define      UZ_GP           28
     57#define      UZ_SP           29
     58#define      UZ_S8           30
     59#define      UZ_RA           31
     60#define      UZ_PTPR         32
     61#define      UZ_EPC          33
     62#define      UZ_SR           34
     63#define      UZ_TH           35
     64#define      UZ_CR           36
     65
     66#define      UZ_REGS         37
    6367
    6468#include <kernel_config.h>
     
    6973        .extern    hal_do_exception
    7074        .extern    hal_do_syscall
    71         .extern    cluster_core_kernel_enter
    72         .extern    cluster_core_kentry_exit
     75    .extern    puts
     76    .extern    putx
     77    .extern    putl
    7378
    7479        .org       0x180
     
    8085        .set       noreorder
    8186
    82 #---------------------------------------------------------------------------------
     87#------------------------------------------------------------------------------------
    8388# Kernel Entry point for Interrupt / Exception / Syscall
    8489# The c2_dext and c2_iext CP2 registers must have been previously set
    8590# to "local_cxy", because the kernel run with MMU desactivated.
    86 #---------------------------------------------------------------------------------
     91#------------------------------------------------------------------------------------
    8792
    8893hal_kentry_enter:
     
    9398        ori     $27,    $0,       0x3           # $27 <= code for MMU OFF
    9499       
    95 #---------------------------------------------------------------------------------------       
     100#------------------------------------------------------------------------------------
    96101# This code is executed when the core is in user mode:
    97102# - save current c2_mode in $26.
     
    106111    move    $27,    $29                 # $27 <= user stack pointer
    107112        mfc0    $29,    $4,   2             # get pointer on thread descriptor from c0_th
    108     addi    $29,    $29,    CONFIG_THREAD_DESC_SIZE
    109     addi    $29,    $29,    -8          # $29 <= kernel stack pointer
     113    addi    $29,    $29,  CONFIG_THREAD_DESC_SIZE
     114    addi    $29,    $29,  -8            # $29 <= kernel stack pointer
    110115    j       unified_mode
    111116    nop
    112117
    113 #---------------------------------------------------------------------------------------       
     118#------------------------------------------------------------------------------------
    114119# This code is executed when the core is already in kernel mode:
    115120# - save current c2_mode in $26.
     
    123128    move    $27,    $29                 # $27 <= current kernel stack pointer
    124129
    125 #---------------------------------------------------------------------------------------       
     130#------------------------------------------------------------------------------------   
    126131# This code is executed in both modes (user or kernel):
    127132# The assumptions are:
     
    131136# - $29 contains the kernel stack pointer.
    132137# We execute the following actions:
    133 # - allocate an uzone in kernel stack, incrementing $29
    134 # - save relevant registers to uzone.
     138# - allocate an uzone in kernel stack, decrementing $29.
     139# - save relevant GPR, CP0 and CP2 registers to uzone.
    135140# - set the SR in kernel mode: IRQ disabled, clear exl.
    136 # - signal the kernel entry.
    137141
    138142unified_mode:
     
    166170        sw      $25,    (UZ_T9*4)($29)
    167171
    168         sw      $26,    (UZ_MODE*4)($29)    # save c2_mode
    169         sw      $27,    (UZ_SP*4)($29)      # save sp
    170 
    171         sw          $28,        (UZ_GP*4)($29)
    172         sw          $30,        (UZ_S8*4)($29)
    173         sw          $31,        (UZ_RA*4)($29)
    174 
    175         mfc0    $16,    $14
    176         sw      $16,    (UZ_EPC*4)($29)     # save c0_epc
    177         mflo    $14
    178         sw      $14,    (UZ_LO*4)($29)      # save lo
    179         mfhi    $15
    180         sw      $15,    (UZ_HI*4)($29)          # save hi
    181         mfc0    $18,    $12
    182         sw          $18,        (UZ_SR*4)($29)          # save c0_sr
    183         mfc0    $17,    $13
    184         sw      $17,    (UZ_CR*4)($29)          # save c0_cr
    185         mfc2    $26,    $1
    186 
    187         srl         $3,     $18,  5
    188         sll     $3,         $3,   5     
    189         mtc0    $3,         $12                         # set new sr
    190 
    191 #---------------------------------------------------------------------------------------
    192 # This code call the relevant Interrupt / Exception / Syscall handler,
     172        mflo    $1
     173        sw      $1,     (UZ_LO*4)($29)      # save lo
     174        mflo    $1
     175        sw      $1,     (UZ_HI*4)($29)      # save hi
     176
     177        sw          $28,        (UZ_GP*4)($29)      # save gp
     178        sw          $27,        (UZ_SP*4)($29)      # save previous sp (can be usp or ksp)
     179        sw          $30,        (UZ_S8*4)($29)      # save s8
     180        sw          $31,        (UZ_RA*4)($29)      # save ra
     181
     182        mfc0    $1,     $14
     183        sw      $1,     (UZ_EPC*4)($29)     # save c0_epc
     184        mfc0    $1,         $12
     185        sw          $1,     (UZ_SR*4)($29)              # save c0_sr
     186        mfc0    $1,     $4,  2
     187        sw      $1,         (UZ_TH*4)($29)              # save c0_th
     188        mfc0    $1,     $13   
     189        sw      $1,         (UZ_CR*4)($29)              # save c0_cr
     190        mfc2    $1,     $0
     191        sw      $1,     (UZ_PTPR*4)($29)        # save c2_ptpr
     192
     193    sw      $26,    (UZ_MODE*4)($29)    # save previous c2_mode (can be user or kernel)
     194
     195    mfc0    $3,     $12
     196        srl         $3,     $3,   5
     197        sll     $3,         $3,   5                 # reset 5 LSB bits
     198        mtc0    $3,         $12                         # set new c0_sr
     199
     200#if CONFIG_KENTRY_DEBUG
     201
     202    # display "enter" message
     203    la      $4,     msg_enter
     204    jal     puts
     205    nop
     206    move    $4,     $29
     207    jal     putx
     208    nop
     209    la      $4,     msg_crlf
     210    jal     puts
     211    nop   
     212    # display saved SP value
     213    la      $4,     msg_sp
     214    jal     puts
     215    nop
     216    lw      $4,         (UZ_SP*4)($29)
     217    jal     putx
     218    nop
     219    la      $4,     msg_crlf
     220    jal     puts
     221    nop   
     222    # display saved RA value
     223    la      $4,     msg_ra
     224    jal     puts
     225    nop
     226    lw      $4,         (UZ_RA*4)($29)
     227    jal     putx
     228    nop
     229    la      $4,     msg_crlf
     230    jal     puts
     231    nop   
     232    # display saved TH value
     233    la      $4,     msg_th
     234    jal     puts
     235    nop
     236    lw      $4,         (UZ_TH*4)($29)
     237    jal     putx
     238    nop
     239    la      $4,     msg_crlf
     240    jal     puts
     241    nop   
     242    # display saved EPC value
     243    la      $4,     msg_epc
     244    jal     puts
     245    nop
     246    lw      $4,         (UZ_EPC*4)($29)
     247    jal     putx
     248    nop
     249    la      $4,     msg_crlf
     250    jal     puts
     251    nop   
     252    # display saved MODE value
     253    la      $4,     msg_mode
     254    jal     puts
     255    nop
     256    lw      $4,         (UZ_MODE*4)($29)
     257    jal     putx
     258    nop
     259    la      $4,     msg_crlf
     260    jal     puts
     261    nop   
     262    # display saved V0 value
     263    la      $4,     msg_v0
     264    jal     puts
     265    nop
     266    lw      $4,         (UZ_V0*4)($29)
     267    jal     putx
     268    nop
     269    la      $4,     msg_crlf
     270    jal     puts
     271    nop   
     272       
     273#endif
     274   
     275#------------------------------------------------------------------------------------
     276# This code update the uzone field in thread descriptor,
     277# and call the relevant Interrupt / Exception / Syscall handler,
    193278# depending on XCODE in CP0_CR.
    194279# assumption: $29 contains the kernel stack pointer, that is the uzone base.
    195 # The three handlers take the same two arguments: thread pointer and uzone pointer.
    196 # The uzone pointer is saved in $19 to be used by kentry_exit.
    197280
    198281        mfc0    $17,    $13                 # $17 <= CR
    199282        andi    $17,    $17,   0x3F         # $17 <= XCODE
    200283
    201         mfc0    $4,     $4,   2             # $4 <= thread pointer (first arg)
    202         or          $5,     $0,   $29               # $5 <= uzone pointer (second arg)
    203         or          $19,    $0,   $29           # $19 <= &uzone (for kentry_exit)
    204 
    205         ori         $8,     $0,   0x20          # $8 <= cause syscall
     284        mfc0    $4,     $4,   2             # $4 <= pointer on thread desc
     285    sw      $29,    8($4)               # update uzone pointer in thread desc
     286
     287        ori         $8,     $0,   0x20
    206288    beq     $8,     $17,  cause_sys     # go to syscall handler
    207289    nop
     
    210292
    211293cause_excp:
    212         la      $1,         hal_do_exception
    213         jalr    $1                              # call exception handler
    214         addiu   $29,    $29,  -8                # hal_do_exception has 2 args
    215         addiu   $29,    $29,  8
     294        jal     hal_do_exception            # call exception handler
     295        nop
    216296        j       kentry_exit                 # jump to kentry_exit
    217297    nop
    218298
    219299cause_sys:
    220         la          $1,         hal_do_syscall
    221         jalr    $1                          # call syscall handler                 
    222         addiu   $29,    $29,  -8            # hal_do_syscall has 2 args
    223         addiu   $29,    $29,  8
     300        jal     hal_do_syscall              # call syscall handler                 
     301    nop
    224302        j           kentry_exit                 # jump to kentry_exit
    225303        nop
    226304       
    227305cause_int:
    228         la          $1,     hal_do_interrupt
    229         jalr    $1                          # call interrupt handler
    230         addiu   $29,    $29,  -8            # hal_do_interrupt has 2 args
    231         addiu   $29,    $29,  8
     306        jal     hal_do_interrupt            # call interrupt handler
     307    nop
    232308
    233309# -----------------------------------------------------------------------------------
    234310# Kernel exit
    235 # The pointer on uzone is supposed to be stored in $19
     311# The pointer on uzone is supposed to be contained in $29
    236312# -----------------------------------------------------------------------------------
    237313kentry_exit:
    238314
     315#if CONFIG_KENTRY_DEBUG
     316
     317    # display "exit" message
     318    la      $4,     msg_exit
     319    jal     puts
     320    nop
     321    move    $4,     $29
     322    jal     putx
     323    nop
     324    la      $4,     msg_crlf
     325    jal     puts
     326    nop   
     327    # display saved SP value
     328    la      $4,     msg_sp
     329    jal     puts
     330    nop
     331    lw      $4,         (UZ_SP*4)($29)
     332    jal     putx
     333    nop
     334    la      $4,     msg_crlf
     335    jal     puts
     336    nop   
     337    # display saved RA value
     338    la      $4,     msg_ra
     339    jal     puts
     340    nop
     341    lw      $4,         (UZ_RA*4)($29)
     342    jal     putx
     343    nop
     344    la      $4,     msg_crlf
     345    jal     puts
     346    nop   
     347    # display saved TH value
     348    la      $4,     msg_th
     349    jal     puts
     350    nop
     351    lw      $4,         (UZ_TH*4)($29)
     352    jal     putx
     353    nop
     354    la      $4,     msg_crlf
     355    jal     puts
     356    nop   
     357    # display saved EPC value
     358    la      $4,     msg_epc
     359    jal     puts
     360    nop
     361    lw      $4,         (UZ_EPC*4)($29)
     362    jal     putx
     363    nop
     364    la      $4,     msg_crlf
     365    jal     puts
     366    nop   
     367    # display saved MODE value
     368    la      $4,     msg_mode
     369    jal     puts
     370    nop
     371    lw      $4,         (UZ_MODE*4)($29)
     372    jal     putx
     373    nop
     374    la      $4,     msg_crlf
     375    jal     puts
     376    nop   
     377    # display saved V0 value
     378    la      $4,     msg_v0
     379    jal     puts
     380    nop
     381    lw      $4,         (UZ_V0*4)($29)
     382    jal     putx
     383    nop
     384    la      $4,     msg_crlf
     385    jal     puts
     386    nop   
     387       
     388#endif
     389   
    239390        # restore registers from uzone
    240         or          $27,    $0, $19             # $27 <= &uzone
    241 
    242         lw          $29,        (UZ_SP*4)($27)          # restore SP from uzone
    243         lw          $16,        (UZ_EPC*4)($27)       
    244         mtc0    $16,    $14                             # restore EPC from uzone
    245         lw          $16,    (UZ_HI*4)($27)
    246         mthi    $16                                         # restore HI from uzone
    247         lw          $16,    (UZ_LO*4)($27)
    248         mtlo    $16                                         # restore LO from uzone
    249 
    250         lw          $17,        (UZ_SR*4)($27)          # get saved SR value from uzone
    251         andi    $17,    $17,    0x1F        # keep only the 5 LSB bits
    252         mfc0    $26,    $12                             # get current SR value from CP0
    253         or          $26,    $26,        $17         # merge the two values
    254         mtc0    $26,    $12                             # setup new SR to CP0
     391        or          $27,    $0, $29             # $27 <= ksp (contains &uzone)
     392
     393        lw          $1,     (UZ_EPC*4)($27)           
     394        mtc0    $1,         $14                         # restore c0_epc from uzone
     395        lw          $1,     (UZ_SR*4)($27)
     396        mtc0    $1,     $12                             # restore c0_sr from uzone
     397
     398        lw          $26,    (UZ_HI*4)($27)
     399        mthi    $26                                         # restore hi from uzone
     400        lw          $26,    (UZ_LO*4)($27)
     401        mtlo    $26                                         # restore lo from uzone
    255402
    256403        lw          $1,     (UZ_AT*4)($27)             
    257         lw          $2,     (UZ_V0*4)($27)
    258         lw          $3,     (UZ_V1*4)($27)
     404    lw      $2,     (UZ_V0*4)($27)
     405    lw      $3,     (UZ_V1*4)($27)
    259406        lw          $4,     (UZ_A0*4)($27)
    260407        lw          $5,     (UZ_A1*4)($27)
     
    279426        lw          $24,    (UZ_T8*4)($27)
    280427        lw          $25,    (UZ_T9*4)($27)     
    281         lw          $28,        (UZ_GP*4)($27)
    282         lw          $30,        (UZ_S8*4)($27)
    283         lw          $31,        (UZ_RA*4)($27)
     428
     429        lw          $28,        (UZ_GP*4)($27)      # restore gp_28 from uzone
     430        lw          $29,        (UZ_SP*4)($27)          # restore sp_29 from uzone
     431        lw          $30,        (UZ_S8*4)($27)      # restore s8_30 from uzone
     432        lw          $31,        (UZ_RA*4)($27)      # restore ra_31 from uzone
    284433
    285434        lw          $26,    (UZ_MODE*4)($27)   
     
    291440
    292441hal_kentry_eret:
    293         nop
    294     eret
     442    eret                                # jump to EPC, reset EXL bit
    295443
    296444    .set reorder
     
    298446
    299447#------------------------------------------------------------------------------------
    300 
     448    .section .kdata
     449
     450msg_sp:
     451    .align 2
     452    .asciiz "- UZ_SP   = "
     453msg_ra:
     454    .align 2
     455    .asciiz "- UZ_RA   = "
     456msg_epc:
     457    .align 2
     458    .asciiz "- UZ_EPC  = "
     459msg_th:
     460    .align 2
     461    .asciiz "- UZ_TH   = "
     462msg_mode:
     463    .align 2
     464    .asciiz "- UZ_MODE = "
     465msg_v0:
     466    .align 2
     467    .asciiz "- UZ_V0   = "
     468msg_crlf:
     469    .align 2
     470    .asciiz "\n"
     471msg_enter:
     472    .align 2
     473    .asciiz "\nenter kernel : &uzone = "
     474msg_exit:
     475    .align 2
     476    .asciiz "\nexit kernel : &uzone = "
     477
Note: See TracChangeset for help on using the changeset viewer.