From dc9b3c0f381f1747eb8020e069649033606342b9 Mon Sep 17 00:00:00 2001 From: Andre Richter Date: Fri, 29 Jan 2021 22:26:45 +0100 Subject: [PATCH] Add isb before timer read --- 08_timestamps/README.md | 19 +++++++++++++++--- 08_timestamps/src/_arch/aarch64/time.rs | 17 ++++++++++++++-- 09_hw_debug_JTAG/src/_arch/aarch64/time.rs | 17 ++++++++++++++-- 10_privilege_level/src/_arch/aarch64/time.rs | 17 ++++++++++++++-- .../src/_arch/aarch64/time.rs | 17 ++++++++++++++-- .../src/_arch/aarch64/time.rs | 17 ++++++++++++++-- .../src/_arch/aarch64/time.rs | 17 ++++++++++++++-- .../src/_arch/aarch64/time.rs | 17 ++++++++++++++-- .../src/_arch/aarch64/time.rs | 17 ++++++++++++++-- X1_JTAG_boot/jtag_boot_rpi3.img | Bin 8144 -> 8144 bytes X1_JTAG_boot/jtag_boot_rpi4.img | Bin 6848 -> 6864 bytes X1_JTAG_boot/src/_arch/aarch64/time.rs | 17 ++++++++++++++-- 12 files changed, 151 insertions(+), 21 deletions(-) diff --git a/08_timestamps/README.md b/08_timestamps/README.md index 83e38ca5..0f8ec5d2 100644 --- a/08_timestamps/README.md +++ b/08_timestamps/README.md @@ -175,7 +175,7 @@ diff -uNr 07_uart_chainloader/src/_arch/aarch64/cpu.rs 08_timestamps/src/_arch/a diff -uNr 07_uart_chainloader/src/_arch/aarch64/time.rs 08_timestamps/src/_arch/aarch64/time.rs --- 07_uart_chainloader/src/_arch/aarch64/time.rs +++ 08_timestamps/src/_arch/aarch64/time.rs -@@ -0,0 +1,105 @@ +@@ -0,0 +1,118 @@ +// SPDX-License-Identifier: MIT OR Apache-2.0 +// +// Copyright (c) 2018-2021 Andre Richter @@ -191,7 +191,7 @@ diff -uNr 07_uart_chainloader/src/_arch/aarch64/time.rs 08_timestamps/src/_arch/ + +use crate::{time, warn}; +use core::time::Duration; -+use cortex_a::regs::*; ++use cortex_a::{barrier, regs::*}; + +//-------------------------------------------------------------------------------------------------- +// Private Definitions @@ -209,6 +209,19 @@ diff -uNr 07_uart_chainloader/src/_arch/aarch64/time.rs 08_timestamps/src/_arch/ +static TIME_MANAGER: GenericTimer = GenericTimer; + +//-------------------------------------------------------------------------------------------------- ++// Private Code ++//-------------------------------------------------------------------------------------------------- ++ ++impl GenericTimer { ++ #[inline(always)] ++ fn read_cntpct(&self) -> u64 { ++ // Prevent that the counter is read ahead of time due to out-of-order execution. ++ unsafe { barrier::isb(barrier::SY) }; ++ CNTPCT_EL0.get() ++ } ++} ++ ++//-------------------------------------------------------------------------------------------------- +// Public Code +//-------------------------------------------------------------------------------------------------- + @@ -227,8 +240,8 @@ diff -uNr 07_uart_chainloader/src/_arch/aarch64/time.rs 08_timestamps/src/_arch/ + } + + fn uptime(&self) -> Duration { ++ let current_count: u64 = self.read_cntpct() * NS_PER_S; + let frq: u64 = CNTFRQ_EL0.get() as u64; -+ let current_count: u64 = CNTPCT_EL0.get() * NS_PER_S; + + Duration::from_nanos(current_count / frq) + } diff --git a/08_timestamps/src/_arch/aarch64/time.rs b/08_timestamps/src/_arch/aarch64/time.rs index 3a766009..63017305 100644 --- a/08_timestamps/src/_arch/aarch64/time.rs +++ b/08_timestamps/src/_arch/aarch64/time.rs @@ -13,7 +13,7 @@ use crate::{time, warn}; use core::time::Duration; -use cortex_a::regs::*; +use cortex_a::{barrier, regs::*}; //-------------------------------------------------------------------------------------------------- // Private Definitions @@ -30,6 +30,19 @@ struct GenericTimer; static TIME_MANAGER: GenericTimer = GenericTimer; +//-------------------------------------------------------------------------------------------------- +// Private Code +//-------------------------------------------------------------------------------------------------- + +impl GenericTimer { + #[inline(always)] + fn read_cntpct(&self) -> u64 { + // Prevent that the counter is read ahead of time due to out-of-order execution. + unsafe { barrier::isb(barrier::SY) }; + CNTPCT_EL0.get() + } +} + //-------------------------------------------------------------------------------------------------- // Public Code //-------------------------------------------------------------------------------------------------- @@ -49,8 +62,8 @@ impl time::interface::TimeManager for GenericTimer { } fn uptime(&self) -> Duration { + let current_count: u64 = self.read_cntpct() * NS_PER_S; let frq: u64 = CNTFRQ_EL0.get() as u64; - let current_count: u64 = CNTPCT_EL0.get() * NS_PER_S; Duration::from_nanos(current_count / frq) } diff --git a/09_hw_debug_JTAG/src/_arch/aarch64/time.rs b/09_hw_debug_JTAG/src/_arch/aarch64/time.rs index 3a766009..63017305 100644 --- a/09_hw_debug_JTAG/src/_arch/aarch64/time.rs +++ b/09_hw_debug_JTAG/src/_arch/aarch64/time.rs @@ -13,7 +13,7 @@ use crate::{time, warn}; use core::time::Duration; -use cortex_a::regs::*; +use cortex_a::{barrier, regs::*}; //-------------------------------------------------------------------------------------------------- // Private Definitions @@ -30,6 +30,19 @@ struct GenericTimer; static TIME_MANAGER: GenericTimer = GenericTimer; +//-------------------------------------------------------------------------------------------------- +// Private Code +//-------------------------------------------------------------------------------------------------- + +impl GenericTimer { + #[inline(always)] + fn read_cntpct(&self) -> u64 { + // Prevent that the counter is read ahead of time due to out-of-order execution. + unsafe { barrier::isb(barrier::SY) }; + CNTPCT_EL0.get() + } +} + //-------------------------------------------------------------------------------------------------- // Public Code //-------------------------------------------------------------------------------------------------- @@ -49,8 +62,8 @@ impl time::interface::TimeManager for GenericTimer { } fn uptime(&self) -> Duration { + let current_count: u64 = self.read_cntpct() * NS_PER_S; let frq: u64 = CNTFRQ_EL0.get() as u64; - let current_count: u64 = CNTPCT_EL0.get() * NS_PER_S; Duration::from_nanos(current_count / frq) } diff --git a/10_privilege_level/src/_arch/aarch64/time.rs b/10_privilege_level/src/_arch/aarch64/time.rs index 3a766009..63017305 100644 --- a/10_privilege_level/src/_arch/aarch64/time.rs +++ b/10_privilege_level/src/_arch/aarch64/time.rs @@ -13,7 +13,7 @@ use crate::{time, warn}; use core::time::Duration; -use cortex_a::regs::*; +use cortex_a::{barrier, regs::*}; //-------------------------------------------------------------------------------------------------- // Private Definitions @@ -30,6 +30,19 @@ struct GenericTimer; static TIME_MANAGER: GenericTimer = GenericTimer; +//-------------------------------------------------------------------------------------------------- +// Private Code +//-------------------------------------------------------------------------------------------------- + +impl GenericTimer { + #[inline(always)] + fn read_cntpct(&self) -> u64 { + // Prevent that the counter is read ahead of time due to out-of-order execution. + unsafe { barrier::isb(barrier::SY) }; + CNTPCT_EL0.get() + } +} + //-------------------------------------------------------------------------------------------------- // Public Code //-------------------------------------------------------------------------------------------------- @@ -49,8 +62,8 @@ impl time::interface::TimeManager for GenericTimer { } fn uptime(&self) -> Duration { + let current_count: u64 = self.read_cntpct() * NS_PER_S; let frq: u64 = CNTFRQ_EL0.get() as u64; - let current_count: u64 = CNTPCT_EL0.get() * NS_PER_S; Duration::from_nanos(current_count / frq) } diff --git a/11_virtual_mem_part1_identity_mapping/src/_arch/aarch64/time.rs b/11_virtual_mem_part1_identity_mapping/src/_arch/aarch64/time.rs index 3a766009..63017305 100644 --- a/11_virtual_mem_part1_identity_mapping/src/_arch/aarch64/time.rs +++ b/11_virtual_mem_part1_identity_mapping/src/_arch/aarch64/time.rs @@ -13,7 +13,7 @@ use crate::{time, warn}; use core::time::Duration; -use cortex_a::regs::*; +use cortex_a::{barrier, regs::*}; //-------------------------------------------------------------------------------------------------- // Private Definitions @@ -30,6 +30,19 @@ struct GenericTimer; static TIME_MANAGER: GenericTimer = GenericTimer; +//-------------------------------------------------------------------------------------------------- +// Private Code +//-------------------------------------------------------------------------------------------------- + +impl GenericTimer { + #[inline(always)] + fn read_cntpct(&self) -> u64 { + // Prevent that the counter is read ahead of time due to out-of-order execution. + unsafe { barrier::isb(barrier::SY) }; + CNTPCT_EL0.get() + } +} + //-------------------------------------------------------------------------------------------------- // Public Code //-------------------------------------------------------------------------------------------------- @@ -49,8 +62,8 @@ impl time::interface::TimeManager for GenericTimer { } fn uptime(&self) -> Duration { + let current_count: u64 = self.read_cntpct() * NS_PER_S; let frq: u64 = CNTFRQ_EL0.get() as u64; - let current_count: u64 = CNTPCT_EL0.get() * NS_PER_S; Duration::from_nanos(current_count / frq) } diff --git a/12_exceptions_part1_groundwork/src/_arch/aarch64/time.rs b/12_exceptions_part1_groundwork/src/_arch/aarch64/time.rs index 3a766009..63017305 100644 --- a/12_exceptions_part1_groundwork/src/_arch/aarch64/time.rs +++ b/12_exceptions_part1_groundwork/src/_arch/aarch64/time.rs @@ -13,7 +13,7 @@ use crate::{time, warn}; use core::time::Duration; -use cortex_a::regs::*; +use cortex_a::{barrier, regs::*}; //-------------------------------------------------------------------------------------------------- // Private Definitions @@ -30,6 +30,19 @@ struct GenericTimer; static TIME_MANAGER: GenericTimer = GenericTimer; +//-------------------------------------------------------------------------------------------------- +// Private Code +//-------------------------------------------------------------------------------------------------- + +impl GenericTimer { + #[inline(always)] + fn read_cntpct(&self) -> u64 { + // Prevent that the counter is read ahead of time due to out-of-order execution. + unsafe { barrier::isb(barrier::SY) }; + CNTPCT_EL0.get() + } +} + //-------------------------------------------------------------------------------------------------- // Public Code //-------------------------------------------------------------------------------------------------- @@ -49,8 +62,8 @@ impl time::interface::TimeManager for GenericTimer { } fn uptime(&self) -> Duration { + let current_count: u64 = self.read_cntpct() * NS_PER_S; let frq: u64 = CNTFRQ_EL0.get() as u64; - let current_count: u64 = CNTPCT_EL0.get() * NS_PER_S; Duration::from_nanos(current_count / frq) } diff --git a/13_integrated_testing/src/_arch/aarch64/time.rs b/13_integrated_testing/src/_arch/aarch64/time.rs index 3a766009..63017305 100644 --- a/13_integrated_testing/src/_arch/aarch64/time.rs +++ b/13_integrated_testing/src/_arch/aarch64/time.rs @@ -13,7 +13,7 @@ use crate::{time, warn}; use core::time::Duration; -use cortex_a::regs::*; +use cortex_a::{barrier, regs::*}; //-------------------------------------------------------------------------------------------------- // Private Definitions @@ -30,6 +30,19 @@ struct GenericTimer; static TIME_MANAGER: GenericTimer = GenericTimer; +//-------------------------------------------------------------------------------------------------- +// Private Code +//-------------------------------------------------------------------------------------------------- + +impl GenericTimer { + #[inline(always)] + fn read_cntpct(&self) -> u64 { + // Prevent that the counter is read ahead of time due to out-of-order execution. + unsafe { barrier::isb(barrier::SY) }; + CNTPCT_EL0.get() + } +} + //-------------------------------------------------------------------------------------------------- // Public Code //-------------------------------------------------------------------------------------------------- @@ -49,8 +62,8 @@ impl time::interface::TimeManager for GenericTimer { } fn uptime(&self) -> Duration { + let current_count: u64 = self.read_cntpct() * NS_PER_S; let frq: u64 = CNTFRQ_EL0.get() as u64; - let current_count: u64 = CNTPCT_EL0.get() * NS_PER_S; Duration::from_nanos(current_count / frq) } diff --git a/14_exceptions_part2_peripheral_IRQs/src/_arch/aarch64/time.rs b/14_exceptions_part2_peripheral_IRQs/src/_arch/aarch64/time.rs index 3a766009..63017305 100644 --- a/14_exceptions_part2_peripheral_IRQs/src/_arch/aarch64/time.rs +++ b/14_exceptions_part2_peripheral_IRQs/src/_arch/aarch64/time.rs @@ -13,7 +13,7 @@ use crate::{time, warn}; use core::time::Duration; -use cortex_a::regs::*; +use cortex_a::{barrier, regs::*}; //-------------------------------------------------------------------------------------------------- // Private Definitions @@ -30,6 +30,19 @@ struct GenericTimer; static TIME_MANAGER: GenericTimer = GenericTimer; +//-------------------------------------------------------------------------------------------------- +// Private Code +//-------------------------------------------------------------------------------------------------- + +impl GenericTimer { + #[inline(always)] + fn read_cntpct(&self) -> u64 { + // Prevent that the counter is read ahead of time due to out-of-order execution. + unsafe { barrier::isb(barrier::SY) }; + CNTPCT_EL0.get() + } +} + //-------------------------------------------------------------------------------------------------- // Public Code //-------------------------------------------------------------------------------------------------- @@ -49,8 +62,8 @@ impl time::interface::TimeManager for GenericTimer { } fn uptime(&self) -> Duration { + let current_count: u64 = self.read_cntpct() * NS_PER_S; let frq: u64 = CNTFRQ_EL0.get() as u64; - let current_count: u64 = CNTPCT_EL0.get() * NS_PER_S; Duration::from_nanos(current_count / frq) } diff --git a/15_virtual_mem_part2_mmio_remap/src/_arch/aarch64/time.rs b/15_virtual_mem_part2_mmio_remap/src/_arch/aarch64/time.rs index 3a766009..63017305 100644 --- a/15_virtual_mem_part2_mmio_remap/src/_arch/aarch64/time.rs +++ b/15_virtual_mem_part2_mmio_remap/src/_arch/aarch64/time.rs @@ -13,7 +13,7 @@ use crate::{time, warn}; use core::time::Duration; -use cortex_a::regs::*; +use cortex_a::{barrier, regs::*}; //-------------------------------------------------------------------------------------------------- // Private Definitions @@ -30,6 +30,19 @@ struct GenericTimer; static TIME_MANAGER: GenericTimer = GenericTimer; +//-------------------------------------------------------------------------------------------------- +// Private Code +//-------------------------------------------------------------------------------------------------- + +impl GenericTimer { + #[inline(always)] + fn read_cntpct(&self) -> u64 { + // Prevent that the counter is read ahead of time due to out-of-order execution. + unsafe { barrier::isb(barrier::SY) }; + CNTPCT_EL0.get() + } +} + //-------------------------------------------------------------------------------------------------- // Public Code //-------------------------------------------------------------------------------------------------- @@ -49,8 +62,8 @@ impl time::interface::TimeManager for GenericTimer { } fn uptime(&self) -> Duration { + let current_count: u64 = self.read_cntpct() * NS_PER_S; let frq: u64 = CNTFRQ_EL0.get() as u64; - let current_count: u64 = CNTPCT_EL0.get() * NS_PER_S; Duration::from_nanos(current_count / frq) } diff --git a/X1_JTAG_boot/jtag_boot_rpi3.img b/X1_JTAG_boot/jtag_boot_rpi3.img index 9f8ada21812d7d7772028c6bfed45c182479b457..4cd4401535b2b3cb1f5cbf807c72b1f69637cedd 100755 GIT binary patch delta 236 zcmca$f5Co&3?utQ+0%@dH@=K#WUSuo$@G{{NP&YPG2yZHI1ct-BmoSYE(Qy}?; zS`%NdW>^U_Q5$F)7Z7K0O^y;e#}*4TvEkcfJz*uL8~-NH5)P7K02;~!#0(A^6BU^o zf}9R$O#Jiv|8xZgg)5Wa2&)J>{r^8b$pK=rzKfYAJ_7O;7!A2>G2yZHI1ct-BmFBu`m zoB|oM5Y?Dh-~Ml909wHW#0(A^6BU^of}9R$Oyv7Bxk@-_@(W=VLC639r)S)9|H;WP tBZzY*!%o}DvLfz`w_4nAa^|8CuL6s>lEk~YYi+f16 zC;^>fw{548`PLREV{F5|mqqOl$WU&>-eMyYx$RnRv4mUL&$b)^_vms!De-BIeMb?E+bh#hO}Aww+HIGEO&Y4IbWA0$Gjt9(u+FpvyM z>zs2hAQzyEV$jSHt&4^wEpb>RGtP<~RKl~1T06C(o`DV{&V)@%e8*UNA$ckJM#eM8 z*^x@OOuZt0H{6N%adYdT#V#3Cb4cVRT5WC^s3@-&tuZ&lO^S*s^T_+ooWA}Q{T?odg zmre%5wT&^Mc!AV|Jt!q=j2D$eJeWv|MuU1FUW`TU`gV6T%1d_Nyf@$Xe&=O(sXNn5 zo-Vc2+G<|dVU_?ahSb7ATbvMJ=Y(q{$36u<69_6P1bsx*2(xFYhAx zvH(roHaSSBuwAR$Y#V;|qwYKgDkSU235l{NdsH&Y zoKis4LX>Dgr`ZANl(gZ-(DwW$hOGg}3{J5dQXmS=w0sQc)=zyd2*Fpw0JApyjI%D- zR;#^G5zD=63R{yVT)7ynL+W$F1{<&scB!E!tv1r~dqUp{gw9m;Ih8N-pb~Sa z#hZ35ana-Mj5(kvqA%@&g@o$^6b;}Xut?(6g(L-a9}&N}2n?AC?TS@QR-t1UsEHTz z7kd@H8~A6sJ~Xad1?Z2+YPAz8pRpiOm`;d~ms3F}+%q`w6*s%P_X_D}F?V3MF^Sta ziAO+N*syyhJ%$SfEwLF9@UBC?Q&cjdQHC$GttQ!+)G;?6UvtZ#~ur2LJ#7 diff --git a/X1_JTAG_boot/src/_arch/aarch64/time.rs b/X1_JTAG_boot/src/_arch/aarch64/time.rs index 3a766009..63017305 100644 --- a/X1_JTAG_boot/src/_arch/aarch64/time.rs +++ b/X1_JTAG_boot/src/_arch/aarch64/time.rs @@ -13,7 +13,7 @@ use crate::{time, warn}; use core::time::Duration; -use cortex_a::regs::*; +use cortex_a::{barrier, regs::*}; //-------------------------------------------------------------------------------------------------- // Private Definitions @@ -30,6 +30,19 @@ struct GenericTimer; static TIME_MANAGER: GenericTimer = GenericTimer; +//-------------------------------------------------------------------------------------------------- +// Private Code +//-------------------------------------------------------------------------------------------------- + +impl GenericTimer { + #[inline(always)] + fn read_cntpct(&self) -> u64 { + // Prevent that the counter is read ahead of time due to out-of-order execution. + unsafe { barrier::isb(barrier::SY) }; + CNTPCT_EL0.get() + } +} + //-------------------------------------------------------------------------------------------------- // Public Code //-------------------------------------------------------------------------------------------------- @@ -49,8 +62,8 @@ impl time::interface::TimeManager for GenericTimer { } fn uptime(&self) -> Duration { + let current_count: u64 = self.read_cntpct() * NS_PER_S; let frq: u64 = CNTFRQ_EL0.get() as u64; - let current_count: u64 = CNTPCT_EL0.get() * NS_PER_S; Duration::from_nanos(current_count / frq) }