intel heci/mei

Andriy Gapon avg at icyb.net.ua
Sat Jan 10 10:32:05 PST 2009


First of all, some relevant terms to google for.
Intel AMT - Active Management Technology
ME - Management Engine
MEI - ME Interface
HECI - Host Embedded Controller Interface, I believe that this is a
different (older?) name for MEI

What this is not about.
This is not about AMT in general; not about remote access/control that
by-passes OS.

What this is about.
Providing a kernel driver and interface that would enable user-land
programs (and/or kernel) to communicate with "agents" residing in ME.
Provided, of course, that those agents are designed to support such
communication.
For me, personally, "Quiet System Technology (QST), formerly Advanced
Fan Speed Control (AFSC)" is of the most interest.

Prior art.
http://openamt.org
Open-sourced GPL/BSD Linux driver developed by Intel that provides in
principle exactly what I want.
http://mail.opensolaris.org/pipermail/opensolaris-arc/2007-October/004572.html
Lengthy discussion of a similar driver for OpenSolaris plus general AMT
issues.

My understanding.
There is a dedicated micro-controller built into a chipset. This is
Management Engine. The micro-controller can execute various firmware
programs that perform control/monitoring/management tasks.
There is a PCI device/function in the chipset that allows host software
(run on main CPU) to communicate with the firmware running in ME. This
is HECI.
There are several memory-mapped registers for the communication. The
communication seems to be symmetric (on the lowest level). The
communication occurs by writing data into a circular buffer and then
writing a bit that causes an interrupt to occur to the peer. Thus, there
are two circular buffers to send data in the opposite directions.
There are can be multiple peers on the host side and on the firmware
side. Peers are addressed by simple 1-byte numbers. Firmware peers are
further uniquely identified by GUIDs.
There is a certain message protocol. There are so called bus messages
and then there are application specific messages.
Via bus messages the following can be done:
1. discover firmware clients (only from the host side)
2. query identities and capabilities/properties of a fw client (only
from the host side)
3. establish or close a connection between a host client and a fw client
 (only from the host side [?])
4. send a flow control message to a connected peer which gives it a
permission to send one application-specific message

All messages have a 4-byte header that specifies peer addresses and
length of message body. Bus messages use broadcast addresses of zero in
the header, peer information (if any) is provided in message body. Bus
messages have a well defined structure.

One logical application message can be consist of several HECI messages,
there is a flag in the message header telling if a message is complete.

Typical communication session can look like this:
1. query fw peers (their addresses)
2. query properties of each available peer until the one of interest is
found
3. send connect message
4. receive connect status message
5. receive flow control message [gives permission for the next step]
6. send application request
7. send flow control message [gives permission for the next step]
8. receive application response
9. receive flow control message [peer is ready for next request]
[...]
10. send disconnect message
11. receive disconnect response


How OpenAMT driver currently works.
Omitting low level details - it enumerates fw clients and creates a
single heci character device. Then there ioctls for userland programs to
connect to client with a specific GUID and then the program can
communicate with it via read and write calls.

What I have in mind.
The driver would enumerate fw clients and create a character device for
each one discovered. Device name could be a stringified GUID and/or some
short name for well-known GUIDs. A userland program would simple
open/close such a device to establish/terminate communication.

There is something I am not sure about, I see 2 possibilities:
1. there will be one driver with multiple character devices, all devices
would behave identically, knowledge of how to talk to each fw client
would lie in userland programs;
2. there will be a heci bus with individual drivers for well-know fw
clients plus maybe a generic driver to talk to unknown clients; each
character device would have a documented API for communication with the
corresponding fw client;

For now I am leaning towards approach #1.

There are also other issues. Like, for example, what is the best API for
exchanging application messages. I assume that there could be different
modes of talking to fw client, typically it is simple request/response,
but it is possible that client might provide something like streaming
data. Also, a messages fro fw client could be multi-part - how do we
tell userland that there is more data and when the message ends.

I have some very very simple code that puts all (really all) the
communication logic into the userland, it only provides a way to talk to
the hardware (correctly reading/writing registers, handling interrupts).
I have some small successes using that code.

I hope to produce something more mature, but as usual the time is the
biggest constraint.

If you have an advice for me or some interest in this area - please
write me.

P.S. I am also thinking about more-or-less porting the OpenAMT code, but
the changes would be quite huge and the code is frequently quite hard
for me to grok.

-- 
Andriy Gapon


More information about the freebsd-acpi mailing list