[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