293 lines
8.6 KiB
ReStructuredText
293 lines
8.6 KiB
ReStructuredText
.. _opal-dumps:
|
|
|
|
==========
|
|
OPAL Dumps
|
|
==========
|
|
|
|
.. code-block:: c
|
|
|
|
#define OPAL_REGISTER_DUMP_REGION 101
|
|
#define OPAL_UNREGISTER_DUMP_REGION 102
|
|
|
|
int64_t opal_register_dump_region(uint32_t id, uint64_t addr, uint64_t size);
|
|
int64_t opal_unregister_dump_region(uint32_t id);
|
|
|
|
In the event of crashes, some service processors and firmware support gathering
|
|
a limited amount of memory from a limited number of memory regions to save into
|
|
a debug dump that can be useful for firmware and operating system developers
|
|
in diagnosing problems. Typically, firmware and kernel log buffers are useful to
|
|
save in a dump.
|
|
|
|
An OS can register a memory region with :ref:`OPAL_REGISTER_DUMP_REGION` and should,
|
|
when the region is no longer valid (e.g. when kexec()ing), it should unregister the
|
|
region with :ref:`OPAL_UNREGISTER_DUMP_REGION`.
|
|
|
|
An OS will be made aware of a dump being available through :ref:`OPAL_EVENT_DUMP_AVAIL`
|
|
being set from a :ref:`OPAL_POLL_EVENTS` call.
|
|
|
|
Retreiving dumps from a service processor can also be performed using the
|
|
:ref:`OPAL_DUMP_INFO`, :ref:`OPAL_DUMP_INFO2`, :ref:`OPAL_DUMP_READ`,
|
|
and :ref:`OPAL_DUMP_RESEND` calls. Dumps are identified by a ``uint32_t``, and
|
|
once a dump is acknowledged, this ID can be re-used.
|
|
|
|
Dumps can also be initiated by OPAL through the :ref:`OPAL_DUMP_INIT` call, which
|
|
will request that the service processor performs the requested type of dump.
|
|
|
|
A call to :ref:`OPAL_DUMP_ACK` indicates to the service processor that we have
|
|
retreived/acknowledged the dump and the service processor can free up the storage
|
|
used by it.
|
|
|
|
.. code-block:: c
|
|
|
|
#define OPAL_DUMP_INIT 81
|
|
#define OPAL_DUMP_INFO 82
|
|
#define OPAL_DUMP_READ 83
|
|
#define OPAL_DUMP_ACK 84
|
|
#define OPAL_DUMP_RESEND 91
|
|
#define OPAL_DUMP_INFO2 94
|
|
|
|
int64_t opal_dump_init(uint8_t dump_type);
|
|
int64_t opal_dump_info(uint32_t *dump_id, uint32_t *dump_size);
|
|
int64_t opal_dump_read(uint32_t dump_id, struct opal_sg_list *list);
|
|
int64_t opal_dump_ack(uint32_t dump_id);
|
|
int64_t opal_dump_resend_notification(void);
|
|
int64_t opal_dump_info2(uint32_t *dump_id, uint32_t *dump_size, uint32_t *dump_type);
|
|
|
|
|
|
.. _OPAL_REGISTER_DUMP_REGION:
|
|
|
|
OPAL_REGISTER_DUMP_REGION
|
|
=========================
|
|
|
|
.. code-block:: c
|
|
|
|
#define OPAL_REGISTER_DUMP_REGION 101
|
|
|
|
int64_t opal_register_dump_region(uint32_t id, uint64_t addr, uint64_t size);
|
|
|
|
This call is used to register regions of memory for a service processor to capture
|
|
when the host crashes.
|
|
|
|
e.g. if an assert is hit in OPAL, a service processor will copy the region of
|
|
memory into some kind of crash dump for further analysis.
|
|
|
|
This is an OPTIONAL feature that may be unsupported, the host OS should use an
|
|
:ref:`OPAL_CHECK_TOKEN` call to find out if :ref:`OPAL_REGISTER_DUMP_REGION` is supported.
|
|
|
|
:ref:`OPAL_REGISTER_DUMP_REGION` accepts 3 parameters:
|
|
|
|
- region ID
|
|
- address
|
|
- length
|
|
|
|
There is a range of region IDs that can be used by the host OS. A host OS should
|
|
start from OPAL_DUMP_REGION_HOST_END and work down if it wants to add a not well
|
|
defined region to dump. Currently the only well defined region is for the host
|
|
OS log buffer (e.g. dmesg on linux). ::
|
|
|
|
/*
|
|
* Dump region ID range usable by the OS
|
|
*/
|
|
#define OPAL_DUMP_REGION_HOST_START 0x80
|
|
#define OPAL_DUMP_REGION_LOG_BUF 0x80
|
|
#define OPAL_DUMP_REGION_HOST_END 0xFF
|
|
|
|
:ref:`OPAL_REGISTER_DUMP_REGION` will return :ref:`OPAL_UNSUPPORTED` if the call is present but
|
|
the system doesn't support registering regions to be dumped.
|
|
|
|
In the event of being passed an invalid region ID, :ref:`OPAL_REGISTER_DUMP_REGION` will
|
|
return :ref:`OPAL_PARAMETER`.
|
|
|
|
Systems likely have a limit as to how many regions they can support being dumped. If
|
|
this limit is reached, :ref:`OPAL_REGISTER_DUMP_REGION` will return :ref:`OPAL_INTERNAL_ERROR`.
|
|
|
|
BUGS
|
|
----
|
|
Some skiboot versions incorrectly returned :ref:`OPAL_SUCCESS` in the case of
|
|
:ref:`OPAL_REGISTER_DUMP_REGION` being supported on a platform (so the call was present)
|
|
but the call being unsupported for some reason (e.g. on an IBM POWER7 machine).
|
|
|
|
See also: :ref:`OPAL_UNREGISTER_DUMP_REGION`
|
|
|
|
.. _OPAL_UNREGISTER_DUMP_REGION:
|
|
|
|
OPAL_UNREGISTER_DUMP_REGION
|
|
===========================
|
|
|
|
.. code-block:: c
|
|
|
|
#define OPAL_UNREGISTER_DUMP_REGION 102
|
|
|
|
int64_t opal_unregister_dump_region(uint32_t id);
|
|
|
|
While :ref:`OPAL_REGISTER_DUMP_REGION` registers a region, :ref:`OPAL_UNREGISTER_DUMP_REGION`
|
|
will unregister a region by region ID.
|
|
|
|
:ref:`OPAL_UNREGISTER_DUMP_REGION` takes one argument: the region ID.
|
|
|
|
A host OS should check :ref:`OPAL_UNREGISTER_DUMP_REGION` is supported through a call to
|
|
:ref:`OPAL_CHECK_TOKEN`.
|
|
|
|
If :ref:`OPAL_UNREGISTER_DUMP_REGION` is called on a system where the call is present but
|
|
unsupported, it will return :ref:`OPAL_UNSUPPORTED`.
|
|
|
|
BUGS
|
|
----
|
|
Some skiboot versions incorrectly returned :ref:`OPAL_SUCCESS` in the case of
|
|
:ref:`OPAL_UNREGISTER_DUMP_REGION` being supported on a platform (so the call was present)
|
|
but the call being unsupported for some reason (e.g. on an IBM POWER7 machine).
|
|
|
|
.. _OPAL_DUMP_INIT:
|
|
|
|
OPAL_DUMP_INIT
|
|
==============
|
|
|
|
.. code-block:: c
|
|
|
|
#define OPAL_DUMP_INIT 81
|
|
|
|
#define DUMP_TYPE_FSP 0x01
|
|
#define DUMP_TYPE_SYS 0x02
|
|
#define DUMP_TYPE_SMA 0x03
|
|
|
|
int64_t opal_dump_init(uint8_t dump_type);
|
|
|
|
Ask the service processor to initiate a dump. Currently, only ``DUMP_TYPE_FSP``
|
|
is supported.
|
|
|
|
Currently only implemented on FSP based systems. Use :ref:`OPAL_CHECK_TOKEN` to
|
|
ensure the call is valid.
|
|
|
|
Returns
|
|
-------
|
|
:ref:`OPAL_SUCCESS`
|
|
Dump initiated
|
|
:ref:`OPAL_PARAMETER`
|
|
Unsupported dump type. Currently only ``DUMP_TYPE_FSP`` is supported and
|
|
only on FSP based platforms.
|
|
:ref:`OPAL_INTERNAL_ERROR`
|
|
Failed to ask service processor to initiated dump.
|
|
|
|
.. _OPAL_DUMP_INFO:
|
|
|
|
OPAL_DUMP_INFO
|
|
==============
|
|
|
|
.. code-block:: c
|
|
|
|
#define OPAL_DUMP_INFO 82
|
|
|
|
int64_t opal_dump_info(uint32_t *dump_id, uint32_t *dump_size);
|
|
|
|
Obsolete, use :ref:`OPAL_DUMP_INFO2` instead.
|
|
|
|
No upstream Linux code ever used :ref:`OPAL_DUMP_INFO`, although early PowerKVM
|
|
trees did. :ref:`OPAL_DUMP_INFO` is implemented as a wrapper around
|
|
:ref:`OPAL_DUMP_INFO2`.
|
|
|
|
.. _OPAL_DUMP_READ:
|
|
|
|
OPAL_DUMP_READ
|
|
==============
|
|
|
|
.. code-block:: c
|
|
|
|
#define OPAL_DUMP_READ 83
|
|
|
|
int64_t opal_dump_read(uint32_t dump_id, struct opal_sg_list *list);
|
|
|
|
Read ``dump_id`` dump from the service processor into memory.
|
|
|
|
|
|
Returns
|
|
-------
|
|
:ref:`OPAL_INTERNAL_ERROR`
|
|
Invalid Dump ID or internal error.
|
|
:ref:`OPAL_PARAMETER`
|
|
Insuffcient space to store dump.
|
|
:ref:`OPAL_BUSY_EVENT`
|
|
Fetching dump, call :ref:`OPAL_POLL_EVENTS` to crank the state machine,
|
|
and call :ref:`OPAL_DUMP_READ` again until neither :ref:`OPAL_BUSY_EVENT`
|
|
nor :ref:`OPAL_BUSY` are returned.
|
|
:ref:`OPAL_PARTIAL`
|
|
Only part of the dump was read.
|
|
:ref:`OPAL_SUCCESS`
|
|
Dump successfully read.
|
|
|
|
.. _OPAL_DUMP_ACK:
|
|
|
|
OPAL_DUMP_ACK
|
|
=============
|
|
|
|
.. code-block:: c
|
|
|
|
#define OPAL_DUMP_ACK 84
|
|
|
|
int64_t opal_dump_ack(uint32_t dump_id);
|
|
|
|
Acknowledge the dump to the service processor. This means the service processor
|
|
can re-claim the storage space used by the dump. Effectively, this is an
|
|
``unlink`` style operation.
|
|
|
|
Returns
|
|
-------
|
|
:ref:`OPAL_SUCCESS`
|
|
Dump successfully acknowledged.
|
|
:ref:`OPAL_INTERNAL_ERROR`
|
|
Failed to acknowledge the dump, e.g. could not communicate with service
|
|
processor.
|
|
:ref:`OPAL_PARAMETER`
|
|
Invalid dump ID.
|
|
|
|
|
|
.. _OPAL_DUMP_RESEND:
|
|
|
|
OPAL_DUMP_RESEND
|
|
================
|
|
|
|
.. code-block:: c
|
|
|
|
#define OPAL_DUMP_RESEND 91
|
|
|
|
int64_t opal_dump_resend_notification(void);
|
|
|
|
Resend notification to the OS if there is a dump available. This will
|
|
cause OPAL to check if a dump is available and set the
|
|
:ref:`OPAL_EVENT_DUMP_AVAIL` bit in the next :ref:`OPAL_POLL_EVENTS` call.
|
|
|
|
Returns
|
|
-------
|
|
:ref:`OPAL_SUCCESS`
|
|
Successfully reset :ref:`OPAL_EVENT_DUMP_AVAIL` bit.
|
|
|
|
In future, this may return other standard OPAL error codes.
|
|
|
|
.. _OPAL_DUMP_INFO2:
|
|
|
|
OPAL_DUMP_INFO2
|
|
===============
|
|
|
|
.. code-block:: c
|
|
|
|
#define OPAL_DUMP_INFO2 94
|
|
|
|
#define DUMP_TYPE_FSP 0x01
|
|
#define DUMP_TYPE_SYS 0x02
|
|
#define DUMP_TYPE_SMA 0x03
|
|
|
|
int64_t opal_dump_info2(uint32_t *dump_id, uint32_t *dump_size, uint32_t *dump_type);
|
|
|
|
Retreives information about a dump, notably it's ``dump_id``, size, and type.
|
|
Call this after the :ref:`OPAL_EVENT_DUMP_AVAIL` bit is set from a
|
|
:ref:`OPAL_POLL_EVENTS` call. It will retreive the information on the *next*
|
|
dump to be retreived and/or ACKed, even though there may be more than one dump
|
|
available for retreiving.
|
|
|
|
This call replaces :ref:`OPAL_DUMP_INFO`.
|
|
|
|
Returns
|
|
-------
|
|
:ref:`OPAL_SUCCESS`
|
|
Information retreived.
|
|
:ref:`OPAL_INTERNAL_ERROR`
|
|
No dump available or internal error.
|