Help - Search - Members - Calendar
Full Version: 64bit p-state
InsanelyMac Forum > InsanelyMac Lounge > The X Labs > Intel SpeedStep
Pages: 1, 2, 3
hnak
As Apple has moved com.apple.unsupported to com.apple.private in 10.6, kernel APIs are not visible from 64bit kexts without Apple's signature. As a result, I could not build 64 bit VoodooPower.

So I split the power management functionality into application and kext, where the kext simply reads/write CPU registers and the application monitors CPU ticks and notifies p-state switching to the kext.
It works in my environment ( Q9300 32/64, Phenom920 32 ). As I do not have Nehalem, I have no idea whether it works with them.

Of course, you do not need this at all if you are comfortable with 32bit ( AMD user has no choice anyway ) or using AppleIntelCPUManagement with DSDT patch. As TSC is not adjusted ( 10.6 kernel has removed rtc_stepping/rtc_stepped ), non-constant TSC CPU ( for example, K8 ) may have bad effect by the clock change.

How to use: Install VoodooPState.kext and launch PStateChanger.app.

The kext is reduced version of VoodooPower 1.2.3 and it generates the same p-state table. It cannot co-exist with power-management kexts which manipulates p-state (for example, VoodooPower ).

binary and source:
--- 10/20 updated : fixed memory leak & added doc icon option, avoid instant kp on Lynfield ---
ver. 1.0.3
leopard build
--- 10/11 updated : animates doc icon when hidden, reflects frequency change to sysctl ---
ver. 1.0.2
just in case you want leopard build
--- 10/1 updated : support preference ---
ver. 1.0.1
--- first release
ver. 1.0.0
mitch_de
Thaks i will try that.
I used voodoo minipower on my C2D in 10.5.
Itried iCPU, but it worked noz 100%. Showed pStates kooekt but didnt trottle or shows trotthling but CPU-X didnt (MSR isnt working in Snow i think).
I will report.
netkas
hehe

I built genericintelcpupm for x32/x64 jsut fine and it links ok against unsupported.kext

just need to use two tricks

but then this kext sometimes gives kp during bootup in x64 sad.gif
hnak
QUOTE (netkas @ Sep 26 2009, 03:01 PM) *
hehe

I built genericintelcpupm for x32/x64 jsut fine and it links ok against unsupported.kext

just need to use two tricks

but then this kext sometimes gives kp during bootup in x64 sad.gif

How do you get the load of all the cores ?
ricom2ger
Is it possible to change the throttling level?
hnak
QUOTE (riws @ Sep 28 2009, 06:56 AM) *
Is it possible to change the throttling level?

Not now. How would you like to change ?

As I included source, you can do whatever you want.
If it is p-state max/min or update interval that you want to change, look into AppDelegate and modify them.
If it is voltage max/min, you can tweak them with kext's Info.plist (Intel only).
mitch_de
Hi, i will test your new tool soon - i dont forget it wink.gif
Q: What do you think about that russian iCPU (now named voodoomonitor ) Snow Leo only - do you testet it?
http://www.applelife.ru/topic/20179-voodoo...-snow-leopard/
I have source 1.0.3 but it looks that no newer source of that is available (1.0.7)
The bad is, i cant russian, and i got an warning asking there (problem no mV changes seen) in english wink.gif

i attached the 1.0.3 source and 1.07 voodoomonitor , because you need to be registered to get the DL)
I think that has its ground in superhai´s voodoopower, but i am not sure.

ricom2ger
QUOTE (hnak @ Sep 28 2009, 09:13 AM) *
Not now. How would you like to change ?

As I included source, you can do whatever you want.
If it is p-state max/min or update interval that you want to change, look into AppDelegate and modify them.
If it is voltage max/min, you can tweak them with kext's Info.plist (Intel only).


I mean, it there are higher needs it will make the Frequency step up quicker.

At Moment as an Example my Dock lags, it I click a Folder on the Dock it wont rise the Frequency.
hnak
QUOTE (mitch_de @ Sep 28 2009, 07:34 AM) *
Hi, i will test your new tool soon - i dont forget it wink.gif
Q: What do you think about that russian iCPU (now named voodoomonitor ) Snow Leo only - do you testet it?

