mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-12-21 04:42:53 +08:00
1368b914e9
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.
402 lines
9.6 KiB
ArmAsm
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
|