How to throttle CPU speed

Create a lower filter to the CPU driver, so your filter is on top of ACPI.sys.

Enumerate child devices with IOCTL_ACPI_ENUM_CHILDREN and with the path and child names it returns evaluate the methods with IOCTL_ACPI_EVAL_METHOD_EX. Store the information this returns for _PCT and _PSS (read ACPI spec to know about these) which tell you the Register access and values respectively to set CPU frequency.

In this case the system returned a Functional Fixed Hardware register in _PCT, so set eax to 0x198 (defined by Intel) and call rdmsr.

Take the 64 bit value and set the lower 4 bytes to the control value retruned in the _PSS data for the lowest frequency supported (lowest P state).

Set eax to 0x199 (defined by Intel) and set eax and edx to the new 64 bit value and call wrmsr.

The CPU is now running at the lowest frequency it supports.

Simple really. Only took me 6 days. :slight_smile:

Please still waiting for what this piece of shit is so I can be sure not
to use it. Really, you state what you have done, but have you tested it
on a wide variety of hardware? I’ve run some old systems that I am sure
would crash with that set of operations.

We suggested approaches that would work correctly, but did not meet your
marketing needs. Sooner or later the market will identify the project
and are likely to hammer it.

Don Burn
Windows Filesystem and Driver Consulting
Website: http://www.windrvr.com
Blog: http://msmvps.com/blogs/WinDrvr

xxxxx@hotmail.com” wrote in message
news:xxxxx@ntdev:

> Create a lower filter to the CPU driver, so your filter is on top of ACPI.sys.
>
> Enumerate child devices with IOCTL_ACPI_ENUM_CHILDREN and with the path and child names it returns evaluate the methods with IOCTL_ACPI_EVAL_METHOD_EX. Store the information this returns for _PCT and _PSS (read ACPI spec to know about these) which tell you the Register access and values respectively to set CPU frequency.
>
> In this case the system returned a Functional Fixed Hardware register in _PCT, so set eax to 0x198 (defined by Intel) and call rdmsr.
>
> Take the 64 bit value and set the lower 4 bytes to the control value retruned in the _PSS data for the lowest frequency supported (lowest P state).
>
> Set eax to 0x199 (defined by Intel) and set eax and edx to the new 64 bit value and call wrmsr.
>
> The CPU is now running at the lowest frequency it supports.
>
> Simple really. Only took me 6 days. :slight_smile:

>have you tested it on a wide variety of hardware

In 6 days? You kidding? :slight_smile:

OK Don, I understand where you are coming from. This is a Win 7 only project, and in any case if the OS is old and doesnt support those IOCTLs the code isnt going to set the MSR so it isnt going to crash anything.

Marketing aside though it is always fun to explore a new part of the OS and this post will perhaps act as a guide to other people who are in the process of interrogating and manipulating ACPI.

No the OS is Win7 the hardware will screw with this. Believe it or not
some of us run some pretty old hardware, with some really early ACPI
BIOS’es with current OS’es at times. You have a hack, not a prototype
and definitely not a product yet.

Don Burn
Windows Filesystem and Driver Consulting
Website: http://www.windrvr.com
Blog: http://msmvps.com/blogs/WinDrvr

xxxxx@hotmail.com” wrote in message
news:xxxxx@ntdev:

> >have you tested it on a wide variety of hardware
>
> In 6 days? You kidding? :slight_smile:
>
> OK Don, I understand where you are coming from. This is a Win 7 only project, and in any case if the OS is old and doesnt support those IOCTLs the code isnt going to set the MSR so it isnt going to crash anything.
>
> Marketing aside though it is always fun to explore a new part of the OS and this post will perhaps act as a guide to other people who are in the process of interrogating and manipulating ACPI.

>some of us run some pretty old hardware

Acording to the docs these IOCTLs came in with Vista and the Intel register with the Pentium 5 chip so it is unlikely such a combination would arise but of course I will add a CPUID check to make sure the HW supports the functionality. Yes, it is an interesting hack yet, but a product it will be.

(I will personally warn you not to install it when it gets released. :slight_smile: )

xxxxx@hotmail.com wrote:


Take the 64 bit value and set the lower 4 bytes to the control value retruned in the _PSS data for the lowest frequency supported (lowest P state).

Set eax to 0x199 (defined by Intel) and set eax and edx to the new 64 bit value and call wrmsr.

