Ignore:
Timestamp:
Jan 8, 2018, 2:25:39 PM (7 years ago)
Author:
alain
Message:

Fix a bug in hal_kentry.S : the "uzone" pointer in the thread descriptor
must not be modified in case of interrupt.

Location:
trunk/hal/tsar_mips32/core
Files:
2 edited

Legend:

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

    r408 r418  
    9999       
    100100#------------------------------------------------------------------------------------
    101 # This code is executed when the core is in user mode:
     101# This code is executed when the core is in user mode,
     102# to handle a syscall, an interrupt, or an user exception.
    102103# - save current c2_mode in $26.
    103104# - set MMU OFF.
    104 # - save user stack pointer in $27.
    105 # - set kernel stack pointer in $29.
     105# - copy user stack pointer in $27 to be saved in uzone.
     106# - set kernel stack pointer in $29 == top_kernel_stack(this).
    106107
    107108user_mode:
     
    117118
    118119#------------------------------------------------------------------------------------
    119 # This code is executed when the core is already in kernel mode:
     120# This code is executed when the core is already in kernel mode,
     121# after a syscall, to handle an interrupt.
    120122# - save current c2_mode in $26.
    121123# - set MMU OFF.
    122 # - save current kernel stack pointer in $27.
     124# - copy current kernel stack pointer in $27.
    123125
    124126kernel_mode:
     
    134136# - $26 contains the previous c2_mode value.
    135137# - $27 contains the previous sp value (can be usp or ksp).
    136 # - $29 contains the kernel stack pointer.
     138# - $29 contains the curren kernel stack pointer.
    137139# We execute the following actions:
    138 # - allocate an uzone in kernel stack, decrementing $29.
     140# - decrement $29 to allocate an uzone in kernel stack
    139141# - save relevant GPR, CP0 and CP2 registers to uzone.
    140142# - set the SR in kernel mode: IRQ disabled, clear exl.
     
    198200        mtc0    $3,         $12                         # set new c0_sr
    199201
    200 #if CONFIG_KENTRY_DEBUG
     202#-----------------------
     203#if CONFIG_KENTRY_DEBUG
    201204
    202205    # display "enter" message
     
    207210    jal     putx
    208211    nop
     212    la      $4,     msg_cycle
     213    jal     puts
     214    nop
     215    jal     hal_time_stamp
     216    nop
     217    move    $4,     $2
     218    jal     putx
     219    nop
    209220    la      $4,     msg_crlf
    210221    jal     puts
     
    270281    jal     puts
    271282    nop   
    272        
     283
    273284#endif
     285#-----
    274286   
    275287#------------------------------------------------------------------------------------
    276 # This code update the uzone field in thread descriptor,
    277 # and call the relevant Interrupt / Exception / Syscall handler,
     288# This code calls the relevant Interrupt / Exception / Syscall handler,
    278289# depending on XCODE in CP0_CR.
    279 # assumption: $29 contains the kernel stack pointer, that is the uzone base.
     290# In case of syscall or exception, it set the "uzone" pointer in thread descriptor,
     291# that is used by the hal_do_syscall() & hal_do_exception() functions.
     292# WARNING: This "uzone" pointer is NOT modified in case of interrupt,
     293# because syscalls can be interrupted, and we want preserve this pointer.
    280294
    281295        mfc0    $17,    $13                 # $17 <= CR
    282296        andi    $17,    $17,   0x3F         # $17 <= XCODE
    283 
    284         mfc0    $4,     $4,   2             # $4 <= pointer on thread desc
    285     sw      $29,    8($4)               # update uzone pointer in thread desc
    286 
    287297        ori         $8,     $0,   0x20
    288298    beq     $8,     $17,  cause_sys     # go to syscall handler
     
    292302
    293303cause_excp:
     304        mfc0    $4,     $4,   2             # get pointer on thread desc
     305    sw      $29,    8($4)               # update uzone pointer in thread desc
    294306        jal     hal_do_exception            # call exception handler
    295307        nop
     
    298310
    299311cause_sys:
     312        mfc0    $4,     $4,   2             # get pointer on thread desc
     313    sw      $29,    8($4)               # update uzone pointer in thread desc
    300314        jal     hal_do_syscall              # call syscall handler                 
    301315    nop
     
    309323# -----------------------------------------------------------------------------------
    310324# Kernel exit
    311 # The pointer on uzone is supposed to be contained in $29
     325# - All registers saved in the uzone are restored, using the pointer on uzone,
     326#   that is contained in $29.
     327# - The "uzone" field in thread descriptor, that has beeen modified at kernel entry
     328#   is restored from value contained in the uzone[UZ_SP] slot.
    312329# -----------------------------------------------------------------------------------
     330
    313331kentry_exit:
    314332
     333#----------------------
    315334#if CONFIG_KENTRY_DEBUG
    316335
     
    322341    jal     putx
    323342    nop
     343    la      $4,     msg_cycle
     344    jal     puts
     345    nop
     346    jal     hal_time_stamp
     347    nop
     348    move    $4,     $2
     349    jal     putx
     350    nop
    324351    la      $4,     msg_crlf
    325352    jal     puts
     
    387414       
    388415#endif
     416#-----
    389417   
    390418        # restore registers from uzone
     
    475503    .align 2
    476504    .asciiz "\nexit kernel : &uzone = "
    477 
     505msg_cycle:
     506    .align 2
     507    .asciiz " / cycle = "
     508
  • trunk/hal/tsar_mips32/core/hal_syscall.c

    r416 r418  
    2929#include <hal_kentry.h>
    3030
     31// @@@
     32// __attribute__((section(".kdata"))) uint32_t * enter_uzone;
     33// __attribute__((section(".kdata"))) uint32_t * exit_uzone;
     34// @@@
    3135
    3236/////////////////////
     
    6973    exit_uzone = (uint32_t *)this->uzone;
    7074
     75// printk("\n@@@ %s exit : enter_uzone = %x / exit_uzone = %x\n",
     76// __FUNCTION__ , enter_uzone , exit_uzone );
     77
    7178    // set syscall return value to uzone
    7279        exit_uzone[UZ_V0] = retval;
     
    7582        exit_uzone[UZ_EPC] += 4;
    7683
     84    hal_fence();
    7785}
Note: See TracChangeset for help on using the changeset viewer.