[openfirmware] r1511 - cpu/x86
svn at openfirmware.info
svn at openfirmware.info
Wed Nov 25 23:20:49 CET 2009
Author: wmb
Date: 2009-11-25 23:20:48 +0100 (Wed, 25 Nov 2009)
New Revision: 1511
Modified:
cpu/x86/acpitimer.fth
cpu/x86/tsc.fth
Log:
Switch back to using ACPI timer for t( and )t, with improvements
in its long-term timekeeping abilities. To prevent rollover on
long t( .. )t runs, you must call t-update from time to time.
Modified: cpu/x86/acpitimer.fth
===================================================================
--- cpu/x86/acpitimer.fth 2009-11-25 22:18:33 UTC (rev 1510)
+++ cpu/x86/acpitimer.fth 2009-11-25 22:20:48 UTC (rev 1511)
@@ -31,16 +31,53 @@
[ifdef] use-acpi-timing
\ Timing tools
-variable timestamp1
-: t( ( -- ) acpi-timer@ timestamp1 ! ;
-: ))t1 ( -- ticks ) acpi-timer@ timestamp1 @ - ;
+2variable timestamp
+0 value timer-high
+: get-timer ( -- d )
+ \ First handle the case where we have aleady rolled over
+ 0 acpi-w@ 1 and if \ Rollover bit changed
+ 1 0 acpi-w! \ Clear indication
+ acpi-timer@ timer-high ( timer.low timer.high )
+ over 0>= if ( timer.low timer.high )
+ 1+ dup to timer-high ( timer.low timer.high' )
+ then ( timer.low timer.high )
+ exit
+ then ( )
+
+ acpi-timer@ timer-high ( timer.low timer.high )
+ 0 acpi-w@ 1 and 0= if exit then \ We are done if rollover bit didn't change
+ 1 0 acpi-w! ( timer.low timer.high )
+ \ Otherwise we must start over, to ensure that low and high are consistent
+
+ 2drop ( )
+ acpi-timer@ timer-high ( timer.low timer.high )
+ over 0>= if ( timer.low timer.high )
+ 1+ dup to timer-high ( timer.low timer.high' )
+ then ( timer.low timer.high )
+;
+: du* ( ud.lo ud.hi u -- res.lo res.mid res.hi ) \ Ignores overflow to third cell
+ tuck um* 2>r ( ud.lo u r: res.mid0 res.hi0 )
+ um* ( res.lo res.mid1 r: res.mid0 res.hi0 )
+ 0 2r> d+ ( res.lo res.mid res.hi )
+;
+: acpi-ticks>usecs ( d.ticks -- usec )
+ d# 50 du* drop ( d.product ) \ The scale factor is 1000/3580 == 50/179
+ d# 179 um/mod nip ( usecs )
+;
+
+\ If you are doing a long timing, call this periodically to handle rollover
+: t-update ( -- ) 0 acpi-w@ 1 and if timer-high 1+ to timer-high then ;
+: t( ( -- ) get-timer timestamp 2! ;
+\ Subtracting 10 accounts for the time it takes to read the ACPI timer,
+\ which is an I/O port and therefore slow to read
+: ))t1 ( -- d.ticks ) get-timer timestamp 2@ d- d# 10. d- 0. dmax ;
: )t ( -- )
- ))t1 d# 1000 d# 3580 */ ( microseconds )
+ ))t1 acpi-ticks>usecs ( microseconds )
push-decimal
<# u# u# u# [char] , hold u# u#s u#> type ." uS "
pop-base
;
-: ))t-sec ( -- sec ) ))t1 d# 3,580,000 / ;
+: ))t-sec ( -- sec ) ))t1 d# 3,580,000 um/mod nip ;
: )t-sec ( -- )
))t-sec ( seconds )
push-decimal
@@ -53,10 +90,7 @@
<# u# u#s u#> type ." :" <# u# u# u#> type ." :" <# u# u# u#> type
pop-base
;
-: )t-hms
- ))t-sec d# 3,580,000 / ( seconds )
- .hms
-;
+: )t-hms ( -- ) ))t-sec .hms ;
[then]
\ LICENSE_BEGIN
Modified: cpu/x86/tsc.fth
===================================================================
--- cpu/x86/tsc.fth 2009-11-25 22:18:33 UTC (rev 1510)
+++ cpu/x86/tsc.fth 2009-11-25 22:20:48 UTC (rev 1511)
@@ -43,6 +43,7 @@
[ifdef] use-tsc-timing \ These are precise but inaccurate, as the TSC varies with clock throttling
\ Timing tools
2variable timestamp
+: t-update ;
: t( ( -- ) tsc@ timestamp 2! ;
: ))t ( -- d.ticks ) tsc@ timestamp 2@ d- ;
: )t ( -- )
More information about the openfirmware
mailing list