That is, assuming you are running on a processor that supports MSR 0x198
and 0x199. You are aware, I presume, that AMD runs a not insignificant
percentage of the Windows desktop market, and AMD has an entirely
different set of MSRs.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Mr. Sykes… I’m not sure what you’re trying to demonstrate to us, beyond the fact that you’re creating a terrible hack that bypasses the mechanisms in the OS that manipulate these processor features.

I realize you think you’re being clever and achieving a greater over-arching goal… but I assure you that what you’re really demonstrating is a lack of deep understanding of how Windows works combined with a serious lapse in engineering judgement. You are NOT serving your client’s best interests by going behind the back of the OS (including both Windows and the vendor-provided processor driver) to manipulate these values. What you’re doing, in fact, is grossly irresponsible.

Mr. Burn is very right in this case.

Peter
OSR

+1

And I leave my machine overnight to perform a 3-D rendering, expecting a
finished image in the morning. I forget that I have this experimental pos
loaded, and it slows the CPU down. Why do you think you have the right to
change my CPU speed setting?

The Power Profile for my laptop says to run at full CPU speed when is
connected to external power. How DARE you change the settings I have
selected!?!

There is no way to think of this hack as other than malware.
joe

Mr. Sykes… I’m not sure what you’re trying to demonstrate to us, beyond
the fact that you’re creating a terrible hack that bypasses the mechanisms
in the OS that manipulate these processor features.

I realize you think you’re being clever and achieving a greater
over-arching goal… but I assure you that what you’re really
demonstrating is a lack of deep understanding of how Windows works
combined with a serious lapse in engineering judgement. You are NOT
serving your client’s best interests by going behind the back of the OS
(including both Windows and the vendor-provided processor driver) to
manipulate these values. What you’re doing, in fact, is grossly
irresponsible.

Mr. Burn is very right in this case.

Peter
OSR


NTDEV is sponsored by OSR

OSR is HIRING!! See http://www.osr.com/careers

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

On Tue, Feb 26, 2013 at 7:47 PM, wrote:

> I realize you think you’re being clever and achieving a greater
> over-arching goal… but I assure you that what you’re really demonstrating
> is a lack of deep understanding of how Windows works combined with a
> serious lapse in engineering judgement. You are NOT serving your client’s
> best interests by going behind the back of the OS (including both Windows
> and the vendor-provided processor driver) to manipulate these values. What
> you’re doing, in fact, is grossly irresponsible.
>

Peter, I must commend you for being considerably more civil and courteous
than others in this discussion :slight_smile:

Often we’re asked by our employers to work around various OS shortcomings
or perceived “shortcomings”. Sometimes it takes one a while to realize he’s
thinking the wrong way about it; often it doesn’t take just time but also
engineering experience. Other times, the requirement is there, and it’s
legit, and the OS just wasn’t planned for this. The OS designers are smart,
but it’s also smart to design for real requirements, not imaginary ones.

Where do you draw the line?

For example, lately I’ve been writing to specific PCI configuration
registers “behind the back” of one of Intel’s device drivers (by having a
filter driver above it and sending IRP_MN_WRITE_CONFIGs). That sounds like
a violation of layering, but there’s no other way I can achieve our goal.
I’m checking the hardware ID of the PCI device I’m tweaking. Other than
that, who knows what the future will bring? Life is short, we have to
achieve some goals, and right now this tweak will let someone get some
business done.

Ilya,

Like the Hippocratic Oath the principal should be do no harm. In
your case yes you are breaking the layering, but since it is for a
specific device and you pretty much know the driver you are bypassing
this is to me a case of minimal risk to achieve a required goal. The
same can be said for using some undocumented calls, if you know the
environments and the calls have been used elsewhere, you are adding a
risk but again a constrained one.

The problem is when people use undocumented calls or mechanisms like
the OP is doing when there are practical alternatives. Those are the
irresponsible cases. For example if you just had hit the PCI config
registers to set your values that would be endangering the health of a
lot of systems (I know a startup who was sued out of existence for
that).

I am one of the people who react harshly to irresponsible
developers, but if you look back at the original thread many people had
explained to the OP that what he was doing was wrong. At some point you
have to assume they are not getting it, and the verbal equivalent of
hitting them over the head with a baseball bat is the only option left.

Don Burn
Windows Filesystem and Driver Consulting
Website: http://www.windrvr.com
Blog: http://msmvps.com/blogs/WinDrvr

“Ilya Konstantinov” wrote in message
news:xxxxx@ntdev:

