summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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