|
|
1.1 ! root 1: ! 2: # ************************************************************************ ! 3: # * "RUN THE CODE" ROUTINE ! 4: # * ! 5: # * This routine will test the current instruction. The instruction will ! 6: # * be moved to a page boundary and executed and the results will be ! 7: # * verified. The code will be tested twice, once with an instruction ! 8: # * cache miss and once with a cache hit. To insure instruction cache ! 9: # * hits, the code will be executed twice -once with all pages validated ! 10: # * in the memory map and the 2nd time with them invalidated. The results ! 11: # * will be checked after the 2nd execution. ! 12: # * Successive calls to this routine will set the page boundary on ! 13: # * different bytes in the code to check page faults at each byte. ! 14: # * The general template of the 16 byte test code will be: ! 15: # * ! 16: # * <op-code> [<addr-mode>] [<offset#1>] [<addr-mode>] [<offset#2>] ! 17: # * ! 18: # * any unused bytes will be padded with NOPs. At the end of the test ! 19: # * code is a jump back to the instruction execution routine (below). ! 20: # * ! 21: # * 25-Jun-85 : added MULL2 / MULL3 changes ! 22: # * 1-Jul-85 : restore operand 2 between executions for MULL2. ! 23: # * 17-Jul-85 : look for FPM traps as instruction completion ! 24: # ************************************************************************ ! 25: .text ! 26: .align 1 ! 27: .globl _run_code ! 28: _run_code: ! 29: .word 0 ! 30: movpsl _run_code_psl /* save the current PSL */ ! 31: callf $4,_fill_code_buff /* stuff the code buffer */ ! 32: callf $4,_set_psl /* set up the initial PSL to use */ ! 33: # Save operand 2 for MULL2 ! 34: movl *$_dmp_byte_op_2,_rc_bop2 /* save byte operand #2 */ ! 35: movl *$_dmp_op_2,_rc_op2 /* save operand #2 */ ! 36: # Set the return from an FPP emulation trap ! 37: clrl _event_return ! 38: tstl _emulated_inst /* should we get an FPM trap? */ ! 39: beql 1f ! 40: moval _run_code_mtpr,_event_return /* set the return address */ ! 41: 1: ! 42: # Run with an instruction cache miss ! 43: clrl _i_cache_hit /* 1st pass gets a cache miss */ ! 44: callf $4,_run_test /* run the test code w/ cache miss */ ! 45: # Run with an instruction cache hit ! 46: movl $1,_i_cache_hit /* 2nd pass gets a cache hit */ ! 47: movl _rc_bop2,*$_dmp_byte_op_2 /* restore byte operand #2 */ ! 48: movl _rc_op2,*$_dmp_op_2 /* restore operand #2 */ ! 49: callf $4,_run_test /* run the test code again */ ! 50: ret /* return */ ! 51: ! 52: ! 53: ! 54: ! 55: ! 56: # ************************************************************************ ! 57: # * ! 58: # * "RUN THE TEST" ROUTINE ! 59: # * ! 60: # * This routine will set up the Instruction Code Cache Key and the ! 61: # * memory map. It will call the routine that actually executes the ! 62: # * test code ('_execute_code'). ! 63: # * looping on error is done in this routine. ! 64: # * ! 65: # ************************************************************************ ! 66: .text ! 67: .align 1 ! 68: .globl _run_test ! 69: _run_test: ! 70: .word 0 ! 71: clrl _trans_acc_error /* clear bad-acc-after-pg-flt flag */ ! 72: clrl _fpm_trap_occurred /* clear got-an-fpm-trap flag */ ! 73: ! 74: ######################################################################### ! 75: # The error loop starts here: ! 76: # Get a new Code Cache Key to invalidate the instruction cache, ! 77: # Invalidate the instruction and data pages in the page table, ! 78: # and execute the test instrcution. ! 79: ######################################################################### ! 80: _shift_loop: ! 81: incl _Codek /* Bump code cache key */ ! 82: cmpl _Codek,$255 /* Last key yet ? */ ! 83: jlss 1f ! 84: movl $1,_Codek /* Reset Code key to 1 */ ! 85: mtpr $1,$PACC /* Purge all code cache */ ! 86: nop ! 87: 1: ! 88: mtpr _Codek,$CCK /* Set new key */ ! 89: ! 90: ######################################################################### ! 91: # If we're running in user mode, set up the stack pointer ! 92: # Invalidate the instruction and data pages in the page table, ! 93: # and execute the test instrcution. ! 94: ######################################################################### ! 95: tstl _user_mode /* are we in User mode? */ ! 96: beql 1f ! 97: callf $4,_set_user_stack /* set up the user stack data */ ! 98: 1: callf $4,_invalidate_pages /* invalidate page tbl entries */ ! 99: callf $4,_execute_code /* execute code with pg faults */ ! 100: ! 101: ######################################################################### ! 102: # If the Force Loop flag is set then loop on the error ! 103: ######################################################################### ! 104: tstl _force_loop /* Is "force_loop" set? */ ! 105: beql 1f ! 106: brw _shift_loop /* then loop on the error */ ! 107: 1: ! 108: ######################################################################### ! 109: # Now verify the results of the instruction. 'test_ptr' points to the ! 110: # test routine to use. Check the Force Loop flag again to see if we ! 111: # just had an error. If we don't start looping then exit. ! 112: # If we're testing an emulated instruction then call the FPM checking ! 113: # routine rather than the instruction's normal test routine. ! 114: ######################################################################### ! 115: callf $4,_get_stored_value /* get results of any store */ ! 116: tstl _emulated_inst /* emulated instruction? */ ! 117: beql 1f ! 118: callf $4,_chk_fpm_trap /* check the FPM interface */ ! 119: brb 2f ! 120: 1: calls $4,*_test_ptr /* verify the final results */ ! 121: 2: tstl _force_loop /* Is "force_loop" set? */ ! 122: beql 1f ! 123: jmp _shift_loop /* then loop on the error */ ! 124: 1: ! 125: ret /* return */ ! 126: ! 127: ! 128: ! 129: ! 130: ! 131: # ************************************************************************** ! 132: # * ! 133: # * "ENABLE MEMORY MANAGEMENT AND EXECUTE THE CODE" Routine ! 134: # * ! 135: # * Enable Memory Management, Load the ACC. and Execute the Test Code ! 136: # * ! 137: # ************************************************************************** ! 138: .text ! 139: .align 1 ! 140: .globl _execute_code ! 141: _execute_code: ! 142: .word 0 ! 143: moval (r13),_ex_code_fp /* save the frame pointer */ ! 144: moval (r14),_ex_code_sp /* save the stack pointer */ ! 145: clrl _no_page_faults /* clear the page fault count */ ! 146: mtpr $1,$TBIA /* purge all Trans Buff entries */ ! 147: mtpr $1,$MME /* enable memory management */ ! 148: jmp 1f /* start the memory management */ ! 149: 1: ! 150: cmpl _acc_ld_size,$DBL ! 151: beql 1f ! 152: ldf _dbl_ld_acc /* load the sgl accumulator */ ! 153: brb 2f /* or */ ! 154: 1: ldd _dbl_ld_acc /* load the dbl accumulator */ ! 155: 2: ! 156: loadr $0x3fff,_load_regs /* load regs 0 - 13 (FP) */ ! 157: movl _init_psl,-(sp) /* push the PSL to use */ ! 158: movl _code_addr,-(sp) /* push the test code's PC */ ! 159: clrl _clock_event /* clear diagnostic clock flag */ ! 160: tstl _emulated_inst /* check if inst is emulated */ ! 161: beql 1f ! 162: movl $FPM_CODE,_exp_event /* expect an FPM event */ ! 163: 1: ! 164: rei /* switch modes & execute code */ ! 165: halt /* we shouldn't ever get here */ ! 166: ! 167: ########################################################################## ! 168: # The only way here (knock on wood) is after the Translation faults. ! 169: # - Save the PSL, the registers, and the accumulator ! 170: ########################################################################## ! 171: .globl _ex_code_return ! 172: _ex_code_return: ! 173: movpsl _psl_val /* save the final PSL */ ! 174: clrl _exp_event /* clear event-expected flag */ ! 175: storer $0x3fff,_store_regs /* store regs 0 - 13 */ ! 176: cmpl _acc_st_size,$DBL ! 177: beql 1f ! 178: stf _dbl_st_acc /* store the sgl accumulator */ ! 179: brb 2f ! 180: 1: std _dbl_st_acc /* store the dbl accumulator */ ! 181: 2: ! 182: ########################################################################## ! 183: # Disable Memory Management and Return ! 184: # If we are in User mode the priveleged instruction fault handler will ! 185: # put us back into the Kernal Mode. ! 186: # ( Return here after a floating point emulation (FPM) trap ) ! 187: ########################################################################## ! 188: .globl _run_code_mtpr ! 189: _run_code_mtpr: ! 190: mtpr $2,$MME /* disable memory management */ ! 191: nop ! 192: mtpr $_pcb0,$PCBB /* set the current PCB addr */ ! 193: movl _ex_code_fp,fp /* reload the frame pointer */ ! 194: movl _ex_code_sp,sp /* reload the stack pointer */ ! 195: ret /* return */ ! 196: ! 197: ! 198: ! 199: ! 200: # ************************************************************************* ! 201: # * ! 202: # * FILL IN THE CODE BUFFER ROUTINE ! 203: # * ! 204: # * Set up the instruction code sequence -shifted by 'shift_count'. ! 205: # * After the instruction code, put a jump back to "run_code" and ! 206: # * fill the rest of the code buffer with NOPs. ! 207: # * ! 208: # ************************************************************************* ! 209: .set NOP_JMP,0x1010719f /* jump to an absolute address */ ! 210: .text ! 211: .align 1 ! 212: .globl _fill_code_buff ! 213: _fill_code_buff: ! 214: .word 0 ! 215: movl $START_OF_CODE,r0 ! 216: addl2 _shift_count,r0 /* get the 1st addr for the code */ ! 217: movl r0,_code_addr /* save the starting address */ ! 218: movab _inst_buf,r1 /* get the address of the code */ ! 219: 1: movb (r1),(r0) /* move the code to the code buf */ ! 220: incl r0 ! 221: aoblss $_end_of_inst_buf,r1,1b ! 222: ! 223: ######################################################################## ! 224: # Fill the rest of the buffer with NOPs ! 225: ######################################################################## ! 226: movl $0x10,r1 /* 0x10 = NOP op-code */ ! 227: 1: movb r1,(r0) /* put NOPs in the code space */ ! 228: aobleq $END_OF_CODE,r0,1b ! 229: ! 230: ######################################################################## ! 231: # After the instruction code, put a jump back to "_ex_code_return" ! 232: ######################################################################## ! 233: movl $NOP_JMP,_sgl_dummy1 /* "<nop><nop><jmp><abs addr>" */ ! 234: clrl r1 ! 235: 1: movb _sgl_dummy1(r1),(r0) /* move 'jmp' to the code buf */ ! 236: incl r0 ! 237: aoblss $4,r1,1b ! 238: ! 239: moval _ex_code_return,_sgl_dummy1 /* jmp to 'ex_code_return' */ ! 240: clrl r1 ! 241: 1: movb _sgl_dummy1(r1),(r0) /* move the code to the code buf */ ! 242: incl r0 ! 243: aoblss $4,r1,1b ! 244: ret /* return */ ! 245: ! 246: ! 247: ! 248: ! 249: ! 250: # *********************************************************************** ! 251: # * ! 252: # * SET UP THE INITIAL PSL TO BE USED WITH THE TEST ! 253: # * ! 254: # *********************************************************************** ! 255: .text ! 256: .align 1 ! 257: .globl _set_psl ! 258: _set_psl: ! 259: .word 0 ! 260: tstl _dbl_ld_acc /* set the PSL flag bits */ ! 261: movpsl _init_psl /* current PSL = base PSL */ ! 262: andl2 $0xffffff7f,_init_psl /* clear the DBL acc bit */ ! 263: cmpl _acc_ld_size,$DBL /* are we loading a DBL acc? */ ! 264: bneq 1f /* -NO, jump */ ! 265: orl2 $PSL_DBL,_init_psl /* -Yes, set the DBL bit */ ! 266: 1: ! 267: mfpr $PCBB,r0 /* get the current PCB pointer */ ! 268: tstl _user_mode /* Run process in USER mode? */ ! 269: bneq 1f /* - yes */ ! 270: andl2 $0xfeffffff,_init_psl /* clear the User Mode bit */ ! 271: brb 2f ! 272: 1: ! 273: andl2 $0xfbe0ffff,_init_psl /* clear Int. Stack bit & IPL */ ! 274: orl2 $0x01000000,_init_psl /* set the PSL's User Mode bit */ ! 275: 2: ! 276: ret /* return */ ! 277: ! 278: ! 279: ! 280: ! 281: ! 282: # ************************************************************************* ! 283: # * ! 284: # * SET UP THE STACK POINTER AND THE STACK DATA FOR TESTS IN USER MODE ! 285: # * ! 286: # * Set up the user stack pointer and set up the stack data for POP's ! 287: # ************************************************************************* ! 288: .text ! 289: .align 1 ! 290: .globl _set_user_stack ! 291: _set_user_stack: ! 292: .word 0 ! 293: mfpr $PCBB,r0 /* get the current PCB pointer */ ! 294: cmpl $0x7e,_addr_code /* PUSH addressing mode ? */ ! 295: bneq 1f ! 296: movl $_sp_page,PCB_USP(r0) /* set init PCB_USP for PUSH */ ! 297: brb 2f ! 298: 1: cmpl $0x67,_op_code /* PUSHD instruction? */ ! 299: bneq 3f ! 300: movl $_sp_plus,PCB_USP(r0) /* set init PCB_USP for PUSHD */ ! 301: brb 2f ! 302: 3: movl $_sp_minus,PCB_USP(r0) /* set init PCB_USP for other */ ! 303: ! 304: ######################################################################### ! 305: # Now set up the data for POP addressing modes ! 306: # ! 307: # This bit of code assumes that if op #1 is a popped that op #2 is too. ! 308: # It also assumes that op #3 is never poppped -just it's address. ! 309: ######################################################################### ! 310: 2: ! 311: cmpl $0x8e,_addr_code /* POP SP addressing? */ ! 312: beql 1f ! 313: cmpl $0x9e,_addr_code /* POP SP deferred addr.? */ ! 314: bneq 2f /* not POP -skip the rest */ ! 315: cmpl $3,_no_ops /* check for 3 operands. */ ! 316: bneq 1f ! 317: movl _sgl_value_10,_sp_plus /* set up 3rd POP operand */ ! 318: 1: cmpl $1,_no_ops /* check for 1 operand. */ ! 319: beql 1f ! 320: movl _sgl_value_9,_sp_page /* set up 2nd POP operand */ ! 321: 1: movl _sgl_value_8,_sp_minus /* set up 1st POP operand */ ! 322: 2: ! 323: ret /* return */ ! 324: ! 325: ! 326: ! 327: ! 328: # ************************************************************************ ! 329: # * ! 330: # * INVALIDATE THE TEST PAGES IN THE PAGE TABLE ROUTINE ! 331: # * ! 332: # ************************************************************************ ! 333: .text ! 334: .align 1 ! 335: .globl _invalidate_pages ! 336: _invalidate_pages: ! 337: .word 0 ! 338: movl $START_OF_CODE,r0 /* get 1st code buffer address */ ! 339: shar $PGSHIFT,r0,r0 /* get 1st page # to invalidate */ ! 340: addl3 $15,r0,r1 /* invalidate 15 pages */ ! 341: 1: ! 342: andl2 $0x7fffffff,_Sysmap[r0] /* mask out the Valid bit */ ! 343: aoblss r1,r0,1b /* ... for all test code pages */ ! 344: ret /* return */ ! 345: ! 346: ! 347: ! 348: ! 349: # ************************************************************************* ! 350: # * ! 351: # * GET THE STORED VALUE FOR STORE OPERATIONS ! 352: # * ! 353: # * The stored data will be put into 'dbl_value_3'. ! 354: # * If the instruction is MULL2 or MULL3 call the appropriate routine. ! 355: # * Otherwise, the store would have been onto the stack, to register(s) 0/1, ! 356: # * or to memory -either in operand #1 or in byte-operand #1. ! 357: # * If the instruction being tested isn't either MULL2, MULL3, or a ! 358: # * floating point store instruction then this routine will just exit. ! 359: # * ! 360: # ************************************************************************* ! 361: .text ! 362: .align 1 ! 363: .globl _get_stored_value ! 364: _get_stored_value: ! 365: .word 0 ! 366: cmpl _op_code,$MULL2_OP_CODE /* Are we testing MULL2? */ ! 367: bneq 1f ! 368: callf $4,_get_mull2_store /* then get MULL2's result */ ! 369: ret /* return */ ! 370: 1: ! 371: cmpl _op_code,$MULL3_OP_CODE /* Are we testing MULL2? */ ! 372: bneq 1f ! 373: callf $4,_get_mull3_store /* then get MULL3's result */ ! 374: ret /* return */ ! 375: 1: ! 376: cmpl $STORE,_op_type /* was it a store operation? */ ! 377: beql 1f ! 378: ret /* return if not a store inst */ ! 379: 1: ! 380: cmpl $0x7e,_addr_code /* PUSH addressing mode ? */ ! 381: beql 1f ! 382: cmpl $0x67,_op_code /* PUSHD instruction? */ ! 383: bneq 2f ! 384: movl _sp_page,_dbl_value_3+4 /* get the LS value pushed */ ! 385: 1: ! 386: movl _sp_minus,_dbl_value_3 /* get the operand pushed */ ! 387: brw 3f ! 388: 2: ! 389: ######################################################################### ! 390: # - Next check to see if the store would be to register 0/1 ! 391: ######################################################################### ! 392: cmpl $ADR_REG,_addr_mode /* register addressing mode? */ ! 393: bneq 1f /* -no */ ! 394: clrl r0 /* -yes, get the MSW stored */ ! 395: movl _store_regs[r0],_dbl_value_3 /* from the final r0. */ ! 396: incl r0 /* get the LSW value stored */ ! 397: movl _store_regs[r0],_dbl_value_3+4 /* from the final r1. */ ! 398: brw 3f ! 399: 1: ! 400: ######################################################################### ! 401: # - If not Stack or Register addressing, then the store went to memory ! 402: ######################################################################### ! 403: cmpl $ADR_B_DSP,_addr_mode /* byte displacement addressing? */ ! 404: bneq 1f /* branch if not byte addr. */ ! 405: movl $_dmp_byte_op_1,r0 /* get the addr of the operand */ ! 406: movl (r0),_dbl_value_3 /* get the MS longwored stored */ ! 407: addl2 $4,r0 ! 408: movl (r0),_dbl_value_3+4 /* get the LS longwored stored */ ! 409: brw 3f ! 410: 1: /* byte disp. rel. addr. mode */ ! 411: movl $_dmp_op_1,r0 /* get the addr of the operand */ ! 412: movl (r0),_dbl_value_3 /* get the MS longwored stored */ ! 413: addl2 $4,r0 ! 414: movl (r0),_dbl_value_3+4 /* get the LS longwored stored */ ! 415: 3: ! 416: ret /* return */ ! 417: ! 418: ! 419: ! 420: ! 421: # ************************************************************************* ! 422: # * ! 423: # * GET THE STORED VALUE FOR THE MULL2 INSTRUCTION ! 424: # * ! 425: # * The stored data will be put into 'dbl_value_2'. ! 426: # * The store would have been into register 4, or to memory -either in ! 427: # * operand #2 or in byte-operand #2. ! 428: # * ! 429: # ************************************************************************* ! 430: .text ! 431: .align 1 ! 432: .globl _get_mull2_store ! 433: _get_mull2_store: ! 434: .word 0 ! 435: ######################################################################### ! 436: # - Check to see if the store would be to register 6 ! 437: ######################################################################### ! 438: cmpl $ADR_REG,_addr_mode /* register addressing mode? */ ! 439: bneq 1f /* -no */ ! 440: movl $4,r0 /* -yes, get the data */ ! 441: movl _store_regs[r0],_dbl_value_3 /* from the final R4. */ ! 442: brw 3f ! 443: 1: ! 444: ######################################################################### ! 445: # - If not Register addressing, then the store went to memory ! 446: ######################################################################### ! 447: cmpl $ADR_B_DSP,_addr_mode /* byte displacement addressing? */ ! 448: bneq 1f /* branch if not byte addr. */ ! 449: movl $_dmp_byte_op_2,r0 /* get the addr of the operand */ ! 450: movl (r0),_dbl_value_3 /* get the data stored */ ! 451: brw 3f ! 452: 1: ! 453: movl $_dmp_op_2,r0 /* get the addr of the operand */ ! 454: movl (r0),_dbl_value_3 /* get the data stored */ ! 455: 3: ! 456: ret /* return */ ! 457: ! 458: ! 459: ! 460: ! 461: # ************************************************************************* ! 462: # * ! 463: # * GET THE STORED VALUE FOR THE MULL3 INSTRUCTION ! 464: # * ! 465: # * The stored data will be put into 'dbl_value_3'. ! 466: # * The store would have been onto the stack, to a register ( R6 or R8 ), ! 467: # * or to memory -either in operand #3 or in byte-operand #3. ! 468: # * ! 469: # ************************************************************************* ! 470: .text ! 471: .align 1 ! 472: .globl _get_mull3_store ! 473: _get_mull3_store: ! 474: .word 0 ! 475: cmpl $0x7e,_addr_code3 /* PUSH addressing mode ? */ ! 476: bneq 1f ! 477: movl _sp_page,_dbl_value_3 /* get the pushed result */ ! 478: brw 3f ! 479: 1: ! 480: ######################################################################### ! 481: # - Next check to see if the store would be to a register ! 482: ######################################################################### ! 483: cmpl $ADR_REG,_addr_mode /* register addressing mode? */ ! 484: bneq 4f /* -no */ ! 485: cmpl $0x56,_addr_code3 /* store to register 6? */ ! 486: bneq 1f /* -no */ ! 487: movl $6,r0 /* -yes, check register 6. */ ! 488: brb 2f ! 489: 1: movl $8,r0 /* get data from register 8. */ ! 490: 2: movl _store_regs[r0],_dbl_value_3 /* get result from reg */ ! 491: brw 3f ! 492: 4: ! 493: ######################################################################### ! 494: # - If not Stack or Register addressing, then the store went to memory ! 495: ######################################################################### ! 496: cmpl $ADR_B_DSP,_addr_mode /* byte displacement addressing? */ ! 497: bneq 1f /* branch if not byte addr. */ ! 498: movl $_dmp_byte_op_3,r0 /* get the addr of the operand */ ! 499: movl (r0),_dbl_value_3 /* get the data stored */ ! 500: brw 3f ! 501: 1: ! 502: movl $_dmp_op_3,r0 /* get the addr of the operand */ ! 503: movl (r0),_dbl_value_3 /* get the data stored */ ! 504: 3: ! 505: ret /* return */ ! 506: ! 507: ! 508: ! 509: ########################################################################### ! 510: # DATA STORAGE ! 511: ########################################################################### ! 512: .align 2 ! 513: _ex_code_sp: /* save stack pointer value here */ ! 514: .long 0 ! 515: _ex_code_fp: /* save frame pointer value here */ ! 516: .long 0 ! 517: _rc_bop2: /* save byte operand #2 here */ ! 518: .long 0 ! 519: _rc_op2: /* save operand #2 here */ ! 520: .long 0 ! 521: ! 522:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.