They have split VoodooPower into kext/app basically based on the same idea as mine.
However, 1.0.3 app does not do anything but monitoring user's slider control and notifying the change to kext. It does not check CPU workload, though later version (VoodooMonitor.app) may do. My app does monitor workload even though the algorithm might be rough.
As far as I understand, the 1.0.3 source is incomplete. For example, GlobalThermal is never initialized but written to msr register and it's scary to test ... forgive me if I am wrong.
I also found that AMD support is missing unlike mine.


QUOTE (riws @ Sep 28 2009, 07:51 AM) *
I mean, it there are higher needs it will make the Frequency step up quicker.

At Moment as an Example my Dock lags, it I click a Folder on the Dock it wont rise the Frequency.

Solution may be shortening the interval ( currently 500 ms ? ) and lowering the threshold to raise p-state ( 0.8 ) of app.
As kext's looptimer interval is 200, you also may have to change the value .
Please tell me if you find good values by experiment.

Note: by clicking any of p-state values ( p-state tab ), you can stop throttling and fix p-state to a certain level in case you want maximum performance regardless of current state ( for example, in games ). Dock lags disappear by doing so ?
ricom2ger
QUOTE (hnak @ Sep 28 2009, 10:12 AM) *
Solution may be shortening the interval ( currently 500 ms ? ) and lowering the threshold to raise p-state ( 0.8 ) of app.
As kext's looptimer interval is 200, you also may have to change the value .
Please tell me if you find good values by experiment.

How to do it? In the source?

QUOTE (hnak @ Sep 28 2009, 10:12 AM) *
Note: by clicking any of p-state values ( p-state tab ), you can stop throttling and fix p-state to a certain level in case you want maximum performance regardless of current state ( for example, in games ). Dock lags disappear by doing so ?

The lag disappears then. It looks the lag appears with the lowest Pstate, 600Mhz for me.
hnak
QUOTE (riws @ Sep 28 2009, 08:58 AM) *
How to do it? In the source?


The lag disappears then. It looks the lag appears with the lowest Pstate, 600Mhz for me.

Yeah, you have to modify soruce ( PStateChangerAppDelegate.m ) and build. It is easy.

Loca the line:
CODE

updateTimer = [[NSTimer scheduledTimerWithTimeInterval:0.5
target:self
selector:@selector(updateInfo:)
userInfo:nil
repeats:YES] retain];

