mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-12-15 04:31:49 +08:00
308 lines
9.2 KiB
ArmAsm
308 lines
9.2 KiB
ArmAsm
|
//Original:/proj/frio/dv/testcases/lmu/lmu_excpt_default/lmu_excpt_default.dsp
|
||
|
// Description: Default protection checks (CPLB disabled)
|
||
|
// - MMR access in User mode
|
||
|
// - DAG1 Access MMRs (supv/user mode, read/write)
|
||
|
// - DAG1 Access Scratch SRAM (user or supervisor mode, read/write)
|
||
|
# mach: bfin
|
||
|
# sim: --environment operating
|
||
|
|
||
|
#include "test.h"
|
||
|
.include "testutils.inc"
|
||
|
start
|
||
|
|
||
|
include(selfcheck.inc)
|
||
|
include(std.inc)
|
||
|
include(mmrs.inc)
|
||
|
|
||
|
#define EXCPT_PROTVIOL 0x23
|
||
|
#define OMODE_SUPV 0 // not used in the hardware
|
||
|
|
||
|
|
||
|
|
||
|
CHECK_INIT(p5, 0xE0000000);
|
||
|
|
||
|
// setup interrupt controller with exception handler address
|
||
|
WR_MMR_LABEL(EVT3, handler, p0, r1);
|
||
|
WR_MMR_LABEL(EVT15, Supv, p0, r1);
|
||
|
WR_MMR(EVT_IMASK, 0xFFFFFFFF, p0, r0);
|
||
|
WR_MMR(EVT_OVERRIDE, 0x00000000, p0, r0);
|
||
|
CSYNC;
|
||
|
|
||
|
A0 = 0;
|
||
|
|
||
|
// go to user mode. and enable exceptions
|
||
|
LD32_LABEL(r0, User);
|
||
|
RETI = R0;
|
||
|
|
||
|
// But first raise interrupt 15 so we can run in supervisor mode.
|
||
|
RAISE 15;
|
||
|
|
||
|
RTI;
|
||
|
|
||
|
Supv:
|
||
|
|
||
|
//-------------------------------------------------------
|
||
|
// DAG1 MMR Write access
|
||
|
|
||
|
|
||
|
|
||
|
LD32(i1, (DCPLB_ADDR0));
|
||
|
LD32_LABEL(p2, Y01); // Exception handler will return to this address
|
||
|
LD32(r0, 0xdeadbeef);
|
||
|
|
||
|
|
||
|
R4 = 0;R5 = 0;R6 = 0;R7 = 0; // Exception handler will set these, reset them first
|
||
|
X01: A0 = 0 || NOP || [ I1 ] = R1; // Exception should occur here
|
||
|
Y01:
|
||
|
|
||
|
// Now check that handler read correct values
|
||
|
CHECKREG(r4, (OMODE_SUPV|EXCPT_PROTVIOL)); // SEQSTAT
|
||
|
CHECKREG(r5, DCPLB_ADDR0); // FAULT ADDRESS
|
||
|
CHECKREG(r6, (FAULT_WRITE|FAULT_DAG1|FAULT_SUPV)); // DCPLB_STATUS
|
||
|
CHECKREG_SYM(r7, X01, r0); // RETX X01: (HARDCODED ADDR!!)
|
||
|
|
||
|
//-------------------------------------------------------
|
||
|
// DAG1 MMR Read access
|
||
|
|
||
|
|
||
|
|
||
|
LD32(i1, (DCPLB_ADDR1));
|
||
|
LD32_LABEL(p2, Y02); // Exception handler will return to this address
|
||
|
|
||
|
|
||
|
R4 = 0;R5 = 0;R6 = 0;R7 = 0; // Exception handler will set these, reset them first
|
||
|
X02: A0 = 0 || NOP || R1 = [ I1 ]; // Exception should occur here
|
||
|
Y02:
|
||
|
|
||
|
// Now check that handler read correct values
|
||
|
CHECKREG(r4, (OMODE_SUPV|EXCPT_PROTVIOL)); // SEQSTAT
|
||
|
CHECKREG(r5, DCPLB_ADDR1); // FAULT ADDRESS
|
||
|
CHECKREG(r6, (FAULT_READ|FAULT_DAG1|FAULT_SUPV)); // DCPLB_STATUS
|
||
|
CHECKREG_SYM(r7, X02, r0); // RETX X02: (HARDCODED ADDR!!)
|
||
|
|
||
|
#if 0
|
||
|
//-------------------------------------------------------
|
||
|
// DAG1 Scratch SRAM Write access
|
||
|
|
||
|
|
||
|
|
||
|
LD32(i1, (( 0xFF800000 + 0x300000)));
|
||
|
LD32_LABEL(p2, Y03); // Exception handler will return to this address
|
||
|
LD32(r1, 0xdeadbeef);
|
||
|
|
||
|
|
||
|
R4 = 0;R5 = 0;R6 = 0;R7 = 0; // Exception handler will set these, reset them first
|
||
|
X03: A0 = 0 || NOP || [ I1 ] = R1; // Exception should occur here
|
||
|
Y03:
|
||
|
|
||
|
// Now check that handler read correct values
|
||
|
CHECKREG(r4, (OMODE_SUPV|EXCPT_PROTVIOL)); // SEQSTAT
|
||
|
CHECKREG(r5, ( 0xFF800000 + 0x300000)); // FAULT ADDRESS
|
||
|
CHECKREG(r6, (FAULT_WRITE|FAULT_DAG1|FAULT_SUPV)); // DCPLB_STATUS
|
||
|
CHECKREG_SYM(r7, X03, r0); // RETX X03: (HARDCODED ADDR!!)
|
||
|
|
||
|
//-------------------------------------------------------
|
||
|
// DAG1 Scratch SRAM Read access
|
||
|
|
||
|
|
||
|
|
||
|
LD32(i1, ((( 0xFF800000 + 0x300000) + 4)));
|
||
|
LD32_LABEL(p2, Y04); // Exception handler will return to this address
|
||
|
|
||
|
|
||
|
R4 = 0;R5 = 0;R6 = 0;R7 = 0; // Exception handler will set these, reset them first
|
||
|
X04: A0 = 0 || NOP || R1 = [ I1 ]; // Exception should occur here
|
||
|
Y04:
|
||
|
|
||
|
// Now check that handler read correct values
|
||
|
CHECKREG(r4, (OMODE_SUPV|EXCPT_PROTVIOL)); // SEQSTAT
|
||
|
CHECKREG(r5, (( 0xFF800000 + 0x300000) + 4)); // FAULT ADDRESS
|
||
|
CHECKREG(r6, (FAULT_READ|FAULT_DAG1|FAULT_SUPV)); // DCPLB_STATUS
|
||
|
CHECKREG_SYM(r7, X04, r0); // RETX X04: (HARDCODED ADDR!!)
|
||
|
#endif
|
||
|
|
||
|
//-------------------------------------------------------
|
||
|
|
||
|
// Now, go to User mode
|
||
|
LD32_LABEL(r0, User);
|
||
|
RETI = R0;
|
||
|
RTI;
|
||
|
|
||
|
|
||
|
User:
|
||
|
|
||
|
//-------------------------------------------------------
|
||
|
// DAG0 MMR Write access (multi-issue)
|
||
|
|
||
|
|
||
|
|
||
|
LD32(i1, (DCPLB_ADDR0));
|
||
|
LD32_LABEL(p2, Y11); // Exception handler will return to this address
|
||
|
LD32(r0, 0xdeadbeef);
|
||
|
|
||
|
|
||
|
R4 = 0;R5 = 0;R6 = 0;R7 = 0; // Exception handler will set these, reset them first
|
||
|
X11: A0 = 0 || [ I1 ] = R1 || NOP; // Exception should occur here
|
||
|
Y11:
|
||
|
|
||
|
// Now check that handler read correct values
|
||
|
CHECKREG(r4, (OMODE_SUPV|EXCPT_PROTVIOL)); // SEQSTAT
|
||
|
CHECKREG(r5, DCPLB_ADDR0); // FAULT ADDRESS
|
||
|
CHECKREG(r6, (FAULT_WRITE|FAULT_DAG0|FAULT_USER)); // DCPLB_STATUS
|
||
|
CHECKREG_SYM(r7, X11, r0); // RETX X11: (HARDCODED ADDR!!)
|
||
|
|
||
|
//-------------------------------------------------------
|
||
|
// DAG0 MMR Read access (multi-issue)
|
||
|
|
||
|
|
||
|
|
||
|
LD32(i1, (DCPLB_ADDR1));
|
||
|
LD32_LABEL(p2, Y12); // Exception handler will return to this address
|
||
|
|
||
|
|
||
|
R4 = 0;R5 = 0;R6 = 0;R7 = 0; // Exception handler will set these, reset them first
|
||
|
X12: A0 = 0 || R1 = [ I1 ] || NOP; // Exception should occur here
|
||
|
Y12:
|
||
|
|
||
|
// Now check that handler read correct values
|
||
|
CHECKREG(r4, (OMODE_SUPV|EXCPT_PROTVIOL)); // SEQSTAT
|
||
|
CHECKREG(r5, DCPLB_ADDR1); // FAULT ADDRESS
|
||
|
CHECKREG(r6, (FAULT_READ|FAULT_DAG0|FAULT_USER)); // DCPLB_STATUS
|
||
|
CHECKREG_SYM(r7, X12, r0); // RETX X12: (HARDCODED ADDR!!)
|
||
|
|
||
|
//-------------------------------------------------------
|
||
|
// DAG1 MMR Write access
|
||
|
|
||
|
|
||
|
|
||
|
LD32(i1, (DCPLB_ADDR0));
|
||
|
LD32_LABEL(p2, Y13); // Exception handler will return to this address
|
||
|
LD32(r0, 0xdeadbeef);
|
||
|
|
||
|
|
||
|
R4 = 0;R5 = 0;R6 = 0;R7 = 0; // Exception handler will set these, reset them first
|
||
|
X13: A0 = 0 || NOP || [ I1 ] = R1; // Exception should occur here
|
||
|
Y13:
|
||
|
|
||
|
// Now check that handler read correct values
|
||
|
CHECKREG(r4, (OMODE_SUPV|EXCPT_PROTVIOL)); // SEQSTAT
|
||
|
CHECKREG(r5, DCPLB_ADDR0); // FAULT ADDRESS
|
||
|
CHECKREG(r6, (FAULT_WRITE|FAULT_DAG1|FAULT_USER)); // DCPLB_STATUS
|
||
|
CHECKREG_SYM(r7, X13, r0); // RETX X13: (HARDCODED ADDR!!)
|
||
|
|
||
|
//-------------------------------------------------------
|
||
|
// DAG1 MMR Read access
|
||
|
|
||
|
|
||
|
|
||
|
LD32(i1, (DCPLB_ADDR1));
|
||
|
LD32_LABEL(p2, Y14); // Exception handler will return to this address
|
||
|
|
||
|
|
||
|
R4 = 0;R5 = 0;R6 = 0;R7 = 0; // Exception handler will set these, reset them first
|
||
|
X14: A0 = 0 || NOP || R1 = [ I1 ]; // Exception should occur here
|
||
|
Y14:
|
||
|
|
||
|
// Now check that handler read correct values
|
||
|
CHECKREG(r4, (OMODE_SUPV|EXCPT_PROTVIOL)); // SEQSTAT
|
||
|
CHECKREG(r5, DCPLB_ADDR1); // FAULT ADDRESS
|
||
|
CHECKREG(r6, (FAULT_READ|FAULT_DAG1|FAULT_USER)); // DCPLB_STATUS
|
||
|
CHECKREG_SYM(r7, X14, r0); // RETX X14: (HARDCODED ADDR!!)
|
||
|
|
||
|
#if 0
|
||
|
//-------------------------------------------------------
|
||
|
// DAG1 Scratch SRAM Write access
|
||
|
|
||
|
|
||
|
|
||
|
LD32(i1, (( 0xFF800000 + 0x300000)));
|
||
|
LD32_LABEL(p2, Y15); // Exception handler will return to this address
|
||
|
LD32(r1, 0xdeadbeef);
|
||
|
|
||
|
|
||
|
R4 = 0;R5 = 0;R6 = 0;R7 = 0; // Exception handler will set these, reset them first
|
||
|
X15: A0 = 0 || NOP || [ I1 ] = R1; // Exception should occur here
|
||
|
Y15:
|
||
|
|
||
|
// Now check that handler read correct values
|
||
|
CHECKREG(r4, (OMODE_SUPV|EXCPT_PROTVIOL)); // SEQSTAT
|
||
|
CHECKREG(r5, ( 0xFF800000 + 0x300000)); // FAULT ADDRESS
|
||
|
CHECKREG(r6, (FAULT_WRITE|FAULT_DAG1|FAULT_USER)); // DCPLB_STATUS
|
||
|
CHECKREG_SYM(r7, X15, r0); // RETX X15: (HARDCODED ADDR!!)
|
||
|
|
||
|
//-------------------------------------------------------
|
||
|
// DAG1 Scratch SRAM Read access
|
||
|
|
||
|
|
||
|
|
||
|
LD32(i1, ((( 0xFF800000 + 0x300000) + 4)));
|
||
|
LD32_LABEL(p2, Y16); // Exception handler will return to this address
|
||
|
|
||
|
|
||
|
R4 = 0;R5 = 0;R6 = 0;R7 = 0; // Exception handler will set these, reset them first
|
||
|
X16: A0 = 0 || NOP || R1 = [ I1 ]; // Exception should occur here
|
||
|
Y16:
|
||
|
|
||
|
// Now check that handler read correct values
|
||
|
CHECKREG(r4, (OMODE_SUPV|EXCPT_PROTVIOL)); // SEQSTAT
|
||
|
CHECKREG(r5, (( 0xFF800000 + 0x300000) + 4)); // FAULT ADDRESS
|
||
|
CHECKREG(r6, (FAULT_READ|FAULT_DAG1|FAULT_USER)); // DCPLB_STATUS
|
||
|
CHECKREG_SYM(r7, X16, r0); // RETX X16: (HARDCODED ADDR!!)
|
||
|
#endif
|
||
|
|
||
|
//-------------------------------------------------------
|
||
|
// DAG0 MMR Write access (single-issue)
|
||
|
|
||
|
|
||
|
|
||
|
LD32(i1, (DCPLB_ADDR0));
|
||
|
LD32_LABEL(p2, Y17); // Exception handler will return to this address
|
||
|
LD32(r0, 0xdeadbeef);
|
||
|
|
||
|
|
||
|
R4 = 0;R5 = 0;R6 = 0;R7 = 0; // Exception handler will set these, reset them first
|
||
|
X17: [ I1 ] = R1; // Exception should occur here
|
||
|
Y17:
|
||
|
|
||
|
// Now check that handler read correct values
|
||
|
CHECKREG(r4, (OMODE_SUPV|EXCPT_PROTVIOL)); // SEQSTAT
|
||
|
CHECKREG(r5, DCPLB_ADDR0); // FAULT ADDRESS
|
||
|
CHECKREG(r6, (FAULT_WRITE|FAULT_DAG0|FAULT_USER)); // DCPLB_STATUS
|
||
|
CHECKREG_SYM(r7, X17, r0); // RETX X17: (HARDCODED ADDR!!)
|
||
|
|
||
|
//-------------------------------------------------------
|
||
|
// DAG0 MMR Read access (single-issue)
|
||
|
|
||
|
|
||
|
|
||
|
LD32(i1, (DCPLB_ADDR1));
|
||
|
LD32_LABEL(p2, Y18); // Exception handler will return to this address
|
||
|
|
||
|
|
||
|
R4 = 0;R5 = 0;R6 = 0;R7 = 0; // Exception handler will set these, reset them first
|
||
|
X18: R1 = [ I1 ]; // Exception should occur here
|
||
|
Y18:
|
||
|
|
||
|
// Now check that handler read correct values
|
||
|
CHECKREG(r4, (OMODE_SUPV|EXCPT_PROTVIOL)); // SEQSTAT
|
||
|
CHECKREG(r5, DCPLB_ADDR1); // FAULT ADDRESS
|
||
|
CHECKREG(r6, (FAULT_READ|FAULT_DAG0|FAULT_USER)); // DCPLB_STATUS
|
||
|
CHECKREG_SYM(r7, X18, r0); // RETX X18: (HARDCODED ADDR!!)
|
||
|
|
||
|
//-------------------------------------------------------
|
||
|
dbg_pass;
|
||
|
|
||
|
|
||
|
handler:
|
||
|
R4 = SEQSTAT; // Get exception cause
|
||
|
|
||
|
// read and check fail addr (addr_which_causes_exception)
|
||
|
// should not be set for alignment exception
|
||
|
RD_MMR(DCPLB_FAULT_ADDR, p0, r5);
|
||
|
RD_MMR(DCPLB_STATUS, p0, r6);
|
||
|
R7 = RETX; // get address of excepting instruction
|
||
|
|
||
|
RETX = P2;
|
||
|
|
||
|
RTX;
|