> On Tue, Feb 26, 2013 at 7:47 PM, wrote:
>
> > I realize you think you’re being clever and achieving a greater
> > over-arching goal… but I assure you that what you’re really demonstrating
> > is a lack of deep understanding of how Windows works combined with a
> > serious lapse in engineering judgement. You are NOT serving your client’s
> > best interests by going behind the back of the OS (including both Windows
> > and the vendor-provided processor driver) to manipulate these values. What
> > you’re doing, in fact, is grossly irresponsible.
> >
>
> Peter, I must commend you for being considerably more civil and courteous
> than others in this discussion :slight_smile:
>
> Often we’re asked by our employers to work around various OS shortcomings
> or perceived “shortcomings”. Sometimes it takes one a while to realize he’s
> thinking the wrong way about it; often it doesn’t take just time but also
> engineering experience. Other times, the requirement is there, and it’s
> legit, and the OS just wasn’t planned for this. The OS designers are smart,
> but it’s also smart to design for real requirements, not imaginary ones.
>
> Where do you draw the line?
>
> For example, lately I’ve been writing to specific PCI configuration
> registers “behind the back” of one of Intel’s device drivers (by having a
> filter driver above it and sending IRP_MN_WRITE_CONFIGs). That sounds like
> a violation of layering, but there’s no other way I can achieve our goal.
> I’m checking the hardware ID of the PCI device I’m tweaking. Other than
> that, who knows what the future will bring? Life is short, we have to
> achieve some goals, and right now this tweak will let someone get some
> business done.

Nobody will read this because it’s a tangent, and it’s far too long. I’m not sure Mr. Konstantinov really wanted an answer, and I’m quite sure he didn’t want such a long answer as this one. Be that as it may…

Thank you, Mr. Konstantinov – That is not a compliment that I frequently receive, in this forum or in life. :slight_smile:

Outstanding question. I hope it was not merely rhetorical.

Here at OSR we very frequently deal in the realm of “Well, Windows doesn’t really support that.” Just like your example, sometimes you have to break the rules to innovate. I agree, and I wholeheartedly support this notion. Having to break the rules to do something really special has its own rewards (for the engineers involved, and for the company) but it also brings its own special kind of responsibility.

First, I think you have to do a certain amount of “due diligence” – You don’t want to break the rules if you don’t have to. If there’s another acceptable means for achieving your over-arching goal, OTHER than resorting to some nasty undocumented hack… in almost all cases you should use it.

Next, I think you need to do the “risk vs benefit” analysis. If the risk (of screwing up the OS, crashing the system, writing code that isn’t compatible across versions or service packs) is small and the benefit you’re gaining is great… EASY decision. To be able to do this, you need to have the technical knowledge (or access to those with the technical knowledge) to accurately gauge the risks. This is critical, right? Just throwing some code onto a target machine and saying “well, it works” does not mean the risk isn’t high. It just means you haven’t suffered the consequences of the risk… yet.

Often, it is very difficult to accurately assess the risk involved when you stray from the approved way of doing things. The problem is that you’re not aware of all the things that you don’t know (assuming anybody but me can even parse that sentence). For example, a driver dev with a few years of experience might think “Oh, I’ll just reach into this structure at a specific offset… what could happen?”… but he doesn’t realize that the undocumented field in the undocumented structure into which you’re reaching is part of a union. Of that the structure is in a LIST that has a lock to which he has no access. Or… any number of things.

Sometimes, it’s easier. There’s a field that’s undocumented. But, you happen to KNOW that the OS uses it in certain places to do certain things. If you ALSO use it in the same way, in the same places and at the same times as the OS would, you know your risk is lower. Not non-existent… you don’t have perfect knowledge. But lower.

Next, I think it’s important that you accurately describe the risk to management. Your technical decision can have business impact. The people making business decisions need to understand the risks involved, and it’s your responsibility to accurately represent the risks and put them in the type of context that manager types will understand.

Finally, I think you need to limit your bad behaviors to only what’s absolutely necessary to achieve your goal. In other words, once you’ve decided to venture into the realm of the undocumented, don’t be tempted to pile things on, to say “Oh well, I’m already doing X – which is unsupported – I might just as well add feature A, B, and C which do Y – which is also unsupported and undocumented.”

I think Mr. Burn captured a lot of the above, at considerably less length, when he said “do no harm.” I just wanted to expound a bit further on my own philosophy on this point.

Peter
OSR

There was a time (Windows 98) when I had to deal with the horrible way UHCI deals with the bulk transfer list exaustion.

