Changeset 1b109cb in mainline


Ignore:
Timestamp:
2006-03-20T13:39:56Z (19 years ago)
Author:
Ondrej Palkovsky <ondrap@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
9d3e185
Parents:
8d25b44
Message:

Cleanup of mips

  • inline register reads
  • better fpu disable/enable - global settings is automatically propagated to task
  • fast syscall
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • arch/mips32/include/cp0.h

    r8d25b44 r1b109cb  
    5959#define cp0_unmask_int(it) cp0_status_write(cp0_status_read() | (1<<(cp0_status_im_shift+(it))))
    6060
    61 extern  __u32 cp0_index_read(void);
    62 extern void cp0_index_write(__u32 val);
     61#define GEN_READ_CP0(nm,reg) static inline __u32 cp0_ ##nm##_read(void) \
     62  { \
     63      __u32 retval; \
     64      asm("mfc0 %0, $" #reg : "=r"(retval)); \
     65      return retval; \
     66  }
    6367
    64 extern __u32 cp0_random_read(void);
     68#define GEN_WRITE_CP0(nm,reg) static inline void cp0_ ##nm##_write(__u32 val) \
     69 { \
     70    asm("mtc0 %0, $" #reg : : "r"(val) ); \
     71 }
    6572
    66 extern __u32 cp0_entry_lo0_read(void);
    67 extern void cp0_entry_lo0_write(__u32 val);
     73GEN_READ_CP0(index, 0);
     74GEN_WRITE_CP0(index, 0);
    6875
    69 extern __u32 cp0_entry_lo1_read(void);
    70 extern void cp0_entry_lo1_write(__u32 val);
     76GEN_READ_CP0(random, 1);
    7177
    72 extern __u32 cp0_context_read(void);
    73 extern void cp0_context_write(__u32 val);
     78GEN_READ_CP0(entry_lo0, 2);
     79GEN_WRITE_CP0(entry_lo0, 2);
    7480
    75 extern __u32 cp0_pagemask_read(void);
    76 extern void cp0_pagemask_write(__u32 val);
     81GEN_READ_CP0(entry_lo1, 3);
     82GEN_WRITE_CP0(entry_lo1, 3);
    7783
    78 extern __u32 cp0_wired_read(void);
    79 extern void cp0_wired_write(__u32 val);
     84GEN_READ_CP0(context, 4);
     85GEN_WRITE_CP0(context, 4);
    8086
    81 extern __u32 cp0_badvaddr_read(void);
     87GEN_READ_CP0(pagemask, 5);
     88GEN_WRITE_CP0(pagemask, 5);
    8289
    83 extern __u32 cp0_count_read(void);
    84 extern void cp0_count_write(__u32 val);
     90GEN_READ_CP0(wired, 6);
     91GEN_WRITE_CP0(wired, 6);
    8592
    86 extern __u32 cp0_entry_hi_read(void);
    87 extern void cp0_entry_hi_write(__u32 val);
     93GEN_READ_CP0(badvaddr, 8);
    8894
    89 extern __u32 cp0_compare_read(void);
    90 extern void cp0_compare_write(__u32 val);
     95GEN_READ_CP0(count, 9);
     96GEN_WRITE_CP0(count, 9);
    9197
    92 extern __u32 cp0_status_read(void);
    93 extern void cp0_status_write(__u32 val);
     98GEN_READ_CP0(entry_hi, 10);
     99GEN_WRITE_CP0(entry_hi, 10);
    94100
    95 extern __u32 cp0_cause_read(void);
    96 extern void cp0_cause_write(__u32 val);
     101GEN_READ_CP0(compare, 11);
     102GEN_WRITE_CP0(compare, 11);
    97103
    98 extern __u32 cp0_epc_read(void);
    99 extern void cp0_epc_write(__u32 val);
     104GEN_READ_CP0(status, 12);
     105GEN_WRITE_CP0(status, 12);
    100106
    101 extern __u32 cp0_prid_read(void);
     107GEN_READ_CP0(cause, 13);
     108GEN_WRITE_CP0(cause, 13);
     109
     110GEN_READ_CP0(epc, 14);
     111GEN_WRITE_CP0(epc, 14);
     112
     113GEN_READ_CP0(prid, 15);
    102114
    103115#endif
  • arch/mips32/include/exception.h

    r8d25b44 r1b109cb  
    9999extern void cache_error_entry(void);
    100100extern void exception_init(void);
     101extern __native syscall_handler(__native a0, __native a1, __native a2,
     102                                __native a3, __native sysnum);
    101103#endif
  • arch/mips32/include/thread.h

    r8d25b44 r1b109cb  
    3232#include <arch/exception.h>
    3333
    34 #define ARCH_THREAD_DATA   istate_t *istate
     34#define ARCH_THREAD_DATA
    3535
    3636#endif
  • arch/mips32/src/asm.S

    r8d25b44 r1b109cb  
    4646.set noreorder
    4747.set nomacro
    48 
    49 .global cp0_index_read
    50 .global cp0_index_write
    51 .global cp0_random_read
    52 .global cp0_entry_lo0_read
    53 .global cp0_entry_lo0_write
    54 .global cp0_entry_lo1_read
    55 .global cp0_entry_lo1_write
    56 .global cp0_context_read
    57 .global cp0_context_write
    58 .global cp0_pagemask_read
    59 .global cp0_pagemask_write
    60 .global cp0_wired_read
    61 .global cp0_wired_write
    62 .global cp0_badvaddr_read
    63 .global cp0_count_read
    64 .global cp0_count_write
    65 .global cp0_entry_hi_read
    66 .global cp0_entry_hi_write
    67 .global cp0_compare_read
    68 .global cp0_compare_write
    69 .global cp0_status_read
    70 .global cp0_status_write
    71 .global cp0_cause_read
    72 .global cp0_cause_write
    73 .global cp0_epc_read
    74 .global cp0_epc_write
    75 .global cp0_prid_read
    76 
    77 cp0_index_read:         cp0_read $0
    78 cp0_index_write:        cp0_write $0
    79 
    80 cp0_random_read:        cp0_read $1
    81 
    82 cp0_entry_lo0_read:     cp0_read $2
    83 cp0_entry_lo0_write:    cp0_write $2
    84 
    85 cp0_entry_lo1_read:     cp0_read $3
    86 cp0_entry_lo1_write:    cp0_write $3
    87 
    88 cp0_context_read:       cp0_read $4
    89 cp0_context_write:      cp0_write $4
    90 
    91 cp0_pagemask_read:      cp0_read $5
    92 cp0_pagemask_write:     cp0_write $5
    93 
    94 cp0_wired_read:         cp0_read $6
    95 cp0_wired_write:        cp0_write $6
    96 
    97 cp0_badvaddr_read:      cp0_read $8
    98 
    99 cp0_count_read:         cp0_read $9
    100 cp0_count_write:        cp0_write $9
    101 
    102 cp0_entry_hi_read:      cp0_read $10
    103 cp0_entry_hi_write:     cp0_write $10
    104 
    105 cp0_compare_read:       cp0_read $11
    106 cp0_compare_write:      cp0_write $11
    107 
    108 cp0_status_read:        cp0_read $12
    109 cp0_status_write:       cp0_write $12
    110 
    111 cp0_cause_read:         cp0_read $13
    112 cp0_cause_write:        cp0_write $13
    113 
    114 cp0_epc_read:           cp0_read $14
    115 cp0_epc_write:          cp0_write $14
    116 
    117 cp0_prid_read:          cp0_read $15
    118 
    11948
    12049.global cpu_halt
  • arch/mips32/src/exception.c

    r8d25b44 r1b109cb  
    130130}
    131131
    132 #include <debug.h>
     132__native syscall_handler(__native a0, __native a1, __native a2,
     133                         __native a3, __native sysnum)
     134{
     135        if (sysnum < SYSCALL_END)
     136                return syscall_table[sysnum](a0,a1,a2,a3);
     137        panic("Undefined syscall %d", sysnum);
     138}
     139
    133140/** Handle syscall userspace call */
    134141static void syscall_exception(int n, istate_t *istate)
    135142{
    136         interrupts_enable();
    137         if (istate->t0 < SYSCALL_END)
    138                 istate->v0 = syscall_table[istate->t0](istate->a0,
    139                                                        istate->a1,
    140                                                        istate->a2,
    141                                                        istate->a3);
    142         else
    143                 panic("Undefined syscall %d", istate->a3);
    144         istate->epc += 4;
    145         interrupts_disable();
    146 }
    147 
    148 void exception(istate_t *istate)
    149 {
    150         int cause;
    151         int excno;
    152 
    153         ASSERT(CPU != NULL);
    154 
    155         /*
    156          * NOTE ON OPERATION ORDERING
    157          *
    158          * On entry, interrupts_disable() must be called before
    159          * exception bit is cleared.
    160          */
    161 
    162         interrupts_disable();
    163         cp0_status_write(cp0_status_read() & ~ (cp0_status_exl_exception_bit |
    164                                                 cp0_status_um_bit));
    165 
    166         /* Save istate so that the threads can access it */
    167         /* If THREAD->istate is set, this is nested exception,
    168          * do not rewrite it
    169          */
    170         if (THREAD && !THREAD->istate)
    171                 THREAD->istate = istate;
    172 
    173         cause = cp0_cause_read();
    174         excno = cp0_cause_excno(cause);
    175         /* Dispatch exception */
    176         exc_dispatch(excno, istate);
    177 
    178         /* Set to NULL, so that we can still support nested
    179          * exceptions
    180          * TODO: We should probably set EXL bit before this command,
    181          * nesting. On the other hand, if some exception occurs between
    182          * here and ERET, it won't set anything on the istate anyway.
    183          */
    184         if (THREAD)
    185                 THREAD->istate = NULL;
     143        panic("Syscall is handled through shortcut");
    186144}
    187145
  • arch/mips32/src/fpu_context.c

    r8d25b44 r1b109cb  
    3737#ifdef ARCH_HAS_FPU
    3838        cp0_status_write(cp0_status_read() & ~cp0_status_fpu_bit);
    39         if (THREAD && THREAD->istate)
    40                 THREAD->istate->status &= ~cp0_status_fpu_bit;
    4139#endif
    4240}
     
    4644#ifdef ARCH_HAS_FPU
    4745        cp0_status_write(cp0_status_read() | cp0_status_fpu_bit);
    48         if (THREAD && THREAD->istate)
    49                 THREAD->istate->status |= cp0_status_fpu_bit;
    5046#endif
    5147}
  • arch/mips32/src/start.S

    r8d25b44 r1b109cb  
    4444.global userspace_asm
    4545
     46# Which status bits should are thread-local
     47#define REG_SAVE_MASK 0x1f # KSU(UM), EXL, ERL, IE
     48       
    4649# Save registers to space defined by \r
    47 # We will change $at on the way
    48 .macro REGISTERS_STORE r
     50# We will change status: Disable ERL,EXL,UM,IE
     51# These changes will be automatically reversed in REGISTER_LOAD
     52.macro REGISTERS_STORE_AND_EXC_RESET r
    4953        sw $at,EOFFSET_AT(\r)
    5054        sw $v0,EOFFSET_V0(\r)
     
    8690        sw $sp,EOFFSET_SP(\r)
    8791
    88         mfc0 $at, $status
    89         sw $at,EOFFSET_STATUS(\r)
    90         mfc0 $at, $epc
    91         sw $at,EOFFSET_EPC(\r)
     92        mfc0 $t0, $status
     93        mfc0 $t1, $epc
     94       
     95        and $t2, $t0, REG_SAVE_MASK  # Save only KSU,EXL,ERL,IE
     96        li $t3, ~(0x1f)
     97        and $t0, $t0, $t3           # Clear KSU,EXL,ERL,IE
     98       
     99        sw $t2,EOFFSET_STATUS(\r)
     100        sw $t1,EOFFSET_EPC(\r)
     101        mtc0 $t0, $status
    92102.endm
    93103
    94104.macro REGISTERS_LOAD r
     105        # Update only UM,EXR,IE from status, the rest
     106        # is controlled by OS and not bound to task
     107        mfc0 $t0, $status
     108        lw $t1,EOFFSET_STATUS(\r)
     109
     110        li $t2, ~REG_SAVE_MASK    # Mask UM,EXL,ERL,IE
     111        and $t0, $t0, $t2
     112       
     113        or $t0, $t0, $t1   # Copy UM,EXL,ERL,IE from saved status
     114        mtc0 $t0, $status
     115       
    95116        lw $v0,EOFFSET_V0(\r)
    96117        lw $v1,EOFFSET_V1(\r)
     
    129150        mthi $at
    130151
    131         lw $at,EOFFSET_STATUS(\r)
    132         mtc0 $at, $status
    133152        lw $at,EOFFSET_EPC(\r)
    134153        mtc0 $at, $epc
     
    189208exception_handler:
    190209        KERNEL_STACK_TO_K0
     210       
     211        mfc0 $k1, $cause
    191212        sub $k0, REGISTER_SPACE
    192         REGISTERS_STORE $k0
    193         add $sp, $k0, 0
    194 
    195         add $a0, $sp, 0
    196         jal exception /* exception(register_space) */
    197         nop
     213       
     214        sra $k1, $k1, 0x2     # cp0_exc_cause() part 1
     215        andi $k1, $k1, 0x1f   # cp0_exc_cause() part 2
     216        sub $k1, 8            # 8=SYSCALL
     217       
     218        beqz $k1, uspace_shortcut
     219        add $k1, 8            # Revert $k1 back to correct exc number
     220       
     221        REGISTERS_STORE_AND_EXC_RESET $k0
     222        move $sp, $k0
     223       
     224        move $a1, $sp
     225        jal exc_dispatch      # exc_dispatch(excno, register_space)
     226        move $a0, $k1
    198227
    199228        REGISTERS_LOAD $sp
     
    201230        eret
    202231        nop
     232
     233# it seems that mips reserves some space on stack for varfuncs???
     234#define SS_ARG4   16
     235#define SS_SP     20
     236#define SS_STATUS 24
     237#define SS_EPC    28
     238#define SS_RA     32
     239uspace_shortcut:
     240        # We have a lot of space on the stack, with free use
     241        sw $sp, SS_SP($k0)
     242        move $sp, $k0
     243        sw $ra, SS_RA($k0)
     244
     245        mfc0 $t1, $epc
     246        mfc0 $t0, $status
     247        sw $t1,SS_EPC($sp)  # Save EPC
     248       
     249        and $t2, $t0, REG_SAVE_MASK # Save only KSU,EXL,ERL,IE
     250        li $t3, ~(0x1f)
     251        and $t0, $t0, $t3           # Clear KSU,EXL,ERL
     252        ori $t0, $t0, 0x1           # Set IE
     253
     254        sw $t2,SS_STATUS($sp)
     255        mtc0 $t0, $status
     256
     257        jal syscall_handler
     258        sw $v0, SS_ARG4($sp)        # save v0 - arg4 to stack
     259
     260        # Restore RA
     261        lw $ra, SS_RA($sp)
     262       
     263        # restore epc+4
     264        lw $t0,SS_EPC($sp)
     265        addi $t0, $t0, 4
     266        mtc0 $t0, $epc
     267       
     268        # restore status
     269        mfc0 $t0, $status
     270        lw $t1,SS_STATUS($sp)
     271
     272        li $t2, ~REG_SAVE_MASK      # Mask UM,EXL,ERL,IE
     273        and $t0, $t0, $t2
     274        or $t0, $t0, $t1            # Copy UM,EXL,ERL,IE from saved status
     275        mtc0 $t0, $status
     276                       
     277        lw $sp,SS_SP($sp) # restore sp
     278       
     279        eret
    203280       
    204281tlb_refill_handler:
    205282        KERNEL_STACK_TO_K0
    206283        sub $k0, REGISTER_SPACE
    207         REGISTERS_STORE $k0
     284        REGISTERS_STORE_AND_EXC_RESET $k0
    208285        add $sp, $k0, 0
    209286
     
    215292
    216293        eret
    217         nop
    218294
    219295cache_error_handler:
    220296        KERNEL_STACK_TO_K0
    221297        sub $sp, REGISTER_SPACE
    222         REGISTERS_STORE $sp
     298        REGISTERS_STORE_AND_EXC_RESET $sp
    223299        add $sp, $k0, 0
    224300
     
    229305
    230306        eret
    231         nop
    232307
    233308userspace_asm:
     
    235310        add $v0, $a1, 0
    236311        eret
    237         nop
    238 
     312
  • contrib/conf/gxemul.sh

    r8d25b44 r1b109cb  
    22# Uspace addresses outside of normal memory (kernel has std. 8 or 16MB)
    33# we place the pages at 24M
    4         gxemul -E testmips -X 0x81800000:init kernel.bin
     4        gxemul $@ -E testmips -X 0x81800000:init kernel.bin
  • kernel.config

    r8d25b44 r1b109cb  
    7575
    7676# Save all interrupt registers
    77 ! [CONFIG_DEBUG=y&(ARCH=amd64|ARCH=mips)] CONFIG_DEBUG_ALLREGS (y/n)
     77! [CONFIG_DEBUG=y&(ARCH=amd64|ARCH=mips32)] CONFIG_DEBUG_ALLREGS (y/n)
    7878
    7979## Run-time configuration directives
Note: See TracChangeset for help on using the changeset viewer.