@@ -1053,6 +1053,82 @@ impl<'a> Initializer<'a> {
10531053 Ok ( ( ) )
10541054 }
10551055
1056+ #[ sel4:: sel4_cfg( KERNEL_MCS ) ]
1057+ fn us_to_ticks ( & self , duration_us : u64 ) -> Result < sel4:: Time > {
1058+ sel4:: sel4_cfg_if! {
1059+ if #[ sel4_cfg( any( ARCH_ARM , ARCH_RISCV ) ) ] {
1060+ const US_IN_SECOND : u64 = 1000 * 1000 ;
1061+
1062+ // On 32-bit platforms, Word is 32-bits, but on 64-bit platforms
1063+ // it is also a u64 and deemed "unnecessary".
1064+ #[ allow( clippy:: useless_conversion) ]
1065+ let f: u64 = sel4:: sel4_cfg_word!( TIMER_FREQUENCY ) . into( ) ;
1066+
1067+ // TODO: Formal correctness of this implementation
1068+ // https://github.com/seL4/capdl/issues/98
1069+ // See also the corresponding implementation in capDL.
1070+
1071+ if ( duration_us / US_IN_SECOND ) >= ( 1u64 << 56 ) / f {
1072+ panic!(
1073+ "Input us {duration_us} would overflow 64-bits of \
1074+ exceed 56-bit output tick maximum @ freq {f} Hz"
1075+ ) ;
1076+ }
1077+
1078+ let s: u64 = duration_us / US_IN_SECOND ;
1079+ let us: u64 = duration_us % US_IN_SECOND ;
1080+
1081+ // The '+ US_IN_S / 2' implements round-to-nearest behaviour
1082+ let ticks = s * f + ( ( us * f + US_IN_SECOND / 2 ) / US_IN_SECOND ) ;
1083+
1084+ Ok ( ticks)
1085+ } else if #[ sel4_cfg( any( ARCH_X86 , ARCH_X86_64 ) ) ] {
1086+ let tsc_freq_bi = self
1087+ . bootinfo
1088+ . extra( )
1089+ . find( |bi| bi. id == sel4:: BootInfoExtraId :: X86TscFreq )
1090+ . expect( "Unable to determine timer frequency as \
1091+ no TSC frequency provided in bootinfo") ;
1092+
1093+ // For x86 platforms, the timer frequency is provided in MHz by the bootinfo
1094+ let tsc_freq_mhz = u32 :: from_le_bytes( tsc_freq_bi. content( ) . try_into( ) . unwrap( ) ) ;
1095+
1096+ let ticks = duration_us
1097+ . checked_mul( tsc_freq_mhz. into( ) )
1098+ . expect( format!(
1099+ "Output would overflow when computing ticks for duration \
1100+ {duration_us} us @ freq {tsc_freq_mhz} MHz") ) ;
1101+
1102+ Ok ( ticks)
1103+ } else {
1104+ compile_error!( "unsupported architecture" ) ;
1105+ }
1106+ }
1107+ }
1108+
1109+ #[ sel4:: sel4_cfg( not( KERNEL_MCS ) ) ]
1110+ fn us_to_ticks ( & self , duration_us : u64 ) -> Result < sel4:: Time > {
1111+ // On non-MCS, 1 tick is equivalent to 1 TIMER_TICK_MS, or an integer multiple
1112+ // of 1 millisecond.
1113+
1114+ // On 32-bit platforms, Word is 32-bits, but on 64-bit platforms it is
1115+ // also a u64 and deemed "unnecessary".
1116+ #[ allow( clippy:: unnecessary_cast) ]
1117+ const TIMER_TICK_MS : u64 = sel4:: sel4_cfg_word!( TIMER_TICK_MS ) as u64 ;
1118+ let period_us: u64 = 1000 * TIMER_TICK_MS ;
1119+ let ticks: u64 = duration_us / period_us;
1120+ let remainder: u64 = duration_us % period_us;
1121+
1122+ if remainder != 0 {
1123+ panic ! (
1124+ "domain schedule duration {duration_us} is not an \
1125+ integer multiple of TIMER_TICK_MS ({TIMER_TICK_MS} ms)"
1126+ ) ;
1127+ }
1128+
1129+ Ok ( ticks)
1130+ }
1131+
10561132 fn init_domain_schedule ( & self ) -> Result < ( ) > {
10571133 if let ArchivedOption :: Some ( domain_schedule) = & self . spec . domain_schedule {
10581134 debug ! ( "Initializing domain schedule" ) ;
@@ -1066,11 +1142,17 @@ impl<'a> Initializer<'a> {
10661142
10671143 // sched_index is used as a shift, and not an invariant for the loop.
10681144 #[ allow( clippy:: explicit_counter_loop) ]
1069- for ArchivedDomainSchedEntry { id, time } in domain_schedule. iter ( ) {
1070- let domain_time = * time;
1145+ for ArchivedDomainSchedEntry { domain, duration } in domain_schedule. iter ( ) {
1146+ let duration_ticks: u64 = match * duration {
1147+ ArchivedDomainSchedDuration :: Ticks ( ticks) => ticks. get ( ) ,
1148+ ArchivedDomainSchedDuration :: Us ( us) => self . us_to_ticks ( us. get ( ) ) ?,
1149+ ArchivedDomainSchedDuration :: EndMarker => 0 ,
1150+ } ;
1151+
10711152 init_thread:: slot:: DOMAIN_SET
10721153 . cap ( )
1073- . domain_set_schedule_configure ( sched_index, * id, domain_time. to_native ( ) ) ?;
1154+ . domain_set_schedule_configure ( sched_index, * domain, duration_ticks) ?;
1155+
10741156 sched_index += 1 ;
10751157 }
10761158 }
0 commit comments