Ignore:
Timestamp:
Aug 29, 2017, 12:03:37 PM (7 years ago)
Author:
alain
Message:

This version executed successfully the user "init" process on a mono-processor TSAR architecture.

File:
1 edited

Legend:

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

    r296 r406  
    2424 */
    2525
    26 #include <mips32_uzone.h>
    27 
    28 #---------------------------------------------------------------------------------
    29 # This code is the unique kernel entry point in case of exception, interrupt,
    30 # or syscall for the TSAR_MIPS32 architecture. 
    31 #
    32 # When we enter the kernel, we test the status register:
    33 # - If the core is in user mode, we desactivate the MMU, and we save
    34 #   the core context in the uzone of the calling thread descriptor.
    35 # - If the core is already in kernel mode (in case of interrupt),
    36 #   we save the context in the kernel stack.
    37 # - In both cases, we increment the cores_in_kernel variable,
    38 #   and we call the relevant exception/interrupt/syscall handler
    39 #
    40 # When we exit the kernel after handler execution:
    41 # - we restore the core context from the uzone
    42 #---------------------------------------------------------------------------------
     26#define      UZ_MODE         0                 
     27#define      UZ_AT           1
     28#define      UZ_V0           2
     29#define      UZ_V1           3
     30#define      UZ_A0           4
     31#define      UZ_A1           5
     32#define      UZ_A2           6
     33#define      UZ_A3           7
     34#define      UZ_T0           8
     35#define      UZ_T1           9
     36#define      UZ_T2           10
     37#define      UZ_T3           11
     38#define      UZ_T4           12
     39#define      UZ_T5           13
     40#define      UZ_T6           14
     41#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
     63
     64#include <kernel_config.h>
    4365
    4466        .section   .kentry, "ax", @progbits
     
    4870        .extern    hal_do_syscall
    4971        .extern    cluster_core_kernel_enter
    50         .extern    cluster_core_kernel_exit
     72        .extern    cluster_core_kentry_exit
    5173
    5274        .org       0x180
    53         .ent       kernel_enter
    54         .global    kernel_enter
     75
     76        .global    hal_kentry_enter
     77    .global    hal_kentry_eret
    5578
    5679        .set       noat
    5780        .set       noreorder
    5881
    59 #define SAVE_SIZE      CPU_REGS_NR*4
    60 #define LID_WIDTH      2
    61 #define CXY_WIDTH      8
    62 #define CXY_MASK       0xFF
    63 #define MMU_MODE_MASK  0xF
    64 #define GID_MASK       0x3FF   
    65 #define LID_MASK       0x3     
    66 
    6782#---------------------------------------------------------------------------------
    6883# Kernel Entry point for Interrupt / Exception / Syscall
     84# The c2_dext and c2_iext CP2 registers must have been previously set
     85# to "local_cxy", because the kernel run with MMU desactivated.
    6986#---------------------------------------------------------------------------------
    7087
    71 kernel_enter:
    72         mfc0    $26,    $12                 # read SR to test user/kernel mode
    73         andi    $26,    $26,  0x10          # User Mode bitmask
    74         beq     $26,    $0,       kernel_mode
    75         ori     $26,    $0,       0x3               # $26 <= MMU OFF value
     88hal_kentry_enter:
     89
     90        mfc0    $26,    $12                 # get c0_sr
     91        andi    $26,    $26,  0x10          # test User Mode bit
     92        beq     $26,    $0,       kernel_mode   # jump if core already in kernel
     93        ori     $27,    $0,       0x3           # $27 <= code for MMU OFF
    7694       
    7795#---------------------------------------------------------------------------------------       
    78 # this code is executed when the core is in user mode:
    79 # - we use the uzone defined in user thread descriptor.
    80 # - we set the MMU off, and save the CP2_MODE register to uzone.
    81 # - we save the user thread stack pointer to uzone and load the kernel stack pointer
    82 # - we store the uzone pointer in $27
     96# This code is executed when the core is in user mode:
     97# - save current c2_mode in $26.
     98# - set MMU OFF.
     99# - save user stack pointer in $27.
     100# - set kernel stack pointer in $29.
    83101
    84102user_mode:
    85         mtc2    $26,    $1                              # set MMU OFF
    86         nop
    87 
    88         mfc0    $26,    $4,   2             # $26 <= thread pointer
    89         lw      $26,    0($26)              # $26 <= uzone pointer
    90 
    91         sw      $29,    (UZ_SP*4)($26)      # save user stack to uzone
    92         lw      $29,    (UZ_KSP*4)($26)     # load kernel stack from uzone
    93 
    94         ori     $27,    $0,       0xF           # MMU old value: assumed ON
    95         sw      $27,    (UZ_MODE*4)($26)    # save MMU MODE to uzone
    96 
    97         j           unified_mode
    98         or      $27,    $0,       $26           # $27 <= uzone
     103
     104    mfc2    $26,    $1                  # $26 <= c2_mode
     105        mtc2    $27,    $1                              # set MMU OFF
     106    move    $27,    $29                 # $27 <= user stack pointer
     107        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
     110    j       unified_mode
     111    nop
    99112
    100113#---------------------------------------------------------------------------------------       
    101 # this code is executed when the core is in kernel mode:
    102 # - we use an uzone dynamically allocated in kernel stack.
    103 # - we set the MMU off, set the MMU data_paddr extension to local_cxy,
    104 #   and save the CP2_MODE and CP2_DEXT to uzone.
    105 # - we save the kernel stack pointer to uzone and load the new kernel stack pointer
    106 # - we store the uzone pointer in $27
     114# This code is executed when the core is already in kernel mode:
     115# - save current c2_mode in $26.
     116# - set MMU OFF.
     117# - save current kernel stack pointer in $27.
    107118
    108119kernel_mode:
    109         mfc2    $26,    $24
    110         andi    $26,    $26,  CXY_MASK      # $26 <= CP2_DEXT
    111 
    112         mfc0    $27,    $15,  1
    113         andi    $27,    $27,  GID_MASK      # $27 <= core_gid (4/4/2 format)   
    114 
    115         srl         $27,    $27,  LID_WIDTH         # $27 <= local_cxy
    116         mtc2    $27,    $24                             # set local_cxy to CP2_DEXT
    117 
    118     # use $26 to save both CP2_MODE (4 bits) and CP2_DEXT (8 bits) values
    119 
    120         mfc2    $27,    $1
    121         andi    $27,    $27,  MMU_MODE_MASK     # $27 <= CP2_MODE
    122         sll         $27,    $27,  CXY_WIDTH         # $27 <= 0x00000M00
    123         or          $26,    $26,  $27           # $26 <= 0x00000MXY
    124 
    125         ori     $27,    $0,       0x3
     120
     121    mfc2    $26,    $1                  # $26 <= c2_mode
    126122        mtc2    $27,    $1                              # set MMU OFF
    127 
    128         # save old SP, CP2_MODE and CP2_DEXT in uzone allocated in kernel stack
    129 
    130         addiu   $27,    $29,  -(SAVE_SIZE)      # allocate an uzone in stack (use $27 as KSP)
    131         sw      $29,    (UZ_SP*4)($27)      # save old KSP in this uzone
    132 
    133         srl     $29,    $26,  CXY_WIDTH
    134         sw      $29,    (UZ_MODE*4)($27)    # save CP2_MODE in this uzone
    135 
    136         andi    $26,    $26,  CXY_MASK 
    137         sw      $26,    (UZ_DEXT*4)($27)    # save CP2_DEXT in this uzone
    138 
    139         or      $29,    $27,    $0          # load new kernel stack pointer
    140 
    141 #--------------------------------------------------------------------------------------
    142 # This code is executed in both modes, and saves the core context,
    143 # with the two following assumptions:
    144 # - $27 contains the pointer on uzone to save the core registers
    145 # - $29 contains the kernel stack pointer
    146 
    147 unified_mode:   
    148         sw      $1,         (UZ_AT*4)($27)
    149         sw      $2,     (UZ_V0*4)($27)
    150         sw      $3,     (UZ_V1*4)($27)
    151         sw      $4,     (UZ_A0*4)($27)
    152         sw      $5,     (UZ_A1*4)($27)
    153         sw      $6,     (UZ_A2*4)($27)
    154         sw      $7,     (UZ_A3*4)($27)
    155         sw      $8,     (UZ_T0*4)($27)
    156         sw      $9,     (UZ_T1*4)($27)
    157         sw      $10,    (UZ_T2*4)($27)
    158         sw      $11,    (UZ_T3*4)($27)
    159         sw      $12,    (UZ_T4*4)($27)
    160         sw      $13,    (UZ_T5*4)($27)
    161         sw      $14,    (UZ_T6*4)($27)
    162         sw      $15,    (UZ_T7*4)($27)
    163         sw      $16,    (UZ_S0*4)($27)
    164         sw      $17,    (UZ_S1*4)($27)
    165         sw          $18,        (UZ_S2*4)($27)
    166         sw          $19,        (UZ_S3*4)($27)
    167         sw          $20,        (UZ_S4*4)($27)
    168         sw          $21,        (UZ_S5*4)($27)
    169         sw          $22,        (UZ_S6*4)($27)
    170         sw          $23,        (UZ_S7*4)($27)
    171         sw      $24,    (UZ_T8*4)($27)
    172         sw      $25,    (UZ_T9*4)($27)
    173         sw          $28,        (UZ_GP*4)($27)
    174         sw          $30,        (UZ_S8*4)($27)
    175         sw          $31,        (UZ_RA*4)($27)
     123    move    $27,    $29                 # $27 <= current kernel stack pointer
     124
     125#---------------------------------------------------------------------------------------       
     126# This code is executed in both modes (user or kernel):
     127# The assumptions are:
     128# - c2_mode contains the MMU OFF value.
     129# - $26 contains the previous c2_mode value.
     130# - $27 contains the previous sp value (can be usp or ksp).
     131# - $29 contains the kernel stack pointer.
     132# We execute the following actions:
     133# - allocate an uzone in kernel stack, incrementing $29
     134# - save relevant registers to uzone.
     135# - set the SR in kernel mode: IRQ disabled, clear exl.
     136# - signal the kernel entry.
     137
     138unified_mode:
     139
     140        addiu   $29,    $29,  -(UZ_REGS*4)      # allocate uzone in kernel stack
     141
     142        sw      $1,         (UZ_AT*4)($29)
     143        sw      $2,     (UZ_V0*4)($29)
     144        sw      $3,     (UZ_V1*4)($29)
     145        sw      $4,     (UZ_A0*4)($29)
     146        sw      $5,     (UZ_A1*4)($29)
     147        sw      $6,     (UZ_A2*4)($29)
     148        sw      $7,     (UZ_A3*4)($29)
     149        sw      $8,     (UZ_T0*4)($29)
     150        sw      $9,     (UZ_T1*4)($29)
     151        sw      $10,    (UZ_T2*4)($29)
     152        sw      $11,    (UZ_T3*4)($29)
     153        sw      $12,    (UZ_T4*4)($29)
     154        sw      $13,    (UZ_T5*4)($29)
     155        sw      $14,    (UZ_T6*4)($29)
     156        sw      $15,    (UZ_T7*4)($29)
     157        sw      $16,    (UZ_S0*4)($29)
     158        sw      $17,    (UZ_S1*4)($29)
     159        sw          $18,        (UZ_S2*4)($29)
     160        sw          $19,        (UZ_S3*4)($29)
     161        sw          $20,        (UZ_S4*4)($29)
     162        sw          $21,        (UZ_S5*4)($29)
     163        sw          $22,        (UZ_S6*4)($29)
     164        sw          $23,        (UZ_S7*4)($29)
     165        sw      $24,    (UZ_T8*4)($29)
     166        sw      $25,    (UZ_T9*4)($29)
     167
     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)
    176174
    177175        mfc0    $16,    $14
    178         sw      $16,    (UZ_EPC*4)($27)     # Save EPC
     176        sw      $16,    (UZ_EPC*4)($29)     # save c0_epc
    179177        mflo    $14
    180         sw      $14,    (UZ_LO*4)($27)      # save LO
     178        sw      $14,    (UZ_LO*4)($29)      # save lo
    181179        mfhi    $15
    182         sw      $15,    (UZ_HI*4)($27)          # save HI
     180        sw      $15,    (UZ_HI*4)($29)          # save hi
    183181        mfc0    $18,    $12
    184         sw          $18,        (UZ_SR*4)($27)          # Save SR
     182        sw          $18,        (UZ_SR*4)($29)          # save c0_sr
    185183        mfc0    $17,    $13
    186         sw      $17,    (UZ_CR*4)($27)          # Save CR
    187 
    188     # put SR in kernel mode, IRQ disabled, clear exl
     184        sw      $17,    (UZ_CR*4)($29)          # save c0_cr
     185        mfc2    $26,    $1
     186
    189187        srl         $3,     $18,  5
    190188        sll     $3,         $3,   5     
    191         mtc0    $3,         $12                         # Set new SR
     189        mtc0    $3,         $12                         # set new sr
    192190
    193191        # signal that core enters kernel
    194192        la      $1,     cluster_core_kernel_enter
    195         jal         $1
     193        jalr    $1
    196194    nop
    197195
    198196#---------------------------------------------------------------------------------------
    199197# This code call the relevant Interrupt / Exception / Syscall handler,
    200 # depending on XCODE in CP0_CR, with the two following assumptions:
    201 # - $27 contains the pointer on uzone containing to save the core registers
    202 # - $29 contains the kernel stack pointer
     198# depending on XCODE in CP0_CR.
     199# assumption: $29 contains the kernel stack pointer, that is the uzone base.
    203200# The three handlers take the same two arguments: thread pointer and uzone pointer.
    204 # The uzone pointer is saved in $19 to be used by kernel_exit.
     201# The uzone pointer is saved in $19 to be used by kentry_exit.
    205202
    206203        mfc0    $17,    $13                 # $17 <= CR
     
    208205
    209206        mfc0    $4,     $4,   2             # $4 <= thread pointer (first arg)
    210         or          $5,     $0,   $27               # $5 <= uzone pointer (second arg)
    211         or          $19,    $0,   $27           # $19 <= &uzone (for kernel_exit)
     207        or          $5,     $0,   $29               # $5 <= uzone pointer (second arg)
     208        or          $19,    $0,   $29           # $19 <= &uzone (for kentry_exit)
    212209
    213210        ori         $8,     $0,   0x20          # $8 <= cause syscall
     
    222219        addiu   $29,    $29,  -8                # hal_do_exception has 2 args
    223220        addiu   $29,    $29,  8
    224         j       kernel_exit                 # jump to kernel_exit
     221        j       kentry_exit                 # jump to kentry_exit
    225222    nop
    226223
     
    230227        addiu   $29,    $29,  -8            # hal_do_syscall has 2 args
    231228        addiu   $29,    $29,  8
    232         j           kernel_exit                 # jump to kernel_exit
     229        j           kentry_exit                 # jump to kentry_exit
    233230        nop
    234231       
     
    243240# The pointer on uzone is supposed to be stored in $19
    244241# -----------------------------------------------------------------------------------
    245 kernel_exit:
     242kentry_exit:
    246243
    247244        # signal that core exit kernel
     
    250247    nop
    251248
    252         # restore context from uzone
     249        # restore registers from uzone
    253250        or          $27,    $0, $19             # $27 <= &uzone
    254251
     
    296293        lw          $31,        (UZ_RA*4)($27)
    297294
    298         lw          $26,    (UZ_DEXT*4)($27)
    299         mtc2    $26,    $24                             # restore CP2_DEXT from uzone
    300 
    301295        lw          $26,    (UZ_MODE*4)($27)   
    302296    mtc2    $26,    $1                  # restore CP2_MODE from uzone
    303297
     298# -----------------------------------------------------------------------------------
     299# eret function
     300# -----------------------------------------------------------------------------------
     301
     302hal_kentry_eret:
    304303        nop
    305304    eret
    306305
    307     .end kernel_enter
    308306    .set reorder
    309307    .set at
    310308
    311 #-------------------------------------------------------------------------------
    312 
     309#------------------------------------------------------------------------------------
     310
Note: See TracChangeset for help on using the changeset viewer.