summaryrefslogtreecommitdiffstats
path: root/src/occ_gpe0/gpe_get_tod.c
diff options
context:
space:
mode:
authorShawn McCarney <shawnmm@us.ibm.com>2017-07-12 16:19:54 -0500
committerMartha Broyles <mbroyles@us.ibm.com>2017-08-02 16:28:58 -0400
commit9b64b7c93ac21aaac19c98eda502ad00b1454120 (patch)
tree91302fdf03eb18d6995bbb9776e82c5765064761 /src/occ_gpe0/gpe_get_tod.c
parent2c6661b3dcabd0aa3a69c3aeb34c760638da4064 (diff)
downloadtalos-occ-9b64b7c93ac21aaac19c98eda502ad00b1454120.tar.gz
talos-occ-9b64b7c93ac21aaac19c98eda502ad00b1454120.zip
Timestamp data when collected
This commit contains the following enhancements: * New IPC function that runs on GPE0 to read the TOD (Time Of Day) registers * New task on the OCC 405 that gets current TOD every tick via IPC function * Sensor update function now sets timestamp to current TOD value Change-Id: I0ea42b01e4df7a93633a68a0f3ed0f839d5e7b3f RTC: 176504 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/43891 Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com> Reviewed-by: William A. Bryan <wilbryan@us.ibm.com> Reviewed-by: Martha Broyles <mbroyles@us.ibm.com>
Diffstat (limited to 'src/occ_gpe0/gpe_get_tod.c')
-rw-r--r--src/occ_gpe0/gpe_get_tod.c154
1 files changed, 154 insertions, 0 deletions
diff --git a/src/occ_gpe0/gpe_get_tod.c b/src/occ_gpe0/gpe_get_tod.c
new file mode 100644
index 0000000..187a61b
--- /dev/null
+++ b/src/occ_gpe0/gpe_get_tod.c
@@ -0,0 +1,154 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/occ_gpe0/gpe_get_tod.c $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2017,2017 */
+/* [+] 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 */
+
+/**
+ * @file gpe_get_tod.c
+ *
+ * This file defines the functions for getting the current value of the Time Of
+ * Day (TOD) register.
+ */
+
+//******************************************************************************
+// Includes
+//******************************************************************************
+
+#include <stdint.h> // For uint*_t
+#include "pk.h" // For PK_TRACE() and pk_halt()
+#include "ipc_api.h" // For ipc_msg_t
+#include "ipc_async_cmd.h" // For ipc_async_cmd_t
+#include "ppe42_scom.h" // For getscom_abs()
+#include "gpe_util.h" // For gpe_set_ffdc()
+#include "get_tod_structs.h" // For gpe_get_tod_args_t
+#include "gpe_err.h" // For GPE_RC_*
+#include "pss_constants.h" // For TOD_STATUS_REG and TOD_VALUE_REG
+
+
+//******************************************************************************
+// Defines
+//******************************************************************************
+
+/**
+ * Returns the IS_RUNNING bit within the TOD_STATUS_REG register.
+ *
+ * IS_RUNNING is bit 20 in the register value. Note that bit 0 is the most
+ * significant bit.
+ *
+ * @param reg_value value of TOD_STATUS_REG register
+ * @return IS_RUNNING bit. If 1, the TOD is running.
+ */
+#define TOD_IS_RUNNING(reg_value) \
+ (((uint8_t) (((uint64_t) (reg_value)) >> 43)) & 0x01u)
+
+/**
+ * Returns the TOD_VALUE field within the TOD_VALUE_REG register.
+ *
+ * The TOD_VALUE field is located in bits 0:59 of the register value. Note that
+ * bit 0 is the most significant bit. In the returned value we must set the low
+ * order 4 bits (60:63) to 0 rather than right shifting 4 bits.
+ *
+ * @param reg_value value of TOD_VALUE_REG register
+ * @return TOD_VALUE field
+ */
+#define TOD_VALUE(reg_value) (((uint64_t) (reg_value)) & 0xFFFFFFFFFFFFFFF0ull)
+
+
+//******************************************************************************
+// Functions
+//******************************************************************************
+
+/**
+ * Reads the value of the TOD_STATUS_REG and TOD_VALUE_REG registers. If the
+ * TOD is running, the current Time Of Day value is stored in the tod field of
+ * the args parameter.
+ *
+ * @param args Arguments passed from the OCC 405 via the IPC framework
+ */
+void gpe_read_tod_registers(gpe_get_tod_args_t * args)
+{
+ // Initialize output arguments to default values
+ args->error.rc = GPE_RC_SUCCESS;
+ args->error.addr = 0;
+ args->error.ffdc = 0;
+ args->tod = TOD_VALUE_UNKNOWN;
+
+ // Read value of TOD_STATUS_REG register
+ uint64_t l_reg_val;
+ uint32_t rc = getscom_abs(TOD_STATUS_REG, &l_reg_val);
+ if (rc != 0)
+ {
+ gpe_set_ffdc(&(args->error), TOD_STATUS_REG, GPE_RC_SCOM_GET_FAILED, rc);
+ return;
+ }
+
+ // Check if TOD is running based on TOD_STATUS_REG value.
+ if (!TOD_IS_RUNNING(l_reg_val))
+ {
+ // TOD is not running. Operating system is likely fixing it. Not an error.
+ return;
+ }
+
+ // Read value of TOD_VALUE_REG register
+ rc = getscom_abs(TOD_VALUE_REG, &l_reg_val);
+ if (rc != 0)
+ {
+ gpe_set_ffdc(&(args->error), TOD_VALUE_REG, GPE_RC_SCOM_GET_FAILED, rc);
+ return;
+ }
+
+ // The TOD_VALUE_REG register contains two fields. Get the TOD_VALUE field
+ // and store that as the Time Of Day value.
+ args->tod = TOD_VALUE(l_reg_val);
+}
+
+
+/**
+ * IPC function that gets the current Time Of Day (TOD) value.
+ *
+ * First reads the TOD_STATUS_REG register to make sure the TOD is running.
+ * Then reads the TOD_VALUE_REG register to get the TOD value.
+ *
+ * @param cmd A pointer to the IPC command message
+ * @param arg IPC function argument. Currently not used.
+ */
+void gpe_get_tod(ipc_msg_t * cmd, void * arg)
+{
+ // Cast command message pointer to more specific type to access cmd_data field
+ ipc_async_cmd_t * async_cmd = (ipc_async_cmd_t *) cmd;
+
+ // Cast cmd_data field to specific type of arguments for this IPC function
+ gpe_get_tod_args_t * args = (gpe_get_tod_args_t *) async_cmd->cmd_data;
+
+ // Read the TOD registers to get the TOD value. Store the result in args.
+ gpe_read_tod_registers(args);
+
+ // Send back a response with IPC success even if ffdc/rc fields are non-zero
+ int rc = ipc_send_rsp(cmd, IPC_RC_SUCCESS);
+ if (rc != 0)
+ {
+ PK_TRACE("gpe_get_tod: Failed to send response back. Halting GPE0. rc=0x%08X", rc);
+ gpe_set_ffdc(&(args->error), 0x00, GPE_RC_IPC_SEND_FAILED, rc);
+ pk_halt();
+ }
+}
OpenPOWER on IntegriCloud