@@ -79,37 +79,52 @@ extern "C" fn set_exception_vector() {
7979 out( "x9" ) _,
8080 ) ;
8181 }
82- // SAFETY: We provide a valid vector table.
8382 #[ cfg( all(
8483 feature = "exceptions" ,
8584 not( any( feature = "el1" , feature = "el2" , feature = "el3" ) )
8685 ) ) ]
87- unsafe {
88- asm ! (
89- "mrs x9, CurrentEL" ,
90- "ubfx x9, x9, #2, #2" ,
91-
92- "cmp x9, #3" ,
93- "b.ne 1f" ,
94- "adr x9, vector_table_el3" ,
95- "msr vbar_el3, x9" ,
96- "b 3f" ,
97-
98- "1:" ,
99- "cmp x9, #2" ,
100- "b.ne 2f" ,
101- "adr x9, vector_table_el2" ,
102- "msr vbar_el2, x9" ,
103- "b 3f" ,
104-
105- "2:" ,
106- "adr x9, vector_table_el1" ,
107- "msr vbar_el1, x9" ,
108-
109- "3:" ,
110- options( nomem, nostack) ,
111- out( "x9" ) _,
112- ) ;
86+ {
87+ let current_el: u64 ;
88+ // SAFETY: Reading CurrentEL is always safe.
89+ unsafe {
90+ asm ! (
91+ "mrs {current_el}, CurrentEL" ,
92+ options( nomem, nostack, preserves_flags) ,
93+ current_el = out( reg) current_el,
94+ ) ;
95+ }
96+ match ( current_el >> 2 ) & 0b11 {
97+ // SAFETY: We provide a valid vector table.
98+ 1 => unsafe {
99+ asm ! (
100+ "adr x9, vector_table_el1" ,
101+ "msr vbar_el1, x9" ,
102+ options( nomem, nostack, preserves_flags) ,
103+ out( "x9" ) _,
104+ ) ;
105+ } ,
106+ // SAFETY: We provide a valid vector table.
107+ 2 => unsafe {
108+ asm ! (
109+ "adr x9, vector_table_el2" ,
110+ "msr vbar_el2, x9" ,
111+ options( nomem, nostack, preserves_flags) ,
112+ out( "x9" ) _,
113+ ) ;
114+ } ,
115+ // SAFETY: We provide a valid vector table.
116+ 3 => unsafe {
117+ asm ! (
118+ "adr x9, vector_table_el3" ,
119+ "msr vbar_el3, x9" ,
120+ options( nomem, nostack, preserves_flags) ,
121+ out( "x9" ) _,
122+ ) ;
123+ } ,
124+ _ => {
125+ panic ! ( "Unexpected EL" ) ;
126+ }
127+ }
113128 }
114129}
115130
0 commit comments