Permalink
Browse files

lm32: mmu: privilege exception support

Raise a priilege exception if we are in user mode and one of the following
opcodes are executed: WCSR, ERET, BRET.

Signed-off-by: Michael Walle <michael@walle.cc>
  • Loading branch information...
1 parent 250c10f commit 1bcfda91bd6a6a2ee7d4d10f8eff9a37df903825 @mwalle committed Dec 6, 2012
View
@@ -825,6 +825,7 @@ wire dtlb_fault_exception;
wire dtlb_exception;
wire itlb_miss_exception;
wire itlb_exception;
+wire privilege_exception;
wire dtlb_miss_x;
wire dtlb_fault_x;
wire itlb_miss_x;
@@ -1847,6 +1848,12 @@ assign dtlb_fault_exception = ( (dtlb_fault_x == `TRUE)
);
assign itlb_exception = (itlb_miss_exception == `TRUE);
assign dtlb_exception = (dtlb_miss_exception == `TRUE) || (dtlb_fault_exception == `TRUE);
+assign privilege_exception = ( (usr == `TRUE)
+ && ( (csr_write_enable_q_x == `TRUE)
+ || (eret_q_x == `TRUE)
+ || (bret_q_x == `TRUE)
+ )
+ );
`endif
`ifdef CFG_DEBUG_ENABLED
@@ -1879,6 +1886,7 @@ assign non_debug_exception_x = (system_call_exception == `TRUE)
`ifdef CFG_MMU_ENABLED
|| (dtlb_exception == `TRUE)
|| (itlb_exception == `TRUE)
+ || (privilege_exception == `TRUE)
`endif
;
@@ -1906,6 +1914,7 @@ assign exception_x = (system_call_exception == `TRUE)
`ifdef CFG_MMU_ENABLED
|| (dtlb_exception == `TRUE)
|| (itlb_exception == `TRUE)
+ || (privilege_exception == `TRUE)
`endif
;
`endif
@@ -1965,6 +1974,9 @@ begin
if (itlb_miss_exception == `TRUE)
eid_x = `LM32_EID_ITLB_MISS;
else
+ if (privilege_exception == `TRUE)
+ eid_x = `LM32_EID_PRIVILEGE;
+ else
`endif
eid_x = `LM32_EID_SCALL;
end
@@ -277,7 +277,7 @@
`define LM32_EID_DTLB_MISS 4'h8
`define LM32_EID_ITLB_MISS 4'h9
`define LM32_EID_DTLB_FAULT 4'ha
-`define LM32_EID_ITLB_FAULT 4'hb
+`define LM32_EID_PRIVILEGE 4'hb
// Pipeline result selection mux controls
@@ -112,3 +112,13 @@ _dtlb_fault_handler:
nop
nop
nop
+
+_privilege_exception_handler:
+ ori r25, r25, 1024
+ addi ra, ea, 4
+ ret
+ nop
+ nop
+ nop
+ nop
+ nop
@@ -234,75 +234,41 @@ test_name MMU_ITLB_EXCEPTION_1
calli disable_itlb
check_excp 64
-# reset PSW for user mode tests
-wcsr PSW, r0
-
test_name MMU_USER_MODE_1
- mvi r3, 0x200
- wcsr PSW, r3
+ mvi r3, 0x200
+ wcsr PSW, r3
+1:
wcsr PSW, r0
- check_csr PSW 0x200
+ check_excp 1024
-test_name MMU_USER_MODE_4
- scall
- check_csr PSW 0x400
- wcsr PSW, r0
+test_name MMU_USER_MODE_2
+ check_reg ea 1b
test_name MMU_USER_MODE_3
- calli enable_user_mode
- wcsr IM, r0
- mvhi r3, 0xdead
- ori r3, r3, 0xbabe
- wcsr IM, r3
- calli disable_user_mode
- check_csr IM 0x0
-
-# eret should be a noop
-test_name MMU_USER_MODE_5
- calli enable_user_mode
- mvi r3, 1
- mvhi ea, hi(1f)
- ori ea, ea, lo(1f)
- eret
- mvi r3, 2
-1:
- calli disable_user_mode
- check_r3 1
-
-# bret should be a noop
-test_name MMU_USER_MODE_6
- calli enable_user_mode
- mvi r3, 1
- mvhi ba, hi(1f)
- ori ba, ba, lo(1f)
- bret
- mvi r3, 2
-1:
- calli disable_user_mode
- check_r3 1
+ check_csr PSW 0x400
# eusr <- usr
-test_name MMU_USER_MODE_7
+test_name MMU_USER_MODE_4
mvi r3, 0x400
- wcsr PSW, r3
+ wcsr PSW, r3
mvhi ea, hi(1f)
ori ea, ea, lo(1f)
- eret
+ eret
1:
rcsr r3, PSW
- calli disable_user_mode
+ calli disable_user_mode
check_r3 0x600
# busr <- usr
-test_name MMU_USER_MODE_8
+test_name MMU_USER_MODE_5
mvi r3, 0x800
- wcsr PSW, r3
+ wcsr PSW, r3
mvhi ba, hi(1f)
ori ba, ba, lo(1f)
- bret
+ bret
1:
rcsr r3, PSW
- calli disable_user_mode
+ calli disable_user_mode
check_r3 0xa00
end

0 comments on commit 1bcfda9

Please sign in to comment.