binutils-gdb/sim/testsuite/bfin/lmu_excpt_prot1.S
Mike Frysinger 1368b914e9 sim: testsuite: flatten tree
Now that all port tests live under testsuite/sim/*/, and none live
in testsuite/ directly, flatten the structure by moving all of the
dirs under testsuite/sim/ to testsuite/ directly.

We need to stop passing --tool to dejagnu so that it searches all
dirs and not just ones that start with "sim".  Since we have no
other dirs in this tree, and no plans to add any, should be fine.
2021-01-15 19:18:34 -05:00

402 lines
9.6 KiB
ArmAsm

//Original:/proj/frio/dv/testcases/lmu/lmu_excpt_prot1/lmu_excpt_prot1.dsp
// Description: LMU protection exceptions
# mach: bfin
# sim: --environment operating
#include "test.h"
.include "testutils.inc"
start
include(selfcheck.inc)
include(std.inc)
include(mmrs.inc)
//-------------------------------------
// Test LMU/CPLB exceptions
// Basic outline:
// Set exception handler
// program CPLB Entries
// Enable CPLB in DMEM_CNTL
// perform access
// verify exception occurred
CHECK_INIT(p5, 0xEFFFFFFC);
A0 = 0;
//-------------------------
// Zero the CPLB Address and Data regs.
LD32(p0, DCPLB_ADDR0);
R0 = 0;
[ P0 ++ ] = R0; // 0
[ P0 ++ ] = R0; // 1
[ P0 ++ ] = R0; // 2
[ P0 ++ ] = R0; // 3
[ P0 ++ ] = R0; // 4
[ P0 ++ ] = R0; // 5
[ P0 ++ ] = R0; // 6
[ P0 ++ ] = R0; // 7
[ P0 ++ ] = R0; // 8
[ P0 ++ ] = R0; // 9
[ P0 ++ ] = R0; // 10
[ P0 ++ ] = R0; // 11
[ P0 ++ ] = R0; // 12
[ P0 ++ ] = R0; // 13
[ P0 ++ ] = R0; // 14
[ P0 ++ ] = R0; // 15
LD32(p0, DCPLB_DATA0);
[ P0 ++ ] = R0; // 0
[ P0 ++ ] = R0; // 1
[ P0 ++ ] = R0; // 2
[ P0 ++ ] = R0; // 3
[ P0 ++ ] = R0; // 4
[ P0 ++ ] = R0; // 5
[ P0 ++ ] = R0; // 6
[ P0 ++ ] = R0; // 7
[ P0 ++ ] = R0; // 8
[ P0 ++ ] = R0; // 9
[ P0 ++ ] = R0; // 10
[ P0 ++ ] = R0; // 11
[ P0 ++ ] = R0; // 12
[ P0 ++ ] = R0; // 13
[ P0 ++ ] = R0; // 14
[ P0 ++ ] = R0; // 15
// Now set the CPLB entries we will need
// Data area for the desired error
WR_MMR(DCPLB_ADDR0, 0x800, p0, r0);
WR_MMR(DCPLB_ADDR1, 0x1000, p0, r0);
WR_MMR(DCPLB_DATA0, PAGE_SIZE_1K|CPLB_VALID|CPLB_DIRTY|CPLB_L1_CACHABLE, p0, r0);
WR_MMR(DCPLB_ADDR2, 0x2000, p0, r0);
WR_MMR(DCPLB_ADDR3, 0x3000, p0, r0);
WR_MMR(DCPLB_ADDR4, 0x4000, p0, r0);
WR_MMR(DCPLB_ADDR5, 0x5000, p0, r0);
WR_MMR(DCPLB_ADDR6, 0x6000, p0, r0);
WR_MMR(DCPLB_ADDR7, 0x7000, p0, r0);
// CHECKREG segment
WR_MMR(DCPLB_ADDR14, 0xEFFFFC00, p0, r0);
WR_MMR(DCPLB_DATA14, PAGE_SIZE_1K|CPLB_VALID|CPLB_DIRTY|CPLB_WT|CPLB_L1_CACHABLE|CPLB_SUPV_WR|CPLB_USER_RW, p0, r0);
// MMR space
WR_MMR(DCPLB_ADDR15, 0xFFC00000, p0, r0);
WR_MMR(DCPLB_DATA15, PAGE_SIZE_4M|CPLB_VALID|CPLB_DIRTY|CPLB_SUPV_WR, p0, r0);
// setup interrupt controller with exception handler address
WR_MMR_LABEL(EVT3, handler, p0, r1);
WR_MMR_LABEL(EVT15, int_15, p0, r1);
WR_MMR(EVT_IMASK, 0xFFFFFFFF, p0, r0);
WR_MMR(EVT_OVERRIDE, 0x00000000, p0, r0);
// enable CPLB
WR_MMR(DMEM_CONTROL, ENDM | ENDCPLB | DMC_AB_CACHE, p0, r0);
NOP;NOP;NOP;NOP;NOP; // in lieu of CSYNC
// Address for slot 0 accesses
// LD32(p4, 0xEFFFFFF8);
// go to user mode. and enable exceptions
LD32_LABEL(r0, User);
RETI = R0;
// But first raise interrupt 15 so we can do one test
// in supervisor mode.
RAISE 15;
NOP;
RTI;
// Nops to work around ICache bug
NOP;NOP;NOP;NOP;NOP;
NOP;NOP;NOP;NOP;NOP;
int_15:
// Interrupt 15 handler - needed to try supervisor access with exceptions enabled
//-------------------------------------------------------
// Protection violation - Illegal Supervisor Write Access
R0 = 0;R1 = 0;R2 = 0;R3 = 0;R4 = 0;R5 = 0;R6 = 0;R7 = 0;
LD32(i1, 0x800);
LD32(r1, 0xDEADBEEF);
LD32(p2, DCPLB_DATA0);
LD32(r2, PAGE_SIZE_1K|CPLB_VALID|CPLB_DIRTY|CPLB_L1_CACHABLE|CPLB_SUPV_WR);
LD32(p3, DCPLB_DATA1);
LD32(r3, PAGE_SIZE_1K|CPLB_VALID|CPLB_DIRTY|CPLB_L1_CACHABLE|CPLB_SUPV_WR);
X0: //[p1] = r1; // Exception should occur here
A0 = 0 || NOP || [ I1 ] = R1; // test access with DAG1
// Now check that handler read correct values
CHECKREG(r4,0x23); // supv and EXCPT_PROT
CHECKREG(r5, 0x800);
CHECKREG(r6, (FAULT_SUPV|FAULT_WRITE|FAULT_DAG1 | FAULT_CPLB0));
CHECKREG_SYM(r7, X0, r0); // RETX should be value of X0 (HARDCODED ADDR!!)
// go to user mode. and enable exceptions
LD32_LABEL(r0, User);
RTI;
NOP;NOP;NOP;NOP;NOP;
NOP;NOP;NOP;NOP;NOP;
User:
NOP;NOP;NOP;NOP;NOP;
//-------------------------------------------------------
// Protection violation - Illegal User Write Access
R0 = 0;R1 = 0;R2 = 0;R3 = 0;R4 = 0;R5 = 0;R6 = 0;R7 = 0;
LD32(i1, 0x1000);
LD32(r1, 0xDEADBEEF);
// values to fix up current test
LD32(p2, DCPLB_DATA1);
LD32(r2, PAGE_SIZE_1K|CPLB_VALID|CPLB_DIRTY|CPLB_L1_CACHABLE|CPLB_USER_RW|CPLB_SUPV_WR);
// values for next test
LD32(p3, DCPLB_DATA2);
LD32(r3, PAGE_SIZE_1K|CPLB_VALID|CPLB_DIRTY|CPLB_L1_CACHABLE);
X1: //[p1] = r1; // Exception should occur here
A0 = 0 || NOP || [ I1 ] = R1; // test access with DAG1
// Now check that handler read correct values
CHECKREG(r4,0x23); // supv and EXCPT_PROT
CHECKREG(r5, 0x1000);
CHECKREG(r6, (FAULT_USER|FAULT_WRITE|FAULT_DAG1 | FAULT_CPLB1));
CHECKREG_SYM(r7, X1, r0); // RETX should be value of X1 (HARDCODED ADDR!!)
//-------------------------------------------------------
// Protection violation - Illegal User Read Access
R0 = 0;R1 = 0;R2 = 0;R3 = 0;R4 = 0;R5 = 0;R6 = 0;R7 = 0;
LD32(i1, 0x2000);
LD32(r1, 0xDEADBEEF);
LD32(p2, DCPLB_DATA2);
LD32(r2, PAGE_SIZE_1K|CPLB_VALID|CPLB_DIRTY|CPLB_L1_CACHABLE|CPLB_USER_RO|CPLB_SUPV_WR);
LD32(p3, DCPLB_DATA3);
LD32(r3, PAGE_SIZE_1K|CPLB_VALID|CPLB_L1_CACHABLE|CPLB_USER_RW|CPLB_SUPV_WR);
X2: //[p1] = r1; // Exception should occur here
A0 = 0 || NOP || R0 = [ I1 ]; // test access with DAG1
// Now check that handler read correct values
CHECKREG(r4,0x23); // supv and EXCPT_PROT
CHECKREG(r5, 0x2000);
CHECKREG(r6, (FAULT_USER|FAULT_READ|FAULT_DAG1 | FAULT_CPLB2));
CHECKREG_SYM(r7, X2, r0); // RETX should be value of X2 (HARDCODED ADDR!!)
//-------------------------------------------------------
// Protection violation - Illegal Dirty Page Access
R0 = 0;R1 = 0;R2 = 0;R3 = 0;R4 = 0;R5 = 0;R6 = 0;R7 = 0;
LD32(i1, 0x3000);
LD32(r1, 0xDEADBEEF);
LD32(p2, DCPLB_DATA3);
LD32(r2, PAGE_SIZE_1K|CPLB_VALID|CPLB_DIRTY|CPLB_L1_CACHABLE|CPLB_USER_RW|CPLB_SUPV_WR);
LD32(p3, DCPLB_DATA4);
LD32(r3, PAGE_SIZE_1K|CPLB_VALID|CPLB_DA0ACC|CPLB_DIRTY|CPLB_L1_CACHABLE|CPLB_SUPV_WR);
X3: //[p1] = r1; // Exception should occur here
A0 = 0 || NOP || [ I1 ] = R1; // test access with DAG1
// Now check that handler read correct values
CHECKREG(r4,0x23); // supv and EXCPT_PROT
CHECKREG(r5, 0x3000);
CHECKREG(r6, (FAULT_USER|FAULT_WRITE|FAULT_DAG1 | FAULT_CPLB3));
CHECKREG_SYM(r7, X3, r0); // RETX should be value of X3 (HARDCODED ADDR!!)
//-------------------------------------------------------
// Protection violation - Illegal DAG1 Access
R0 = 0;R1 = 0;R2 = 0;R3 = 0;R4 = 0;R5 = 0;R6 = 0;R7 = 0;
LD32(i1, 0x4000);
LD32(r1, 0xDEADBEEF);
LD32(p2, DCPLB_DATA4);
LD32(r2, PAGE_SIZE_1K|CPLB_VALID|CPLB_DIRTY|CPLB_L1_CACHABLE|CPLB_USER_RW|CPLB_SUPV_WR);
LD32(p3, DCPLB_DATA5);
LD32(r3, PAGE_SIZE_1K|CPLB_VALID|CPLB_DIRTY|CPLB_L1_CACHABLE|CPLB_USER_RW|CPLB_SUPV_WR);
X4: //[p1] = r1; // Exception should occur here
A0 = 0 || NOP || [ I1 ] = R1; // test access with DAG1
// Now check that handler read correct values
CHECKREG(r4,0x23); // supv and EXCPT_PROT
CHECKREG(r5, 0x4000);
CHECKREG(r6, (FAULT_USER|FAULT_WRITE|FAULT_DAG1 | FAULT_CPLB4));
CHECKREG_SYM(r7, X4, r0); // RETX should be value of X4 (HARDCODED ADDR!!)
//-------------------------------------------------------
// L1Miss not implemented yet - skip for now....
// //-------------------------------------------------------
// // Protection violation - L1 Miss
// r0=0;r1=0;r2=0;r3=0;r4=0;r5=0;r6=0;r7=0;
//
// LD32(p1, 0x6000);
// LD32(r1, 0xDEADBEEF);
//
// LD32(p2, DCPLB_DATA6);
// LD32(r2, PAGE_SIZE_1K|CPLB_VALID|CPLB_DIRTY|CPLB_L1_CACHABLE|CPLB_USER_RW|CPLB_SUPV_WR);
//
// LD32(p3, DCPLB_DATA7);
// LD32(r3, PAGE_SIZE_1K|CPLB_VALID|CPLB_DIRTY|CPLB_USER_RW|CPLB_SUPV_WR);
//
//
//X6: //[p1] = r1; // Exception should occur here
// r0 = [p1];
//
//
// // Now check that handler read correct values
// CHECKREG(r4,0x23); // supv and EXCPT_PROT
// CHECKREG(r5, 0x6000);
// // CHECKREG(r6, FAULT_USER|FAULT_WRITE|FAULT_DAG1 | FAULT_CPLB6);
// CHECKREG_SYM(r7, X6, r0); // RETX should be value of X6 (HARDCODED ADDR!!)
//-------------------------------------------------------
dbg_pass;
handler:
// generic protection exception handler
// Inputs:
// p2: addr of CPLB entry to be modified ( current test)
// r2: new data for CPLB entry
//
// p3: addr of CPLB entry to be modified ( next test)
// r3: new data for CPLB entry
//
// Outputs:
// r4: SEQSTAT
// r5: DCPLB_FAULT_ADDR
// r6: DCPLB_STATUS
// r7: RETX (instruction addr where exception occurred)
R4 = SEQSTAT; // Get exception cause
// read data addr which caused exception
RD_MMR(DCPLB_FAULT_ADDR, p0, r5);
RD_MMR(DCPLB_STATUS, p0, r6);
// Reset status regs
WR_MMR(DCPLB_FAULT_ADDR, 0, p0, r0);
WR_MMR(DCPLB_STATUS, 0, p0, r0);
R7 = RETX; // get address of excepting instruction
// modify CPLB to allow access. Main pgm passes in addr and data
[ P2 ] = R2;
// Set up for next test
[ P3 ] = R3;
NOP;NOP;NOP;NOP;NOP;NOP;NOP; // in lieu of CSYNC;
// return from exception and re-execute offending instruction
RTX;
// Nops to work around ICache bug
NOP;NOP;NOP;NOP;NOP;
NOP;NOP;NOP;NOP;NOP;
.section MEM_0x800,"aw"
.dd 0x00000000
.dd 0x00000000
.dd 0x00000000
.dd 0x00000000
.section MEM_0x1000,"aw"
.dd 0x00000000
.dd 0x00000000
.dd 0x00000000
.dd 0x00000000
.section MEM_0x2000,"aw"
.dd 0x00000000
.dd 0x00000000
.dd 0x00000000
.dd 0x00000000
.section MEM_0x3000,"aw"
.dd 0x00000000
.dd 0x00000000
.dd 0x00000000
.dd 0x00000000
.section MEM_0x4000,"aw"
.dd 0x00000000
.dd 0x00000000
.dd 0x00000000
.dd 0x00000000
.section MEM_0x5000,"aw"
.dd 0x00000000
.dd 0x00000000
.dd 0x00000000
.dd 0x00000000
// Need a cache miss to test CPLB_L1REF
//.data 0x6000
// .dd 0x00000000
// .dd 0x00000000
// .dd 0x00000000
// .dd 0x00000000
.section MEM_0x7000,"aw"
.dd 0x00000000
.dd 0x00000000
.dd 0x00000000
.dd 0x00000000