summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Cain <cjcain@us.ibm.com>2019-03-25 14:48:21 -0500
committerChristopher J. Cain <cjcain@us.ibm.com>2019-03-29 09:40:48 -0500
commitde361c2a961fcbebac06b70af07515bf2f22620e (patch)
tree938e79ee8ea057e33bf69a0941b06a9b4e984cd4
parentad9bb2d1e41c1f0222c2d23474238bfa3b925c6c (diff)
downloadtalos-occ-de361c2a961fcbebac06b70af07515bf2f22620e.tar.gz
talos-occ-de361c2a961fcbebac06b70af07515bf2f22620e.zip
New NVDIMM save procedure
Change-Id: I6eb7ab75951b1e29b13bbdeb06ff4a5c79bc04cd CQ: SW458983 Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/75111 Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com> Reviewed-by: Martha Broyles <mbroyles@us.ibm.com> Reviewed-by: Douglas R. Gilbert <dgilbert@us.ibm.com> Reviewed-by: Christopher J. Cain <cjcain@us.ibm.com>
-rw-r--r--src/common/mca_addresses.h2
-rwxr-xr-xsrc/occ_405/occbuildname.c2
-rw-r--r--src/occ_gpe1/gpe1_dimm_control.c341
3 files changed, 146 insertions, 199 deletions
diff --git a/src/common/mca_addresses.h b/src/common/mca_addresses.h
index 8b38b8c..a1e0b52 100644
--- a/src/common/mca_addresses.h
+++ b/src/common/mca_addresses.h
@@ -88,8 +88,6 @@ mc23.port3 0x080108C0 + 0x134/135/118 = 0x080109F4 = 0x0801
// Required for NVDIMM procedure
#define DDR_IF_SCOM_CTRL(mc,port) (DIMM_MCA_BASE_ADDRESS + 0x0118 + MC_PORT_SPACE(mc,port))
-#define FINAL_ARB_PARMS(mc,port) (DIMM_MCA_BASE_ADDRESS + 0x0113 + MC_PORT_SPACE(mc,port))
-#define DDR_PORT_STATUS_REG(mc,port) (DIMM_MCA_BASE_ADDRESS + 0x0119 + MC_PORT_SPACE(mc,port))
// DIMM Control
/*
diff --git a/src/occ_405/occbuildname.c b/src/occ_405/occbuildname.c
index 7e7c6d8..9855c75 100755
--- a/src/occ_405/occbuildname.c
+++ b/src/occ_405/occbuildname.c
@@ -34,6 +34,6 @@ volatile const char G_occ_buildname[16] __attribute__((section(".buildname"))) =
#else
-volatile const char G_occ_buildname[16] __attribute__((section(".buildname"))) = /*<BuildName>*/ "op_occ_190322a\0" /*</BuildName>*/ ;
+volatile const char G_occ_buildname[16] __attribute__((section(".buildname"))) = /*<BuildName>*/ "op_occ_190328a\0" /*</BuildName>*/ ;
#endif
diff --git a/src/occ_gpe1/gpe1_dimm_control.c b/src/occ_gpe1/gpe1_dimm_control.c
index 29a435d..a481d82 100644
--- a/src/occ_gpe1/gpe1_dimm_control.c
+++ b/src/occ_gpe1/gpe1_dimm_control.c
@@ -98,256 +98,205 @@ void gpe1_sleep(uint32_t i_microseconds)
void gpe_scom_nvdimms_nimbus(ipc_msg_t* cmd, void* arg)
{
int rc = 0;
- int mc = 0;
+ int mc = 1;
int port = 0;
+ uint32_t regAddr = 0;
uint64_t regValue = 0;
- uint64_t mbarpc_regValue = 0;
- uint64_t mbastr_regValue = 0;
ipc_async_cmd_t *async_cmd = (ipc_async_cmd_t*)cmd;
epow_gpio_args_t *args = (epow_gpio_args_t*)async_cmd->cmd_data;
- PK_TRACE("gpe_scom_nvdimms_nimbus: configured_mbas: 0x%04x",
- args->configured_mbas );
+ PK_TRACE("gpe_scom_nvdimms_nimbus: configured_mbas: 0x%04x", args->configured_mbas );
- // If mc is configured, send scoms
-
- // OCC does not know which slots the NVDIMMs are installed in.
- // NVDIMMs will only be installed in ports 6 & 7
- // To expedite the save of data, the scoms will only be done for those 2 ports
- // mc=0 => MCS0 --> MCA port 0 --> DIMM0/1
- // MCA port 1 --> DIMM0/1
- // MCS1 --> MCA port 2 --> DIMM0/1
- // MCA port 3 --> DIMM0/1
- // mc=1 => MCS2 --> MCA port 4 --> DIMM0/1
- // MCA port 5 --> DIMM0/1
- // MCS3 --> MCA port 6 --> DIMM0/1 (potential NVDIMMs)
- // MCA port 7 --> DIMM0/1 (potential NVDIMMs)
+ // Step 1: Stop mcbist, select all ports (or just the ports with NVDIMM, but we are going down anyways so who cares)
+ //
+ // MC01.MCBIST.MBA_SCOMFIR.MCB_CNTLQ - MCBIST Control Register
+ // bit 0: start bit
+ // bit 1: stop bit
+ // bit 2:5 ports to run MCBIST
+ //
+ regAddr = MCBIST_CTRL_REG(mc);
+ rc = getscom_abs(regAddr, &regValue);
+ if (rc)
+ {
+ PK_TRACE("E>gpe_scom_nvdimms_nimbus: Failed to read MCB_CNTLQ Reg:0x%08X, rc:0x%08x",
+ regAddr, rc);
+ }
+ else
+ {
+ regValue |= 0x7C00000000000000; // set stop bit and all ports
+ PK_TRACE("gpe_scom_nvdimms_nimbus: Writing MCB_CNTLQ (0x%08X) to 0x%08X%08X",
+ regAddr, WORD_HIGH(regValue), WORD_LOW(regValue));
+ rc = putscom_abs(regAddr, regValue);
+ if (rc)
+ {
+ PK_TRACE("E>gpe_scom_nvdimms_nimbus: Failed to update MCB_CNTLQ"
+ " Reg:0x%08X, Data:0x%08X %08X, rc:0x%08x",
+ regAddr, WORD_HIGH(regValue), WORD_LOW(regValue), rc);
+ gpe_set_ffdc(&(args->error), regAddr,
+ GPE_RC_SCOM_PUT_FAILED, rc);
+ }
+ }
- mc = 1;
+ // Step 2: Enable maint. addr and broadcast
+ //
+ // MC01.MCBIST.MBA_SCOMFIR.MCBAGRAQ - Address Generator Configuration Register
+ // bit 10 enable maint address mode
+ // bit 11 enable maint_addr_mode to broadcast commands to multiple ports
+ regAddr = 0x070123D6 + (MCA_MCPAIR_SPACE * mc);
+ rc = getscom_abs(regAddr, &regValue);
+ if (rc)
+ {
+ PK_TRACE("E>gpe_scom_nvdimms_nimbus: Failed to read MCBAGRAQ Reg:0x%08X, rc:0x%08x",
+ regAddr, rc);
+ }
+ else
+ {
+ regValue |= 0x0030000000000000; // enable maintenance address & broadcast
+ PK_TRACE("gpe_scom_nvdimms_nimbus: Writing MCBAGRAQ (0x%08X) to 0x%08X%08X",
+ regAddr, WORD_HIGH(regValue), WORD_LOW(regValue));
+ rc = putscom_abs(regAddr, regValue);
+ if (rc)
+ {
+ PK_TRACE("E>gpe_scom_nvdimms_nimbus: Failed to update MCBAGRAQ"
+ " Reg:0x%08X, Data:0x%08X %08X, rc:0x%08x",
+ regAddr, WORD_HIGH(regValue), WORD_LOW(regValue), rc);
+ gpe_set_ffdc(&(args->error), regAddr,
+ GPE_RC_SCOM_PUT_FAILED, rc);
+ }
+ }
- // Step 0 - In MCFGP, set MCFGP_VALID
+ // Step 3: Enable sync for broadcast
//
- // bit 0 - MCFGP_VALID
- const uint32_t MCFGP_ADDRESS_MCS3 = 0x0301088A;
- rc = getscom_abs(MCFGP_ADDRESS_MCS3, &regValue);
+ // MC01.MCBIST.MBA_SCOMFIR.MCBCFGQ - MCBIST Configuration Register
+ // bit 0 Enable sync for broadcast
+ regAddr = 0x070123E0 + (MCA_MCPAIR_SPACE * mc);
+ rc = getscom_abs(regAddr, &regValue);
if (rc)
{
- PK_TRACE("E>gpe_scom_nvdimms_nimbus: Failed to read (MCFGP) Reg:0x%08X, rc:0x%08x",
- MCFGP_ADDRESS_MCS3, rc);
+ PK_TRACE("E>gpe_scom_nvdimms_nimbus: Failed to read MCBCFGQ Reg:0x%08X, rc:0x%08x",
+ regAddr, rc);
}
else
{
- regValue |= 0x8000000000000000; // set MCFGP_VALID (bit 0)
- PK_TRACE("gpe_scom_nvdimms_nimbus: Writing MCFGP (0x%08X) to 0x%08X%08X",
- MCFGP_ADDRESS_MCS3, WORD_HIGH(regValue), WORD_LOW(regValue));
- rc = putscom_abs(MCFGP_ADDRESS_MCS3, regValue);
+ regValue |= 0x8000000000000000; // enable sync for broadcast
+ PK_TRACE("gpe_scom_nvdimms_nimbus: Writing MCBCFGQ (0x%08X) to 0x%08X%08X",
+ regAddr, WORD_HIGH(regValue), WORD_LOW(regValue));
+ rc = putscom_abs(regAddr, regValue);
if (rc)
{
- PK_TRACE("E>gpe_scom_nvdimms_nimbus: Failed to set MCFGP_VALID (MCFGP)"
+ PK_TRACE("E>gpe_scom_nvdimms_nimbus: Failed to update MCBCFGQ"
" Reg:0x%08X, Data:0x%08X %08X, rc:0x%08x",
- MCFGP_ADDRESS_MCS3, WORD_HIGH(regValue), WORD_LOW(regValue), rc);
- gpe_set_ffdc(&(args->error), MCFGP_ADDRESS_MCS3,
+ regAddr, WORD_HIGH(regValue), WORD_LOW(regValue), rc);
+ gpe_set_ffdc(&(args->error), regAddr,
GPE_RC_SCOM_PUT_FAILED, rc);
}
}
- const uint32_t reg_MCBIST = MCBIST_CTRL_REG(mc);
- rc = getscom_abs(reg_MCBIST, &regValue);
+ // Step 4: required for DDR_RESETn
+ //
+ // MC01.MCBIST.MBA_SCOMFIR.CCS_MODEQ - Configured Command Sequence Mode Register
+ // bit 60 Idle pattern for CCS DDR Address Bank Bit 2
+ regAddr = 0x070123A7 + (MCA_MCPAIR_SPACE * mc);
+ rc = getscom_abs(regAddr, &regValue);
if (rc)
{
- PK_TRACE("E>gpe_scom_nvdimms_nimbus: Failed to read (MCBIST) Reg:0x%08X, rc:0x%08x",
- reg_MCBIST, rc);
+ PK_TRACE("E>gpe_scom_nvdimms_nimbus: Failed to read CCS_MODEQ Reg:0x%08X, rc:0x%08x",
+ regAddr, rc);
}
else
{
- // Step 1 - In MCBIST_CTRL_REG, stop mcbist
- // (must be done first)
- //
- // bit 1 - MCB_STOP
- regValue |= 0x4000000000000000; // stop mcbist (set bit 1)
- rc = putscom_abs(reg_MCBIST, regValue);
+ regValue |= 0x0000000000000008;
+ PK_TRACE("gpe_scom_nvdimms_nimbus: Writing CCS_MODEQ (0x%08X) to 0x%08X%08X",
+ regAddr, WORD_HIGH(regValue), WORD_LOW(regValue));
+ rc = putscom_abs(regAddr, regValue);
if (rc)
{
- PK_TRACE("E>gpe_scom_nvdimms_nimbus: Failed to stop mcbist (MCBIST)"
+ PK_TRACE("E>gpe_scom_nvdimms_nimbus: Failed to update CCS_MODEQ"
" Reg:0x%08X, Data:0x%08X %08X, rc:0x%08x",
- reg_MCBIST, WORD_HIGH(regValue), WORD_LOW(regValue), rc);
- gpe_set_ffdc(&(args->error), reg_MCBIST, GPE_RC_SCOM_PUT_FAILED, rc);
+ regAddr, WORD_HIGH(regValue), WORD_LOW(regValue), rc);
+ gpe_set_ffdc(&(args->error), regAddr,
+ GPE_RC_SCOM_PUT_FAILED, rc);
}
}
+ // Step 5: Enable CCS address mux and allow RESETn per NVDIMM port
+ //
+ // MC01.PORT0.SRQ.MBA_FARB5Q - DDR Interface SCOM Control
+ // bit 5: CCS Addresss Mux Sel
+ // bit 6: CSS_INST_ARR0 will be driven out to DDR Resetn
+
// Iterate over each bit in configured_mbas for MCS3 (MCA port 6 and 7)
+
+ // OCC does not know which slots the NVDIMMs are installed in.
+ // NVDIMMs will only be installed in ports 6 & 7
+ // To expedite the save of data, some scoms will only be done for those 2 ports
+ // mc=0 => MCS0 --> MCA port 0 --> DIMM0/1
+ // MCA port 1 --> DIMM0/1
+ // MCS1 --> MCA port 2 --> DIMM0/1
+ // MCA port 3 --> DIMM0/1
+ // mc=1 => MCS2 --> MCA port 4 --> DIMM0/1
+ // MCA port 5 --> DIMM0/1
+ // MCS3 --> MCA port 6 --> DIMM0/1 (potential NVDIMMs)
+ // MCA port 7 --> DIMM0/1 (potential NVDIMMs)
uint16_t mask = 0x8000 >> 6; // Starting at MCS3 / MCA port 6
for (port = 2; port < NUM_PORTS_PER_MBA; ++port)
{
if (args->configured_mbas & mask)
{
- PK_TRACE("gpe_scom_nvdimms_nimbus: scoms for mc: %d, port: %d", mc, port);
-
- const uint32_t reg_MBARPC0Q = POWER_CTRL_REG0(mc,port);
- rc = getscom_abs(reg_MBARPC0Q, &mbarpc_regValue);
+ regAddr = DDR_IF_SCOM_CTRL(mc,port);
+ PK_TRACE("gpe_scom_nvdimms_nimbus: MBA_FARB5Q (0x%08X) for mc: %d, port: %d ", regAddr, mc, port);
+ rc = getscom_abs(regAddr, &regValue);
if (rc)
{
- PK_TRACE("E>gpe_scom_nvdimms_nimbus: Failed to read (MBARPC0Q) Reg:0x%08X, rc:0x%08x",
- reg_MBARPC0Q, rc);
+ PK_TRACE("E>gpe_scom_nvdimms_nimbus: Failed to read (MBA_FARB5Q) Reg:0x%08X, rc:0x%08x",
+ regAddr, rc);
}
else
{
- // Step 2 - In MBARPC0Q, disable power domain control
- // (must be done before domains are set)
- //
- // bit 2 - power domain control
- mbarpc_regValue &= 0xDFFFFFFFFFFFFFFF; // disable power control (clear bit 2)
- rc = putscom_abs(reg_MBARPC0Q, mbarpc_regValue);
- if (rc)
- {
- PK_TRACE("E>gpe_scom_nvdimms_nimbus: Failed to disable power domain control (MBARPC0Q)"
- " Reg:0x%08X, Data:0x%08X %08X, rc:0x%08x",
- reg_MBARPC0Q, WORD_HIGH(mbarpc_regValue), WORD_LOW(mbarpc_regValue), rc);
- gpe_set_ffdc(&(args->error), reg_MBARPC0Q,
- GPE_RC_SCOM_PUT_FAILED, rc);
- }
-
- // Step 3 - In MBARPC0Q, set domain to MAXALL_MIN0(0b010),
- // disable minimum domain reduction and set power down delay to 0
- //
- // bits 3:5 - min/max domains
- // bit 22 - min domain reduction enable
- // bit 23:32 - min domain reduction time
- mbarpc_regValue &= 0xEBFFFC007FFFFFFF; // MAXALL_MIN0 & delay (clear bits 3,5,22-32)
- mbarpc_regValue |= 0x0800000000000000; // MAXALL_MIN0 (set bit 4)
- rc = putscom_abs(reg_MBARPC0Q, mbarpc_regValue);
+ regValue |= 0x0600000000000000; // set bit 5 and 6
+ rc = putscom_abs(regAddr, regValue);
if (rc)
{
- PK_TRACE("E>gpe_scom_nvdimms_nimbus: Failed to set domains (MBARPC0Q)"
+ PK_TRACE("E>gpe_scom_nvdimms_nimbus: Failed to update MBA_FARB5Q"
" Reg:0x%08X, Data:0x%08X %08X, rc:0x%08x",
- reg_MBARPC0Q, WORD_HIGH(mbarpc_regValue), WORD_LOW(mbarpc_regValue), rc);
- gpe_set_ffdc(&(args->error), reg_MBARPC0Q,
+ regAddr, WORD_HIGH(regValue), WORD_LOW(regValue), rc);
+ gpe_set_ffdc(&(args->error), regAddr,
GPE_RC_SCOM_PUT_FAILED, rc);
}
-
- // Step 4 - In MBASTR0Q, enable STR entry and set entry delay to 0
- //
- // bit 0 - STR enable
- // bit 2:11 - STR entry time
- const uint32_t reg_MBASTR0Q = STR_REG0(mc,port);
- rc = getscom_abs(reg_MBASTR0Q, &mbastr_regValue);
- if (rc)
- {
- PK_TRACE("E>gpe_scom_nvdimms_nimbus: Failed to read (MBASTR0Q) Reg:0x%08X, rc:0x%08x",
- reg_MBASTR0Q, rc);
- }
- else
- {
- mbastr_regValue &= 0xC00FFFFFFFFFFFFF; // set entry time to 0 (clear bits 2-11)
- mbastr_regValue |= 0x8000000000000000; // enable STR (set bit 0)
- rc = putscom_abs(reg_MBASTR0Q, mbastr_regValue);
- if (rc)
- {
- PK_TRACE("E>gpe_scom_nvdimms_nimbus: Failed to enable STR entry (MBASTR0Q)"
- " Reg:0x%08X, Data:0x%08X %08X, rc:0x%08x",
- reg_MBASTR0Q, WORD_HIGH(mbastr_regValue), WORD_LOW(mbastr_regValue), rc);
- gpe_set_ffdc(&(args->error), reg_MBASTR0Q,
- GPE_RC_SCOM_PUT_FAILED, rc);
- }
- }
-
- // Step 5 - In MBARPC0Q, re-enable power domain control
- //
- // bit 2 - power domain control
- mbarpc_regValue |= 0x2000000000000000; // enable power control (set bit 2)
- rc = putscom_abs(reg_MBARPC0Q, mbarpc_regValue);
- if (rc)
- {
- PK_TRACE("E>gpe_scom_nvdimms_nimbus: Failed to re-enable power domain control (MBARPC0Q)"
- " Reg:0x%08X, Data:0x%08X %08X, rc:0x%08x",
- reg_MBARPC0Q, WORD_HIGH(mbarpc_regValue), WORD_LOW(mbarpc_regValue), rc);
- gpe_set_ffdc(&(args->error), reg_MBARPC0Q,
- GPE_RC_SCOM_PUT_FAILED, rc);
- }
-
- // Step 6 (new) - In FARB0Q (Final Arb parameters), disable rcd recovery
- //
- // bit 54 - Disable the rcd recovery procedure
- const uint32_t reg_FARB0Q = FINAL_ARB_PARMS(mc,port);
- rc = getscom_abs(reg_FARB0Q, &regValue);
- if (rc)
- {
- PK_TRACE("E>gpe_scom_nvdimms_nimbus: Failed to read (FARB0Q) Reg:0x%08X, rc:0x%08x",
- reg_FARB0Q, rc);
- }
- else
- {
- regValue |= 0x0000000000000200; // disable rcd recovery procedure (set bit 54)
- rc = putscom_abs(reg_FARB0Q, regValue);
- if (rc)
- {
- PK_TRACE("E>gpe_scom_nvdimms_nimbus: Failed to disable rcd procedure (FARB0Q)"
- " Reg:0x%08X, Data:0x%08X %08X, rc:0x%08x",
- reg_FARB0Q, WORD_HIGH(regValue), WORD_LOW(regValue), rc);
- gpe_set_ffdc(&(args->error), reg_FARB0Q,
- GPE_RC_SCOM_PUT_FAILED, rc);
- }
- }
-
- // Step 7 (new) - In FARB6Q (DDR Port Status Register), check if DRAMS are in STR
- //
- // bit 15 - Indicates if DRAMS on this port are in STR
- const uint32_t reg_FARB6Q = DDR_PORT_STATUS_REG(mc,port);
- PK_TRACE("gpe_scom_nvdimms_nimbus: Waiting for DRAM to reach STR (0x%08X)", reg_FARB6Q);
- uint64_t lastReg = 0;
- do
- {
- rc = getscom_abs(reg_FARB6Q, &regValue);
- if (rc)
- {
- PK_TRACE("E>gpe_scom_nvdimms_nimbus: Failed to read (FARB6Q) Reg:0x%08X, rc:0x%08x",
- reg_FARB6Q, rc);
- break;
- }
- else
- {
- if (lastReg != regValue)
- {
- PK_TRACE("gpe_scom_nvdimms_nimbus: FARB6Q = 0x%08X %08X", WORD_HIGH(regValue), WORD_LOW(regValue));
- lastReg = regValue;
- }
- }
- }
- while ((regValue & 0x0001000000000000) == 0); // wait for bit 15 to get set
- if (rc == 0)
- {
- PK_TRACE("gpe_scom_nvdimms_nimbus: DRAM is in STR");
- }
-
- // Step 8 (was 6) - In FARB5Q (DDR Interface SCOM Control), assert ddr_resetn
- //
- // bit 4 - assert ddr_resetn
- const uint32_t reg_FARB5Q = DDR_IF_SCOM_CTRL(mc,port);
- rc = getscom_abs(reg_FARB5Q, &regValue);
- if (rc)
- {
- PK_TRACE("E>gpe_scom_nvdimms_nimbus: Failed to read (FARB5Q) Reg:0x%08X, rc:0x%08x",
- reg_FARB5Q, rc);
- }
- else
- {
- regValue &= 0xF7FFFFFFFFFFFFFF; // assert ddr_resetn (clear bit 4)
- rc = putscom_abs(reg_FARB5Q, regValue);
- if (rc)
- {
- PK_TRACE("E>gpe_scom_nvdimms_nimbus: Failed to assert ddr_resetn (FARB5Q)"
- " Reg:0x%08X, Data:0x%08X %08X, rc:0x%08x",
- reg_FARB5Q, WORD_HIGH(regValue), WORD_LOW(regValue), rc);
- gpe_set_ffdc(&(args->error), reg_FARB5Q,
- GPE_RC_SCOM_PUT_FAILED, rc);
- }
- }
}
}
mask = mask >> 1;
} // for each MBA port
+ // Step 6: Start CCS
+ //
+ // MC01.MCBIST.MBA_SCOMFIR.CCS_CNTLQ - Configured Command Sequence Control Register
+ // bit 0: start bit
+ //
+ regAddr = 0x070123A5 + (MCA_MCPAIR_SPACE * mc);
+ rc = getscom_abs(regAddr, &regValue);
+ if (rc)
+ {
+ PK_TRACE("E>gpe_scom_nvdimms_nimbus: Failed to read CCS_CNTLQ Reg:0x%08X, rc:0x%08x",
+ regAddr, rc);
+ }
+ else
+ {
+ regValue |= 0x8000000000000000; // set start bit
+ PK_TRACE("gpe_scom_nvdimms_nimbus: Writing CCS_CNTLQ (0x%08X) to 0x%08X%08X",
+ regAddr, WORD_HIGH(regValue), WORD_LOW(regValue));
+ rc = putscom_abs(regAddr, regValue);
+ if (rc)
+ {
+ PK_TRACE("E>gpe_scom_nvdimms_nimbus: Failed to update CCS_CNTLQ"
+ " Reg:0x%08X, Data:0x%08X %08X, rc:0x%08x",
+ regAddr, WORD_HIGH(regValue), WORD_LOW(regValue), rc);
+ gpe_set_ffdc(&(args->error), regAddr,
+ GPE_RC_SCOM_PUT_FAILED, rc);
+ }
+ }
+
PK_TRACE("gpe_scom_nvdimms_nimbus: completed (rc=%d)", rc);
// Always send back success
OpenPOWER on IntegriCloud