When the list becomes empty (all TD become dummy), UHCI continues to fetch the descriptors looping over it. As a result, it comsumes a lot of bandwidth, and the machines of those times become very sluggish.

So I reverse engineered the UHCI driver structures, and replaced the last dummy descriptor with the one that tries to write to USB address 127, while ignoring the error that will occur. I know, it’s bad. Of course, I checked that the pointers lead there. Of course, next OS update broke that.

For a while, I’m sure you’ve saved someone’s day, and as long as
significantly more days were saved than ruined… :slight_smile:

I’m currently dealing with bugs of the various XHCI controllers. For the
Windows 7 generation, there won’t be an MS XHCI driver so every IHV is
rolling their own (Intel, Renesas/NEC, Via, …), and they’re definitely
not bug-for-bug compatible with MS.

On Wed, Feb 27, 2013 at 12:10 AM, wrote:

> There was a time (Windows 98) when I had to deal with the horrible way
> UHCI deals with the bulk transfer list exaustion.
>
> When the list becomes empty (all TD become dummy), UHCI continues to fetch
> the descriptors looping over it. As a result, it comsumes a lot of
> bandwidth, and the machines of those times become very sluggish.
>
> So I reverse engineered the UHCI driver structures, and replaced the last
> dummy descriptor with the one that tries to write to USB address 127, while
> ignoring the error that will occur. I know, it’s bad. Of course, I checked
> that the pointers lead there. Of course, next OS update broke that.
>
> —
> NTDEV is sponsored by OSR
>
> OSR is HIRING!! See http://www.osr.com/careers
>
> For our schedule of WDF, WDM, debugging and other seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer
>

> The problem is that you’re not aware of all the things that you don’t know (assuming anybody

but me can even parse that sentence).

Well, you can mostly guess it. I would say it boils down to 3 basic things that you have to to worry about:

  1. A conflict with legitimate resource owner. Once you access the resource without coordinating your actions with the resource owner you have to worry about synchronization. This part theoretically may be solved by so-called “CPU corralling”. However, again, there are two possible problems here

A. If resource is accessible by its owner in a schedulable context you may potentially get into the middle of an operation that is supposed to be atomic. For example, if an operation involves updating two registers
a thread may be preempted after having updated the first one and before updating the second one. Now consider what happens if your “unofficial” update comes in between - you get into the middle of an operation, effectively leaving a device in inconsistent state

B. You may read a register that is supposed to be read-once. Again, you may leave a device in inconsistent state if you do it, because the info about the device that the actual device owner gets by reading this register
may be already inaccurate because of your operation

In other words, as far as synchronization is concerned, the maximum you can ensure is that no one gets in the middle of your operation. However, it still does not eliminate all potential issues.

  1. Your product may be broken by any system update if you rely upon some undocumented field of a structure (that, btw, may possibly undocumented as well). Once this structure is not fully documented, its binary layout may change in the next OS version or service pack. The same holds true for undocumented function calls. Once function is not documented, anything may happen to it under the new OS version. For example, its argument list may be changed without notice. Funny, ugh…

  2. There is no guarantee that you are the only one who wants to access this resource/field/etc
    “unofficially”. If some other third-party product tries the same you may get into a conflict with it. This conflict
    may be just about anything. To begin with, the behavior of the third-party product may be not identical to that of OS-provided one. For example, KAV is just notorious in this respect (or at least used to be notorious at the time I worked on Windows drivers) when it comes to the network stack. To make it even worse, this product may try to neutralize yours because it wants to be the first one (or, maybe, instead, the last one) in a call chain

Anton Bassov

>Simple really. Only took me 6 days. :slight_smile:

It will take you much longer to get this working and tested on the wide
variety of hardware that exists and you will anyway end up with a kludge
that will likely disstabiize a lot of systems if not worse. This, while all
that you needed is to add Sleep(Ex) to your code as you have been told. If
there are no other threads to run, Sleep will cause the system idle thread
to get invoked. Nowadays that mostly means that it calls into the processor
driver which will activate some P or C state on the processor at its
discretion.

Apparently not exciting enough as you said the requirement was to do it from
a driver. How about this alternative: write a driver that calls
KeDelayExecutionThread which is the equivalent of SleepEx ?

//Daniel

> Often, it is very difficult to accurately assess the risk involved when you stray from the approved way of doing things

I think the acceptable risk is also very dependent on the context.

A startup, with no existing customers, and a make it work somehow or go out of business kind of problem might be much more open to risk than say a multi-billion dollar public company who is risking a long term reputation and millions of dollars in sales.

