Inside the IBM POWER8 chip there’s another processor! That’s right folks, you get another CPU for no extra cost (It’s a lot funnier if you say these previous two sentences as if you were presenting an informercial for a special TV offer).
It is, however, not what you’d consider a general purpose processor. It is, in fact, a PowerPC 405 – so your POWER8 processor also has another PowerPC chip in it. What’s the purpose of this chip? It’s named the On Chip Controller and it has the job of helping make the main processor (the POWER8) work.
It has two jobs:
- Monitor temperature and keep the system thermally safe
- Monitor power usage and keep the system power safe
It runs a hard Real Time OS which has just been released up on github.com/open-power/occ
There’s more complete documentation on OCC here.
It’s fairly exciting to see more of the software that runs on every POWER8 system make it out into the world.
RT @stewartsmith: More OpenPower Firmware code released: OCC: Inside the IBM POWER8 chip there’s another processor! That’s right f… http:…
Intetersing! I’ve not heard about that.
The documentation says “There is one OCC per POWER processor chip.” Does that mean that for scale-out systems we have two OCCs per DCM?
From https://github.com/open-power/skiboot/blob/master/hw/occ.c
static bool wait_for_all_occ_init(void)
{
…
for_each_chip(chip) {
…
while((occ_data->valid != 1) && tries–) {
time_wait_ms(100);
}
…
}
prlog(PR_NOTICE, “OCC: All Chip Rdy after %lld ms\n”,
Hi Alexander and Stewart,
AFAICT from the OCC init/reset functions in Hostboot, and following the functions to write to the SCOM registers (per Chip), there’s one OCC per chip.
This is contrary to this video, which shows one OCC per ‘P8 Module’ (which, as in DCM – dual chip module – has 2 chips), but this is not a very tech-details video.
http://youtu.be/Z-4Q0_l9nt8?t=13s
The spec (open-power/docs) doesn’t mention per-core/per-chip.. so I think the best official answer would be from its author, Martha Broyles. Or someone who is more familiar w/ the Hostboot source code and can be certain of my hyphotesis above.
In summary:
both
//Start the OCC on primary chip of DCM
and
// Start the OCC on slave chip of DCM
call
p8_occ_control() for a specific chip target
which calls
putScom -> fapiPutScom
which
* @brief Writes a SCOM register on a Chip
Trace/details:
open-power/hostboot/src/usr/hwpf/hwp/occ/occ_common.C
* @brief Start OCC for specified DCM pair of processors.
* If 2nd input is NULL, OCC will be setup on just
* one target.
*
* @param[in] i_target0: target of first processor in DCM pair
* @param[in] i_target1: target of second processor in DCM pair
* @param[out] o_failedTarget failed target in case of an error
*
* @return errlHndl_t Error log of startOCC failed
*/
errlHndl_t startOCC (Target* i_target0,
Target* i_target1,
Target *& o_failedTarget)
{
…
//==============================
//Start the OCC on primary chip of DCM
//==============================
FAPI_INVOKE_HWP( l_errl,
p8_occ_control,
l_fapiTarg0,
PPC405_RESET_OFF,
PPC405_BOOT_MEM );
…
//==============================
// Start the OCC on slave chip of DCM
//==============================
if ( l_fapiTarg1.getType() != fapi::TARGET_TYPE_NONE )
{
FAPI_INVOKE_HWP( l_errl,
p8_occ_control,
l_fapiTarg1,
PPC405_RESET_OFF,
PPC405_BOOT_MEM );
…
open-power/hostboot/src/usr/hwpf/hwp/occ/occ_procedures/p8_pm_prep_for_reset.C
// ******************************************************************
// Put OCC PPC405 into reset safely
// ******************************************************************
FAPI_INF(“Put OCC PPC405 into reset safely”);
FAPI_DBG(“Executing: p8_occ_control.C”);
FAPI_EXEC_HWP(rc, p8_occ_control, i_primary_chip_target, PPC405_RESET_SEQUENCE, 0);
…
if ( i_secondary_chip_target.getType() != TARGET_TYPE_NONE )
{
FAPI_EXEC_HWP(rc, p8_occ_control, i_secondary_chip_target, PPC405_RESET_SEQUENCE, 0);
…
}
open-power/hostboot/src/usr/hwpf/hwp/occ/occ_procedures/p8_occ_control.C
/// \param[in] i_target => Chip Target
/// \param[in] i_ppc405_reset_ctrl => PPC405_RESET_NULL : do nothing PPC405_RESET_OFF : set ppc405 reset=0 PPC405_RESET_ON : set ppc405 reset=1
/// \param[in] i_ppc405_boot_ctrl => PPC405_BOOT_NULL : do nothing PPC405_BOOT_SRAM : boot from sram PPC405_BOOT_MEM : boot from memory PPC405_BOOT_OLD : boot from sram (OLD tests)
/// \retval FAPI_RC_SUCCESS
/// \retval ERROR defined in xml
fapi::ReturnCode
p8_occ_control(const Target& i_target, const uint8_t i_ppc405_reset_ctrl, const uint8_t i_ppc405_boot_ctrl)
{
…
case PPC405_RESET_OFF:
…
rc = putScom(i_target, OCC_CONTROL_AND_0x0006B001, ~BIT(0));
…
case PPC405_RESET_SEQUENCE:
…
rc = putScom(i_target, OCC_CONTROL_OR_0x0006B002, BIT(0));
…
open-power/hostboot/src/include/usr/hwpf/fapi/fapiHwAccess.H
/**
* @brief Writes a SCOM register on a Chip
* @param[in] i_target Target to operate on
* @param[in] i_address Scom address to write to
* @param[in] i_data ecmdDataBufferBase object that holds data to write into
* address
* @return ReturnCode. Zero on success, else platform specified error
*/
fapi::ReturnCode fapiPutScom(const fapi::Target& i_target,
const uint64_t i_address,
ecmdDataBufferBase & i_data);
open-power/hostboot/src/usr/hwpf/plat/fapiPlatHwAccess.C
fapi::ReturnCode platPutScom(const fapi::Target& i_target,
const uint64_t i_address,
ecmdDataBufferBase & i_data)
{
…
// Extract the component pointer
TARGETING::Target* l_target =
reinterpret_cast(i_target.get());
open-power/hostboot/src/include/usr/targeting/common/target.H
typedef Target* TargetHandle_t;
open-power/hostboot/src/usr/diag/prdf/test/prdfsimScrDataSet.H
typedef TARGETING::TargetHandle_t ChipId
Oops, typo:
Here: the spec (open-power/docs) doesn’t mention per-core/per-chip …
Read: per-*module*/per-chip.
And all the indentation is gone in previous comment. :/ But you can get the idea.