Since until now, the code running on the management engine is: - Signed by its manufacturer - Proprietary software, without corresponding source code It can desirable to run the least ammount possible of such code, which is what me_cleaner[1] enables.
It does it by removing partitions of the management engine firmwares, however when doing so, the HECI interface might not be present anymore.
So it is desirable not to have the RAM initialisation code wait forever for the HECI interface to appear.
[1] https://github.com/corna/me_cleaner/
Change-Id: Iebafa353ecd8875395d6c3a986da6082772e2e18 Signed-off-by: Denis 'GNUtoo' Carikli GNUtoo@no-log.org --- src/northbridge/intel/nehalem/raminit.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/src/northbridge/intel/nehalem/raminit.c b/src/northbridge/intel/nehalem/raminit.c index 122b8ac7cf..27065d139e 100644 --- a/src/northbridge/intel/nehalem/raminit.c +++ b/src/northbridge/intel/nehalem/raminit.c @@ -1753,23 +1753,27 @@ static const struct ram_training *get_cached_training(void) } #endif
-/* FIXME: add timeout. */ static void wait_heci_ready(void) { - while (!(read32(DEFAULT_HECIBAR + 0xc) & 8)); // = 0x8000000c + int i = 1000*1000; + + while (i-- && !(read32(DEFAULT_HECIBAR + 0xc) & 8)) /* = 0x8000000c */ + udelay(1); write32((DEFAULT_HECIBAR + 0x4), (read32(DEFAULT_HECIBAR + 0x4) & ~0x10) | 0xc); }
-/* FIXME: add timeout. */ static void wait_heci_cb_avail(int len) { + int i = 1000*1000; + union { struct mei_csr csr; u32 raw; } csr;
- while (!(read32(DEFAULT_HECIBAR + 0xc) & 8)); + while (i-- && !(read32(DEFAULT_HECIBAR + 0xc) & 8)) + udelay(1);
do csr.raw = read32(DEFAULT_HECIBAR + 0x4);
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
On 03/27/2017 03:05 PM, Denis 'GNUtoo' Carikli wrote:
Since until now, the code running on the management engine is:
- Signed by its manufacturer
- Proprietary software, without corresponding source code
It can desirable to run the least ammount possible of such code, which is what me_cleaner[1] enables.
It does it by removing partitions of the management engine firmwares, however when doing so, the HECI interface might not be present anymore.
So it is desirable not to have the RAM initialisation code wait forever for the HECI interface to appear.
[1] https://github.com/corna/me_cleaner/
Change-Id: Iebafa353ecd8875395d6c3a986da6082772e2e18 Signed-off-by: Denis 'GNUtoo' Carikli GNUtoo@no-log.org
src/northbridge/intel/nehalem/raminit.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/src/northbridge/intel/nehalem/raminit.c b/src/northbridge/intel/nehalem/raminit.c index 122b8ac7cf..27065d139e 100644 --- a/src/northbridge/intel/nehalem/raminit.c +++ b/src/northbridge/intel/nehalem/raminit.c @@ -1753,23 +1753,27 @@ static const struct ram_training *get_cached_training(void) } #endif
-/* FIXME: add timeout. */ static void wait_heci_ready(void) {
- while (!(read32(DEFAULT_HECIBAR + 0xc) & 8)); // = 0x8000000c
- int i = 1000*1000;
- while (i-- && !(read32(DEFAULT_HECIBAR + 0xc) & 8)) /* = 0x8000000c */
write32((DEFAULT_HECIBAR + 0x4), (read32(DEFAULT_HECIBAR + 0x4) & ~0x10) | 0xc);udelay(1);
}
-/* FIXME: add timeout. */ static void wait_heci_cb_avail(int len) {
- int i = 1000*1000;
- union { struct mei_csr csr; u32 raw; } csr;
- while (!(read32(DEFAULT_HECIBAR + 0xc) & 8));
while (i-- && !(read32(DEFAULT_HECIBAR + 0xc) & 8))
udelay(1);
do csr.raw = read32(DEFAULT_HECIBAR + 0x4);
In general static timeouts are not a good idea. Is there a reliable way for coreboot to determine if the ME image has been "cleaned" (i.e. can it parse the ME descriptor and not even search for the HECI interface if the ME size is less than a certain value?)
- -- Timothy Pearson Raptor Engineering +1 (415) 727-8645 (direct line) +1 (512) 690-0200 (switchboard) https://www.raptorengineering.com
Timothy Pearson wrote:
In general static timeouts are not a good idea.
In general infinite loops are a worse idea.
can it parse the ME descriptor and not even search for the HECI interface if the ME size is less than a certain value?
That's a good idea! But put the timeout in to begin with.
//Peter
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
On 03/27/2017 04:29 PM, Peter Stuge wrote:
Timothy Pearson wrote:
In general static timeouts are not a good idea.
In general infinite loops are a worse idea.
Agreed. That being said, this sort of "quick fix" with timeouts is one way that projects end up adding unneeded boot delay that sticks around and becomes harder to fix as the years go by. I've even seen this in Linux desktop environments; the "fastest" fix to multi-process startup is often to add a delay to force process start order. It's almost never the correct solution, but can serve as a useful backup if something goes wrong.
can it parse the ME descriptor and not even search for the HECI interface if the ME size is less than a certain value?
That's a good idea! But put the timeout in to begin with.
//Peter
- -- Timothy Pearson Raptor Engineering +1 (415) 727-8645 (direct line) +1 (512) 690-0200 (switchboard) https://www.raptorengineering.com
On Mon, 27 Mar 2017 15:19:17 -0500 Timothy Pearson tpearson@raptorengineering.com wrote:
In general static timeouts are not a good idea. Is there a reliable way for coreboot to determine if the ME image has been "cleaned" (i.e. can it parse the ME descriptor and not even search for the HECI interface if the ME size is less than a certain value?)
Good point, there probably is: - The GM45 datasheet has ways to determine that, so on nehalem there is probably something similar. - Flashrom also has ways to determine that. - GM45 RAM init probably also have ways to determine if HECI is present, I didn't check yet.
Note that I don't have nehalem hardware to test with, and may not have the time to work in a full solution.
Denis.
Hi,
On 03/27/2017 01:05 PM, Denis 'GNUtoo' Carikli wrote:
Since until now, the code running on the management engine is:
- Signed by its manufacturer
- Proprietary software, without corresponding source code
It can desirable to run the least ammount possible of such code, which is what me_cleaner[1] enables.
It does it by removing partitions of the management engine firmwares, however when doing so, the HECI interface might not be present anymore.
So it is desirable not to have the RAM initialisation code wait forever for the HECI interface to appear.
I do not know how ME cleaner operates but I believe security engine may be going into "recovery mode". This means it may never indicate readyness status. However the fact it is in recovery mode can be figured out programmatically as one of FWSTS registers. So you can try checking if security engine is in recovery and just skip waiting altogether. Try looking at "Current state" bits or "OP mode" bits. I suspect either of them will change after ME cleaner. FWSTS sits in ME PCI device config space and should be easily accessible. Typically FWSTS registers they sit in offset 0x40,0x48,0x60 and so on. Please try to compare them before and after ME cleaner.
Best, Andrey
On Mon, 27 Mar 2017 14:33:23 -0700 Andrey Petrov andrey.petrov@intel.com wrote:
Hi,
On 03/27/2017 01:05 PM, Denis 'GNUtoo' Carikli wrote:
Since until now, the code running on the management engine is:
- Signed by its manufacturer
- Proprietary software, without corresponding source code
It can desirable to run the least ammount possible of such code, which is what me_cleaner[1] enables.
It does it by removing partitions of the management engine firmwares, however when doing so, the HECI interface might not be present anymore.
So it is desirable not to have the RAM initialisation code wait forever for the HECI interface to appear.
I do not know how ME cleaner operates but I believe security engine may be going into "recovery mode".
That is my understanding too. If I understood correctly, the only partitions left contain code meant to intialize the management engine just enough to be able to boot the computer and reflash the boot flash.
This means it may never indicate readyness status. However the fact it is in recovery mode can be figured out programmatically as one of FWSTS registers.
So you can try checking if security engine is in recovery and just skip waiting altogether. Try looking at "Current state" bits or "OP mode" bits. I suspect either of them will change after ME cleaner. FWSTS sits in ME PCI device config space and should be easily accessible. Typically FWSTS registers they sit in offset 0x40,0x48,0x60 and so on. Please try to compare them before and after ME cleaner.
Thanks, I might try to do it if I can find the time.
Denis.