summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSuraj Jitindar Singh <sjitindarsingh@gmail.com>2017-04-11 13:36:15 +1000
committerSuraj Jitindar Singh <sjitindarsingh@gmail.com>2017-04-11 15:17:06 +1000
commit04e8ffda0daaf1e0dd034a91b421bab2b3eb9723 (patch)
treeba3029c6c3980880f8b0137dc877b643385e86d4
parentf6e0cf00706a252985d86aee5f9ae2330db68d62 (diff)
downloadphosphor-mboxd-04e8ffda0daaf1e0dd034a91b421bab2b3eb9723.tar.gz
phosphor-mboxd-04e8ffda0daaf1e0dd034a91b421bab2b3eb9723.zip
docs: Create Documentation folder and add mboxd and mboxctl documentation
Create a separate folder for documentation called Documentation. Move the protocol definition into a file in this folder called mbox_protocol.md and update the README.md to explain the files in the docs folder. Also add two other files to the folder called mboxd.md and mboxctl.md which document the operation of the reference implementations of the mailbox daemon and the mailbox control program respectively. Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com> Change-Id: I9f818700ad1e36a396a828f0f085b42cc106b550
-rw-r--r--Documentation/mbox_protocol.md653
-rw-r--r--Documentation/mboxctl.md110
-rw-r--r--Documentation/mboxd.md181
-rw-r--r--README.md646
4 files changed, 953 insertions, 637 deletions
diff --git a/Documentation/mbox_protocol.md b/Documentation/mbox_protocol.md
new file mode 100644
index 0000000..5a0879e
--- /dev/null
+++ b/Documentation/mbox_protocol.md
@@ -0,0 +1,653 @@
+Copyright 2017 IBM
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+## Intro
+
+This document describes a protocol for host to BMC communication via the
+mailbox registers present on the Aspeed 2400 and 2500 chips.
+This protocol is specifically designed to allow a host to request and manage
+access to the flash with the specifics of how the host is required to control
+this described below.
+
+## Version
+
+Both version 1 and version 2 of the protocol are described below with version 2
+specificities represented with V2 in brackets - (V2).
+
+## Problem Overview
+
+"mbox" is the name we use to represent a protocol we have established between
+the host and the BMC via the Aspeed mailbox registers. This protocol is used
+for the host to control the flash.
+
+Prior to the mbox protocol, the host uses a backdoor into the BMC address space
+(the iLPC-to-AHB bridge) to directly manipulate the BMCs own flash controller.
+
+This is not sustainable for a number of reasons. The main ones are:
+
+1. Every piece of the host software stack that needs flash access (HostBoot,
+ OCC, OPAL, ...) has to have a complete driver for the flash controller,
+ update it on each BMC generation, have all the quirks for all the flash
+ chips supported etc... We have 3 copies on the host already in addition to
+ the one in the BMC itself.
+
+2. There are serious issues of access conflicts to that controller between the
+ host and the BMC.
+
+3. It's very hard to support "BMC reboots" when doing that
+
+4. It's slow
+
+5. Last but probably most important, having that backdoor open is a security
+ risk. It means the host can access any address on the BMC internal bus and
+ implant malware in the BMC itself. So if the host is a "bare metal" shared
+ system in some kind of data center, not only the host flash needs to be
+ reflashed when switching from one customer to another, but the entire BMC
+ flash too as nothing can be trusted. So we want to disable it.
+
+To address all these, we have implemented a new mechanism that we call mbox.
+
+When using this mechanism, the BMC is solely responsible for directly accessing
+the flash controller. All flash erase and write operations are performed by the
+BMC and the BMC only. (We can allow direct reads from flash under some
+circumstances but we tend to prefer going via memory).
+
+The host uses the mailbox registers to send "commands" to the BMC, which
+responds via the same mechanism. Those commands allow the host to control a
+"window" (which is the LPC -> AHB FW space mapping) that is either a read
+window or a write window onto the flash.
+
+When set for writing, the BMC makes the window point to a chunk of RAM instead.
+When the host "commits" a change (via MBOX), then the BMC can perform the
+actual flashing from the data in the RAM window.
+
+The idea is to have the LPC FW space be routed to an active "window". That
+window can be a read or a write window. The commands allow to control which
+window and which offset into the flash it maps.
+
+* A read window can be a direct window to the flash controller space (ie.
+ 0x3000\_0000) or it can be a window to a RAM image of a flash. It doesn't have
+ to be the full size of the flash per protocol (commands can be use to "slide"
+ it to various parts of the flash) but if its set to map the actual flash
+ controller space at 0x3000\_0000, it's probably simpler to make it the full
+ flash. The host makes no assumption, it's your choice what to provide. The
+ simplest implementation is to just route to the flash read/only.
+
+* A write window has to be a chunk of BMC memory. The minimum size is not
+ defined in the spec, but it should be at least one block (4k for now but it
+ should support larger block sizes in the future). When the BMC receive the
+ command to map the write window at a given offset of the flash, the BMC should
+ copy that portion of the flash into a reserved memory buffer, and modify the
+ LPC mapping to point to that buffer.
+
+The host can then write to that window directly (updating the BMC memory) and
+send a command to "commit" those updates to flash.
+
+Finally there is a `RESET_STATE`. It's the state in which the bootloader in the
+SEEPROM of the POWER9 chip will find what it needs to load HostBoot. The
+details are still being ironed out: either mapping the full flash read only or
+reset to a "window" that is either at the bottom or top of the flash. The
+current implementation resets to point to the full flash.
+
+## Where is the code?
+
+The mbox userspace is available [on GitHub](https://github.com/openbmc/mboxbridge)
+This is Apache licensed but we are keen to see any enhancements you may have.
+
+The kernel driver is still in the process of being upstreamed but can be found
+in the OpenBMC Linux kernel staging tree:
+
+https://github.com/openbmc/linux/commit/85770a7d1caa6a1fa1a291c33dfe46e05755a2ef
+
+## Building
+
+The autotools of this requires the autoconf-archive package for your
+system
+
+## The Hardware
+
+The Aspeed mailbox consists of 16 (8 bit) data registers see Layout for their
+use. Mailbox interrupt enabling, masking and triggering is done using a pair
+of control registers, one accessible by the host the other by the BMC.
+Interrupts can also be raised per write to each data register, for BMC and
+host. Write tiggered interrupts are configured using two 8 bit registers where
+each bit represents a data register and if an interrupt should fire on write.
+Two 8 bit registers are present to act as a mask for write triggered
+interrupts.
+
+### Layout
+
+```
+Byte 0: COMMAND
+Byte 1: Sequence
+Byte 2-12: Arguments
+Byte 13: Response code
+Byte 14: Host controlled status reg
+Byte 15: BMC controlled status reg
+```
+
+## Low Level Protocol Flow
+
+What we essentially have is a set of registers which either the host or BMC can
+write to in order to communicate to the other which will respond in some way.
+There are 3 basic types of communication.
+
+1. Commands sent from the Host to the BMC
+2. Responses sent from the BMC to the Host in response to commands
+3. Asyncronous events raised by the BMC
+
+### General Use
+
+Messages usually originate from the host to the BMC. There are special
+cases for a back channel for the BMC to pass new information to the
+host which will be discussed later.
+
+To initiate a request the host must set a command code (see
+Commands) into mailbox data register 0. It is also the hosts
+responsibility to generate a unique sequence number into mailbox
+register 1. After this any command specific data should be written
+(see Layout). The host must then generate an interrupt to the BMC by
+using bit 0 of its control register and wait for an interrupt on the
+response register. Generating an interrupt automatically sets bit 7 of the
+corresponding control register. This bit can be used to poll for
+messages.
+
+On receiving an interrupt (or polling on bit 7 of its Control
+Register) the BMC should read the message from the general registers
+of the mailbox and perform the necessary action before responding. On
+responding the BMC must ensure that the sequence number is the same as
+the one in the request from the host. The BMC must also ensure that
+mailbox data regsiter 13 is a valid response code (see Responses). The
+BMC should then use its control register to generate an interrupt for
+the host to notify it of a response.
+
+### Asynchronous BMC to Host Events
+
+BMC to host communication is also possible for notification of events
+from the BMC. This requires that the host have interrupts enabled on
+mailbox data register 15 (or otherwise poll on bit 7 of mailbox status
+register 1). On receiving such a notification the host should read
+mailbox data register 15 to determine the event code which was set by the
+BMC (see BMC Event notifications in Commands for detail). Events which are
+defined as being able to be acknowledged by the host must be with a
+BMC_EVENT_ACK command.
+
+## High Level Protocol Flow
+
+When a host wants to communicate with the BMC via the mbox protocol the first
+thing it should do it call MBOX_GET_INFO in order to establish the protocol
+version which each understands. Before this the only other commands which are
+allowed are RESET_STATE and BMC_EVENT_ACK.
+
+After this the host can open and close windows with the CREATE_READ_WINDOW,
+CREATE_WRITE_WINDOW and CLOSE_WINDOW commands. Creating a window is how the
+host requests access to a section of flash. It is worth noting that the host
+can only ever have one window that it is accessing at a time - hence forth
+referred to as the active window.
+
+When the active window is a write window the host can perform MARK_WRITE_DIRTY,
+MARK_WRITE_ERASED and WRITE_FLUSH commands to identify changed blocks and
+control when the changed blocks are written to flash.
+
+Independently, and at any point not during an existing mbox command
+transaction, the BMC may raise raise asynchronous events with the host to
+communicate a change in state.
+
+### Version Negotiation
+
+Given that a majority of command and response arguments are specified as a
+multiple of block size it is necessary for the host and BMC to agree on a
+protocol version as this determines the block size. In V1 it is hard coded at
+4K and in V2 the BMC chooses and specifies this to the host as a response
+argument to MBOX_GET_INFO. Thus the host must always call MBOX_GET_INFO before
+any other command which specifies an argument in block size.
+
+The host must tell the BMC the highest protocol level which it supports. The
+BMC will then respond with a protocol level. If the host doesn't understand
+the protocol level specified by the BMC then it must not continue to
+communicate with the BMC. Otherwise the protocol level specified by the
+BMC is taken to be the protocol level used for further communication and can
+only be changed by another call to MBOX_GET_INFO. The BMC should use the
+request from the host to influence its protocol version choice.
+
+### Window Management
+
+In order to access flash contents the host must request a window be opened at
+the flash offset it would like to access. The host may give a hint as to how
+much data it would like to access or otherwise set this argument to zero. The
+BMC must respond with the lpc bus address to access this window and the
+window size. The host must not access past the end of the active window.
+
+There is only ever one active window which is the window created by the most
+recent CREATE_READ_WINDOW or CREATE_WRITE_WINDOW call which succeeded. Even
+though there are two types of windows there can still only be one active window
+irrespective of type. A host must not write to a read window. A host may read
+from a write window and the BMC must guarantee that the window reflects what
+the host has written there.
+
+A window can be closed by calling CLOSE_WINDOW in which case there is no active
+window and the host must not access the LPC window after it has been closed.
+If the host closes an active write window then the BMC must perform an
+implicit flush. If the host tries to open a new window with an already active
+window then the active window is closed (and implicitly flushed if it was a
+write window). If the new window is successfully opened then it is the new
+active window, if the command fails then there is no active window and the
+previous active window must no longer be accessed.
+
+The host must not access an lpc address other than that which is contained by
+the active window. The host must not use write management functions (see below)
+if the active window is a read window or if there is no active window.
+
+### Write Management
+
+The BMC has no method for intercepting writes that occur over the LPC bus. Thus
+the host must explicitly notify the BMC of where and when a write has
+occured. The host must use the MARK_WRITE_DIRTY command to tell the BMC where
+within the write window it has modified. The host may also use the
+MARK_WRITE_ERASED command to erase large parts of the active window without the
+need to write 0xFF. The BMC must ensure that if the host
+reads from an area it has erased that the read values are 0xFF. Any part of the
+active window marked dirty/erased is only marked for the lifetime of the current
+active write window and does not persist if the active window is closed either
+implicitly or explicitly by the host or the BMC. The BMC may at any time
+or must on a call to WRITE_FLUSH flush the changes which it has been notified
+of back to the flash, at which point the dirty or erased marking is cleared
+for the active window. The host must not assume that any changes have been
+written to flash unless an explicit flush call was successful, a close of an
+active write window was successful or a create window command with an active
+write window was successful - otherwise consistency between the flash and memory
+contents cannot be guaranteed.
+
+The host is not required to perform an erase before a write command and the
+BMC must ensure that a write performs as expected - that is if an erase is
+required before a write then the BMC must perform this itself.
+
+### BMC Events
+
+The BMC can raise events with the host asynchronously to communicate to the
+host a change in state which it should take notice of. The host must (if
+possible for the given event) acknowledge it to inform the BMC it has been
+received.
+
+If the BMC raises a BMC Reboot event then the host must renegotiate the
+protocol version so that both the BMC and the host agree on the block size.
+A BMC Reboot event implies a BMC Windows Reset event.
+If the BMC raises a BMC Windows Reset event then the host must
+assume that there is no longer an active window - that is if there was an
+active window it has been closed by the BMC and if it was a write window
+then the host must not assume that it was flushed unless a previous explicit
+flush call was successful.
+
+The BMC may at some points require access to the flash and the BMC daemon must
+set the BMC Flash Control Lost event when the BMC is accessing the flash behind
+the BMC daemons back. When this event is set the host must assume that the
+contents of the active window could be inconsistent with the contents of flash.
+
+## Protocol Definition
+
+### Commands
+
+```
+RESET_STATE 0x01
+GET_MBOX_INFO 0x02
+GET_FLASH_INFO 0x03
+CREATE_READ_WINDOW 0x04
+CLOSE_WINDOW 0x05
+CREATE_WRITE_WINDOW 0x06
+MARK_WRITE_DIRTY 0x07
+WRITE_FLUSH 0x08
+BMC_EVENT_ACK 0x09
+MARK_WRITE_ERASED 0x0a (V2)
+```
+
+### Sequence
+
+The host must ensure a unique sequence number at the start of a
+command/response pair. The BMC must ensure the responses to
+a particular message contain the same sequence number that was in the
+command request from the host.
+
+### Responses
+
+```
+SUCCESS 1
+PARAM_ERROR 2
+WRITE_ERROR 3
+SYSTEM_ERROR 4
+TIMEOUT 5
+BUSY 6 (V2)
+WINDOW_ERROR 7 (V2)
+```
+
+#### Description:
+
+SUCCESS - Command completed successfully
+
+PARAM_ERROR - Error with parameters supplied or command invalid
+
+WRITE_ERROR - Error writing to the backing file system
+
+SYSTEM_ERROR - Error in BMC performing system action
+
+TIMEOUT - Timeout in performing action
+
+BUSY - Daemon in suspended state (currently unable to access flash)
+ - Retry again later
+
+WINDOW_ERROR - Command not valid for active window or no active window
+ - Try opening an appropriate window and retrying the command
+
+### Information
+- All multibyte messages are LSB first (little endian)
+- All responses must have a valid return code in byte 13
+
+
+### Commands in detail
+
+Note in V1 block size is hard coded to 4K, in V2 it is variable and must be
+queried with GET_MBOX_INFO.
+Sizes and addresses are specified in either bytes - (bytes)
+ or blocks - (blocks)
+Sizes and addresses specified in blocks must be converted to bytes by
+multiplying by the block size.
+```
+Command:
+ RESET_STATE
+ Implemented in Versions:
+ V1, V2
+ Arguments:
+ -
+ Response:
+ -
+ Notes:
+ This command is designed to inform the BMC that it should put
+ host LPC mapping back in a state where the SBE will be able to
+ use it. Currently this means pointing back to BMC flash
+ pre mailbox protocol. Final behavour is still TBD.
+
+Command:
+ GET_MBOX_INFO
+ Implemented in Versions:
+ V1, V2
+ Arguments:
+ V1:
+ Args 0: API version
+
+ V2:
+ Args 0: API version
+
+ Response:
+ V1:
+ Args 0: API version
+ Args 1-2: default read window size (blocks)
+ Args 3-4: default write window size (blocks)
+
+ V2:
+ Args 0: API version
+ Args 1-2: reserved
+ Args 3-4: reserved
+ Args 5: Block size as power of two (encoded as a shift)
+
+Command:
+ GET_FLASH_INFO
+ Implemented in Versions:
+ V1, V2
+ Arguments:
+ -
+ Response:
+ V1:
+ Args 0-3: Flash size (bytes)
+ Args 4-7: Erase granule (bytes)
+
+ V2:
+ Args 0-1: Flash size (blocks)
+ Args 2-3: Erase granule (blocks)
+
+Command:
+ CREATE_{READ/WRITE}_WINDOW
+ Implemented in Versions:
+ V1, V2
+ Arguments:
+ V1:
+ Args 0-1: Window location as offset into flash (blocks)
+
+ V2:
+ Args 0-1: Window location as offset into flash (blocks)
+ Args 2-3: Requested window size (blocks)
+
+ Response:
+ V1:
+ Args 0-1: LPC bus address of window (blocks)
+
+ V2:
+ Args 0-1: LPC bus address of window (blocks)
+ Args 2-3: Actual window size (blocks)
+ Args 4-5: Actual window location as offset into flash (blocks)
+ Notes:
+ Window location is always given as an offset into flash as
+ taken from the start of flash - that is it is an absolute
+ address.
+
+ LPC bus address is always given from the start of the LPC
+ address space - that is it is an absolute address.
+
+ The requested window size is only a hint. The response
+ indicates the actual size of the window. The BMC may
+ want to use the requested size to pre-load the remainder
+ of the request. The host must not access past the end of the
+ active window.
+
+ The actual window location indicates the absolute flash offset
+ that the window actually maps and is not required to be equal
+ to the flash offset requested by the host, but however must be
+ less than or equal to it. Thus the first block of the window at
+ the lpc address in the response will map the first block at the
+ actual flash offset also contained in the response. It is the
+ responsibility of the host to use this information to access
+ any offset which is required.
+
+ The requested window size may be zero. In this case the
+ BMC is free to create any sized window but it must contain
+ atleast the first block of data requested by the host. A large
+ window is of course preferred and should correspond to
+ the default size returned in the GET_MBOX_INFO command.
+
+ If this command returns successfully then the window which the
+ host requested is the active window. If it fails then there is
+ no active window.
+
+Command:
+ CLOSE_WINDOW
+ Implemented in Versions:
+ V1, V2
+ Arguments:
+ V1:
+ -
+
+ V2:
+ Args 0: Flags
+ Response:
+ -
+ Notes:
+ Closes the active window. Any further access to the LPC bus
+ address specified to address the previously active window will
+ have undefined effects. If the active window is a
+ write window then the BMC must perform an implicit flush.
+
+ The Flags argument allows the host to provide some
+ hints to the BMC. Defined Values:
+ 0x01 - Short Lifetime:
+ The window is unlikely to be accessed
+ anytime again in the near future. The effect of
+ this will depend on BMC implementation. In
+ the event that the BMC performs some caching
+ the BMC daemon could mark data contained in a
+ window closed with this flag as first to be
+ evicted from the cache.
+
+Command:
+ MARK_WRITE_DIRTY
+ Implemented in Versions:
+ V1, V2
+ Arguments:
+ V1:
+ Args 0-1: Flash offset to mark from base of flash (blocks)
+ Args 2-5: Number to mark dirty at offset (bytes)
+
+ V2:
+ Args 0-1: Window offset to mark (blocks)
+ Args 2-3: Number to mark dirty at offset (blocks)
+
+ Response:
+ -
+ Notes:
+ The BMC has no method for intercepting writes that
+ occur over the LPC bus. The host must explicitly notify
+ the daemon of where and when a write has occured so it
+ can be flushed to backing storage.
+
+ Offsets are given as an absolute (either into flash (V1) or the
+ active window (V2)) and a zero offset refers to the first
+ block. If the offset + number exceeds the size of the active
+ window then the command must not succeed.
+
+Command
+ WRITE_FLUSH
+ Implemented in Versions:
+ V1, V2
+ Arguments:
+ V1:
+ Args 0-1: Flash offset to mark from base of flash (blocks)
+ Args 2-5: Number to mark dirty at offset (bytes)
+
+ V2:
+ -
+
+ Response:
+ -
+ Notes:
+ Flushes any dirty/erased blocks in the active window to
+ the backing storage.
+
+ In V1 this can also be used to mark parts of the flash
+ dirty and flush in a single command. In V2 the explicit
+ mark dirty command must be used before a call to flush
+ since there are no longer any arguments. If the offset + number
+ exceeds the size of the active window then the command must not
+ succeed.
+
+
+Command:
+ BMC_EVENT_ACK
+ Implemented in Versions:
+ V1, V2
+ Arguments:
+ Args 0: Bits in the BMC status byte (mailbox data
+ register 15) to ack
+ Response:
+ *clears the bits in mailbox data register 15*
+ Notes:
+ The host should use this command to acknowledge BMC events
+ supplied in mailbox register 15.
+
+Command:
+ MARK_WRITE_ERASED
+ Implemented in Versions:
+ V2
+ Arguments:
+ V2:
+ Args 0-1: Window offset to erase (blocks)
+ Args 2-3: Number to erase at offset (blocks)
+ Response:
+ -
+ Notes:
+ This command allows the host to erase a large area
+ without the need to individually write 0xFF
+ repetitively.
+
+ Offset is the offset within the active window to start erasing
+ from (zero refers to the first block of the active window) and
+ number is the number of blocks of the active window to erase
+ starting at offset. If the offset + number exceeds the size of
+ the active window then the command must not succeed.
+```
+
+### BMC Events in Detail:
+
+If the BMC needs to tell the host something then it simply
+writes to Byte 15. The host should have interrupts enabled
+on that register, or otherwise be polling it.
+
+#### Bit Definitions:
+
+Events which should be ACKed:
+```
+0x01: BMC Reboot
+0x02: BMC Windows Reset (V2)
+```
+
+Events which cannot be ACKed (BMC will clear when no longer
+applicable):
+```
+0x40: BMC Flash Control Lost (V2)
+0x80: BMC MBOX Daemon Ready (V2)
+```
+
+#### Event Description:
+
+Events which must be ACKed:
+The host should acknowledge these events with BMC_EVENT_ACK to
+let the BMC know that they have been received and understood.
+```
+0x01 - BMC Reboot:
+ Used to inform the host that a BMC reboot has occured.
+ The host must perform protocol verison negotiation again and
+ must assume it has no active window. The host must not assume
+ that any commands which didn't respond as such succeeded.
+0x02 - BMC Windows Reset: (V2)
+ The host must assume that its active window has been closed and
+ that it no longer has an active window. The host is not
+ required to perform protocol version negotiation again. The
+ host must not assume that any commands which didn't respond as such
+ succeeded.
+```
+
+Events which cannot be ACKed:
+These events cannot be acknowledged by the host and a call to
+BMC_EVENT_ACK with these bits set will have no effect. The BMC
+will clear these bits when they are no longer applicable.
+```
+0x40 - BMC Flash Control Lost: (V2)
+ The BMC daemon has been suspended and thus no longer
+ controls access to the flash (most likely because some
+ other process on the BMC required direct access to the
+ flash and has suspended the BMC daemon to preclude
+ concurrent access).
+ The BMC daemon must clear this bit itself when it regains
+ control of the flash (the host isn't able to clear it
+ through an acknowledge command).
+ The host must not assume that the contents of the active window
+ correctly reflect the contents of flash while this bit is set.
+0x80 - BMC MBOX Daemon Ready: (V2)
+ Used to inform the host that the BMC daemon is ready to
+ accept command requests. The host isn't able to clear
+ this bit through an acknowledge command, the BMC daemon must
+ clear it before it terminates (assuming it didn't
+ terminate unexpectedly).
+ The host should not expect a response while this bit is
+ not set.
+ Note that this bit being set is not a guarantee that the BMC daemon
+ will respond as it or the BMC may have crashed without clearing
+ it.
+```
diff --git a/Documentation/mboxctl.md b/Documentation/mboxctl.md
new file mode 100644
index 0000000..49bf90e
--- /dev/null
+++ b/Documentation/mboxctl.md
@@ -0,0 +1,110 @@
+Copyright 2017 IBM
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+## Intro
+
+This document describes the reference mailbox control program contained in this
+repository.
+
+The mailbox control program is a program which can be used to generate dbus
+messages to control the operation of the mailbox daemon.
+
+## Files
+
+The mailbox control program is implemented entirely in the mboxctl.c file.
+
+## Operation
+
+### Invocation
+
+The mailbox control program is invoked with a command and any arguments which
+that command takes.
+
+### Sending Command
+
+The appropriate dbus message is then generated and sent on the dbus.
+
+### Receiving Commands
+
+After sending a command mboxctl then waits for a response from the daemon on
+the dbus and processes the response.
+
+A message is printed to convey the response provided by the daemon. It mboxctl
+is run in silent mode then no output is generated and the exit code reflects
+the response.
+
+## DBUS Protocol
+
+### Commands
+
+```
+0x00: Ping - Ping the daemon
+ - Args: NONE
+ - Resp: NONE
+0x01: Daemon State - Get the daemon status
+ - Args: NONE
+ - Resp[0]: Daemon Status:
+ 0x00 - Active
+ 0x01 - Suspended
+0x02: Reset - Reset the daemon (same as the reset mbox command)
+ - Args: NONE
+ - Resp: NONE
+0x03: Suspend - Suspend the daemon
+ - Allow the BMC to manage concurrent flash
+ access
+ - The daemon will return BUSY to mbox window
+ commands
+ - Will return Success if daemon successfully
+ of already suspended
+ - Args: NONE
+ - Resp: NONE
+0x04: Resume - Resume the daemon
+ - Will return Sucess if daemon successfully
+ or already resumed
+ - Args[0]: Flash Modified:
+ "clean" - Not Modified (daemon won't
+ clear its cache)
+ "modified" - Modified (daemon will clear
+ its cache)
+ - Resp: NONE
+0x05: Clear Cache - Tell the daemon its data source has been modified
+ - Causes the daemon to clear its cache
+ - Args: NONE
+ - Resp: NONE
+0x06: Kill - Terminates the daemon
+ - Args: NONE
+ - Resp: NONE
+0x07: LPC State - Query the state of the lpc mapping
+ - Args: NONE
+ - Resp[0]: LPC Bus Mapping State:
+ 0x00 - Invalid (implies internal daemon
+ error)
+ 0x01 - Flash (LPC bus maps flash)
+ 0x02 - Memory (LPC bus maps reserved
+ memory)
+```
+
+### Return Values
+
+```
+0x00: Success - Command succeeded
+0x01: Internal - Internal DBUS Error
+0x02: Invalid - Invalid command or parameters
+0x03: Rejected - Daemon rejected the request
+ - If this occurs on a suspend command then the BMC must
+ not access the flash device until a suspend command
+ succeeds
+0x04: Hardware - BMC Hardware Error
+0x05: Memory - Memory Allocation Failed
+```
diff --git a/Documentation/mboxd.md b/Documentation/mboxd.md
new file mode 100644
index 0000000..d60925d
--- /dev/null
+++ b/Documentation/mboxd.md
@@ -0,0 +1,181 @@
+Copyright 2017 IBM
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+## Intro
+
+This document describes the reference mailbox daemon contained in this
+repository.
+
+## Files
+
+The main mailbox daemon is implemented in mboxd.c. This file uses helper
+functions from the various mboxd_*.c files.
+
+```
+mboxd_dbus.c - Contains the handlers for the dbus commands which the daemon can
+ receive.
+mboxd_flash.c - Contains the functions for performing flash access including
+ read, write and erase.
+mboxd_lpc.c - Contains the functions for controlling the lpc bus mapping
+ including pointing the bus so it maps flash and memory.
+mboxd_msg.c - Contains the handlers for the mbox commands which the daemon
+ can receive.
+mboxd_windows.c - Contains the functions for managing the window cache.
+```
+
+## Daemon State
+
+The daemon is a state machine with 5 valid states:
+
+```
+UNINITIALISED - The daemon is still in the initialisation phase and
+ will not respond
+ACTIVE_MAPS_FLASH - The daemon is polling for incoming commands, is not
+ currently suspended and the lpc bus maps the flash
+ device.
+SUSPEND_MAPS_FLASH - The daemon is polling for incoming commands, is
+ currently suspended and the lpc bus maps the flash
+ device.
+ACTIVE_MAPS_MEM - The daemon is polling for incoming commands, is not
+ currently suspended and the lpc bus maps the reserved
+ memory region.
+SUSPEND_MAPS_MEM - The daemon is polling for incoming commands, is
+ currently suspended and the lpc bus maps the reserved
+ memory region.
+```
+
+As described in the protocol, the daemon can be suspended to allow the BMC to
+access flash without the daemon interfering. The daemon will still respond to
+commands while suspended but won't allow the host to, or itself, access the
+flash.
+
+### State Transitions
+
+```
+UNINITIALISED -> ACTIVE_MAPS_FLASH - Uninitiated: Occurs when the daemon is
+ finished initialising.
+ACTIVE_MAPS_FLASH -> SUSPEND_MAPS_FLASH - Suspend command received over
+ dbus
+SUSPEND_MAPS_FLASH -> ACTIVE_MAPS_FLASH - Resume command received over
+ dbus
+ACTIVE_MAPS_MEM -> SUSPEND_MAPS_MEM - Suspend command received over dbus
+SUSPEND_MAPS_MEM -> ACTIVE_MAPS_MEM - Resume command received over dbus
+ACTIVE_MAPS_FLASH -> ACTIVE_MAPS_MEM - GET_MBOX_INFO command received
+SUSPEND_MAPS_FLASH -> SUSPEND_MAPS_MEM - GET_MBOX_INFO command received
+ACTIVE_MAPS_MEM -> ACTIVE_MAPS_FLASH - Reset dbus or mbox command received
+SUSPEND_MAPS_MEM -> SUSPEND_MAPS_FLASH - Transition not allowed, we
+ don't let the host modify flash
+ while the daemon is suspended.
+```
+
+## Window Cache
+
+While the protocol describes that there is only one active window at a time,
+the daemon keeps a cache of previously accessed windows to avoid the need to
+reload them from flash should the host access them again in the future.
+
+The reserved memory region is divided among a number of windows which make up
+the window cache. When the host requests a flash offset the cache is searched
+for one which contains that offset. If one is found we simply point the host to
+it at the correct lpc offset for that windows location and the requested flash
+offset.
+
+If there is no window in the cache which contains the requested flash offset
+then we have to find one to load with the requested flash contents. If there
+are any windows which are empty then we choose those, otherwise we choose one to
+evict using a least recently used (LRU) scheme. The flash is then copied into
+this window and the host pointed at its location on the lpc bus.
+
+When ever the flash is changed we have to invalidate all windows in the window
+cache as their contents may no longer accurately reflect those of the flash.
+
+## Daemon Operation
+
+### Invocation
+
+The daemon is invoked on the command line with a few parameters:
+
+```
+(*) - required
+(#) - optional but recommended
+(~) - optional
+
+--flash * - The size of the PNOR image on the flash device
+--window-size # - The size to make each window in the cache
+--window-num # - The number of windows to have in the cache
+--verbose ~ - Increase the verbosity with which the daemon runs
+--sys-log ~ - Use the system log rather than outputing to the console
+```
+
+If any of the required parameters are missing or invalid an error will be
+printed and the daemon will terminate.
+If window-size and window-num aren't specified then the default is to have a
+single window which spans the entire reserved memory region.
+
+### Initialisation
+
+After the command line has been parsed the daemon will initalise its various
+interfaces. If any of these initialisations fail it will print an error and the
+daemon will terminate.
+
+After initilisation the daemon points the lpc mapping to the actual flash
+device, sets the BMC_READY BMC event and starts polling.
+
+### Polling
+
+The daemon sits in a poll loop waiting for an event to happen on one or more of
+the mbox, dbus or signal file descriptors.
+
+#### Handling MBOX Commands
+
+When an event occurs on the mbox file descriptor the mbox request is read from
+the mbox registers and processed.
+
+The command is validated and then the appropriate handler called. The response
+is then written back to the mbox registers to indicate the outcome of the
+command and an interrupt generated to the host.
+
+#### Handling DBUS Commands
+
+When an event occurs on the dbus file descriptor the dbus request is read from
+the dbus interface and processed.
+
+The command is validated and then the appropriate handler called. The response
+is then written back to the dbus interface to indicate the outcome of the
+command.
+
+#### Handling Signals
+
+The daemon blocks SIGINTs, SIGTERMs, and SIGHUPs and instead polls for them on
+a signal file descriptor.
+
+When an event occurs on this file descriptor the signal received is determined
+and processed as follows:
+
+```
+SIGINT - Terminate the daemon
+SIGTERM - Terminate the daemon
+SIGHUP - Clear the window cache and point the lpc bus mapping back to
+ flash
+```
+
+### Termination
+
+The daemon can be terminated for multiple reasons; invalid command line, unable
+to initialise, received SIGINT or SIGTERM, or because it received the kill dbus
+command.
+
+On termination the daemon clears the window cache and notifys the host that the
+active window has been closed, points the lpc bus mapping back to flash, clears
+the BMC_READY BMC event bit and frees all of its allocated resources.
diff --git a/README.md b/README.md
index 1a29648..4293bbd 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-Copyright 2016 IBM
+Copyright 2017 IBM
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -12,642 +12,14 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-## Intro
+## MBOX
-This document describes a protocol for host to BMC communication via the
-mailbox registers present on the Aspeed 2400 and 2500 chips.
-This protocol is specifically designed to allow a host to request and manage
-access to the flash with the specifics of how the host is required to control
-this described below.
+This repo contains the protocol definition for the host to BMC mailbox
+communication specification which can be found in
+Documentation/mbox_procotol.md.
-## Version
+There is also a reference implementation of a BMC mailbox daemon, the details
+of which can be found in Documentation/mboxd.md.
-Both version 1 and version 2 of the protocol are described below with version 2
-specificities represented with V2 in brackets - (V2).
-
-## Problem Overview
-
-"mbox" is the name we use to represent a protocol we have established between
-the host and the BMC via the Aspeed mailbox registers. This protocol is used
-for the host to control the flash.
-
-Prior to the mbox protocol, the host uses a backdoor into the BMC address space
-(the iLPC-to-AHB bridge) to directly manipulate the BMCs own flash controller.
-
-This is not sustainable for a number of reasons. The main ones are:
-
-1. Every piece of the host software stack that needs flash access (HostBoot,
- OCC, OPAL, ...) has to have a complete driver for the flash controller,
- update it on each BMC generation, have all the quirks for all the flash
- chips supported etc... We have 3 copies on the host already in addition to
- the one in the BMC itself.
-
-2. There are serious issues of access conflicts to that controller between the
- host and the BMC.
-
-3. It's very hard to support "BMC reboots" when doing that
-
-4. It's slow
-
-5. Last but probably most important, having that backdoor open is a security
- risk. It means the host can access any address on the BMC internal bus and
- implant malware in the BMC itself. So if the host is a "bare metal" shared
- system in some kind of data center, not only the host flash needs to be
- reflashed when switching from one customer to another, but the entire BMC
- flash too as nothing can be trusted. So we want to disable it.
-
-To address all these, we have implemented a new mechanism that we call mbox.
-
-When using this mechanism, the BMC is solely responsible for directly accessing
-the flash controller. All flash erase and write operations are performed by the
-BMC and the BMC only. (We can allow direct reads from flash under some
-circumstances but we tend to prefer going via memory).
-
-The host uses the mailbox registers to send "commands" to the BMC, which
-responds via the same mechanism. Those commands allow the host to control a
-"window" (which is the LPC -> AHB FW space mapping) that is either a read
-window or a write window onto the flash.
-
-When set for writing, the BMC makes the window point to a chunk of RAM instead.
-When the host "commits" a change (via MBOX), then the BMC can perform the
-actual flashing from the data in the RAM window.
-
-The idea is to have the LPC FW space be routed to an active "window". That
-window can be a read or a write window. The commands allow to control which
-window and which offset into the flash it maps.
-
-* A read window can be a direct window to the flash controller space (ie.
- 0x3000\_0000) or it can be a window to a RAM image of a flash. It doesn't have
- to be the full size of the flash per protocol (commands can be use to "slide"
- it to various parts of the flash) but if its set to map the actual flash
- controller space at 0x3000\_0000, it's probably simpler to make it the full
- flash. The host makes no assumption, it's your choice what to provide. The
- simplest implementation is to just route to the flash read/only.
-
-* A write window has to be a chunk of BMC memory. The minimum size is not
- defined in the spec, but it should be at least one block (4k for now but it
- should support larger block sizes in the future). When the BMC receive the
- command to map the write window at a given offset of the flash, the BMC should
- copy that portion of the flash into a reserved memory buffer, and modify the
- LPC mapping to point to that buffer.
-
-The host can then write to that window directly (updating the BMC memory) and
-send a command to "commit" those updates to flash.
-
-Finally there is a `RESET_STATE`. It's the state in which the bootloader in the
-SEEPROM of the POWER9 chip will find what it needs to load HostBoot. The
-details are still being ironed out: either mapping the full flash read only or
-reset to a "window" that is either at the bottom or top of the flash. The
-current implementation resets to point to the full flash.
-
-## Where is the code?
-
-The mbox userspace is available [on GitHub](https://github.com/openbmc/mboxbridge)
-This is Apache licensed but we are keen to see any enhancements you may have.
-
-The kernel driver is still in the process of being upstreamed but can be found
-in the OpenBMC Linux kernel staging tree:
-
-https://github.com/openbmc/linux/commit/85770a7d1caa6a1fa1a291c33dfe46e05755a2ef
-
-## Building
-
-The autotools of this requires the autoconf-archive package for your
-system
-
-## The Hardware
-
-The Aspeed mailbox consists of 16 (8 bit) data registers see Layout for their
-use. Mailbox interrupt enabling, masking and triggering is done using a pair
-of control registers, one accessible by the host the other by the BMC.
-Interrupts can also be raised per write to each data register, for BMC and
-host. Write tiggered interrupts are configured using two 8 bit registers where
-each bit represents a data register and if an interrupt should fire on write.
-Two 8 bit registers are present to act as a mask for write triggered
-interrupts.
-
-### Layout
-
-```
-Byte 0: COMMAND
-Byte 1: Sequence
-Byte 2-12: Arguments
-Byte 13: Response code
-Byte 14: Host controlled status reg
-Byte 15: BMC controlled status reg
-```
-
-## Low Level Protocol Flow
-
-What we essentially have is a set of registers which either the host or BMC can
-write to in order to communicate to the other which will respond in some way.
-There are 3 basic types of communication.
-
-1. Commands sent from the Host to the BMC
-2. Responses sent from the BMC to the Host in response to commands
-3. Asyncronous events raised by the BMC
-
-### General Use
-
-Messages usually originate from the host to the BMC. There are special
-cases for a back channel for the BMC to pass new information to the
-host which will be discussed later.
-
-To initiate a request the host must set a command code (see
-Commands) into mailbox data register 0. It is also the hosts
-responsibility to generate a unique sequence number into mailbox
-register 1. After this any command specific data should be written
-(see Layout). The host must then generate an interrupt to the BMC by
-using bit 0 of its control register and wait for an interrupt on the
-response register. Generating an interrupt automatically sets bit 7 of the
-corresponding control register. This bit can be used to poll for
-messages.
-
-On receiving an interrupt (or polling on bit 7 of its Control
-Register) the BMC should read the message from the general registers
-of the mailbox and perform the necessary action before responding. On
-responding the BMC must ensure that the sequence number is the same as
-the one in the request from the host. The BMC must also ensure that
-mailbox data regsiter 13 is a valid response code (see Responses). The
-BMC should then use its control register to generate an interrupt for
-the host to notify it of a response.
-
-### Asynchronous BMC to Host Events
-
-BMC to host communication is also possible for notification of events
-from the BMC. This requires that the host have interrupts enabled on
-mailbox data register 15 (or otherwise poll on bit 7 of mailbox status
-register 1). On receiving such a notification the host should read
-mailbox data register 15 to determine the event code which was set by the
-BMC (see BMC Event notifications in Commands for detail). Events which are
-defined as being able to be acknowledged by the host must be with a
-BMC_EVENT_ACK command.
-
-## High Level Protocol Flow
-
-When a host wants to communicate with the BMC via the mbox protocol the first
-thing it should do it call MBOX_GET_INFO in order to establish the protocol
-version which each understands. Before this the only other commands which are
-allowed are RESET_STATE and BMC_EVENT_ACK.
-
-After this the host can open and close windows with the CREATE_READ_WINDOW,
-CREATE_WRITE_WINDOW and CLOSE_WINDOW commands. Creating a window is how the
-host requests access to a section of flash. It is worth noting that the host
-can only ever have one window that it is accessing at a time - hence forth
-referred to as the active window.
-
-When the active window is a write window the host can perform MARK_WRITE_DIRTY,
-MARK_WRITE_ERASED and WRITE_FLUSH commands to identify changed blocks and
-control when the changed blocks are written to flash.
-
-Independently, and at any point not during an existing mbox command
-transaction, the BMC may raise raise asynchronous events with the host to
-communicate a change in state.
-
-### Version Negotiation
-
-Given that a majority of command and response arguments are specified as a
-multiple of block size it is necessary for the host and BMC to agree on a
-protocol version as this determines the block size. In V1 it is hard coded at
-4K and in V2 the BMC chooses and specifies this to the host as a response
-argument to MBOX_GET_INFO. Thus the host must always call MBOX_GET_INFO before
-any other command which specifies an argument in block size.
-
-The host must tell the BMC the highest protocol level which it supports. The
-BMC will then respond with a protocol level. If the host doesn't understand
-the protocol level specified by the BMC then it must not continue to
-communicate with the BMC. Otherwise the protocol level specified by the
-BMC is taken to be the protocol level used for further communication and can
-only be changed by another call to MBOX_GET_INFO. The BMC should use the
-request from the host to influence its protocol version choice.
-
-### Window Management
-
-In order to access flash contents the host must request a window be opened at
-the flash offset it would like to access. The host may give a hint as to how
-much data it would like to access or otherwise set this argument to zero. The
-BMC must respond with the lpc bus address to access this window and the
-window size. The host must not access past the end of the active window.
-
-There is only ever one active window which is the window created by the most
-recent CREATE_READ_WINDOW or CREATE_WRITE_WINDOW call which succeeded. Even
-though there are two types of windows there can still only be one active window
-irrespective of type. A host must not write to a read window. A host may read
-from a write window and the BMC must guarantee that the window reflects what
-the host has written there.
-
-A window can be closed by calling CLOSE_WINDOW in which case there is no active
-window and the host must not access the LPC window after it has been closed.
-If the host closes an active write window then the BMC must perform an
-implicit flush. If the host tries to open a new window with an already active
-window then the active window is closed (and implicitly flushed if it was a
-write window). If the new window is successfully opened then it is the new
-active window, if the command fails then there is no active window and the
-previous active window must no longer be accessed.
-
-The host must not access an lpc address other than that which is contained by
-the active window. The host must not use write management functions (see below)
-if the active window is a read window or if there is no active window.
-
-### Write Management
-
-The BMC has no method for intercepting writes that occur over the LPC bus. Thus
-the host must explicitly notify the BMC of where and when a write has
-occured. The host must use the MARK_WRITE_DIRTY command to tell the BMC where
-within the write window it has modified. The host may also use the
-MARK_WRITE_ERASED command to erase large parts of the active window without the
-need to write 0xFF. The BMC must ensure that if the host
-reads from an area it has erased that the read values are 0xFF. Any part of the
-active window marked dirty/erased is only marked for the lifetime of the current
-active write window and does not persist if the active window is closed either
-implicitly or explicitly by the host or the BMC. The BMC may at any time
-or must on a call to WRITE_FLUSH flush the changes which it has been notified
-of back to the flash, at which point the dirty or erased marking is cleared
-for the active window. The host must not assume that any changes have been
-written to flash unless an explicit flush call was successful, a close of an
-active write window was successful or a create window command with an active
-write window was successful - otherwise consistency between the flash and memory
-contents cannot be guaranteed.
-
-The host is not required to perform an erase before a write command and the
-BMC must ensure that a write performs as expected - that is if an erase is
-required before a write then the BMC must perform this itself.
-
-### BMC Events
-
-The BMC can raise events with the host asynchronously to communicate to the
-host a change in state which it should take notice of. The host must (if
-possible for the given event) acknowledge it to inform the BMC it has been
-received.
-
-If the BMC raises a BMC Reboot event then the host must renegotiate the
-protocol version so that both the BMC and the host agree on the block size.
-A BMC Reboot event implies a BMC Windows Reset event.
-If the BMC raises a BMC Windows Reset event then the host must
-assume that there is no longer an active window - that is if there was an
-active window it has been closed by the BMC and if it was a write window
-then the host must not assume that it was flushed unless a previous explicit
-flush call was successful.
-
-The BMC may at some points require access to the flash and the BMC daemon must
-set the BMC Flash Control Lost event when the BMC is accessing the flash behind
-the BMC daemons back. When this event is set the host must assume that the
-contents of the active window could be inconsistent with the contents of flash.
-
-## Protocol Definition
-
-### Commands
-
-```
-RESET_STATE 0x01
-GET_MBOX_INFO 0x02
-GET_FLASH_INFO 0x03
-CREATE_READ_WINDOW 0x04
-CLOSE_WINDOW 0x05
-CREATE_WRITE_WINDOW 0x06
-MARK_WRITE_DIRTY 0x07
-WRITE_FLUSH 0x08
-BMC_EVENT_ACK 0x09
-MARK_WRITE_ERASED 0x0a (V2)
-```
-
-### Sequence
-
-The host must ensure a unique sequence number at the start of a
-command/response pair. The BMC must ensure the responses to
-a particular message contain the same sequence number that was in the
-command request from the host.
-
-### Responses
-
-```
-SUCCESS 1
-PARAM_ERROR 2
-WRITE_ERROR 3
-SYSTEM_ERROR 4
-TIMEOUT 5
-BUSY 6 (V2)
-WINDOW_ERROR 7 (V2)
-```
-
-#### Description:
-
-SUCCESS - Command completed successfully
-
-PARAM_ERROR - Error with parameters supplied or command invalid
-
-WRITE_ERROR - Error writing to the backing file system
-
-SYSTEM_ERROR - Error in BMC performing system action
-
-TIMEOUT - Timeout in performing action
-
-BUSY - Daemon in suspended state (currently unable to access flash)
- - Retry again later
-
-WINDOW_ERROR - Command not valid for active window or no active window
- - Try opening an appropriate window and retrying the command
-
-### Information
-- All multibyte messages are LSB first (little endian)
-- All responses must have a valid return code in byte 13
-
-
-### Commands in detail
-
-Note in V1 block size is hard coded to 4K, in V2 it is variable and must be
-queried with GET_MBOX_INFO.
-Sizes and addresses are specified in either bytes - (bytes)
- or blocks - (blocks)
-Sizes and addresses specified in blocks must be converted to bytes by
-multiplying by the block size.
-```
-Command:
- RESET_STATE
- Implemented in Versions:
- V1, V2
- Arguments:
- -
- Response:
- -
- Notes:
- This command is designed to inform the BMC that it should put
- host LPC mapping back in a state where the SBE will be able to
- use it. Currently this means pointing back to BMC flash
- pre mailbox protocol. Final behavour is still TBD.
-
-Command:
- GET_MBOX_INFO
- Implemented in Versions:
- V1, V2
- Arguments:
- V1:
- Args 0: API version
-
- V2:
- Args 0: API version
-
- Response:
- V1:
- Args 0: API version
- Args 1-2: default read window size (blocks)
- Args 3-4: default write window size (blocks)
-
- V2:
- Args 0: API version
- Args 1-2: reserved
- Args 3-4: reserved
- Args 5: Block size as power of two (encoded as a shift)
-
-Command:
- GET_FLASH_INFO
- Implemented in Versions:
- V1, V2
- Arguments:
- -
- Response:
- V1:
- Args 0-3: Flash size (bytes)
- Args 4-7: Erase granule (bytes)
-
- V2:
- Args 0-1: Flash size (blocks)
- Args 2-3: Erase granule (blocks)
-
-Command:
- CREATE_{READ/WRITE}_WINDOW
- Implemented in Versions:
- V1, V2
- Arguments:
- V1:
- Args 0-1: Window location as offset into flash (blocks)
-
- V2:
- Args 0-1: Window location as offset into flash (blocks)
- Args 2-3: Requested window size (blocks)
-
- Response:
- V1:
- Args 0-1: LPC bus address of window (blocks)
-
- V2:
- Args 0-1: LPC bus address of window (blocks)
- Args 2-3: Actual window size (blocks)
- Args 4-5: Actual window location as offset into flash (blocks)
- Notes:
- Window location is always given as an offset into flash as
- taken from the start of flash - that is it is an absolute
- address.
-
- LPC bus address is always given from the start of the LPC
- address space - that is it is an absolute address.
-
- The requested window size is only a hint. The response
- indicates the actual size of the window. The BMC may
- want to use the requested size to pre-load the remainder
- of the request. The host must not access past the end of the
- active window.
-
- The actual window location indicates the absolute flash offset
- that the window actually maps and is not required to be equal
- to the flash offset requested by the host, but however must be
- less than or equal to it. Thus the first block of the window at
- the lpc address in the response will map the first block at the
- actual flash offset also contained in the response. It is the
- responsibility of the host to use this information to access
- any offset which is required.
-
- The requested window size may be zero. In this case the
- BMC is free to create any sized window but it must contain
- atleast the first block of data requested by the host. A large
- window is of course preferred and should correspond to
- the default size returned in the GET_MBOX_INFO command.
-
- If this command returns successfully then the window which the
- host requested is the active window. If it fails then there is
- no active window.
-
-Command:
- CLOSE_WINDOW
- Implemented in Versions:
- V1, V2
- Arguments:
- V1:
- -
-
- V2:
- Args 0: Flags
- Response:
- -
- Notes:
- Closes the active window. Any further access to the LPC bus
- address specified to address the previously active window will
- have undefined effects. If the active window is a
- write window then the BMC must perform an implicit flush.
-
- The Flags argument allows the host to provide some
- hints to the BMC. Defined Values:
- 0x01 - Short Lifetime:
- The window is unlikely to be accessed
- anytime again in the near future. The effect of
- this will depend on BMC implementation. In
- the event that the BMC performs some caching
- the BMC daemon could mark data contained in a
- window closed with this flag as first to be
- evicted from the cache.
-
-Command:
- MARK_WRITE_DIRTY
- Implemented in Versions:
- V1, V2
- Arguments:
- V1:
- Args 0-1: Flash offset to mark from base of flash (blocks)
- Args 2-5: Number to mark dirty at offset (bytes)
-
- V2:
- Args 0-1: Window offset to mark (blocks)
- Args 2-3: Number to mark dirty at offset (blocks)
-
- Response:
- -
- Notes:
- The BMC has no method for intercepting writes that
- occur over the LPC bus. The host must explicitly notify
- the daemon of where and when a write has occured so it
- can be flushed to backing storage.
-
- Offsets are given as an absolute (either into flash (V1) or the
- active window (V2)) and a zero offset refers to the first
- block. If the offset + number exceeds the size of the active
- window then the command must not succeed.
-
-Command
- WRITE_FLUSH
- Implemented in Versions:
- V1, V2
- Arguments:
- V1:
- Args 0-1: Flash offset to mark from base of flash (blocks)
- Args 2-5: Number to mark dirty at offset (bytes)
-
- V2:
- -
-
- Response:
- -
- Notes:
- Flushes any dirty/erased blocks in the active window to
- the backing storage.
-
- In V1 this can also be used to mark parts of the flash
- dirty and flush in a single command. In V2 the explicit
- mark dirty command must be used before a call to flush
- since there are no longer any arguments. If the offset + number
- exceeds the size of the active window then the command must not
- succeed.
-
-
-Command:
- BMC_EVENT_ACK
- Implemented in Versions:
- V1, V2
- Arguments:
- Args 0: Bits in the BMC status byte (mailbox data
- register 15) to ack
- Response:
- *clears the bits in mailbox data register 15*
- Notes:
- The host should use this command to acknowledge BMC events
- supplied in mailbox register 15.
-
-Command:
- MARK_WRITE_ERASED
- Implemented in Versions:
- V2
- Arguments:
- V2:
- Args 0-1: Window offset to erase (blocks)
- Args 2-3: Number to erase at offset (blocks)
- Response:
- -
- Notes:
- This command allows the host to erase a large area
- without the need to individually write 0xFF
- repetitively.
-
- Offset is the offset within the active window to start erasing
- from (zero refers to the first block of the active window) and
- number is the number of blocks of the active window to erase
- starting at offset. If the offset + number exceeds the size of
- the active window then the command must not succeed.
-```
-
-### BMC Events in Detail:
-
-If the BMC needs to tell the host something then it simply
-writes to Byte 15. The host should have interrupts enabled
-on that register, or otherwise be polling it.
-
-#### Bit Definitions:
-
-Events which should be ACKed:
-```
-0x01: BMC Reboot
-0x02: BMC Windows Reset (V2)
-```
-
-Events which cannot be ACKed (BMC will clear when no longer
-applicable):
-```
-0x40: BMC Flash Control Lost (V2)
-0x80: BMC MBOX Daemon Ready (V2)
-```
-
-#### Event Description:
-
-Events which must be ACKed:
-The host should acknowledge these events with BMC_EVENT_ACK to
-let the BMC know that they have been received and understood.
-```
-0x01 - BMC Reboot:
- Used to inform the host that a BMC reboot has occured.
- The host must perform protocol verison negotiation again and
- must assume it has no active window. The host must not assume
- that any commands which didn't respond as such succeeded.
-0x02 - BMC Windows Reset: (V2)
- The host must assume that its active window has been closed and
- that it no longer has an active window. The host is not
- required to perform protocol version negotiation again. The
- host must not assume that any commands which didn't respond as such
- succeeded.
-```
-
-Events which cannot be ACKed:
-These events cannot be acknowledged by the host and a call to
-BMC_EVENT_ACK with these bits set will have no effect. The BMC
-will clear these bits when they are no longer applicable.
-```
-0x40 - BMC Flash Control Lost: (V2)
- The BMC daemon has been suspended and thus no longer
- controls access to the flash (most likely because some
- other process on the BMC required direct access to the
- flash and has suspended the BMC daemon to preclude
- concurrent access).
- The BMC daemon must clear this bit itself when it regains
- control of the flash (the host isn't able to clear it
- through an acknowledge command).
- The host must not assume that the contents of the active window
- correctly reflect the contents of flash while this bit is set.
-0x80 - BMC MBOX Daemon Ready: (V2)
- Used to inform the host that the BMC daemon is ready to
- accept command requests. The host isn't able to clear
- this bit through an acknowledge command, the BMC daemon must
- clear it before it terminates (assuming it didn't
- terminate unexpectedly).
- The host should not expect a response while this bit is
- not set.
- Note that this bit being set is not a guarantee that the BMC daemon
- will respond as it or the BMC may have crashed without clearing
- it.
-```
+Finally there is also an implementation of a mailbox daemon control program, the
+details of which can be found in Documentation/mboxctl.md.
OpenPOWER on IntegriCloud