|
|
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.