Change the value "0.5" to "0.2" for shorter interval. Any value less then 0.2 is meaningless unless kext is modified.
To change threshods, locate the code block:
CODE
if(autoThrottle){
if(load > 0.95){ // up to highest
newState = 0;
} else if(load > 0.8){
if(newState > 0)
newState -= 1;
} else if(load < 0.4){
newState += 1;
} else if(load < 0.1){ // down to lowest
newState = _pstateCount-1;
}

Then change the value "0.8" to "0.7", for example. In the case, you also should change "0.4" to "0.35".

600MHz is very low. What's your CPU ?
ricom2ger
QUOTE (hnak @ Sep 28 2009, 11:20 AM) *
600MHz is very low. What's your CPU ?

T7250 2Ghz with 7 (0-7) Pstates: 2000-1800-1600-1400-1200-1000-800-600. I disabled the EFI FSB in Info.plist, if its enabled, it gets wrong FSB - 183Mhz.

*With Coolbook it works fine with 600Mhz, the throttling level is set to very high.


With these settings it feels smooth.

CODE
scheduledTimerWithTimeInterval:0.2



CODE
        if(load > 0.95){    // up to highest
            newState = 0;
        } else if(load > 0.1){
            if(newState > 0)
                newState -= 1;
        } else if(load < 0.1){
            newState += 1;
        } else if(load < 0.1){    // down to lowest
            newState = _pstateCount-1;
        }


So the App has to run to get these changed Settings?
hnak
QUOTE (riws @ Sep 28 2009, 09:29 AM) *
T7250 2Ghz with 7 (0-7) Pstates: 2000-1800-1600-1400-1200-1000-800-600. I disabled the EFI FSB in Info.plist, if its enabled, it gets wrong FSB - 183Mhz.

*With Coolbook it works fine with 600Mhz, the throttling level is set to very high.


With these settings it feels it smooth.

CODE
scheduledTimerWithTimeInterval:0.2



CODE
        if(load > 0.95){    // up to highest
            newState = 0;
        } else if(load > 0.1){
            if(newState > 0)
                newState -= 1;
        } else if(load < 0.1){
            newState += 1;
        } else if(load < 0.1){    // down to lowest
            newState = _pstateCount-1;
        }


So the App has to run to get these changed Settings?

It's App which does throttling. So, p-state never changes if App is not running. Does p-state change to the lowest with such settings you made ( at workload = 10%, p-state is raised ) ?
ricom2ger
It goes to the lowest.
hnak
QUOTE (riws @ Sep 28 2009, 10:37 AM) *
It goes to the lowest.

Thanks, I rarely see the highest p-state except for during vide encoding. I will play with thresholds myself.
mitch_de
For pstates checking (highest) you can also run geekbench - always much cpu load.
mitch_de
Tested pstate with C2D E7300 2.66 GHZ/266MHz*10 OC @ 3.0 GHZ / 333 MHz*9
Works !
BUT , major problem : In Voodoopower or minipower (leo 32 Bit) there is an key in .plist which can set Pstate Limit Highest higher than 0.
Means if set to 1, cpu never will set to P-State 0.
I need this (used with Leo minivoodoopower with success !) because if pstate is set to 0, 10* 333 is much to high = KP. 3330 MHz too high. In my BIOS FSB Multi set to 9.
Can you add this P-State high(low) Limits keys in .plist for usage in the new 64 Bit version too ?
Thanks
hnak
QUOTE (mitch_de @ Sep 28 2009, 06:22 PM) *
Can you add this P-State high(low) Limits keys in .plist for usage in the new 64 Bit version too ?


Thanks.

It is possible to put the limits into application preference rather than kext plist.
I will write some code to save limits, interval and thresholds in preference soon.
hnak
I updated the donwload link in my first post.
It supports preference now.
mitch_de
QUOTE (hnak @ Oct 1 2009, 03:56 PM) *
I updated the donwload link in my first post.
It supports preference now.


THANKS!

But how can i set that PstateLimit High (fastest) to 1 ?
I started the Pstatechanger, PREFS and changed the P-Min (is that same as PstateLimitHigh in screenshoot i have in voodoopower?) but i only hear "DONG", error beep. If i leave the Pstatechanger and run again the vefore added new values are not saved. I clicked APPLY + SAVE but onl heared the DONG sound.
Also no .plist was created in the preferences (home).

I must have that Pstate Limit before i can load the .kext, because without that KP if short Pstate 0.

Can i put that key (which name ?) in the .kext itself as an workaround ?

Here the screenshoot of my voodoopower .plist, which works perfect chaning that Limit from 0 > 1

cparm
hi,

i wondered how to set my vmin and vmax

as you can see here vmin=987 and vmax=1100





but accordding to the intel website those value should be vmax=1362.5mv and vmin=850mv
mitch_de
Maybe the calulation from the right VID to mV is other than expected.
For my knowledge there are 2 ways to calculate them , depends on cpu type.
Also an reason why for example MSR tool shows other mV than voodoopower , even both use same VID (hex)!
hnak
QUOTE (mitch_de @ Oct 1 2009, 07:47 PM) *
THANKS!

But how can i set that PstateLimit High (fastest) to 1 ?
I started the Pstatechanger, PREFS and changed the P-Min (is that same as PstateLimitHigh in screenshoot i have in voodoopower?) but i only hear "DONG", error beep. If i leave the Pstatechanger and run again the vefore added new values are not saved. I clicked APPLY + SAVE but onl heared the DONG sound.
Also no .plist was created in the preferences (home).

I must have that Pstate Limit before i can load the .kext, because without that KP if short Pstate 0.

Can i put that key (which name ?) in the .kext itself as an workaround ?

Here the screenshoot of my voodoopower .plist, which works perfect chaning that Limit from 0 > 1

You hear "DONG" if you set pstate-min (highest) > p-state max (lowest). Did you change only pstate-min from default ?
mitch_de
I only want to change PstateLimitHigh (so named in voodoopower .plist, Screenshoot 2 post above) from 0 > 1.
What the key name in the pref i must change ? One was 0 one was -1 by default.
hnak
QUOTE (mitch_de @ Oct 1 2009, 11:23 PM) *
I only want to change PstateLimitHigh (so named in voodoopower .plist, Screenshoot 2 post above) from 0 > 1.
What the key name in the pref i must change ? One was 0 one was -1 by default.

Set p-state max to 1 ( default = 0 ) and leave p-state max as is ( default = 4 ? ).
hnak
QUOTE (cparm @ Oct 1 2009, 09:02 PM) *
as you can see here vmin=987 and vmax=1100
...
but according to the intel website those value should be vmax=1362.5mv and vmin=850mv

As far as I know, Intel Core CPU's voltage is calculated as ( maybe ) :
voltage = 850.0 + VID * 0.0125 ( desktop CPU )
voltage = 712.5 + VID * 0.0125 ( mobile CPU )
and VoodooPower follows those equations.
Though VID-Voltage relationship is defined for VID = 0..0x3F, available max/min VIDs defined by BIOS may differ among CPU/MB, so the range is different from the widest range in spec.
userx
This works great. Thanks!

Any way of making a Sys Pref Pane for this instead of

using the App, or minimizing it to the menubar?
hnak
QUOTE (userx @ Oct 2 2009, 04:17 AM) *
This works great. Thanks!

Any way of making a Sys Pref Pane for this instead of

using the App, or minimizing it to the menubar?

As the app needs to be resident, it is hard to do p-state switching solely by PrefPane.
It is possible in theory by splitting app into daemon / PrefPane ( or converting it into toolbar app ), though it is not an easy programing exercise.

For now, just hide it from Apple Menu.
mitch_de
QUOTE (hnak @ Oct 2 2009, 01:52 AM) *
Set p-state max to 1 ( default = 0 ) and leave p-state max as is ( default = 4 ? ).

Thanks will try that later and report.
tdh
Working well on the hp mini 2140 thanks!!
rals2007
hnak

Is it possible to make this kext a standalone (will work even without launching the app)?

Thanks,
hnak
QUOTE (rals2007 @ Oct 7 2009, 08:06 AM) *
hnak

Is it possible to make this kext a standalone (will work even without launching the app)?

Thanks,

Please read my first post --- at least, I could not make it.
If you are comfortable with 32bit, VoodooPower is all that you need.
Brewers
Works quite well with my E6600 and Snow Leopard, thanks!

I found out that CPU-X doesn't show the correct CPU frequency when this tool does set the CPU to a lower P-state, e.g. PStateChanger shows 1600Mhz (lowest PState), but CPU-X always shows 2400Mhz (stock freq). This was not the case with VoodooPower and CPU-X under Leopard. Did someone else observe this behaviour?

And, might it somehow be possible to add more PStates with this tool?
And of course... a toolbar app would be _very_ nice!
hnak
QUOTE (Brewers @ Oct 10 2009, 11:35 AM) *
Works quite well with my E6600 and Snow Leopard, thanks!

I found out that CPU-X doesn't show the correct CPU frequency when this tool does set the CPU to a lower P-state, e.g. PStateChanger shows 1600Mhz (lowest PState), but CPU-X always shows 2400Mhz (stock freq). This was not the case with VoodooPower and CPU-X under Leopard. Did someone else observe this behaviour?

And, might it somehow be possible to add more PStates with this tool?
And of course... a toolbar app would be _very_ nice!

It's because VoodooPState.kext does not update CPU frequency variables of kernel. I thought it is not necessary as PStateChanger.app shows the values.

The number of p-state is the same as VoodooPower. You need to tweak the code if you want more.

I looked at a menubar app sample code, but Apple discourages ordinary applications to use the menubar.
1.0.2 shows workloads/pstates in doc icon when it's hidden. Just launch and hide it (command-H).

By the way, I use the same MB (P5B-E Plus) patching AppleYukon2 Info.plist.
mitch_de
Would be really nice if you adding that "changing freq for variables of kernel" so that an sysctl -a or any other tool reads out that can see the pstate changes =MHz changes also !
Only MSR read Tools like MSR would be able to readout the real MHz, but for my knowledge no MSR SL is available. And also if i use MSR after some time (minutes) it stalls may whole system.
Thanks for already done great work !!!
hnak
QUOTE (mitch_de @ Oct 10 2009, 05:47 PM) *
Would be really nice if you adding that "changing freq for variables of kernel" so that an sysctl -a or any other tool reads out that can see the pstate changes =MHz changes also !
Only MSR read Tools like MSR would be able to readout the real MHz, but for my knowledge no MSR SL is available. And also if i use MSR after some time (minutes) it stalls may whole system.
Thanks for already done great work !!!

I made a build to reflect frequency change and updated 1.0.2 links in the first post.
pug999
when wake form sleep,


sleep will kill "Auto pstate" ,

have to cancel & select "Auto" once

Intel T3200 2.0GHZ (Pentium Dual-Core)
voodoopower 1.2.3 fine
but only 32bit in snowleopoard
hnak
QUOTE (pug999 @ Oct 12 2009, 01:50 AM) *
when wake form sleep,


sleep will kill "Auto pstate" ,

have to cancel & select "Auto" once

Intel T3200 2.0GHZ (Pentium Dual-Core)
voodoopower 1.2.3 fine
but only 32bit in snowleopoard

It seems to be an application side problem. Quit and relaunch works ?
Unfortunately, however, sleep never works on my system, so the the symptom cannot be reproducible here and I cannot fix it.
I wish someone who has sleep-enabled system solve this problem.
pug999
Quit and relaunch works ?


Yes,Quit and relaunch is ok..

But, no need.
Just do once ----- cancel & select "Auto"
hnak
QUOTE (pug999 @ Oct 12 2009, 07:00 AM) *
Quit and relaunch works ?


Yes,Quit and relaunch is ok..

So the problem is not in kext but application. It should be easy if my system could sleep...
Brewers
QUOTE (hnak @ Oct 12 2009, 09:10 AM) *
So the problem is not in kext but application. It should be easy if my system could sleep...


My system can sleep, and as you quoted, we use the same MB... I will post a list of my kexts and further configuration when I get home this afternoon, so that we can set up your system for sleep smile.gif
mitch_de
QUOTE (hnak @ Oct 2 2009, 12:02 AM) *
You hear "DONG" if you set pstate-min (highest) > p-state max (lowest). Did you change only pstate-min from default ?

Sorry, i dl lastest and also dong, dong, dong in the preferences.
I cant change anything, also the threshoots not.
Always on "dong". Only when i press Defaults no dong and the default is shown.
If i change any of the prefs and press Apply or Save i hear a dong.

So how i can set my PStateLimit to 1 (not going to PSate 0) ?

Can you add those prefs not also in the .kext ?
This may be needed, because i cant kextload the .kext and must first setup the Limit to 1 in the Psatechanger.
Or does all dongs come because at this moment no .kext is loaded ? As i said i cant load the kext without be sure that it didnt switch in Pstate 0 (highest Mhz).


hnak
QUOTE (mitch_de @ Oct 12 2009, 11:26 AM) *
Sorry, i dl lastest and also dong, dong, dong in the preferences.
I cant change anything, also the threshoots not.
Always on "dong". Only when i press Defaults no dong and the default is shown.
If i change any of the prefs and press Apply or Save i hear a dong.

So how i can set my PStateLimit to 1 (not going to PSate 0) ?

Can you add those prefs not also in the .kext ?
This may be needed, because i cant kextload the .kext and must first setup the Limit to 1 in the Psatechanger.
Or does all dongs come because at this moment no .kext is loaded ? As i said i cant load the kext without be sure that it didnt switch in Pstate 0 (highest Mhz).

You cannot change prefs unless you load the kext. It checks if p-state <= max.
It's safe to load the kext as it switches p-state to max available (lowest clock) at startup.
mitch_de
QUOTE (hnak @ Oct 12 2009, 02:56 PM) *
You cannot change prefs unless you load the kext. It checks if p-state <= max.
It's safe to load the kext as it switches p-state to max available (lowest clock) at startup.

Excat !
I did load now the .kext and set the pState Limit later. So it does work now. I thought it would be better to set the klimit before using the .kext.
How does the .kext knows at next usage about that setting ?
Its because i didnt know where that limit is saved. For example if i kextload it at next boottime (without starting the PstateChanger again) in an high cpu usage situation and it will not now that limit i will get KP for sure.

Thanks !!
hnak
QUOTE (mitch_de @ Oct 12 2009, 05:18 PM) *
Excat !
I did load now the .kext and set the pState Limit later. So it does work now. I thought it would be better to set the klimit before using the .kext.
How does the .kext knows at next usage about that setting ?
Its because i didnt know where that limit is saved. For example if i kextload it at next boottime (without starting the PstateChanger again) in an high cpu usage situation and it will not now that limit i will get KP for sure.

Thanks !!

Good! I make the mechanism a little bit clearer.
Kext does not know anything about the setting. It just sets p-state to the lowest clock at startup and waits for incoming requests of p-state switch.
Preference is saved/loaded by PStateChanger application. So, p-state never rises unless the application runs.
mitch_de
QUOTE (hnak @ Oct 13 2009, 12:41 AM) *
Good! I make the mechanism a little bit clearer.
Kext does not know anything about the setting. It just sets p-state to the lowest clock at startup and waits for incoming requests of p-state switch.
Preference is saved/loaded by PStateChanger application. So, p-state never rises unless the application runs.

That could be problematic in my case (never should switch to Psate 0)- if i would kextload it in an high cpu load situation it will KP my system getting to Pstate 0 before i can run the PStateChanger to Limit Pstate to 1.
would be nice to add, like you have done for Voltage settings and voodoopower has for all settings, to include the Pstate Limits also in the .plist of the .kext.


hnak
QUOTE (mitch_de @ Oct 13 2009, 06:32 AM) *
That could be problematic in my case (never should switch to Psate 0)- if i would kextload it in an high cpu load situation it will KP my system getting to Pstate 0 before i can run the PStateChanger to Limit Pstate to 1.
would be nice to add, like you have done for Voltage settings and voodoopower has for all settings, to include the Pstate Limits also in the .plist of the .kext.

PState.kext NEVER raises p-state from the lowest level unless PStateChanger is launched ( no matter how much cpu load exists ). So, if you kextload in high cpu load situation, it just slows down CPU, or does nothing if already in the lowest state.
Only PStateChanger changes p-state.
Just launch PStateChanger when your cpu is not busy, then apply & save prefs. It will not take 10 seconds.

If you think 10 seconds are too long, just modify the code to set min p-state to 1 and build your customized app.
Change defaultPref() of preference.c as:
CODE
void defaultPref(PSTATECHANGER_PREF* pPref, int pstateCount){
...
pPref->pstate_min = 1; // 0;
...
}


In which p-state does your system boot when there is no p-state controlling kext loaded ?
mitch_de
THANKS !! No need for .plist changes if the .kext leave CPU on slowest MHZ (Pstate) until the control app is started.
highest
Without any OS X .kext for pstates ? I think it will stay always in the fastest MHZ available.
Because the bios limits the multi (9*333 , default: 10*266) i have Psates für multi 6+7+8+9 (not 10).
All that 4 (not the 10*) are as psates listed in the dsdt.
Whats funny is that, if i use that iMark (was iCPU) tool (also app + .kext set) it switches never to the problematic pstate 0 (10* ) , their i get pstate 4 (6*) up to pstate 1 (9*).


Have you ever tried to limit (set down one for an test) the multi in your bios ? It should not damage you CPU if you switch down one multilevel.
The .kext seems to not see / acept that and tries to set highest multi (in my case 10 *) even if not available (limited by bios).
Brewers
hnak,

can you modify the app so that it doesn't show the CPU graph in the dock, or best, doesn't show up at all? smile.gif The graph is quite ugly, and I do not like moving things in my dock. I searched for a way to hide apps there, but Google wasn't particularly helpful.

Maybe you can make this behaviour optional, for those that like a CPU graph in their dock wink.gif
hnak
QUOTE (mitch_de @ Oct 13 2009, 05:40 PM) *
Have you ever tried to limit (set down one for an test) the multi in your bios ? It should not damage you CPU if you switch down one multilevel.
The .kext seems to not see / acept that and tries to set highest multi (in my case 10 *) even if not available (limited by bios).

No, I haven't.
I actually did not change the logic of kext and it is exactly the same as VoodooPower, which does not extract information from BIOS.

QUOTE (Brewers @ Oct 13 2009, 06:29 PM) *
hnak,

can you modify the app so that it doesn't show the CPU graph in the dock, or best, doesn't show up at all? smile.gif The graph is quite ugly, and I do not like moving things in my dock. I searched for a way to hide apps there, but Google wasn't particularly helpful.

Maybe you can make this behaviour optional, for those that like a CPU graph in their dock wink.gif

For now, you can use 1.0.1 to avoid Doc icon animation.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.