Changeset 32f415d in rtems for cpukit/score/cpu/mips/cpu_asm.S
- Timestamp:
- 12/13/00 18:09:48 (22 years ago)
- Branches:
- 4.10, 4.11, 4.8, 4.9, 5, master
- Children:
- 0289674
- Parents:
- 0ef748fb
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
cpukit/score/cpu/mips/cpu_asm.S
r0ef748fb r32f415d 1 /* cpu_asm.S 2 * 1 /* 3 2 * This file contains the basic algorithms for all assembly code used 4 3 * in an specific CPU port of RTEMS. These algorithms must be implemented 5 4 * in assembly language 6 5 * 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. 25 27 * On-Line Applications Research Corporation (OAR). 26 28 * … … 31 33 * $Id$ 32 34 */ 33 /* @(#)cpu_asm.S 08/20/96 1.15 */ 34 35 #include "cpu_asm.h" 36 35 36 #include <asm.h> 37 37 #include "iregdef.h" 38 38 #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_reg45 #define ENDFRAME(name) \46 .end name47 39 48 40 #define EXCP_STACK_SIZE (NREGS*R_SZ) … … 124 116 * 125 117 * _CPU_ISR_Get_level 118 * 119 * unsigned32 _CPU_ISR_Get_level( void ) 120 * 121 * This routine returns the current interrupt level. 126 122 */ 127 128 #if 0129 unsigned32 _CPU_ISR_Get_level( void )130 {131 /*132 * This routine returns the current interrupt level.133 */134 }135 #endif136 123 137 124 #if __mips == 3 … … 189 176 190 177 /* 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 */ 209 180 210 181 #else … … 226 197 227 198 /* void _CPU_Context_save_fp( 228 * void **fp_context_ptr 229 * ) 230 * { 231 * } 199 * void **fp_context_ptr 200 * ); 232 201 */ 233 202 … … 286 255 287 256 /* void _CPU_Context_restore_fp( 288 * void **fp_context_ptr257 * void **fp_context_ptr 289 258 * ) 290 * {291 * }292 259 */ 293 260 … … 338 305 339 306 /* void _CPU_Context_switch( 340 * Context_Control *run,341 * Context_Control *heir307 * Context_Control *run, 308 * Context_Control *heir 342 309 * ) 343 * {344 * }345 310 */ 346 311 #if __mips == 3 … … 403 368 404 369 mfc0 t0,C0_SR 405 370 li t1,~SR_IEC 406 371 sw t0,C0_SR_OFFSET*4(a0) /* save status register */ 407 372 and t0,t1 … … 437 402 lw t0,C0_EPC_OFFSET*4(a1) 438 403 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 443 412 444 413 _CPU_Context_1: … … 460 429 * 461 430 * NOTE: May be unnecessary to reload some registers. 431 * 432 * void _CPU_Context_restore( 433 * Context_Control *new_context 434 * ); 462 435 */ 463 464 #if 0465 void _CPU_Context_restore(466 Context_Control *new_context467 )468 {469 }470 #endif471 436 472 437 #if __mips == 3 … … 503 468 * This routine provides the RTEMS interrupt management. 504 469 * 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 * 505 492 */ 506 507 #if 0508 void _ISR_Handler()509 {510 /*511 * This discussion ignores a lot of the ugly details in a real512 * implementation such as saving enough registers/state to be513 * able to do something real. Keep in mind that the goal is514 * to invoke a user's ISR handler which is written in C and515 * 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 of519 * _ISR_Handler while requirements for setting520 */521 522 /*523 * At entry to "common" _ISR_Handler, the vector number must be524 * available. On some CPUs the hardware puts either the vector525 * number or the offset into the vector table for this ISR in a526 * known place. If the hardware does not give us this information,527 * then the assembly portion of RTEMS for this port will contain528 * a set of distinct interrupt entry points which somehow place529 * the vector number in a known place (which is safe if another530 * interrupt nests this one) and branches to _ISR_Handler.531 *532 */533 #endif534 493 535 494 #if __mips == 3 … … 584 543 mfc0 k0,C0_CAUSE 585 544 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 */ 588 547 mfc0 k1,C0_SR 589 548 and k0,k1 590 549 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 */ 592 552 nop 593 553 … … 1036 996 #endif 1037 997 1038 FRAME(mips_enable_interrupts,sp,0,ra)1039 mfc0 t0,C0_SR /* get status reg */1040 nop1041 or t0,t0,a01042 mtc0 t0,C0_SR /* save updated status reg */1043 j ra1044 nop1045 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 ra1055 nop1056 ENDFRAME(mips_disable_interrupts)1057 1058 #if __mips == 31059 1060 FRAME(mips_enable_global_interrupts,sp,0,ra)1061 mfc0 t0,C0_SR /* get status reg */1062 nop1063 ori t0,SR_IE1064 mtc0 t0,C0_SR /* save updated status reg */1065 j ra1066 nop1067 ENDFRAME(mips_enable_global_interrupts)1068 1069 FRAME(mips_disable_global_interrupts,sp,0,ra)1070 li t1,SR_IE1071 mfc0 t0,C0_SR /* get status reg */1072 not t11073 and t0,t11074 mtc0 t0,C0_SR /* save updated status reg */1075 j ra1076 nop1077 ENDFRAME(mips_disable_global_interrupts)1078 1079 #elif __mips == 11080 1081 FRAME(mips_enable_global_interrupts,sp,0,ra)1082 mfc0 t0,C0_SR /* get status reg */1083 nop1084 ori t0,SR_IEC1085 mtc0 t0,C0_SR /* save updated status reg */1086 j ra1087 nop1088 ENDFRAME(mips_enable_global_interrupts)1089 1090 FRAME(mips_disable_global_interrupts,sp,0,ra)1091 li t1,SR_IEC1092 mfc0 t0,C0_SR /* get status reg */1093 not t11094 and t0,t11095 mtc0 t0,C0_SR /* save updated status reg */1096 j ra1097 nop1098 ENDFRAME(mips_disable_global_interrupts)1099 1100 #else1101 1102 #error "__mips is not set to 1 or 3"1103 1104 #endif1105 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_SR1109 j ra1110 nop1111 ENDFRAME(mips_get_sr)1112 1113 998 FRAME(mips_break,sp,0,ra) 1114 999 #if 1 … … 1121 1006 ENDFRAME(mips_break) 1122 1007 1123 1124 /**************************************************************************1125 **1126 ** enable_int(mask) - enables interrupts - mask is positioned so it only1127 ** needs to be or'ed into the status reg. This1128 ** also does some other things !!!! caution should1129 ** be used if invoking this while in the middle1130 ** of a debugging session where the client may have1131 ** nested interrupts.1132 **1133 ****************************************************************************/1134 FRAME(enable_int,sp,0,ra)1135 .set noreorder1136 mfc0 t0,C0_SR1137 or a0,11138 or t0,a01139 mtc0 t0,C0_SR1140 j ra1141 nop1142 .set reorder1143 ENDFRAME(enable_int)1144 1145 1146 /***************************************************************************1147 **1148 ** disable_int(mask) - disable the interrupt - mask is the complement1149 ** of the bits to be cleared - i.e. to clear ext int1150 ** 5 the mask would be - 0xffff7fff1151 **1152 ****************************************************************************/1153 FRAME(disable_int,sp,0,ra)1154 .set noreorder1155 mfc0 t0,C0_SR1156 nop1157 and t0,a01158 mtc0 t0,C0_SR1159 j ra1160 nop1161 ENDFRAME(disable_int)1162 1163 1164 /*PAGE1165 *1166 * _CPU_Internal_threads_Idle_thread_body1167 *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 known1176 * to stop the DMA if the CPU were put in IDLE mode. This might1177 * also be a problem with other on-chip peripherals. So use this1178 * hook with caution.1179 */1180 1181 #if __mips == 31182 1183 FRAME(_CPU_Thread_Idle_body,sp,0,ra)1184 wait /* enter low power mode */1185 j _CPU_Thread_Idle_body1186 nop1187 ENDFRAME(_CPU_Thread_Idle_body)1188 1189 #elif __mips == 11190 1191 FRAME(_CPU_Thread_Idle_body,sp,0,ra)1192 nop /* no wait instruction */1193 j _CPU_Thread_Idle_body1194 nop1195 ENDFRAME(_CPU_Thread_Idle_body)1196 1197 #else1198 1199 #error "__mips not set to 1 or 3"1200 1201 #endif1202 1203 /**************************************************************************1204 **1205 ** init_exc_vecs() - moves the exception code into the addresses1206 ** reserved for exception vectors1207 **1208 ** UTLB Miss exception vector at address 0x800000001209 **1210 ** General exception vector at address 0x800000801211 **1212 ** RESET exception vector is at address 0xbfc000001213 **1214 ***************************************************************************/1215 1216 #define VEC_CODE_LENGTH 10*41217 1218 FRAME(init_exc_vecs,sp,0,ra)1219 1220 #if __mips == 11221 1222 .set noreorder1223 la t1,exc_utlb_code1224 la t2,exc_norm_code1225 li t3,UT_VEC1226 li t4,E_VEC1227 li t5,VEC_CODE_LENGTH1228 1:1229 lw t6,0(t1)1230 lw t7,0(t2)1231 sw t6,0(t3)1232 sw t7,0(t4)1233 addiu t1,41234 addiu t3,41235 addiu t4,41236 subu t5,41237 bne t5,zero,1b1238 addiu t2,41239 move t5,ra # assumes clear_cache doesnt use t51240 li a0,UT_VEC1241 jal clear_cache /* Check out clear cache.... */1242 li a1,VEC_CODE_LENGTH1243 nop1244 li a0,E_VEC1245 jal clear_cache1246 li a1,VEC_CODE_LENGTH1247 move ra,t5 # restore ra1248 j ra1249 nop1250 .set reorder1251 1252 #elif __mips == 31253 1254 .set reorder1255 move t5,ra # assumes clear_cache doesnt use t51256 1257 /* TLB exception vector */1258 la t1,exc_tlb_code1259 li t2,T_VEC |K1BASE1260 li t3,VEC_CODE_LENGTH1261 1:1262 lw t6,0(t1)1263 addiu t1,41264 subu t3,41265 sw t6,0(t2)1266 addiu t2,41267 bne t3,zero,1b1268 1269 li a0,T_VEC1270 li a1,VEC_CODE_LENGTH1271 jal clear_cache1272 1273 la t1,exc_xtlb_code1274 li t2,X_VEC |K1BASE1275 li t3,VEC_CODE_LENGTH1276 1:1277 lw t6,0(t1)1278 addiu t1,41279 subu t3,41280 sw t6,0(t2)1281 addiu t2,41282 bne t3,zero,1b1283 1284 /* extended TLB exception vector */1285 li a0,X_VEC1286 li a1,VEC_CODE_LENGTH1287 jal clear_cache1288 1289 /* cache error exception vector */1290 la t1,exc_cache_code1291 li t2,C_VEC |K1BASE1292 li t3,VEC_CODE_LENGTH1293 1:1294 lw t6,0(t1)1295 addiu t1,41296 subu t3,41297 sw t6,0(t2)1298 addiu t2,41299 bne t3,zero,1b1300 1301 li a0,C_VEC1302 li a1,VEC_CODE_LENGTH1303 jal clear_cache1304 1305 /* normal exception vector */1306 la t1,exc_norm_code1307 li t2,E_VEC |K1BASE1308 li t3,VEC_CODE_LENGTH1309 1:1310 lw t6,0(t1)1311 addiu t1,41312 subu t3,41313 sw t6,0(t2)1314 addiu t2,41315 bne t3,zero,1b1316 1317 li a0,E_VEC1318 li a1,VEC_CODE_LENGTH1319 jal clear_cache1320 1321 move ra,t5 # restore ra1322 j ra1323 1324 #else1325 #error "__mips not set to 1 or 3"1326 #endif1327 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 k01333 nop1334 ENDFRAME(exc_utlb_code)1335 1336 FRAME(exc_norm_code,sp,0,ra)1337 la k0, _ISR_Handler /* generic external int hndlr */1338 j k01339 nop1340 ENDFRAME(exc_norm_code)1341 1342 /*1343 ** Again, reliance on SIM. Not good.1344 */1345 #if __mips == 31346 1347 FRAME(exc_tlb_code,sp,0,ra)1348 la k0, (R_VEC+((112)*8)) /* R4000 Sim location */1349 j k01350 nop1351 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 k01356 nop1357 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 k01363 nop1364 ENDFRAME(exc_cache_code)1365 1366 #elif __mips == 11367 /* ------------------------------------------------------ */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 k01371 nop1372 ENDFRAME(exc_tlb_code)1373 1374 FRAME(exc_cache_code,sp,0,ra)1375 la k0, (R_VEC+((48)*8))1376 j k01377 nop1378 ENDFRAME(exc_cache_code)1379 1380 #else1381 1382 #error "__mips is not set to 1 or 3"1383 1384 #endif1385
Note: See TracChangeset
for help on using the changeset viewer.