Changeset 32f415d in rtems for cpukit/score/cpu/mips/cpu_asm.S


Ignore:
Timestamp:
12/13/00 18:09:48 (22 years ago)
Author:
Joel Sherrill <joel.sherrill@…>
Branches:
4.10, 4.11, 4.8, 4.9, 5, master
Children:
0289674
Parents:
0ef748fb
Message:

2000-12-13 Joel Sherrill <joel@…>

  • cpu_asm.h: Removed.
  • Makefile.am: Remove cpu_asm.h.
  • rtems/score/mips64orion.h: Renamed mips.h.
  • rtems/score/mips.h: New file, formerly mips64orion.h. Header rewritten. (mips_get_sr, mips_set_sr, mips_enable_in_interrupt_mask, mips_disable_in_interrupt_mask): New macros.
  • rtems/score/Makefile.am: Reflect renaming mips64orion.h.
  • asm.h: Include <mips.h> not <mips64orion.h>. Now includes the few defines that were in <cpu_asm.h>.
  • cpu.c (_CPU_ISR_Get_level): Added MIPS ISA I version of this routine. MIPS ISA 3 is still in assembly for now. (_CPU_Thread_Idle_body): Rewrote in C.
  • cpu_asm.S: Rewrote file header. (FRAME,ENDFRAME) now in asm.h. (_CPU_ISR_Get_level): Removed ISA I version and rewrote in C. (_CPU_ISR_Set_level): Removed ISA I version and rewrote in C. (_CPU_Context_switch): MIPS ISA I now manages preserves SR_IEC and leaves other bits in SR alone on task switch. (mips_enable_interrupts,mips_disable_interrupts, mips_enable_global_interrupts,mips_disable_global_interrupts, disable_int, enable_int): Removed. (mips_get_sr): Rewritten as C macro. (_CPU_Thread_Idle_body): Rewritten in C. (init_exc_vecs): Rewritten in C as mips_install_isr_entries() and placed in libcpu. (exc_tlb_code, exc_xtlb_code, exc_cache_code, exc_norm_code): Moved to libcpu/mips/shared/interrupts. (general): Cleaned up comment blocks and #if 0 areas.
  • idtcpu.h: Made ifdef report an error.
  • iregdef.h: Removed warning.
  • rtems/score/cpu.h (CPU_INTERRUPT_NUMBER_OF_VECTORS): Now a variable number defined by libcpu. (_CPU_ISR_Disable, _CPU_ISR_Enable): Rewritten to use new routines to access SR. (_CPU_ISR_Set_level): Rewritten as macro for ISA I. (_CPU_Context_Initialize): Honor ISR level in task initialization. (_CPU_Fatal_halt): Use new _CPU_ISR_Disable() macro.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • cpukit/score/cpu/mips/cpu_asm.S

    r0ef748fb r32f415d  
    1 /*  cpu_asm.S
    2  *
     1/*
    32 *  This file contains the basic algorithms for all assembly code used
    43 *  in an specific CPU port of RTEMS.  These algorithms must be implemented
    54 *  in assembly language
    65 *
    7  *  Author:     Craig Lebakken <craigl@transition.com>
    8  *
    9  *  COPYRIGHT (c) 1996 by Transition Networks Inc.
    10  *
    11  *  To anyone who acknowledges that this file is provided "AS IS"
    12  *  without any express or implied warranty:
    13  *      permission to use, copy, modify, and distribute this file
    14  *      for any purpose is hereby granted without fee, provided that
    15  *      the above copyright notice and this notice appears in all
    16  *      copies, and that the name of Transition Networks not be used in
    17  *      advertising or publicity pertaining to distribution of the
    18  *      software without specific, written prior permission.
    19  *      Transition Networks makes no representations about the suitability
    20  *      of this software for any purpose.
    21  *
    22  *  Derived from c/src/exec/score/cpu/no_cpu/cpu_asm.s:
    23  *
    24  *  COPYRIGHT (c) 1989-1999.
     6 *  History:
     7 *    Baseline: no_cpu
     8 *    1996:     Ported to MIPS64ORION by Craig Lebakken <craigl@transition.com>
     9 *          COPYRIGHT (c) 1996 by Transition Networks Inc.
     10 *          To anyone who acknowledges that the modifications to this file to
     11 *          port it to the MIPS64ORION are provided "AS IS" without any
     12 *          express or implied warranty:
     13 *             permission to use, copy, modify, and distribute this file
     14 *             for any purpose is hereby granted without fee, provided that
     15 *             the above copyright notice and this notice appears in all
     16 *             copies, and that the name of Transition Networks not be used in
     17 *             advertising or publicity pertaining to distribution of the
     18 *             software without specific, written prior permission. Transition
     19 *             Networks makes no representations about the suitability
     20 *             of this software for any purpose.
     21 *    2000: Reworked by Alan Cudmore <alanc@linuxstart.com> to become
     22 *          the more general MIPS port.  Joel Sherrill <joel@OARcorp.com>
     23 *          continued this rework, rewriting as much as possible in
     24 *          C and testing on the TX39.
     25 * 
     26 *  COPYRIGHT (c) 1989-2000.
    2527 *  On-Line Applications Research Corporation (OAR).
    2628 *
     
    3133 *  $Id$
    3234 */
    33 /* @(#)cpu_asm.S       08/20/96     1.15 */
    34 
    35 #include "cpu_asm.h"
    36 
     35
     36#include <asm.h>
    3737#include "iregdef.h"
    3838#include "idtcpu.h"
    39 
    40 #define FRAME(name,frm_reg,offset,ret_reg)      \
    41         .globl  name;                           \
    42         .ent    name;                           \
    43 name:;                                          \
    44         .frame  frm_reg,offset,ret_reg
    45 #define ENDFRAME(name)                          \
    46         .end name
    4739
    4840#define EXCP_STACK_SIZE (NREGS*R_SZ)
     
    124116 *
    125117 *  _CPU_ISR_Get_level
     118 *
     119 *  unsigned32 _CPU_ISR_Get_level( void )
     120 *
     121 *  This routine returns the current interrupt level.
    126122 */
    127 
    128 #if 0
    129 unsigned32 _CPU_ISR_Get_level( void )
    130 {
    131   /*
    132    *  This routine returns the current interrupt level.
    133    */
    134 }
    135 #endif
    136123
    137124#if __mips == 3
     
    189176
    190177/* MIPS ISA 1 ( R3000 ) */
    191 /* These routines might not be needed for the R3000 */
    192 /* Q:Who calls _CPU_ISR_Get/Set_level? */
    193 FRAME(_CPU_ISR_Get_level,sp,0,ra)
    194         mfc0 v0,C0_SR
    195         nop
    196         andi v0, SR_IEC
    197         j ra
    198 ENDFRAME(_CPU_ISR_Get_level)
    199 
    200 FRAME(_CPU_ISR_Set_level,sp,0,ra)
    201         nop
    202         mfc0 t0,C0_SR
    203         andi a0, SR_IEC
    204         or   t0, a0
    205         mtc0 t0,C0_SR
    206         nop
    207         j ra
    208 ENDFRAME(_CPU_ISR_Set_level)
     178/* _CPU_ISR_Get/Set_level are called as part of task mode manipulation. */
     179/*  and are defined in C for the __mips == 1 */
    209180
    210181#else
     
    226197
    227198/* void _CPU_Context_save_fp(
    228  * void **fp_context_ptr
    229  * )
    230  * {
    231  * }
     199 *   void **fp_context_ptr
     200 * );
    232201 */
    233202
     
    286255
    287256/* void _CPU_Context_restore_fp(
    288  * void **fp_context_ptr
     257 *   void **fp_context_ptr
    289258 * )
    290  * {
    291  * }
    292259 */
    293260
     
    338305
    339306/* void _CPU_Context_switch(
    340  * Context_Control  *run,
    341  * Context_Control  *heir
     307 *   Context_Control  *run,
     308 *   Context_Control  *heir
    342309 * )
    343  * {
    344  * }
    345310 */
    346311#if __mips == 3
     
    403368
    404369        mfc0 t0,C0_SR
    405         li t1,~SR_IEC
     370        li t1,~SR_IEC
    406371        sw t0,C0_SR_OFFSET*4(a0)        /* save status register */
    407372        and t0,t1
     
    437402        lw t0,C0_EPC_OFFSET*4(a1)
    438403        mtc0 t0,C0_EPC
    439         lw t1, C0_SR_OFFSET*4(a1)
    440         mtc0 t1,C0_SR
    441 
    442         /* Q:Changes needed to SR_IEC bit in SR/_CPU_Context_switch_restore? */
     404        lw t0, C0_SR_OFFSET*4(a1)
     405        andi t0,SR_IEC                  /* we know IEC=0, e.g. disabled */
     406        beq t0,$0,_CPU_Context_1        /* set IEC level from restore context */
     407        mfc0 t0,C0_SR
     408        nop
     409        or  t0,SR_IEC                   /* new_sr = sr | SR_IEC */
     410        mtc0 t0,C0_SR                   /* set with enabled */
     411       
    443412
    444413_CPU_Context_1:
     
    460429 *
    461430 *  NOTE: May be unnecessary to reload some registers.
     431 *
     432 *  void _CPU_Context_restore(
     433 *    Context_Control *new_context
     434 *  );
    462435 */
    463 
    464 #if 0
    465 void _CPU_Context_restore(
    466   Context_Control *new_context
    467 )
    468 {
    469 }
    470 #endif
    471436
    472437#if __mips == 3
     
    503468 *  This routine provides the RTEMS interrupt management.
    504469 *
     470 *  void _ISR_Handler()
     471 *
     472 *
     473 *  This discussion ignores a lot of the ugly details in a real
     474 *  implementation such as saving enough registers/state to be
     475 *  able to do something real.  Keep in mind that the goal is
     476 *  to invoke a user's ISR handler which is written in C and
     477 *  uses a certain set of registers.
     478 *
     479 *  Also note that the exact order is to a large extent flexible.
     480 *  Hardware will dictate a sequence for a certain subset of
     481 *  _ISR_Handler while requirements for setting
     482 *
     483 *  At entry to "common" _ISR_Handler, the vector number must be
     484 *  available.  On some CPUs the hardware puts either the vector
     485 *  number or the offset into the vector table for this ISR in a
     486 *  known place.  If the hardware does not give us this information,
     487 *  then the assembly portion of RTEMS for this port will contain
     488 *  a set of distinct interrupt entry points which somehow place
     489 *  the vector number in a known place (which is safe if another
     490 *  interrupt nests this one) and branches to _ISR_Handler.
     491 *
    505492 */
    506 
    507 #if 0
    508 void _ISR_Handler()
    509 {
    510    /*
    511     *  This discussion ignores a lot of the ugly details in a real
    512     *  implementation such as saving enough registers/state to be
    513     *  able to do something real.  Keep in mind that the goal is
    514     *  to invoke a user's ISR handler which is written in C and
    515     *  uses a certain set of registers.
    516     *
    517     *  Also note that the exact order is to a large extent flexible.
    518     *  Hardware will dictate a sequence for a certain subset of
    519     *  _ISR_Handler while requirements for setting
    520     */
    521 
    522   /*
    523    *  At entry to "common" _ISR_Handler, the vector number must be
    524    *  available.  On some CPUs the hardware puts either the vector
    525    *  number or the offset into the vector table for this ISR in a
    526    *  known place.  If the hardware does not give us this information,
    527    *  then the assembly portion of RTEMS for this port will contain
    528    *  a set of distinct interrupt entry points which somehow place
    529    *  the vector number in a known place (which is safe if another
    530    *  interrupt nests this one) and branches to _ISR_Handler.
    531    *
    532    */
    533 #endif
    534493
    535494#if __mips == 3
     
    584543        mfc0 k0,C0_CAUSE
    585544        and k1,k0,CAUSE_EXCMASK
    586         bnez k1,_ISR_Handler_prom_exit /* not an external interrup
    587 t, pass exception to Monitor */
     545        bnez k1,_ISR_Handler_prom_exit /* not an external interrupt,
     546                                                pass exception to Monitor */
    588547        mfc0 k1,C0_SR
    589548        and k0,k1
    590549        and k0,CAUSE_IPMASK
    591         beq k0,zero,_ISR_Handler_quick_exit /* external interrupt not enabled, ignore */
     550        beq k0,zero,_ISR_Handler_quick_exit /* external interrupt not
     551                                                        enabled, ignore */
    592552        nop
    593553
     
    1036996#endif
    1037997
    1038 FRAME(mips_enable_interrupts,sp,0,ra)
    1039         mfc0 t0,C0_SR           /* get status reg */
    1040         nop
    1041         or t0,t0,a0             
    1042         mtc0 t0,C0_SR           /* save updated status reg */
    1043         j ra
    1044         nop
    1045 ENDFRAME(mips_enable_interrupts)
    1046 
    1047 FRAME(mips_disable_interrupts,sp,0,ra)
    1048         mfc0 v0,C0_SR           /* get status reg */
    1049         li t1,SR_IMASK          /* t1 = load interrupt mask word */
    1050         not t0,t1               /* t0 = ~t1 */
    1051         and t0,v0               /* clear imask bits */
    1052         mtc0 t0,C0_SR           /* save status reg */
    1053         and v0,t1               /* mask return value (only return imask bits) */
    1054         jr ra
    1055         nop
    1056 ENDFRAME(mips_disable_interrupts)
    1057 
    1058 #if __mips == 3
    1059 
    1060 FRAME(mips_enable_global_interrupts,sp,0,ra)
    1061         mfc0 t0,C0_SR           /* get status reg */
    1062         nop
    1063         ori t0,SR_IE
    1064         mtc0 t0,C0_SR           /* save updated status reg */
    1065         j ra
    1066         nop
    1067 ENDFRAME(mips_enable_global_interrupts)
    1068 
    1069 FRAME(mips_disable_global_interrupts,sp,0,ra)
    1070         li t1,SR_IE
    1071         mfc0 t0,C0_SR           /* get status reg */
    1072         not t1
    1073         and t0,t1
    1074         mtc0 t0,C0_SR           /* save updated status reg */
    1075         j ra
    1076         nop
    1077 ENDFRAME(mips_disable_global_interrupts)
    1078 
    1079 #elif __mips == 1
    1080 
    1081 FRAME(mips_enable_global_interrupts,sp,0,ra)
    1082         mfc0 t0,C0_SR           /* get status reg */
    1083         nop
    1084         ori t0,SR_IEC
    1085         mtc0 t0,C0_SR           /* save updated status reg */
    1086         j ra
    1087         nop
    1088 ENDFRAME(mips_enable_global_interrupts)
    1089 
    1090 FRAME(mips_disable_global_interrupts,sp,0,ra)
    1091         li t1,SR_IEC
    1092         mfc0 t0,C0_SR           /* get status reg */
    1093         not t1
    1094         and t0,t1
    1095         mtc0 t0,C0_SR           /* save updated status reg */
    1096         j ra
    1097         nop
    1098 ENDFRAME(mips_disable_global_interrupts)
    1099 
    1100 #else
    1101 
    1102    #error "__mips is not set to 1 or 3"
    1103 
    1104 #endif
    1105 
    1106 /* return the value of the status register in v0.  Used for debugging */
    1107 FRAME(mips_get_sr,sp,0,ra)
    1108         mfc0 v0,C0_SR
    1109         j ra
    1110         nop
    1111 ENDFRAME(mips_get_sr)
    1112 
    1113998FRAME(mips_break,sp,0,ra)
    1114999#if 1
     
    11211006ENDFRAME(mips_break)
    11221007
    1123 
    1124 /**************************************************************************
    1125 **
    1126 ** enable_int(mask) - enables interrupts - mask is positioned so it only
    1127 **                      needs to be or'ed into the status reg. This
    1128 **                      also does some other things !!!! caution should
    1129 **                      be used if invoking this while in the middle
    1130 **                      of a debugging session where the client may have
    1131 **                      nested interrupts.
    1132 **
    1133 ****************************************************************************/
    1134 FRAME(enable_int,sp,0,ra)
    1135         .set    noreorder
    1136         mfc0    t0,C0_SR
    1137         or      a0,1
    1138         or      t0,a0
    1139         mtc0    t0,C0_SR
    1140         j       ra
    1141         nop
    1142         .set    reorder
    1143 ENDFRAME(enable_int)
    1144 
    1145 
    1146 /***************************************************************************
    1147 **
    1148 **      disable_int(mask) - disable the interrupt - mask is the complement
    1149 **                          of the bits to be cleared - i.e. to clear ext int
    1150 **                          5 the mask would be - 0xffff7fff
    1151 **
    1152 ****************************************************************************/
    1153 FRAME(disable_int,sp,0,ra)
    1154         .set    noreorder
    1155         mfc0    t0,C0_SR
    1156         nop
    1157         and     t0,a0
    1158         mtc0    t0,C0_SR
    1159         j       ra
    1160         nop
    1161 ENDFRAME(disable_int)
    1162 
    1163 
    1164 /*PAGE
    1165  *
    1166  *  _CPU_Internal_threads_Idle_thread_body
    1167  *
    1168  *  NOTES:
    1169  *
    1170  *  1. This is the same as the regular CPU independent algorithm.
    1171  *
    1172  *  2. If you implement this using a "halt", "idle", or "shutdown"
    1173  *     instruction, then don't forget to put it in an infinite loop.
    1174  *
    1175  *  3. Be warned. Some processors with onboard DMA have been known
    1176  *     to stop the DMA if the CPU were put in IDLE mode.  This might
    1177  *     also be a problem with other on-chip peripherals.  So use this
    1178  *     hook with caution.
    1179  */
    1180 
    1181 #if __mips == 3
    1182 
    1183 FRAME(_CPU_Thread_Idle_body,sp,0,ra)
    1184         wait                    /* enter low power mode */
    1185         j _CPU_Thread_Idle_body
    1186         nop
    1187 ENDFRAME(_CPU_Thread_Idle_body)
    1188 
    1189 #elif __mips == 1
    1190 
    1191 FRAME(_CPU_Thread_Idle_body,sp,0,ra)
    1192         nop                     /* no wait instruction */
    1193         j _CPU_Thread_Idle_body
    1194         nop
    1195 ENDFRAME(_CPU_Thread_Idle_body)
    1196 
    1197 #else
    1198 
    1199    #error "__mips not set to 1 or 3"
    1200    
    1201 #endif
    1202 
    1203 /**************************************************************************
    1204 **
    1205 **      init_exc_vecs() - moves the exception code into the addresses
    1206 **                        reserved for exception vectors
    1207 **
    1208 **      UTLB Miss exception vector at address 0x80000000
    1209 **
    1210 **      General exception vector at address 0x80000080
    1211 **
    1212 **      RESET exception vector is at address 0xbfc00000
    1213 **
    1214 ***************************************************************************/
    1215 
    1216 #define VEC_CODE_LENGTH 10*4
    1217 
    1218 FRAME(init_exc_vecs,sp,0,ra)
    1219 
    1220 #if __mips == 1
    1221 
    1222         .set    noreorder
    1223         la      t1,exc_utlb_code
    1224         la      t2,exc_norm_code
    1225         li      t3,UT_VEC
    1226         li      t4,E_VEC
    1227         li      t5,VEC_CODE_LENGTH
    1228 1:
    1229         lw      t6,0(t1)
    1230         lw      t7,0(t2)
    1231         sw      t6,0(t3)
    1232         sw      t7,0(t4)
    1233         addiu   t1,4
    1234         addiu   t3,4
    1235         addiu   t4,4
    1236         subu    t5,4
    1237         bne     t5,zero,1b
    1238         addiu   t2,4
    1239         move    t5,ra           # assumes clear_cache doesnt use t5
    1240         li      a0,UT_VEC
    1241         jal     clear_cache          /* Check out clear cache.... */
    1242         li      a1,VEC_CODE_LENGTH
    1243         nop
    1244         li      a0,E_VEC
    1245         jal     clear_cache
    1246         li      a1,VEC_CODE_LENGTH
    1247         move    ra,t5           # restore ra
    1248         j       ra
    1249         nop
    1250         .set    reorder
    1251 
    1252 #elif __mips == 3
    1253 
    1254         .set reorder
    1255         move    t5,ra           # assumes clear_cache doesnt use t5
    1256 
    1257         /* TLB exception vector */
    1258         la      t1,exc_tlb_code
    1259         li      t2,T_VEC |K1BASE
    1260         li      t3,VEC_CODE_LENGTH
    1261 1:
    1262         lw      t6,0(t1)
    1263         addiu   t1,4
    1264         subu    t3,4
    1265         sw      t6,0(t2)
    1266         addiu   t2,4
    1267         bne     t3,zero,1b
    1268 
    1269         li      a0,T_VEC
    1270         li      a1,VEC_CODE_LENGTH
    1271         jal     clear_cache
    1272 
    1273         la      t1,exc_xtlb_code
    1274         li      t2,X_VEC |K1BASE
    1275         li      t3,VEC_CODE_LENGTH
    1276 1:
    1277         lw      t6,0(t1)
    1278         addiu   t1,4
    1279         subu    t3,4
    1280         sw      t6,0(t2)
    1281         addiu   t2,4
    1282         bne     t3,zero,1b
    1283 
    1284         /* extended TLB exception vector */
    1285         li      a0,X_VEC
    1286         li      a1,VEC_CODE_LENGTH
    1287         jal     clear_cache
    1288 
    1289         /* cache error exception vector */
    1290         la      t1,exc_cache_code
    1291         li      t2,C_VEC |K1BASE
    1292         li      t3,VEC_CODE_LENGTH
    1293 1:
    1294         lw      t6,0(t1)
    1295         addiu   t1,4
    1296         subu    t3,4
    1297         sw      t6,0(t2)
    1298         addiu   t2,4
    1299         bne     t3,zero,1b
    1300 
    1301         li      a0,C_VEC
    1302         li      a1,VEC_CODE_LENGTH
    1303         jal     clear_cache
    1304 
    1305         /* normal exception vector */
    1306         la      t1,exc_norm_code
    1307         li      t2,E_VEC |K1BASE
    1308         li      t3,VEC_CODE_LENGTH
    1309 1:
    1310         lw      t6,0(t1)
    1311         addiu   t1,4
    1312         subu    t3,4
    1313         sw      t6,0(t2)
    1314         addiu   t2,4
    1315         bne     t3,zero,1b
    1316 
    1317         li      a0,E_VEC
    1318         li      a1,VEC_CODE_LENGTH
    1319         jal     clear_cache
    1320 
    1321         move    ra,t5           # restore ra
    1322         j       ra
    1323 
    1324 #else
    1325    #error "__mips not set to 1 or 3"
    1326 #endif
    1327 
    1328 ENDFRAME(init_exc_vecs)
    1329 
    1330 FRAME(exc_utlb_code,sp,0,ra)
    1331         la      k0, _ISR_Handler /* XXX not right -- but need to link*/
    1332         j       k0
    1333         nop
    1334 ENDFRAME(exc_utlb_code)
    1335 
    1336 FRAME(exc_norm_code,sp,0,ra)
    1337         la      k0, _ISR_Handler /* generic external int hndlr */
    1338         j       k0
    1339         nop
    1340 ENDFRAME(exc_norm_code)
    1341 
    1342 /*
    1343 ** Again, reliance on SIM. Not good.
    1344 */
    1345 #if __mips == 3
    1346 
    1347 FRAME(exc_tlb_code,sp,0,ra)
    1348         la      k0, (R_VEC+((112)*8)) /* R4000 Sim location */
    1349         j       k0
    1350         nop
    1351 ENDFRAME(exc_tlb_code)
    1352 
    1353 FRAME(exc_xtlb_code,sp,0,ra)
    1354         la      k0, (R_VEC+((112)*8)) /* R4000 Sim location */
    1355         j       k0
    1356         nop
    1357 
    1358 ENDFRAME(exc_xtlb_code)
    1359 
    1360 FRAME(exc_cache_code,sp,0,ra)
    1361         la      k0, (R_VEC+((112)*8)) /* R4000 Sim location */
    1362         j       k0
    1363         nop
    1364 ENDFRAME(exc_cache_code)
    1365 
    1366 #elif __mips == 1
    1367 /* ------------------------------------------------------ */
    1368 FRAME(exc_tlb_code,sp,0,ra)
    1369         la      k0, (R_VEC+((48)*8))  /* Need something else here besides IDT/SIM call */
    1370         j       k0
    1371         nop
    1372 ENDFRAME(exc_tlb_code)
    1373 
    1374 FRAME(exc_cache_code,sp,0,ra)
    1375         la      k0, (R_VEC+((48)*8))
    1376         j       k0
    1377         nop
    1378 ENDFRAME(exc_cache_code)
    1379 
    1380 #else
    1381 
    1382    #error "__mips is not set to 1 or 3"
    1383 
    1384 #endif
    1385 
Note: See TracChangeset for help on using the changeset viewer.