summaryrefslogtreecommitdiffstats
path: root/pk/kernel/pk_init.c
diff options
context:
space:
mode:
authorGlenn Miles <milesg@us.ibm.com>2015-03-23 13:13:04 -0500
committerGlenn R. Miles <milesg@us.ibm.com>2015-03-23 14:48:23 -0500
commite3ee55f1932041cefe3e2ebba49207aa9805e51e (patch)
tree1ed53a284799f8d491b5eecd123acbd438845d12 /pk/kernel/pk_init.c
parentd2dd0140d007bce8214fcf022041c0dd5b522dc2 (diff)
downloadtalos-sbe-e3ee55f1932041cefe3e2ebba49207aa9805e51e.tar.gz
talos-sbe-e3ee55f1932041cefe3e2ebba49207aa9805e51e.zip
Add efficient time scaling support
Also removed automatic rescheduling of periodic timers Change-Id: I6427a8d8ed5ca4b75389c3610a16dba10783a8ae Reviewed-on: http://gfw160.aus.stglabs.ibm.com:8080/gerrit/16537 Reviewed-by: Glenn R. Miles <milesg@us.ibm.com> Tested-by: Glenn R. Miles <milesg@us.ibm.com>
Diffstat (limited to 'pk/kernel/pk_init.c')
-rw-r--r--pk/kernel/pk_init.c49
1 files changed, 43 insertions, 6 deletions
diff --git a/pk/kernel/pk_init.c b/pk/kernel/pk_init.c
index 2ac06f33..0add4214 100644
--- a/pk/kernel/pk_init.c
+++ b/pk/kernel/pk_init.c
@@ -15,8 +15,46 @@
#include "pk_trace.h"
uint32_t __pk_timebase_frequency_hz;
-uint32_t __pk_timebase_frequency_khz;
-uint32_t __pk_timebase_frequency_mhz;
+
+/// The timebase frequency is passed into PK during initialization. It cannot
+/// be set statically because there is a requirement to support a frequency
+/// that can change from one IPL to the next. On the 405, scaling of time
+/// intervals is accomplished by doing a 32x32 bit multiplication which is
+/// supported by the ppc405 instruction set. PPE42 does not support 32x32 bit
+/// multiplication directly and some applications can not afford to use a
+/// function call to emulate the operation. Instead we scale the time
+/// interval by shifting the value X bits to the right and adding it to itself.
+/// This can scale the value by 2, 1.5, 1.25, 1.125, etc.
+///
+/// This is the right shift value.
+/// NOTE: shifting by 0 gives a 2x scale factor, shifting by 32 gives a 1x
+/// scale factor.
+uint8_t __pk_timebase_rshift = 32;
+
+void pk_set_timebase_rshift(uint32_t timebase_freq_hz)
+{
+ //Use 1.0 scale if less than halfway between 1.0 and 1.25
+ if(timebase_freq_hz <= (PK_BASE_FREQ_HZ + (PK_BASE_FREQ_HZ >> 3)))
+ {
+ __pk_timebase_rshift = 32;
+ }
+
+ //use 1.25 scale if less than halfway between 1.25 and 1.5
+ else if(timebase_freq_hz <= (PK_BASE_FREQ_HZ + (PK_BASE_FREQ_HZ >> 3) + (PK_BASE_FREQ_HZ >> 2)))
+ {
+ __pk_timebase_rshift = 2;
+ }
+ //use 1.5 scale if less than halfway between 1.5 and 2.0
+ else if(timebase_freq_hz <= (PK_BASE_FREQ_HZ + (PK_BASE_FREQ_HZ >> 2) + (PK_BASE_FREQ_HZ >> 1)))
+ {
+ __pk_timebase_rshift = 1;
+ }
+ //use 2.0 scale if greater than 1.5
+ else
+ {
+ __pk_timebase_rshift = 0;
+ }
+}
/// Initialize PK.
///
@@ -69,8 +107,6 @@ pk_initialize(PkAddress noncritical_stack,
}
__pk_timebase_frequency_hz = timebase_frequency_hz;
- __pk_timebase_frequency_khz = timebase_frequency_hz / 1000;
- __pk_timebase_frequency_mhz = timebase_frequency_hz / 1000000;
__pk_thread_machine_context_default = PK_THREAD_MACHINE_CONTEXT_DEFAULT;
@@ -98,12 +134,13 @@ extern PkTraceBuffer g_pk_trace_buf;
// Schedule the timer that puts a 64bit timestamp in the trace buffer
// periodically. This allows us to use 32bit timestamps.
pk_timer_schedule(&g_pk_trace_timer,
- PK_TRACE_TIMER_PERIOD,
- 0);
+ PK_TRACE_TIMER_PERIOD);
//set the trace timebase HZ
g_pk_trace_buf.hz = timebase_frequency_hz;
+ pk_set_timebase_rshift(timebase_frequency_hz);
+
//set the timebase ajdustment for trace synchronization
pk_trace_set_timebase(initial_timebase);
OpenPOWER on IntegriCloud