Even for a medium size company, there have been cases where using an ugly hack was worth millions of dollars of sales. A classic example was in the old days, somebody figured out that if you didn’t check the command fifo of a graphics card for space before writing to it, you gained 10% or so in benchmark performance, which made your do better on magazine’s benchmarks, and as a result your graphics card was crowned top dog and sold way better. Of course the magazine benchmarks only measured game performance, it didn’t notice that the top performing graphic card caused a serial port to malfunction, which often made your serial mouse drop events, like the down to up button transition event. This was because if the write to the fifo didn’t have space, the cpu would be locked on the PCI write until the fifo drained a bit (and not responding to interrupts), and it turned out scrolling the screen, like your press the scroll down button on the scroll bar, could take many milliseconds. The end behavior of better graphics performance was you would click scroll up/down in your word processor and it just kept on scrolling, if you happened to use a serial mouse. There were even registry entries to force the graphics driver to properly check the fifo status, making your serial mouse work correctly again. It wasn’t exactly intuitive that to fix your malfunctioning mouse you needed to set a graphics card driver registry entry. These were not exactly startups, and it was well known technically what the issues were, but business decisions were made by upper management to screw up your serial mouse so they could sell more products. Personally, I decided never to put a product from that company again.

I think the same kind of risk tradeoffs occur with individual developers. If you’re a developer at your first job and your manager says do it certain way, you’re much less likely to push back than if your one of us old folks who already did stupid things when were young and na?ve and know what getting burned by doing stupid things is like.

Jan

And it will take 6 years for you to repair the damage to your reputation as an engineer. You know Matt, when you interview, people will do Goggle searches.

You may also have damaged your credibility in the green industry, as your CO2 calculation software is likely not green as you claim. For hard science research, credibility matters, a lot.

Jan

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@hotmail.com
Sent: Tuesday, February 26, 2013 8:19 AM
To: Windows System Software Devs Interest List
Subject: [ntdev] How to throttle CPU speed

Create a lower filter to the CPU driver, so your filter is on top of ACPI.sys.

Enumerate child devices with IOCTL_ACPI_ENUM_CHILDREN and with the path and child names it returns evaluate the methods with IOCTL_ACPI_EVAL_METHOD_EX. Store the information this returns for _PCT and _PSS (read ACPI spec to know about these) which tell you the Register access and values respectively to set CPU frequency.

In this case the system returned a Functional Fixed Hardware register in _PCT, so set eax to 0x198 (defined by Intel) and call rdmsr.

Take the 64 bit value and set the lower 4 bytes to the control value retruned in the _PSS data for the lowest frequency supported (lowest P state).

Set eax to 0x199 (defined by Intel) and set eax and edx to the new 64 bit value and call wrmsr.

The CPU is now running at the lowest frequency it supports.

Simple really. Only took me 6 days. :slight_smile:

Excellent point, Mr. Bottorff. I totally agree.

If you’re a startup, a small company, heck… you can pretty much view what you’re building as a prototype. Gotta get SOMEthing out there to make you some money, demonstrate your concept. By definition, your customers are early adopters. You can take a few liberties.

Another way of looking at context that I failed to mention is “context in which the solution will be deployed.” If you’re writing a solution that has to work only in a well defined environment, like an embedded system, you by definition have a less risk… and you can sometimes take more chances. After all, you can much more accurately predict how and where your software will be used. And this lets you more accurately asses risk.

On the other hand, if you’re writing software for the mass market, you have considerably LESS insight into how your software will be used. For example, any time I checked a change into Windows I would worry, because I knew that code might potentially run on MILLIONS and millions… or tens of millions… of systems. That’s the kind of thing that makes me want to make conservative engineering decisions, you know?

Peter
OSR

>That is, assuming you are running on a processor that supports MSR 0x198

and 0x199. You are aware, I presume, that AMD runs a not insignificant
percentage of the Windows desktop market, and AMD has an entirely
different set of MSRs.

If you read the ACPI spec you will see that evaluating _PCT tells you the registers used. My test box was Intel 32, it returned FFW registers. No doubt the AMD 64 will return a different way of interacting with the kernel.

>Mr. Sykes… I’m not sure what you’re trying to demonstrate to us, beyond the

fact that you’re creating a terrible hack that bypasses the mechanisms in the OS
that manipulate these processor features.

Hack? All this is defined by the ACPI spec, to which Intel AMD and Microsoft adhere. This is not only NOT a hack it is the CORRECT way to do it.