diff options
author | Shawn McCarney <shawnmm@us.ibm.com> | 2017-07-12 16:19:54 -0500 |
---|---|---|
committer | Martha Broyles <mbroyles@us.ibm.com> | 2017-08-02 16:28:58 -0400 |
commit | 9b64b7c93ac21aaac19c98eda502ad00b1454120 (patch) | |
tree | 91302fdf03eb18d6995bbb9776e82c5765064761 /src/occ_gpe0/gpe_get_tod.c | |
parent | 2c6661b3dcabd0aa3a69c3aeb34c760638da4064 (diff) | |
download | talos-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.c | 154 |
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(); + } +} |