1//Original:/proj/frio/dv/testcases/lmu/lmu_excpt_prot1/lmu_excpt_prot1.dsp 2// Description: LMU protection exceptions 3# mach: bfin 4# sim: --environment operating 5 6#include "test.h" 7.include "testutils.inc" 8start 9 10include(selfcheck.inc) 11include(std.inc) 12include(mmrs.inc) 13 14//------------------------------------- 15 16// Test LMU/CPLB exceptions 17 18// Basic outline: 19// Set exception handler 20// program CPLB Entries 21// Enable CPLB in DMEM_CNTL 22// perform access 23// verify exception occurred 24 25CHECK_INIT(p5, 0xEFFFFFFC); 26 27 A0 = 0; 28 29//------------------------- 30// Zero the CPLB Address and Data regs. 31 32 LD32(p0, DCPLB_ADDR0); 33 R0 = 0; 34 [ P0 ++ ] = R0; // 0 35 [ P0 ++ ] = R0; // 1 36 [ P0 ++ ] = R0; // 2 37 [ P0 ++ ] = R0; // 3 38 [ P0 ++ ] = R0; // 4 39 [ P0 ++ ] = R0; // 5 40 [ P0 ++ ] = R0; // 6 41 [ P0 ++ ] = R0; // 7 42 [ P0 ++ ] = R0; // 8 43 [ P0 ++ ] = R0; // 9 44 [ P0 ++ ] = R0; // 10 45 [ P0 ++ ] = R0; // 11 46 [ P0 ++ ] = R0; // 12 47 [ P0 ++ ] = R0; // 13 48 [ P0 ++ ] = R0; // 14 49 [ P0 ++ ] = R0; // 15 50 51 LD32(p0, DCPLB_DATA0); 52 [ P0 ++ ] = R0; // 0 53 [ P0 ++ ] = R0; // 1 54 [ P0 ++ ] = R0; // 2 55 [ P0 ++ ] = R0; // 3 56 [ P0 ++ ] = R0; // 4 57 [ P0 ++ ] = R0; // 5 58 [ P0 ++ ] = R0; // 6 59 [ P0 ++ ] = R0; // 7 60 [ P0 ++ ] = R0; // 8 61 [ P0 ++ ] = R0; // 9 62 [ P0 ++ ] = R0; // 10 63 [ P0 ++ ] = R0; // 11 64 [ P0 ++ ] = R0; // 12 65 [ P0 ++ ] = R0; // 13 66 [ P0 ++ ] = R0; // 14 67 [ P0 ++ ] = R0; // 15 68 69 // Now set the CPLB entries we will need 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 // Data area for the desired error 96 WR_MMR(DCPLB_ADDR0, 0x800, p0, r0); 97 WR_MMR(DCPLB_ADDR1, 0x1000, p0, r0); 98 WR_MMR(DCPLB_DATA0, PAGE_SIZE_1K|CPLB_VALID|CPLB_DIRTY|CPLB_L1_CACHABLE, p0, r0); 99 WR_MMR(DCPLB_ADDR2, 0x2000, p0, r0); 100 WR_MMR(DCPLB_ADDR3, 0x3000, p0, r0); 101 WR_MMR(DCPLB_ADDR4, 0x4000, p0, r0); 102 WR_MMR(DCPLB_ADDR5, 0x5000, p0, r0); 103 WR_MMR(DCPLB_ADDR6, 0x6000, p0, r0); 104 WR_MMR(DCPLB_ADDR7, 0x7000, p0, r0); 105 106 // CHECKREG segment 107 WR_MMR(DCPLB_ADDR14, 0xEFFFFC00, p0, r0); 108 WR_MMR(DCPLB_DATA14, PAGE_SIZE_1K|CPLB_VALID|CPLB_DIRTY|CPLB_WT|CPLB_L1_CACHABLE|CPLB_SUPV_WR|CPLB_USER_RW, p0, r0); 109 110 // MMR space 111 WR_MMR(DCPLB_ADDR15, 0xFFC00000, p0, r0); 112 WR_MMR(DCPLB_DATA15, PAGE_SIZE_4M|CPLB_VALID|CPLB_DIRTY|CPLB_SUPV_WR, p0, r0); 113 114 // setup interrupt controller with exception handler address 115 WR_MMR_LABEL(EVT3, handler, p0, r1); 116 WR_MMR_LABEL(EVT15, int_15, p0, r1); 117 WR_MMR(EVT_IMASK, 0xFFFFFFFF, p0, r0); 118 WR_MMR(EVT_OVERRIDE, 0x00000000, p0, r0); 119 120 // enable CPLB 121 WR_MMR(DMEM_CONTROL, ENDM | ENDCPLB | DMC_AB_CACHE, p0, r0); 122 NOP;NOP;NOP;NOP;NOP; // in lieu of CSYNC 123 124 // Address for slot 0 accesses 125 // LD32(p4, 0xEFFFFFF8); 126 127 // go to user mode. and enable exceptions 128 LD32_LABEL(r0, User); 129 RETI = R0; 130 131 // But first raise interrupt 15 so we can do one test 132 // in supervisor mode. 133 RAISE 15; 134 NOP; 135 136 RTI; 137 138 // Nops to work around ICache bug 139 NOP;NOP;NOP;NOP;NOP; 140 NOP;NOP;NOP;NOP;NOP; 141 142 143int_15: 144 // Interrupt 15 handler - needed to try supervisor access with exceptions enabled 145 //------------------------------------------------------- 146 // Protection violation - Illegal Supervisor Write Access 147 R0 = 0;R1 = 0;R2 = 0;R3 = 0;R4 = 0;R5 = 0;R6 = 0;R7 = 0; 148 149 LD32(i1, 0x800); 150 LD32(r1, 0xDEADBEEF); 151 152 LD32(p2, DCPLB_DATA0); 153 LD32(r2, PAGE_SIZE_1K|CPLB_VALID|CPLB_DIRTY|CPLB_L1_CACHABLE|CPLB_SUPV_WR); 154 155 LD32(p3, DCPLB_DATA1); 156 LD32(r3, PAGE_SIZE_1K|CPLB_VALID|CPLB_DIRTY|CPLB_L1_CACHABLE|CPLB_SUPV_WR); 157 158 159X0: //[p1] = r1; // Exception should occur here 160 A0 = 0 || NOP || [ I1 ] = R1; // test access with DAG1 161 162 163 // Now check that handler read correct values 164 CHECKREG(r4,0x23); // supv and EXCPT_PROT 165 CHECKREG(r5, 0x800); 166 CHECKREG(r6, (FAULT_SUPV|FAULT_WRITE|FAULT_DAG1 | FAULT_CPLB0)); 167 CHECKREG_SYM(r7, X0, r0); // RETX should be value of X0 (HARDCODED ADDR!!) 168 169 // go to user mode. and enable exceptions 170 LD32_LABEL(r0, User); 171 RTI; 172 NOP;NOP;NOP;NOP;NOP; 173 NOP;NOP;NOP;NOP;NOP; 174 175 176User: 177 NOP;NOP;NOP;NOP;NOP; 178 179 //------------------------------------------------------- 180 // Protection violation - Illegal User Write Access 181 R0 = 0;R1 = 0;R2 = 0;R3 = 0;R4 = 0;R5 = 0;R6 = 0;R7 = 0; 182 183 LD32(i1, 0x1000); 184 LD32(r1, 0xDEADBEEF); 185 186 187 // values to fix up current test 188 LD32(p2, DCPLB_DATA1); 189 LD32(r2, PAGE_SIZE_1K|CPLB_VALID|CPLB_DIRTY|CPLB_L1_CACHABLE|CPLB_USER_RW|CPLB_SUPV_WR); 190 191 // values for next test 192 LD32(p3, DCPLB_DATA2); 193 LD32(r3, PAGE_SIZE_1K|CPLB_VALID|CPLB_DIRTY|CPLB_L1_CACHABLE); 194 195X1: //[p1] = r1; // Exception should occur here 196 A0 = 0 || NOP || [ I1 ] = R1; // test access with DAG1 197 198 // Now check that handler read correct values 199 200 CHECKREG(r4,0x23); // supv and EXCPT_PROT 201 CHECKREG(r5, 0x1000); 202 CHECKREG(r6, (FAULT_USER|FAULT_WRITE|FAULT_DAG1 | FAULT_CPLB1)); 203 CHECKREG_SYM(r7, X1, r0); // RETX should be value of X1 (HARDCODED ADDR!!) 204 205 206 //------------------------------------------------------- 207 // Protection violation - Illegal User Read Access 208 R0 = 0;R1 = 0;R2 = 0;R3 = 0;R4 = 0;R5 = 0;R6 = 0;R7 = 0; 209 210 LD32(i1, 0x2000); 211 LD32(r1, 0xDEADBEEF); 212 213 LD32(p2, DCPLB_DATA2); 214 LD32(r2, PAGE_SIZE_1K|CPLB_VALID|CPLB_DIRTY|CPLB_L1_CACHABLE|CPLB_USER_RO|CPLB_SUPV_WR); 215 216 LD32(p3, DCPLB_DATA3); 217 LD32(r3, PAGE_SIZE_1K|CPLB_VALID|CPLB_L1_CACHABLE|CPLB_USER_RW|CPLB_SUPV_WR); 218 219X2: //[p1] = r1; // Exception should occur here 220 A0 = 0 || NOP || R0 = [ I1 ]; // test access with DAG1 221 222 223 // Now check that handler read correct values 224 CHECKREG(r4,0x23); // supv and EXCPT_PROT 225 CHECKREG(r5, 0x2000); 226 CHECKREG(r6, (FAULT_USER|FAULT_READ|FAULT_DAG1 | FAULT_CPLB2)); 227 CHECKREG_SYM(r7, X2, r0); // RETX should be value of X2 (HARDCODED ADDR!!) 228 229 //------------------------------------------------------- 230 // Protection violation - Illegal Dirty Page Access 231 R0 = 0;R1 = 0;R2 = 0;R3 = 0;R4 = 0;R5 = 0;R6 = 0;R7 = 0; 232 233 LD32(i1, 0x3000); 234 LD32(r1, 0xDEADBEEF); 235 236 LD32(p2, DCPLB_DATA3); 237 LD32(r2, PAGE_SIZE_1K|CPLB_VALID|CPLB_DIRTY|CPLB_L1_CACHABLE|CPLB_USER_RW|CPLB_SUPV_WR); 238 239 LD32(p3, DCPLB_DATA4); 240 LD32(r3, PAGE_SIZE_1K|CPLB_VALID|CPLB_DA0ACC|CPLB_DIRTY|CPLB_L1_CACHABLE|CPLB_SUPV_WR); 241 242 243X3: //[p1] = r1; // Exception should occur here 244 A0 = 0 || NOP || [ I1 ] = R1; // test access with DAG1 245 246 247 // Now check that handler read correct values 248 CHECKREG(r4,0x23); // supv and EXCPT_PROT 249 CHECKREG(r5, 0x3000); 250 CHECKREG(r6, (FAULT_USER|FAULT_WRITE|FAULT_DAG1 | FAULT_CPLB3)); 251 CHECKREG_SYM(r7, X3, r0); // RETX should be value of X3 (HARDCODED ADDR!!) 252 253 //------------------------------------------------------- 254 // Protection violation - Illegal DAG1 Access 255 R0 = 0;R1 = 0;R2 = 0;R3 = 0;R4 = 0;R5 = 0;R6 = 0;R7 = 0; 256 257 LD32(i1, 0x4000); 258 LD32(r1, 0xDEADBEEF); 259 260 LD32(p2, DCPLB_DATA4); 261 LD32(r2, PAGE_SIZE_1K|CPLB_VALID|CPLB_DIRTY|CPLB_L1_CACHABLE|CPLB_USER_RW|CPLB_SUPV_WR); 262 263 LD32(p3, DCPLB_DATA5); 264 LD32(r3, PAGE_SIZE_1K|CPLB_VALID|CPLB_DIRTY|CPLB_L1_CACHABLE|CPLB_USER_RW|CPLB_SUPV_WR); 265 266 267X4: //[p1] = r1; // Exception should occur here 268 A0 = 0 || NOP || [ I1 ] = R1; // test access with DAG1 269 270 271 // Now check that handler read correct values 272 CHECKREG(r4,0x23); // supv and EXCPT_PROT 273 CHECKREG(r5, 0x4000); 274 CHECKREG(r6, (FAULT_USER|FAULT_WRITE|FAULT_DAG1 | FAULT_CPLB4)); 275 CHECKREG_SYM(r7, X4, r0); // RETX should be value of X4 (HARDCODED ADDR!!) 276 277 //------------------------------------------------------- 278 // L1Miss not implemented yet - skip for now.... 279 280// //------------------------------------------------------- 281// // Protection violation - L1 Miss 282// r0=0;r1=0;r2=0;r3=0;r4=0;r5=0;r6=0;r7=0; 283// 284// LD32(p1, 0x6000); 285// LD32(r1, 0xDEADBEEF); 286// 287// LD32(p2, DCPLB_DATA6); 288// LD32(r2, PAGE_SIZE_1K|CPLB_VALID|CPLB_DIRTY|CPLB_L1_CACHABLE|CPLB_USER_RW|CPLB_SUPV_WR); 289// 290// LD32(p3, DCPLB_DATA7); 291// LD32(r3, PAGE_SIZE_1K|CPLB_VALID|CPLB_DIRTY|CPLB_USER_RW|CPLB_SUPV_WR); 292// 293// 294//X6: //[p1] = r1; // Exception should occur here 295// r0 = [p1]; 296// 297// 298// // Now check that handler read correct values 299// CHECKREG(r4,0x23); // supv and EXCPT_PROT 300// CHECKREG(r5, 0x6000); 301// // CHECKREG(r6, FAULT_USER|FAULT_WRITE|FAULT_DAG1 | FAULT_CPLB6); 302// CHECKREG_SYM(r7, X6, r0); // RETX should be value of X6 (HARDCODED ADDR!!) 303 304 305 //------------------------------------------------------- 306 dbg_pass; 307 308 309handler: 310 // generic protection exception handler 311 // Inputs: 312 // p2: addr of CPLB entry to be modified ( current test) 313 // r2: new data for CPLB entry 314 // 315 // p3: addr of CPLB entry to be modified ( next test) 316 // r3: new data for CPLB entry 317 // 318 // Outputs: 319 // r4: SEQSTAT 320 // r5: DCPLB_FAULT_ADDR 321 // r6: DCPLB_STATUS 322 // r7: RETX (instruction addr where exception occurred) 323 324 325 R4 = SEQSTAT; // Get exception cause 326 327 // read data addr which caused exception 328 RD_MMR(DCPLB_FAULT_ADDR, p0, r5); 329 RD_MMR(DCPLB_STATUS, p0, r6); 330 331 // Reset status regs 332 WR_MMR(DCPLB_FAULT_ADDR, 0, p0, r0); 333 WR_MMR(DCPLB_STATUS, 0, p0, r0); 334 335 R7 = RETX; // get address of excepting instruction 336 337 338 // modify CPLB to allow access. Main pgm passes in addr and data 339 [ P2 ] = R2; 340 341 // Set up for next test 342 [ P3 ] = R3; 343 344 NOP;NOP;NOP;NOP;NOP;NOP;NOP; // in lieu of CSYNC; 345 346 // return from exception and re-execute offending instruction 347 RTX; 348 349 // Nops to work around ICache bug 350 NOP;NOP;NOP;NOP;NOP; 351 NOP;NOP;NOP;NOP;NOP; 352 353 354.section MEM_0x800,"aw" 355 .dd 0x00000000 356 .dd 0x00000000 357 .dd 0x00000000 358 .dd 0x00000000 359 360.section MEM_0x1000,"aw" 361 .dd 0x00000000 362 .dd 0x00000000 363 .dd 0x00000000 364 .dd 0x00000000 365 366.section MEM_0x2000,"aw" 367 .dd 0x00000000 368 .dd 0x00000000 369 .dd 0x00000000 370 .dd 0x00000000 371 372.section MEM_0x3000,"aw" 373 .dd 0x00000000 374 .dd 0x00000000 375 .dd 0x00000000 376 .dd 0x00000000 377 378.section MEM_0x4000,"aw" 379 .dd 0x00000000 380 .dd 0x00000000 381 .dd 0x00000000 382 .dd 0x00000000 383 384.section MEM_0x5000,"aw" 385 .dd 0x00000000 386 .dd 0x00000000 387 .dd 0x00000000 388 .dd 0x00000000 389 390// Need a cache miss to test CPLB_L1REF 391//.data 0x6000 392// .dd 0x00000000 393// .dd 0x00000000 394// .dd 0x00000000 395// .dd 0x00000000 396 397.section MEM_0x7000,"aw" 398 .dd 0x00000000 399 .dd 0x00000000 400 .dd 0x00000000 401 .dd 0x00000000 402