@@ -21,9 +21,10 @@ pub enum Exception {
2121 EnvironmentCallFromUMode ,
2222 EnvironmentCallFromSMode ,
2323 EnvironmentCallFromMMode ,
24- InstructionPageFault ,
25- LoadPageFault ,
26- StoreAMOPageFault ,
24+ // Stores a trap value (the faulting address) for page fault exceptions.
25+ InstructionPageFault ( u64 ) ,
26+ LoadPageFault ( u64 ) ,
27+ StoreAMOPageFault ( u64 ) ,
2728}
2829
2930/// All the trap kinds.
@@ -57,9 +58,9 @@ impl Exception {
5758 Exception :: EnvironmentCallFromUMode => 8 ,
5859 Exception :: EnvironmentCallFromSMode => 9 ,
5960 Exception :: EnvironmentCallFromMMode => 11 ,
60- Exception :: InstructionPageFault => 12 ,
61- Exception :: LoadPageFault => 13 ,
62- Exception :: StoreAMOPageFault => 15 ,
61+ Exception :: InstructionPageFault ( _ ) => 12 ,
62+ Exception :: LoadPageFault ( _ ) => 13 ,
63+ Exception :: StoreAMOPageFault ( _ ) => 15 ,
6364 }
6465 }
6566
@@ -73,6 +74,32 @@ impl Exception {
7374 }
7475 }
7576
77+ fn trap_value ( & self , pc : u64 ) -> u64 {
78+ // 3.1.17 Machine Trap Value Register (mtval)
79+ // 4.1.9 Supervisor Trap Value Register (stval)
80+ // "When a hardware breakpoint is triggered, or an address-misaligned, access-fault, or
81+ // page-fault exception occurs on an instruction fetch, load, or store, mtval (stval) is
82+ // written with the faulting virtual address. On an illegal instruction trap, mtval (stval)
83+ // may be written with the first XLEN or ILEN bits of the faulting instruction as described
84+ // below. For other traps, mtval (stval) is set to zero, but a future standard may redefine
85+ // mtval's (stval's) setting for other traps."
86+ //
87+ // TODO: support illegal instruction trap.
88+ match self {
89+ Exception :: InstructionAddressMisaligned
90+ | Exception :: InstructionAccessFault
91+ | Exception :: Breakpoint
92+ | Exception :: LoadAddressMisaligned
93+ | Exception :: LoadAccessFault
94+ | Exception :: StoreAMOAddressMisaligned
95+ | Exception :: StoreAMOAccessFault => pc,
96+ Exception :: InstructionPageFault ( val)
97+ | Exception :: LoadPageFault ( val)
98+ | Exception :: StoreAMOPageFault ( val) => * val,
99+ _ => 0 ,
100+ }
101+ }
102+
76103 /// Update CSRs and the program counter depending on an exception.
77104 pub fn take_trap ( & self , cpu : & mut Cpu ) -> Trap {
78105 // 1.2 Privilege Levels
@@ -126,12 +153,7 @@ impl Exception {
126153 // "When a trap is taken into S-mode, stval is written with exception-specific
127154 // information to assist software in handling the trap. Otherwise, stval is never
128155 // written by the implementation, though it may be explicitly written by software."
129- // "When a hardware breakpoint is triggered, or an instruction-fetch, load, or
130- // store address-misaligned, access, or page-fault exception occurs, stval is
131- // written with the faulting virtual address. On an illegal instruction trap,
132- // stval may be written with the first XLEN or ILEN bits of the faulting
133- // instruction as described below. For other exceptions, stval is set to zero."
134- cpu. state . write ( STVAL , 0 ) ;
156+ cpu. state . write ( STVAL , self . trap_value ( exception_pc) ) ;
135157
136158 // Set a previous interrupt-enable bit for supervisor mode (SPIE, 5) to the value
137159 // of a global interrupt-enable bit for supervisor mode (SIE, 1).
@@ -172,12 +194,7 @@ impl Exception {
172194 // exception-specific information to assist software in handling the trap.
173195 // Otherwise, mtval is never written by the implementation, though it may be
174196 // explicitly written by software."
175- // "When a hardware breakpoint is triggered, or an instruction-fetch, load, or
176- // store address-misaligned, access, or page-fault exception occurs, mtval is
177- // written with the faulting virtual address. On an illegal instruction trap,
178- // mtval may be written with the first XLEN or ILEN bits of the faulting
179- // instruction as described below. For other traps, mtval is set to zero."
180- cpu. state . write ( MTVAL , 0 ) ;
197+ cpu. state . write ( MTVAL , self . trap_value ( exception_pc) ) ;
181198
182199 // Set a previous interrupt-enable bit for supervisor mode (MPIE, 7) to the value
183200 // of a global interrupt-enable bit for supervisor mode (MIE, 3).
@@ -208,9 +225,9 @@ impl Exception {
208225 Exception :: EnvironmentCallFromUMode
209226 | Exception :: EnvironmentCallFromSMode
210227 | Exception :: EnvironmentCallFromMMode => Trap :: Requested ,
211- Exception :: InstructionPageFault
212- | Exception :: LoadPageFault
213- | Exception :: StoreAMOPageFault => Trap :: Invisible ,
228+ Exception :: InstructionPageFault ( _ )
229+ | Exception :: LoadPageFault ( _ )
230+ | Exception :: StoreAMOPageFault ( _ ) => Trap :: Invisible ,
214231 }
215232 }
216233}
0 commit comments