@@ -841,25 +841,39 @@ mod rt {
841841 let prio = INTERRUPT_TO_PRIORITY [ cpu_intr as usize ] ;
842842 let configured_interrupts = vectored:: configured_interrupts ( core, status, prio) ;
843843
844+ // Change the current runlevel so that interrupt handlers can access the correct runlevel.
845+ let level = unsafe { change_current_runlevel ( prio) } ;
846+
847+ // When nesting is possible, we run the nestable interrupts first. This ensures that we
848+ // don't violate assumptions made by non-nestable handlers.
849+
850+ if prio != Priority :: max ( ) {
851+ for interrupt_nr in configured_interrupts. iterator ( ) {
852+ let handler =
853+ unsafe { pac:: __EXTERNAL_INTERRUPTS[ interrupt_nr as usize ] . _handler } as usize ;
854+ let nested = ( handler & 1 ) == 0 ;
855+ if nested {
856+ let handler: fn ( ) =
857+ unsafe { core:: mem:: transmute :: < usize , fn ( ) > ( handler & !1 ) } ;
858+
859+ unsafe { riscv:: interrupt:: nested ( handler) } ;
860+ }
861+ }
862+ }
863+
864+ // Now we can run the non-nestable interrupt handlers.
865+
844866 for interrupt_nr in configured_interrupts. iterator ( ) {
845867 let handler =
846868 unsafe { pac:: __EXTERNAL_INTERRUPTS[ interrupt_nr as usize ] . _handler } as usize ;
847869 let not_nested = ( handler & 1 ) == 1 ;
848- let handler = handler & !1 ;
870+ if not_nested || prio == Priority :: max ( ) {
871+ let handler: fn ( ) = unsafe { core:: mem:: transmute :: < usize , fn ( ) > ( handler & !1 ) } ;
849872
850- let handler: fn ( ) = unsafe { core:: mem:: transmute :: < usize , fn ( ) > ( handler) } ;
851-
852- if not_nested || prio == Priority :: Priority15 {
853873 handler ( ) ;
854- } else {
855- let elevated = prio as u8 ;
856- unsafe {
857- let level =
858- change_current_runlevel ( unwrap ! ( Priority :: try_from( elevated as u32 ) ) ) ;
859- riscv:: interrupt:: nested ( handler) ;
860- change_current_runlevel ( level) ;
861- }
862874 }
863875 }
876+
877+ unsafe { change_current_runlevel ( level) } ;
864878 }
865879}
0 commit comments