            Using ipmi_sim For A Real BMC
            -----------------------------

So you want to create a real BMC.  This is now possible with the
simulator.  So it's really not a simulator in this case, but that's
its heritage, so the name is still stuck.  Maybe I'll change it later.

Anyway, It can do most of the work without even writing any C code,
just with configuration.  It probably won't do everything you want out
of the box, though, so it has plugin capability to let you add your
own code to handle special conditions.

This documentation assumes a good working knowledge of IPMI.


How It Works
------------

The simulator has the two standard configuration files as defined in
the ipmi_sim_cmd.5 and ipmi_lan.5 man pages.  The LAN configuration
file defines the lan interfaces and a few other things, like SOL
configuration.

The emulator command file has commands to define the IPMI structure of
the system, like management controllers, sensors, FRU data, SDRs, etc.

So to create a BMC, you define the LAN interfaces, the management
controllers, the sensors, etc. in your system.  You can tie the FRU
data to physical files on the system (like EEPROMS in sysfs, or real
files).  You can tie the sensors to files, like sensors in sysfs.  You
can also write custom code and tie it in to set the sensor values.


Management Controllers
----------------------

To have a management controller handled by ipmi_sim, you have to add
it via the mc_add command, then you have to enable it with mc_enable.
This is a virtual management controller.  You have to add the BMC at
0x20, of course, but you can add others, too, if that makes sense.
For instance, if you have multiple boards in the system, it may make
sense to define a virtual MC for each board.  This is pretty simple.
Note that the capabilities you set with the mc_add command affect what
the MC can do.  You can't add SDRs, for instance, if the MC doesn't
have SDR capability.


LAN Configuration
-----------------

The LAN configuration file mostly defines the LAN interfaces.  It also
has a lot of simulator configuration, like how to start virtual
machine sessions tied to the management controllers and how the VMs
interface to the simulator.  These aren't terribly useful for a real
BMC (though the serial interface might one day with some
modifications).

The name of the BMC is set here.  This is used for a few things, like
to tell where to store persistent information (in
/var/ipmi_sim/<name>) and in logging.

A few other things in the file are SOL configuration, chassis control
handling, and loading custom code.  These are discussed later.


Sensors
-------

Sensors are added with the emulator command file with the sensor_add
command.  This command also lets you poll a file for data and has a
lot of options for massaging the data from the file into the 256 byte
value returned by an IPMI sensor.  It also lets you tie a dependency
to a discrete sensor, so that the enabling of the sensor can be done
based on a bit in the other discrete sensor.  For instance, a power
supply sensor has a presence bit in it, the power supply voltage and
current sensors can depend on that bit to be enabled or disabled.

If you are writing custom code to handle a sensor, you still have to
add it with sensor_add, then you can use the sensor number to
manipulate the sensor's value.  You have three main functions to do
this:

ipmi_mc_sensor_set_enabled() will let you enable or disable a sensor
directly.  Generally you would modify the sensor enable based upon the
presence of the entity the sensor measures.

ipmi_mc_sensor_set_value() sets a threshold sensor's value.

ipmi_mc_sensor_set_bit() sets/clears a discrete sensor bit.


SDRs
----

If you have sensors, you need SDRs to describe them.  You can directly
add these via the emulator command main_sdr_add (or device_sdr_add),
but that only deals with raw data and is a fairly inconvenient way to
do this.

The main SDRs for an MC are persistent and stored in
/var/ipmi_sim/<system-name/sdr.<ipmb-addr>.main.  For instance, the
main SDRs for a BMC at 0x20 are in /var/ipmi_sim/<name>/sdr.20.main.
If the user makes changes, they are stored there.  But, you can store
your SDRs here, too.

The easier way is to use the SDR compiler in the sdrcomp directory,
which can output data in the persistence format.  Then you can write
your SDRs in a more human-readable (or perhaps ipmi-engineer-readable)
format rather than just a bunch of bits.  Then generate the file and
copy it into the right place.


Serial Over LAN
---------------

As mentioned earlier, you can define SOL port in the lan configuration
file.  You can assign a physical serial port to a SOL port.  This is
described in the docs and is pretty straightforward.

There are a couple of unusual things about this, though.

One is that you can create a SOL interface on an MC besides the BMC.
But the standard SOL protocol will still work with it.  This means you
can use "ipmitool -t <mc>" to address a specific SOL instance, which
is convenient if you want to tie SOL interfaces to specific MCs.  Yes,
it's kind of an abuse of the spec, but it works and is convenient.

The other unusual thing about the SOL implementation is that it can
have a history buffer.  So say you want to keep around the last 64K or
so of data without having to be constantly connected to the BMC.  You
can define a 64K history buffer and connect to the BMC later to fetch
it.

You have two ways to fetch it.  The first is that the history buffer
appears as a second SOL instance at instance 2.  So you can connect to
SOL instance 2 and it will dump all the history.  The disadvantage of
this approach is that ipmitool cannot connect to SOL instances besides
1 without a special patch.

The other way to fetch it is to define a FRU data buffer that holds
the history.  You can define which FRU device does this.  Then you can
use the FRU data fetching commands to get the data.  The disadvantage
of this is that FRU data is limited to 64K.


FRU Data
--------

FRU data has already been mentioned with respect to SOL, but you can
create FRU data for an MC with the mc_add_fru_data emulator command.
You can either directly define the FRU data there (not ideal for a
real BMC) or tie it to a file.  Reading and writing all work.


Chassis Control
---------------

You can define an external command to handle chassis control commands.
The ipmi_sim_chassiscontrol file gives a framework for writing your
own script for handling this, and defines the various things that can
be done.  This is how reset, power, and boot control are done.


Custom Code
-----------

As mentioned before, you can load your own custom modules to do
whatever you like.  

Any module must define the following function:

int ipmi_sim_module_init(sys_data_t *sys, const char *initstr);

This is used to initialize the module.  It is called after the
configuration has been read from the LAN configuration file, but
before the emulator commands are run.  The module must also define the
following function:

int ipmi_sim_module_print_version(sys_data_t *sys, char *initstr);

This should print out an identifier and version number to standard out.

The module may optionally define the following function:

int ipmi_sim_module_post_init(sys_data_t *sys);

This is called after the emulator command file is run.  This can be
used to finish up configuration of things, add functions to sensors,
do any sensor initialization, or anything else that needs to be done
after the emulator commands are run.

The include files in lanserv/OpenIPMI define the interface function
that a module may use.  Primarily, serv.h and mcserv.c.


Threading
---------

The ipmi_sim code itself is not multi-threaded.  You cannot have
concurrent calls into any of the code.  You can, however, define your
own threads using pthreads as long as none of them call into the
ipmi_sim code.


What's Still Missing
--------------------

ipmi_sim currently does not have any provisions for direct IPMI
support or the handling of any I2C commands.  This should be fairly
easy to add, but has not yet been needed.

Lots of other things are probably missing, too, of course, but it's
hard to know what you don't know...