@@ -5,21 +5,22 @@ use aarch64_cpu::registers::*;
55
66/// A struct representing the AArch64 CPU context frame.
77///
8- /// This context frame includes the general-purpose registers (GPRs),
9- /// the stack pointer (SP), the exception link register (ELR), and
10- /// the saved program status register (SPSR).
8+ /// This context frame includes
9+ /// * the general-purpose registers (GPRs),
10+ /// * the stack pointer associated with EL0 (SP_EL0),
11+ /// * the exception link register (ELR),
12+ /// * the saved program status register (SPSR).
1113///
1214/// The `#[repr(C)]` attribute ensures that the struct has a C-compatible
1315/// memory layout, which is important when interfacing with hardware or
1416/// other low-level components.
1517#[ repr( C ) ]
16- #[ derive( Copy , Clone , Debug , Default ) ]
18+ #[ derive( Copy , Clone , Debug ) ]
1719pub struct Aarch64ContextFrame {
1820 /// An array of 31 `u64` values representing the general-purpose registers.
1921 pub gpr : [ u64 ; 31 ] ,
20- /// The stack pointer.
21- /// The value currently stored in this field is meaningless (the base address of Aarch64ContextFrame).
22- pub sp : u64 ,
22+ /// The stack pointer associated with EL0 (SP_EL0)
23+ pub sp_el0 : u64 ,
2324 /// The exception link register, which stores the return address after an exception.
2425 pub elr : u64 ,
2526 /// The saved program status register, which holds the state of the program at the time of an exception.
@@ -37,16 +38,16 @@ impl core::fmt::Display for Aarch64ContextFrame {
3738 }
3839 writeln ! ( f, "spsr:{:016x}" , self . spsr) ?;
3940 write ! ( f, "elr: {:016x}" , self . elr) ?;
40- writeln ! ( f, " sp : {:016x}" , self . sp ) ?;
41+ writeln ! ( f, " sp_el0 : {:016x}" , self . sp_el0 ) ?;
4142 Ok ( ( ) )
4243 }
4344}
4445
45- impl Aarch64ContextFrame {
46+ impl Default for Aarch64ContextFrame {
4647 /// Returns the default context frame.
4748 ///
4849 /// The default state sets the SPSR to mask all exceptions and sets the mode to EL1h.
49- pub fn default ( ) -> Aarch64ContextFrame {
50+ fn default ( ) -> Self {
5051 Aarch64ContextFrame {
5152 gpr : [ 0 ; 31 ] ,
5253 spsr : ( SPSR_EL1 :: M :: EL1h
@@ -56,34 +57,12 @@ impl Aarch64ContextFrame {
5657 + SPSR_EL1 :: D :: Masked )
5758 . value ,
5859 elr : 0 ,
59- sp : 0 ,
60+ sp_el0 : 0 ,
6061 }
6162 }
63+ }
6264
63- /// Creates a new context frame with a specific program counter, stack pointer, and argument.
64- ///
65- /// Sets the SPSR to mask all exceptions and sets the mode to EL1h by default.
66- /// # Arguments
67- ///
68- /// * `pc` - The initial program counter (PC).
69- /// * `sp` - The initial stack pointer (SP).
70- /// * `arg` - The argument to be passed in register x0.
71- pub fn new ( pc : usize , sp : usize , arg : usize ) -> Self {
72- let mut r = Aarch64ContextFrame {
73- gpr : [ 0 ; 31 ] ,
74- spsr : ( SPSR_EL1 :: M :: EL1h
75- + SPSR_EL1 :: I :: Masked
76- + SPSR_EL1 :: F :: Masked
77- + SPSR_EL1 :: A :: Masked
78- + SPSR_EL1 :: D :: Masked )
79- . value ,
80- elr : pc as u64 ,
81- sp : sp as u64 ,
82- } ;
83- r. set_argument ( arg) ;
84- r
85- }
86-
65+ impl Aarch64ContextFrame {
8766 /// Returns the exception program counter (ELR).
8867 pub fn exception_pc ( & self ) -> usize {
8968 self . elr as usize
@@ -98,23 +77,6 @@ impl Aarch64ContextFrame {
9877 self . elr = pc as u64 ;
9978 }
10079
101- /// Returns the stack pointer (SP).
102- /// Note: currently returned value is meaningless.
103- pub fn stack_pointer ( & self ) -> usize {
104- self . sp as usize
105- }
106-
107- /// Sets the stack pointer (SP).
108- ///
109- /// Note: currently useless.
110- ///
111- /// # Arguments
112- ///
113- /// * `sp` - The new stack pointer value.
114- pub fn set_stack_pointer ( & mut self , sp : usize ) {
115- self . sp = sp as u64 ;
116- }
117-
11880 /// Sets the argument in register x0.
11981 ///
12082 /// # Arguments
@@ -200,7 +162,7 @@ pub struct GuestSystemRegisters {
200162 pub vmpidr_el2 : u64 ,
201163
202164 // 64bit EL1/EL0 register
203- sp_el0 : u64 ,
165+ pub sp_el0 : u64 ,
204166 sp_el1 : u64 ,
205167 elr_el1 : u64 ,
206168 spsr_el1 : u32 ,
@@ -300,7 +262,9 @@ impl GuestSystemRegisters {
300262 asm ! ( "msr CNTV_CVAL_EL0, {0}" , in( reg) self . cntv_cval_el0) ;
301263 asm ! ( "msr CNTKCTL_EL1, {0:x}" , in ( reg) self . cntkctl_el1) ;
302264 asm ! ( "msr CNTV_CTL_EL0, {0:x}" , in ( reg) self . cntv_ctl_el0) ;
303- asm ! ( "msr SP_EL0, {0}" , in( reg) self . sp_el0) ;
265+ // The restoration of SP_EL0 is done in `exception_return_el2`,
266+ // which move the value from `self.ctx.sp_el0` to `SP_EL0`.
267+ // asm!("msr SP_EL0, {0}", in(reg) self.sp_el0);
304268 asm ! ( "msr SP_EL1, {0}" , in( reg) self . sp_el1) ;
305269 asm ! ( "msr ELR_EL1, {0}" , in( reg) self . elr_el1) ;
306270 asm ! ( "msr SPSR_EL1, {0:x}" , in( reg) self . spsr_el1) ;
0 commit comments