summaryrefslogtreecommitdiffstats
path: root/src/occ_gpe1
diff options
context:
space:
mode:
authorWael El-Essawy <welessa@us.ibm.com>2016-08-29 19:33:20 -0500
committerWael El-Essawy <welessa@us.ibm.com>2016-09-16 11:19:15 -0400
commit8a7d7b2d13098453380fbdf69c0136515ba33b06 (patch)
tree9ce20ff68625d0a6d4b5d118514a48949232e173 /src/occ_gpe1
parent444caf2b8e674263f27963b3c9739e48aa793d00 (diff)
downloadtalos-occ-8a7d7b2d13098453380fbdf69c0136515ba33b06.tar.gz
talos-occ-8a7d7b2d13098453380fbdf69c0136515ba33b06.zip
Memory Temperature Control Loop (memory throttling)
* Memory throttling due to over temp * Throttle when reach timeout getting new temperature readings * Log error for temperature exceeding ERROR threshold Change-Id: I089c88aadba84e7296ad87b8cb87fa8c045ff912 RTC: 131188 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/28933 Reviewed-by: Wael El-Essawy <welessa@us.ibm.com> Tested-by: Wael El-Essawy <welessa@us.ibm.com>
Diffstat (limited to 'src/occ_gpe1')
-rw-r--r--src/occ_gpe1/gpe1_dimm_control.c121
-rw-r--r--src/occ_gpe1/gpe1_dimm_read.c2
-rw-r--r--src/occ_gpe1/gpe1_dimm_reset.c1
-rw-r--r--src/occ_gpe1/ipc_func_tables.c3
-rw-r--r--src/occ_gpe1/topfiles.mk3
5 files changed, 127 insertions, 3 deletions
diff --git a/src/occ_gpe1/gpe1_dimm_control.c b/src/occ_gpe1/gpe1_dimm_control.c
new file mode 100644
index 0000000..99d5395
--- /dev/null
+++ b/src/occ_gpe1/gpe1_dimm_control.c
@@ -0,0 +1,121 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/occ_gpe1/gpe1_dimm_control.c $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015,2016 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* 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. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+#include "pk.h"
+#include "ppe42_scom.h"
+#include "ipc_api.h"
+#include "ipc_async_cmd.h"
+#include "gpe_err.h"
+#include "gpe_util.h"
+#include "dimm_structs.h"
+#include "gpe1.h"
+
+/*
+ * Function Specifications:
+ *
+ * Name: gpe_dimm_control
+ *
+ * Description: DIMM control code on the GPE
+ *
+ * Inputs: cmd is a pointer to IPC msg's cmd and cmd_data struct
+ *
+ * Outputs: error: sets rc, address, and ffdc in the cmd_data's
+ * GpeErrorStruct
+ *
+ * End Function Specification
+ */
+
+#define NUM_NIMBUS_MC_PAIRS 2
+#define MAX_NUM_MCU_PORTS 4
+
+void gpe_dimm_control(ipc_msg_t* cmd, void* arg)
+{
+ // Note: arg was set to 0 in ipc func table (ipc_func_tables.c), so don't use it.
+ // the ipc arguments passed through the ipc_msg_t structure, has a pointer
+ // to the G_gpe_start_pwr_meas_read_args struct.
+
+ int rc;
+ uint64_t regValue; // a pointer to hold the putscom_abs register value
+ ipc_async_cmd_t *async_cmd = (ipc_async_cmd_t*)cmd;
+ dimm_control_args_t *args = (dimm_control_args_t*)async_cmd->cmd_data;
+
+ int mc = args->mc, port = args->port; // memory controller pair and port
+
+ args->error.error = 0;
+ args->error.ffdc = 0;
+
+ do
+ { // read N/M DIMM Throttling Control SCOM Register for specified MC pair and port numbers
+ rc = getscom_abs(N_M_DIMM_TCR(mc,port), &regValue);
+ if(rc)
+ {
+ PK_TRACE("gpe_dimm_control: N/M DIMM Throttling Control Register read fails"
+ "MC#|Port:0x%08x, Address:0x%08x, rc:0x%08x",
+ (uint32_t)((mc << 16) | port),
+ N_M_DIMM_TCR(mc,port), rc);
+
+ gpe_set_ffdc(&(args->error), N_M_DIMM_TCR(mc,port),
+ GPE_RC_SCOM_GET_FAILED, rc);
+ break;
+ }
+
+ // Clear old N values for slot and port
+ regValue &= 0x1FFFFFFFF;
+ // copy slot and port N values (31 bits) from passed dimmNumeratorValues
+ regValue |= ((uint64_t) (args->dimmNumeratorValues.word32 & 0xFFFFFFFE)) << 32 ;
+
+ // Write new slot and port N Values
+ rc = putscom_abs(N_M_DIMM_TCR(mc,port), regValue);
+ if(rc)
+ {
+ PK_TRACE("gpe_dimm_control: N/M DIMM Throttling Control Register write fails"
+ "dimm#:%d, Address:0x%04x, Nvalues:0x%08x, rc:0x%08x",
+ (uint16_t)((mc << 8) | port),
+ N_M_DIMM_TCR(mc,port), regValue, rc);
+
+ gpe_set_ffdc(&(args->error), N_M_DIMM_TCR(mc,port),
+ GPE_RC_SCOM_GET_FAILED, rc);
+ break;
+ }
+ else
+ {
+ GPE1_DIMM_DBG("gpe_dimm_control: N/M DIMM Throttling Control Register write"
+ "mc|port#:0x%04x, Address:0x%08x, Nvalues:0x%08x",
+ (uint16_t)((mc << 8) | port),
+ N_M_DIMM_TCR(mc,port), regValue);
+ }
+ } while(0);
+
+ // send back a response, IPC success even if ffdc/rc are non zeros
+ rc = ipc_send_rsp(cmd, IPC_RC_SUCCESS);
+ if(rc)
+ {
+ PK_TRACE("gpe_dimm_control: Failed to send response back. Halting GPE1", rc);
+ gpe_set_ffdc(&(args->error), 0x00, GPE_RC_IPC_SEND_FAILED, rc);
+ pk_halt();
+ }
+}
+
+
diff --git a/src/occ_gpe1/gpe1_dimm_read.c b/src/occ_gpe1/gpe1_dimm_read.c
index d89b0bf..8f542d6 100644
--- a/src/occ_gpe1/gpe1_dimm_read.c
+++ b/src/occ_gpe1/gpe1_dimm_read.c
@@ -34,7 +34,7 @@
#include "ipc_async_cmd.h"
#include "gpe1.h"
#include "gpe1_dimm.h"
-
+#include "dimm_structs.h"
void dimm_write_int_mask(ipc_msg_t* cmd, void* arg);
void dimm_write_mode(ipc_msg_t* cmd, void* arg);
diff --git a/src/occ_gpe1/gpe1_dimm_reset.c b/src/occ_gpe1/gpe1_dimm_reset.c
index eedc917..0463977 100644
--- a/src/occ_gpe1/gpe1_dimm_reset.c
+++ b/src/occ_gpe1/gpe1_dimm_reset.c
@@ -34,6 +34,7 @@
#include "ipc_async_cmd.h"
#include "gpe1.h"
#include "gpe1_dimm.h"
+#include "dimm_structs.h"
/*
diff --git a/src/occ_gpe1/ipc_func_tables.c b/src/occ_gpe1/ipc_func_tables.c
index 113dacd..ab352c6 100644
--- a/src/occ_gpe1/ipc_func_tables.c
+++ b/src/occ_gpe1/ipc_func_tables.c
@@ -25,6 +25,7 @@
#include "ipc_api.h"
#include "gpe1_dimm.h"
+void gpe_dimm_control(ipc_msg_t* cmd, void* arg);
// Function table for multi target (common) functions
IPC_MT_FUNC_TABLE_START
@@ -41,7 +42,7 @@ IPC_MT_FUNC_TABLE_END
// Function table for single target (processor-specific) functions
IPC_ST_FUNC_TABLE_START
IPC_HANDLER(gpe_dimm_sm, 0) // 0 - IPC_ST_DIMM_SM_FUNCID
-IPC_HANDLER_DEFAULT // 1
+IPC_HANDLER(gpe_dimm_control, 0) // 1 - IPC_ST_DIMM_CONTROL_FUNCID
IPC_HANDLER_DEFAULT // 2
IPC_HANDLER_DEFAULT // 3
IPC_HANDLER_DEFAULT // 4
diff --git a/src/occ_gpe1/topfiles.mk b/src/occ_gpe1/topfiles.mk
index d1a957c..4499c81 100644
--- a/src/occ_gpe1/topfiles.mk
+++ b/src/occ_gpe1/topfiles.mk
@@ -23,7 +23,8 @@
#
# IBM_PROLOG_END_TAG
-TOP-C-SOURCES = gpe1_main.c gpe1_dimm_read.c gpe1_dimm_reset.c pk_app_irq_table.c ipc_func_tables.c
+TOP-C-SOURCES = gpe1_main.c gpe1_dimm_read.c gpe1_dimm_reset.c \
+ pk_app_irq_table.c ipc_func_tables.c gpe1_dimm_control.c
TOP-S-SOURCES =
TOP_OBJECTS = $(TOP-C-SOURCES:.c=.o) $(TOP-S-SOURCES:.S=.o)
OpenPOWER on IntegriCloud