|
|
1.1 root 1:
2:
3: #include "definitions"
4:
5: extern long iob0, iob1, iob2, iob3, ss1;
6: extern long unused, u0p1pt, u0p2pt, scb, savvec4, savvec5, savvec6, savvec7;
7: extern long *p_ptr, ret_adr, exp_par0, exp_par1, exp_par2, exp_par3;
8: extern long savvec3 ,act_par0, act_par1, act_par2, act_par3;
9: extern long Failpc, test_va, Tpsl;
10:
11: vl_test()
12: { long *temp;
13:
14: if (ss1) writes("** Subtest3 : Limit and translation fault\n");
15: temp = (long *)0;
16: asm("mfpr $SBR,_savvec4");
17: savvec4 |= 0xc0000000;
18: asm("mtpr _savvec4,$P0BR"); /* Double map P0 into System space */
19: asm("mfpr $SLR,_savvec4");
20: asm("mtpr _savvec4,$P0LR");
21:
22: /* Set up P1PT */
23: temp = &u0p1pt;
24: *temp = IOB2; /* 1st PTE in P1 map to IOB2 */
25: savvec4 = ((long)temp) | SADDR;
26: asm("mtpr _savvec4,$P1BR");
27: asm("mtpr $1,$P1LR");
28:
29: /* Set up P2PT */
30: temp = &u0p2pt;
31: *temp = IOB3; /* 1st PTE in P2 map to IOB3 */
32: savvec4 = ((long)temp) | SADDR;
33: savvec4 -= (LAST_VPGNO << 2);
34: asm("mtpr _savvec4, $P2BR");
35: asm("mtpr $0xffffe, $P2LR"); /* Use only 1 entry */
36:
37: asm("mtpr $0,$TBIA");
38: asm("mtpr $0,$PADC");
39: asm("mtpr $1,$MME");
40: asm("jmp *$0f"); /* Go virtual */
41: asm("0:");
42: limit_chk(); /* Limit test */
43: vbit_chk(); /* valid bit test */
44:
45: asm("mtpr $0,$MME"); /* back to physical */
46: asm("mtpr $0,$P0LR"); /* Invalidate P0 space */
47: }
48:
49:
50: limit_chk()
51: /* this test will validate that TAHOE will detect any off limit
52: access to SPT, P0PT, P1PT, P2PT.
53: */
54: {
55: long sys_vadr, fault_vadr, pte_ref, fault_type;
56:
57: length_chk(SLR, SADDR); /* Test on SPT */
58: length_chk(P0LR, P0ADDR); /* Test on P0PT */
59: length_chk(P1LR, P1ADDR); /* Test on P1PT */
60: length_chk(P2LR, P2ADDR); /* Test on P2PT */
61:
62: /* Check limit fault on SPT when access P1 space */
63: asm("mfpr $P1LR,_savvec7"); /* save P1LR */
64: asm("mtpr $0x1ffff,$P1LR"); /* set P1LR to very large value */
65:
66: asm("mfpr $SLR,_savvec4");
67: sys_vadr = ((savvec4+1) << PGSHIFT) | SADDR;
68: asm("mfpr $P1BR,_savvec4");
69: fault_vadr = (((unsigned)(sys_vadr-savvec4) >> 2) << PGSHIFT) | P1ADDR;
70: pte_ref = TRUE;
71: fault_type = LENGTH;
72: lmt_fault(fault_vadr, pte_ref, fault_type);
73:
74: /* restore original SLR, P1LR */
75: asm("mtpr _savvec7,$P1LR");
76: }
77:
78: length_chk(table, space)
79: long table, space;
80: { long fault_vadr, pte_ref, fault_type;
81:
82: savvec6 = table;
83: asm("mfpr _savvec6,_savvec4"); /* Get length of table */
84: if (table==P2LR) savvec4--;
85: else savvec4++;
86: fault_vadr = (savvec4<<PGSHIFT)|space;
87: fault_type = LENGTH;
88: pte_ref = FALSE;
89: lmt_fault(fault_vadr, pte_ref, fault_type);
90:
91: }
92:
93:
94: vbit_chk()
95: /* This test force translation not valid fault on SPT, P0PT,
96: P1PT, P2PT.
97: */
98: {
99: long fault_vadr, t_pgno, *pt_base, fault_type, pte_ref;
100: long saved_p1lr;
101:
102: valid_chk(SBR, TEST_PTESYS, SADDR); /* Test on SPT */
103: valid_chk(P0BR, TEST_PTEP0, P0ADDR); /* Test on P0PT */
104: valid_chk(P1BR, TEST_PTEP1, P1ADDR); /* Test on P1PT */
105: valid_chk(P2BR, TEST_PTEP2, P2ADDR); /* Test on P2PT */
106:
107: /* Check translation not valid fault on SPT when access P1 space */
108:
109: asm("mfpr $P1LR,_savvec5");
110: saved_p1lr = savvec5; /* save P1LR */
111: asm("mtpr $768,$P1LR"); /* Set P1LR to have 768 PTEs which */
112: /* is 3 page long. */
113: /* Virtual addr used to force the fault will need PTE #512 in P1PT */
114: fault_vadr = (long)((512<<PGSHIFT)|P1ADDR);
115: /* invalidate PTE in SPT which map 3rd page of P1PT */
116: asm("mfpr $SBR,_savvec5");
117: pt_base = (long *)savvec5;
118: t_pgno = (U0_P1PT) + 2;
119: pt_base += t_pgno; /* address of PTE in SPT that */
120: /* mapped the 3rd page of P1PT */
121: *pt_base = *pt_base & 0x7fffffff; /* Turn off valid bit */
122:
123: fault_type = VALID;
124: pte_ref = TRUE;
125: lmt_fault(fault_vadr, pte_ref, fault_type);
126:
127: /* restore original SLR, P1LR */
128: *pt_base = *pt_base | 0x80000000; /* Turn on valid bit */
129: savvec5 = saved_p1lr;
130: asm("mtpr _savvec5,$P1LR");
131: }
132:
133: valid_chk(table, test_pte, space)
134: long table, test_pte, space;
135: { long *pt_base, saved_pte, fault_vadr, pte_ref, fault_type;
136:
137: savvec6 = table;
138: asm("mfpr _savvec6,_savvec5");
139: pt_base = (long *)savvec5;
140: pt_base += test_pte; /* address of test PTE */
141: fault_vadr = (test_pte<<PGSHIFT)|space;
142: saved_pte = *pt_base; /* save original PTE */
143: /* Turn off valid bit and set access to User,Kernel R/W */
144: *pt_base = (*pt_base & 0x7ffffff) | PTE_UW;
145: fault_type = VALID;
146: pte_ref = FALSE;
147: lmt_fault(fault_vadr, pte_ref, fault_type);
148: *pt_base = saved_pte; /* Restore original PTE */
149: }
150:
151:
152: /* Force limit and valid fault */
153:
154: lmt_fault(fault_vadr, pte_ref, fault_type)
155: long fault_vadr, pte_ref, fault_type;
156: {
157: long saved_vec, *scb_base, lx, *lptr, access;
158:
159: scb_base = &scb;
160: if (fault_type == LENGTH)
161: {
162: scb_base += PROT_VEC;
163:
164: /* Make new PTE : If this logic "mkpte" is taken out */
165: /* and this test passed that imply TAHOE will generate */
166: /* limit fault before access prot. and translation not */
167: /* valid fault. */
168:
169: if (pte_ref==FALSE) mkpte(fault_vadr);
170: }
171: else scb_base += TRANS_VEC;
172:
173: saved_vec = *scb_base; /* save old protection fault vector */
174: asm("movab handler1,_savvec4");
175:
176: exp_par1 = fault_vadr; /* Set up expect fault parameters */
177: test_va = exp_par1;
178: asm("movpsl _exp_par3"); /* PSL at time of fault */
179: exp_par3 &= 0xffffffc0; /* Mask out PSW flags */
180: Tpsl = exp_par3;
181: asm("movab okret,_ret_adr");
182: for (access = READ; access <= WRITE; access++)
183: {
184: /* length ,R/W violation */
185: if (fault_type == LENGTH)
186: exp_par0 = 1 | (access<<2) | (pte_ref<<1);
187: else
188: exp_par0 = (access<<2) | (pte_ref<<1);
189: *scb_base = savvec4; /* Set new handler */
190: asm("movl _exp_par1,r0");
191: if (access==WRITE)
192: {
193: asm("movab pc_fault1,_exp_par2"); /* PC at fault */
194: Failpc = exp_par2;
195: asm("pc_fault1:");
196: asm("movl $0,(r0)"); /* Try with write access */
197: }
198: else
199: {
200: asm("movab pc_fault2,_exp_par2"); /* PC at fault */
201: Failpc = exp_par2;
202: asm("pc_fault2:");
203: asm("movl (r0),r12"); /* Try with read access */
204: }
205: /* Error if program comes to this point */
206: if (fault_type == LENGTH)
207: writes("** Expected limit fault didnot happen\n");
208: else
209: writes("** Expected translation fault didnot happen\n");
210: ac_error1();
211: *scb_base = saved_vec; /* Restore ILL_ACCESS vector */
212: asm("halt");
213: asm("okret:");
214: *scb_base = saved_vec; /* Restore ILL_ACCESS vector */
215: if (fault_type == LENGTH)
216: chk_fpars("** Page Table Limit exception\n");
217: else
218: chk_fpars("** Translation not valid exception\n");
219: }
220: }
221:
222: mkpte(flt_vadr)
223: long flt_vadr;
224: { long space, oldpte, pteno, regno;
225:
226: space = (flt_vadr >> 30) & 0x3;
227: pteno = (flt_vadr >> PGSHIFT) & 0xfffff;
228: if (space==3) regno = SBR; /* System */
229: if (space==2) { regno = P2BR; /* P2 */
230: pteno = LAST_VPGNO - 2; }
231: if (space==1) regno = P1BR; /* P1 */
232: if (space==0) regno = P0BR; /* P0 */
233:
234: /* All access, V_BIT on */
235: fixpv_pte(regno,pteno,&oldpte,PTE_KW | PTE_V);
236:
237: }
238:
239: prot_handler()
240: {
241: asm(".align 2");
242: asm("handler1:");
243: asm("movab _act_par0,_p_ptr"); /* Set pointer to fault parameters */
244: asm("movl (sp)+,_act_par0");
245: asm("movl (sp)+,_act_par1");
246: asm("movl (sp)+,_act_par2");
247: asm("movl (sp)+,_act_par3");
248: asm("jmp *_ret_adr");
249: }
250:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.