From: Gerhard Pircher <hidden> Date: 2008-02-21 20:08:00
Hi,
I'm wondering how to disable or enable CPU features based on the board the
kernel is running on. In my case I want to disable the
CPU_FTR_NEED_COHERENT flag for 74xx CPUs, because it locks up the machine.
I tried to clear the flag in the platform's *_probe() function with the
following code:
cur_cpu_spec->cpu_features &= ~CPU_FTR_NEED_COHERENT;
First I thought that this works fine, because the kernel booted once till
the console login prompt (and died afterwards). Therefore I suspected that
another change or bug in the kernel conflicts with my hardware (usually
the machine died much earlier on older kernels, if the flag wasn't
cleared).
Now I removed all CPU_FTR_NEED_COHERENT entries from the cputable.h file
and the kernel boots just fine without any lockups (reproducable).
I don't quite understand the difference between dynamically clearing the
flag in the platform setup code and removing the flag for all CPU
defines in cputable.h. I can only suspect that clearing the flag in the
platform probe function is too late, as the MMU and BATs may already be
set up.
Can anybody confirm my suspicion or give me a hint how to implement it
correctly? (I don't want to tinker with cputable.h)
Thanks!
regards,
Gerhard
--
Psst! Geheimtipp: Online Games kostenlos spielen bei den GMX Free Games!
http://games.entertainment.web.de/de/entertainment/games/free
From: Milton Miller <hidden> Date: 2008-02-22 17:23:34
At Fri Feb 22 07:07:58 EST 2008, Gerhard Pircher wrote:
I'm wondering how to disable or enable CPU features based on the board
the
kernel is running on. In my case I want to disable the
CPU_FTR_NEED_COHERENT flag for 74xx CPUs, because it locks up the
machine.
I tried to clear the flag in the platform's *_probe() function with the
following code:
cur_cpu_spec->cpu_features &= ~CPU_FTR_NEED_COHERENT;
First I thought that this works fine, because the kernel booted once
till
the console login prompt (and died afterwards). Therefore I suspected
that
another change or bug in the kernel conflicts with my hardware (usually
the machine died much earlier on older kernels, if the flag wasn't
cleared).
Now I removed all CPU_FTR_NEED_COHERENT entries from the cputable.h
file
and the kernel boots just fine without any lockups (reproducable).
I don't quite understand the difference between dynamically clearing
the
flag in the platform setup code and removing the flag for all CPU
defines in cputable.h. I can only suspect that clearing the flag in the
platform probe function is too late, as the MMU and BATs may already be
set up.
Can anybody confirm my suspicion or give me a hint how to implement it
correctly? (I don't want to tinker with cputable.h)
We handle cpu features in a couple of ways:
(1) we replace assembly instructions with nop early in the kernel boot
(2) we test the feature flags in c code
In (2), we form two expressions for features that are
(a) always set
(b) never set
so that the compiler can eliminate the test based on the config.
To change a flag, you must make sure its in POSSIBLE but not ALWAYS,
and also set it before it is used, either to nop out instructions (see
early_init in setup-32.c for 32 bit), or tested by c code (in this
case, maybe the initial_mmu setup is testing NEED_COHERENT, which is
between early_init and probe). The code path is a bit
different for 64 bit.
milton
From: Gerhard Pircher <hidden> Date: 2008-02-22 19:05:32
Hi,
-------- Original-Nachricht --------
Datum: Fri, 22 Feb 2008 11:24:38 -0600
Von: Milton Miller [off-list ref]
An: Gerhard Pircher [off-list ref]
CC: ppcdev <redacted>
Betreff: Re: How to dynamically disable/enable CPU features?
We handle cpu features in a couple of ways:
(1) we replace assembly instructions with nop early in the kernel boot
I'm pretty sure that is the problem.
(2) we test the feature flags in c code
In (2), we form two expressions for features that are
(a) always set
(b) never set
so that the compiler can eliminate the test based on the config.
To change a flag, you must make sure its in POSSIBLE but not ALWAYS,
and also set it before it is used, either to nop out instructions (see
early_init in setup-32.c for 32 bit), or tested by c code (in this
case, maybe the initial_mmu setup is testing NEED_COHERENT, which is
between early_init and probe). The code path is a bit different for 64
bit.
The flag is in POSSIBLE. I now use this code in the platform probe
function to nop out the code affected by the flag:
cur_cpu_spec->cpu_features &= ~CPU_FTR_NEED_COHERENT;
/* Patch out unwanted feature. */
do_feature_fixups(cur_cpu_spec->cpu_features,
PTRRELOC(&__start___ftr_fixup),
PTRRELOC(&__stop___ftr_fixup));
It seems to work so far, but I would like to know if this is the right
way to do it, or if calling do_feature_fixups() more than once can have
any side effects.
regards,
Gerhard
--
Psssst! Schon vom neuen GMX MultiMessenger gehört?
Der kann`s mit allen: http://www.gmx.net/de/go/multimessenger
From: Benjamin Herrenschmidt <benh@kernel.crashing.org> Date: 2008-02-22 22:26:42
On Thu, 2008-02-21 at 21:07 +0100, Gerhard Pircher wrote:
Hi,
I'm wondering how to disable or enable CPU features based on the board the
kernel is running on. In my case I want to disable the
CPU_FTR_NEED_COHERENT flag for 74xx CPUs, because it locks up the machine.
I tried to clear the flag in the platform's *_probe() function with the
following code:
cur_cpu_spec->cpu_features &= ~CPU_FTR_NEED_COHERENT;
That works on 64 bits but unfortunately not on 32 bits. This is a
longstanding issue that we need to fix. ie. we need to move the
fixups later in the boot process (if possible put them in the
same place for 32 and 64 bits), though that needs to be done very
carefully, making sure nothing that requires those fixups ends up
happening before they happen as a result of the move.
Ben.
From: Benjamin Herrenschmidt <benh@kernel.crashing.org> Date: 2008-02-22 22:32:39
The flag is in POSSIBLE. I now use this code in the platform probe
function to nop out the code affected by the flag:
cur_cpu_spec->cpu_features &= ~CPU_FTR_NEED_COHERENT;
/* Patch out unwanted feature. */
do_feature_fixups(cur_cpu_spec->cpu_features,
PTRRELOC(&__start___ftr_fixup),
PTRRELOC(&__stop___ftr_fixup));
It seems to work so far, but I would like to know if this is the right
way to do it, or if calling do_feature_fixups() more than once can have
any side effects.
It's a bit hairy... Things -could- have been nop'ed out by the first
call as a result of CPU_FTR_NEED_COHERENT being set and the second
call will not be able to put them back in... now that may not be the
case (depends what kind of patching is done with that flag) and so
'happen' to work for this specific bit but it isn't a nice solution...
A better long term approach is to look at moving the fixup to after
the machine probe() after carefully checking whether that can cause
any problem...
Ben.
From: Gerhard Pircher <hidden> Date: 2008-02-24 14:47:48
-------- Original-Nachricht --------
Datum: Sat, 23 Feb 2008 09:32:01 +1100
Von: Benjamin Herrenschmidt [off-list ref]
An: Gerhard Pircher [off-list ref]
CC: Milton Miller <redacted>, linuxppc-dev@ozlabs.org
Betreff: Re: How to dynamically disable/enable CPU features?
quoted
The flag is in POSSIBLE. I now use this code in the platform probe
function to nop out the code affected by the flag:
cur_cpu_spec->cpu_features &= ~CPU_FTR_NEED_COHERENT;
/* Patch out unwanted feature. */
do_feature_fixups(cur_cpu_spec->cpu_features,
PTRRELOC(&__start___ftr_fixup),
PTRRELOC(&__stop___ftr_fixup));
It seems to work so far, but I would like to know if this is the right
way to do it, or if calling do_feature_fixups() more than once can have
any side effects.
It's a bit hairy... Things -could- have been nop'ed out by the first
call as a result of CPU_FTR_NEED_COHERENT being set and the second
call will not be able to put them back in... now that may not be the
case (depends what kind of patching is done with that flag) and so
'happen' to work for this specific bit but it isn't a nice solution...
I checked this now. Looks like it only needs to nop out some code (mainly
in the hash table code).
A better long term approach is to look at moving the fixup to after
the machine probe() after carefully checking whether that can cause
any problem...
Well, that's a job for an more experienced kernel developer. :)
Thanks!
Gerhard
--
Psssst! Schon vom neuen GMX MultiMessenger gehört?
Der kann`s mit allen: http://www.gmx.net/de/go/multimessenger