summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDouglas Gilbert <dgilbert@us.ibm.com>2018-08-20 12:00:00 -0500
committerWilliam A. Bryan <wilbryan@us.ibm.com>2019-05-01 14:06:09 -0500
commitafa37a7e9bc0fa22fb2271fb2e7ea2557376181e (patch)
tree5b39ee8a394474649721a51c1c0d4968e52cac08
parenta880ffe3a854a8eb219ea92e7fbc4845d8fa2511 (diff)
downloadtalos-occ-afa37a7e9bc0fa22fb2271fb2e7ea2557376181e.tar.gz
talos-occ-afa37a7e9bc0fa22fb2271fb2e7ea2557376181e.zip
Explorer MSBUF monitoring
Change-Id: Ia8e48ba5c3ad7836dbd249f3965768e79083c181 Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/73263 Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com> Reviewed-by: Christopher J. Cain <cjcain@us.ibm.com> Reviewed-by: Martha Broyles <mbroyles@us.ibm.com> Reviewed-by: William A. Bryan <wilbryan@us.ibm.com>
-rw-r--r--src/common/centaur_configuration.h200
-rw-r--r--src/common/centaur_structs.h64
-rw-r--r--src/common/gpe_err.h1
-rw-r--r--src/common/ipc_func_ids.h6
-rw-r--r--src/common/membuf_configuration.h240
-rw-r--r--src/common/membuf_structs.h92
-rw-r--r--src/common/ocmb_mem_data.h87
-rw-r--r--src/include/registers/ocmb_firmware_registers.h93
-rw-r--r--src/include/registers/ocmb_register_addresses.h39
-rw-r--r--src/include/registers/p9a_firmware_registers.h79
-rw-r--r--src/include/registers/p9a_misc_scom_addresses.h43
-rw-r--r--src/occ_405/amec/amec_sensors_ocmb.c634
-rw-r--r--src/occ_405/amec/amec_sensors_ocmb.h36
-rwxr-xr-xsrc/occ_405/amec/amec_slave_smh.c89
-rwxr-xr-xsrc/occ_405/cent/centaur_control.c36
-rwxr-xr-xsrc/occ_405/cent/centaur_data.c252
-rwxr-xr-xsrc/occ_405/cent/centaur_data.h26
-rwxr-xr-xsrc/occ_405/cent/centaur_data_service_codes.h1
-rw-r--r--src/occ_405/cent/ocmb_control.c191
-rw-r--r--src/occ_405/cent/ocmb_data.c162
-rw-r--r--src/occ_405/cent/ocmb_membuf.h47
-rwxr-xr-xsrc/occ_405/dimm/dimm.c2
-rw-r--r--src/occ_405/mem/memory.c36
-rw-r--r--src/occ_405/occLinkInputFile3
-rwxr-xr-xsrc/occ_405/occbuildname.c2
-rw-r--r--src/occ_405/topfiles.mk3
-rw-r--r--src/occ_gpe0/firdata/firData.c8
-rw-r--r--src/occ_gpe0/firdata/homerData_common.h2
-rw-r--r--src/occ_gpe1/gpe1_main.c29
-rw-r--r--src/occ_gpe1/gpe_centaur.c726
-rw-r--r--src/occ_gpe1/gpe_centaur.h61
-rw-r--r--src/occ_gpe1/gpe_centaur_configuration.c497
-rw-r--r--src/occ_gpe1/gpe_centaur_scom.c762
-rw-r--r--src/occ_gpe1/gpe_membuf.c147
-rw-r--r--src/occ_gpe1/gpe_membuf.h177
-rw-r--r--src/occ_gpe1/gpe_membuf_scom.c605
-rw-r--r--src/occ_gpe1/gpe_ocmb.c630
-rw-r--r--src/occ_gpe1/ipc_func_tables.c8
-rw-r--r--src/occ_gpe1/link.cmd2
-rw-r--r--src/occ_gpe1/occ_gpe1_machine_check_handler.c38
-rw-r--r--src/occ_gpe1/topfiles.mk5
41 files changed, 4318 insertions, 1843 deletions
diff --git a/src/common/centaur_configuration.h b/src/common/centaur_configuration.h
deleted file mode 100644
index 46f9521..0000000
--- a/src/common/centaur_configuration.h
+++ /dev/null
@@ -1,200 +0,0 @@
-#if !defined(__CENTAUR_CONFIGURATION_H__)
-#define __CENTAUR_CONFIGURATION_H__
-
-//#include "occhw_common.h"
-#include "gpe_pba_parms.h"
-#include "centaur_firmware_registers.h"
-
-#define OCCHW_NCENTAUR 8
-
-/// Error return codes set/returned by centaur_configuration_create()
-
-typedef enum
-{
-
- CENTAUR_INVALID_ARGUMENT = 0x007ccc01,
- CENTAUR_MCSMODE0_SCOM_FAILURE = 0x007ccc02,
- CENTAUR_MCSMODE0_19_FAILURE = 0x007ccc03,
- CENTAUR_ADDRESS_27_FAILURE = 0x007ccc04,
- CENTAUR_MULTIPLE_DESIGNATED_SYNC = 0x007ccc05,
- CENTAUR_NO_DESIGNATED_SYNC = 0x007ccc06,
- CENTAUR_BAR_MASK_ERROR = 0x007ccc07,
- CENTAUR_CONFIGURATION_FAILED = 0x007ccc08,
- CENTAUR_DATA_SETUP_ERROR = 0x007ccc09,
- CENTAUR_SCOM_SETUP_ERROR = 0x007ccc0a,
- CENTAUR_NOT_CONFIGURED = 0x007ccc0b,
- CENTAUR_MASK_ERROR = 0x007ccc0c,
- CENTAUR_READ_TPC_ID_FAILURE = 0x007ccc0d,
- CENTAUR_BARMSKN_PUTSCOM_FAILURE = 0x007ccc0e,
- CENTAUR_BARN_PUTSCOM_FAILURE = 0x007ccc0f,
- CENTAUR_BARMSKN_GETSCOM_FAILURE = 0x007ccc10,
- CENTAUR_BARN_GETSCOM_FAILURE = 0x007ccc11,
-} CentaurConfigurationCreateRc;
-
-/**
- * Definition of the CentaurConfiguration data.
- * @note location must be 8-byte aligned, size must be multiple of 8 bytes.
- */
-typedef struct
-{
-
- /// Centaur base addresses for in-band operations
- ///
- uint64_t baseAddress[OCCHW_NCENTAUR];
-
- /// Contents of Centaur device id registers
- ///
- /// These are the device ID SCOMs (0x000f000f) read from configured
- /// Centaur during initialization. A 0 value indicates an unconfigured
- /// Centaur. These values are deconstructed by the memory buffer (mb)
- /// APIs mb_id(), mb_chip_type() and mb_ec_level().
- centaur_device_id_t deviceId[OCCHW_NCENTAUR];
-
- /// Designated sync scom address
- /// \note One and Only one of the MCS units can be targeted with SYNC
- /// commands. The design includes a private bus connecting all MCS on the
- /// chip that allows this "SYNC master" to broadcast the SYNC to all other
- /// MCS on the chip.
- uint32_t mcSyncAddr;
- uint32_t reserved; // keep 8 byte aligned
-
- /// A GpePbaParms parameter block for gpe_mem_data()
- ///
- /// This parameter block is set up in advance and used by the GPE
- /// procedure gpe_mem_data(). Given the complexity of accessing Centaur
- /// sensors and SCOM through the PBA it is simpler to set these up ahead
- /// of time and simply have the GPE procedures access preconfigured global
- /// data. The \a dataParms and \a scomParms members are distinguished by
- /// the different way the PBA slave needs to be configured to access
- /// either the Centaur sensor cache or Centaur SCOMs.
- GpePbaParms dataParms;
-
- /// A GpePbaParms parameter block for IPC_ST_CENTAUR_SCOM().
- GpePbaParms scomParms;
-
- /// A "chip configuration" bit mask denoting valid Centaur
- ///
- /// It shoud always be true that a bit denoting a configured Centaur is
- /// associated with a non-0 \a baseAddress and vice-versa.
- uint32_t config;
-
-
- /// The final return code from centaur_configuration_create().
- /// @see CentaurConfigurationCreateRc
- /// If initialization fails then this value can be used to diagnose what
- /// happend. This field should be statically initialized to a non-0 value
- /// (CENTAUR_NOT_CONFIGURED) and can then be checked against 0 to
- /// determine if the structure has been correctly initialized.
- int32_t configRc;
-
-} CentaurConfiguration_t __attribute__((aligned(8)));
-
-// Moved CentaurGetMemDataParms_t to centaur_structs.h
-
-typedef struct
-{
- union
- {
- struct
- {
- uint32_t scom;
- uint8_t reserved;
- uint8_t errorFlags;
- uint8_t instanceNumber;
- uint8_t commandType;
- };
- uint64_t command;
- };
- uint64_t mask;
- union
- {
- uint64_t data;
- struct
- {
- uint32_t unused;
- uint64_t* pData;
- };
- };
-} scomList_t;
-
-
-// Centaur Scom Return Codes
-enum
-{
- // rc 1 - 7 reserved from scom rc
- CENTAUR_ACCESS_INACTIVE = 98,
- CENTAUR_ACCESS_IN_PROGRESS = 99,
- CENTAUR_INVALID_SCOM = 100,
- CENTAUR_GET_MEM_DATA_COLLECT_INVALID = 200,
- CENTAUR_GET_MEM_DATA_UPDATE_INVALID = 201,
- CENTAUR_GET_MEM_DATA_DIED = 202,
- CENTAUR_CHANNEL_CHECKSTOP = 203,
-};
-
-// Centaur Scom Operations
-typedef enum
-{
- /// No operation
- CENTAUR_SCOM_NOP,
-
- /// Read from SCOM, depositing read data into the \a data field of the
- /// scomList_t.
- CENTAUR_SCOM_READ,
-
- /// Write to SCOM, taking write data from the \a data field of the scomList_t.
- CENTAUR_SCOM_WRITE,
-
- /// Read-Modify-Write.
- ///
- /// This operation first reads the SCOM. Bits under the \a mask field of the
- /// scomList_t are then cleared in the read data. The masked read data is then
- /// ORed with the contents of the \a data field of the scomList_t and the
- /// result is written back to the SCOM address.
- ///
- /// \note This command \e does \e not apply the mask to the data from the \a
- /// data field of the scomList_t. The caller should do this (if necessary)
- /// when setting up the scomList_t.
- ///
- /// \note The procedures do not provide a way to distinguish errors that may
- /// have occurred on the initial read vs. those that may have occurred on the
- /// subsequenct write.
- CENTAUR_SCOM_RMW,
-
- /// For IPC_ST_CENTAUR_SCOM(), the \a data field of the scomList_t contains a
- /// 32-bit pointer (cast to a uint64_t) to an array of PGP_NCENTAUR uint64_t
- /// values. SCOM read data for each configured Centaur (MCS) is deposited in
- /// this array. Array entries for unconfigured Centaur are zeroed.
- CENTAUR_SCOM_READ_VECTOR,
-
- /// For IPC_ST_CENTAUR_SCOM(), write the \a data field of the scomList_t to
- /// all configured Centaur. Currently unsupported for gpe_scom_p8().
- CENTAUR_SCOM_WRITE_ALL,
-
- /// For IPC_ST_CENTAUR_SCOM(), perform read-modify write for all configured
- /// Centaur. Currently unsupported for gpe_scom_p8().
- CENTAUR_SCOM_RMW_ALL,
-
- // Send Centaur SYNC to broadcast new throttle values.
- CENTAUR_SCOM_CENTAUR_SYNC,
-
-} centaur_scom_operation_t;
-
-#define MCS_MCSYNC_SYNC_GO 0x0000800000000000ull
-
-// BAR and PBA_SLAVE assigned to gpe1 centaur
-// - @see POWER Energy Management Hcode/HWP spec
-#define PBA_BAR_CENTAUR 1
-#define PBA_SLAVE_CENTAUR 2
-
-// This is used to setup CentaurConfiguration.config field
-#define CHIP_CONFIG_MCS_BASE 16
-#define CHIP_CONFIG_MCS(n) \
- ((0x80000000ul >> CHIP_CONFIG_MCS_BASE) >> (n))
-
-#define CHIP_CONFIG_CENTAUR_BASE 24
-#define CHIP_CONFIG_CENTAUR(n) \
- ((0x80000000ul >> CHIP_CONFIG_CENTAUR_BASE) >> (n))
-
-#endif
-
-
diff --git a/src/common/centaur_structs.h b/src/common/centaur_structs.h
deleted file mode 100644
index c0b7a66..0000000
--- a/src/common/centaur_structs.h
+++ /dev/null
@@ -1,64 +0,0 @@
-#if !defined(_CENTAUR_STRUCTS_H)
-#define _CENTAUR_STRUCTS_H
-
-#include "stdint.h"
-#include "gpe_export.h"
-#include "centaur_configuration.h"
-
-// IPC message payload for call to IPC_ST_CENTAUR_INIT_FUNCID
-typedef struct
-{
- GpeErrorStruct error;
- CentaurConfiguration_t * centaurConfiguration;
-
-} CentaurConfigParms_t;
-
-// IPC message payload for call to IPC_ST_CENTAUR_SCOM_FUNCID
-typedef struct
-{
- GpeErrorStruct error;
-
- /**
- * Input: The SCOM list
- * This is a pointer to an array of scomList_t objects
- * describing the sequence of commands to execute.
- */
- scomList_t* scomList;
-
- /**
- * Input: The number of entries in the scomList.
- * @note It is considered an error if \a entries is 0, under the
- * assumption that the caller must have neglected to initialize the
- * structure.
- */
- int entries;
-
-} CentaurScomParms_t;
-
-// IPC message payload for call to IPC_ST_CENTAUR_DATA_FUNCID
-typedef struct
-{
- GpeErrorStruct error;
-
- /**
- * The index (0 .. PGP_NCENTAUR - 1) of the Centaur whose sensor cache
- * data to collect, or -1 to bypass collection.
- */
- int collect;
-
- /**
- * The index (0 .. PGP_NCENTAUR - 1) of the Centaur to "poke" to cause it
- * to begin collecting the next round of data into its sensor cache, or
- * -1 to bypass updating
- */
- int update;
-
- /**
- * Pointer to data collected. Needs to be set if collect != -1
- * otherwise it's not used.
- */
- uint64_t * data;
-} CentaurGetMemDataParms_t;
-
-
-#endif
diff --git a/src/common/gpe_err.h b/src/common/gpe_err.h
index 66e9295..b6cdb45 100644
--- a/src/common/gpe_err.h
+++ b/src/common/gpe_err.h
@@ -44,6 +44,7 @@
#define GPE_RC_INVALID_MEM_PWR_CTL 0x20 // Invalid value for the memory power control command
// Centaur mem ctl codes
#define GPE_RC_CONFIG_DATA_NULL_PTR 0x30 // centaurConfiguration data ptr NULL
+#define GPE_RC_INVALID_MEMBUF_TYPE 0x31 // membuf type is not valid.
// APSS Specific gpe return Codes
#define GPE_RC_INVALID_APSS_MODE 0x40 // OCC requested undefined APSS mode
diff --git a/src/common/ipc_func_ids.h b/src/common/ipc_func_ids.h
index 748a337..8258255 100644
--- a/src/common/ipc_func_ids.h
+++ b/src/common/ipc_func_ids.h
@@ -75,9 +75,9 @@ IPC_FUNCIDS_TABLE_START
IPC_FUNC_ID(IPC_ST_MEM_POWER_CONTROL_FUNCID)
IPC_FUNC_ID(IPC_ST_GPU_SM_FUNCID)
IPC_FUNC_ID(IPC_ST_GPE_GPU_INIT_FUNCID)
- IPC_FUNC_ID(IPC_ST_CENTAUR_SCOM_FUNCID)
- IPC_FUNC_ID(IPC_ST_CENTAUR_DATA_FUNCID)
- IPC_FUNC_ID(IPC_ST_CENTAUR_INIT_FUNCID)
+ IPC_FUNC_ID(IPC_ST_MEMBUF_SCOM_FUNCID)
+ IPC_FUNC_ID(IPC_ST_MEMBUF_DATA_FUNCID)
+ IPC_FUNC_ID(IPC_ST_MEMBUF_INIT_FUNCID)
IPC_FUNC_ID(IPC_ST_EPOW_GPIO_ASSERT_FUNCID)
IPC_FUNCIDS_ST_END(OCCHW_INST_ID_GPE1)
diff --git a/src/common/membuf_configuration.h b/src/common/membuf_configuration.h
new file mode 100644
index 0000000..576f6b4
--- /dev/null
+++ b/src/common/membuf_configuration.h
@@ -0,0 +1,240 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/common/membuf_configuration.h $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016,2018 */
+/* [+] 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 */
+
+/* This header file is used by both occ_405 and occ_gpe1. */
+/* Contains common structures and globals. */
+#if !defined(__MEMBUF_CONFIGURATION_H__)
+#define __MEMBUF_CONFIGURATION_H__
+
+//#include "occhw_common.h"
+#include "gpe_pba_parms.h"
+#include "centaur_firmware_registers.h"
+
+#define OCCHW_N_MEMBUF 8
+
+#define MEMTYPE_CENTAUR 1
+#define MEMTYPE_OCMB 2
+
+/// Error return codes set/returned by gpe_*_configuration_create()
+
+typedef enum
+{
+
+ MEMBUF_INVALID_ARGUMENT = 0x007ccc01,
+ MEMBUF_BAR_MASK_ERROR = 0x007ccc07,
+ MEMBUF_DATA_SETUP_ERROR = 0x007ccc09,
+ MEMBUF_SCOM_SETUP_ERROR = 0x007ccc0a,
+ MEMBUF_NOT_CONFIGURED = 0x007ccc0b,
+ MEMBUF_MASK_ERROR = 0x007ccc0c,
+ MEMBUF_BARN_GETSCOM_FAILURE = 0x007ccc0d,
+ MEMBUF_BARMSKN_PUTSCOM_FAILURE = 0x007ccc0e,
+ MEMBUF_BARN_PUTSCOM_FAILURE = 0x007ccc0f,
+ MEMBUF_BARMSKN_GETSCOM_FAILURE = 0x007ccc10,
+ MEMBUF_PBMODE_GETSCOM_FAILURE = 0x007ccc11,
+ MEMBUF_PMODE_DATA_MISMATCH = 0x007ccc12,
+} MemBufConfigurationCreateRc;
+
+/**
+ * Definition of the MemBufConfiguration data.
+ * @note location must be 8-byte aligned, size must be multiple of 8 bytes.
+ */
+typedef struct
+{
+
+ /// Membuf base addresses for in-band MMIO/SCOM operations
+ ///
+ uint64_t baseAddress[OCCHW_N_MEMBUF];
+
+ /// Contents of the Centaur device id register which includes cfam_id
+ // and module_id.
+ // (Not used on OCMB)
+ ///
+ uint64_t deviceId[OCCHW_N_MEMBUF];
+
+ /// Designated sync scom address
+ /// \note One and Only one of the MCS units can be targeted with SYNC
+ /// commands. The design includes a private bus connecting all MCS on the
+ /// chip that allows this "SYNC master" to broadcast the SYNC to all other
+ /// MCS on the chip.
+ uint32_t mcSyncAddr;
+
+ // Membuf_type is MEMTYPE_CENTAUR | MEMTYPE_OCMB | etc.
+ uint32_t membuf_type; // keep 8 byte aligned
+
+ /// A GpePbaParms parameter block for gpe_mem_data()
+ ///
+ /// This parameter block is set up in advance and used by the GPE
+ /// procedure gpe_membuf_data(). Given the complexity of accessing memory
+ /// sensors and SCOM through the PBA it is simpler to set these up ahead
+ /// of time and simply have the GPE procedures access preconfigured global
+ /// data. The \a dataParms and \a scomParms members are distinguished by
+ /// the different way the PBA slave needs to be configured to access
+ /// either the memory sensor cache or inband SCOMs.
+ GpePbaParms dataParms;
+
+ /// A GpePbaParms parameter block for inband scom.
+ GpePbaParms scomParms;
+
+ /// A "chip configuration" bit mask denoting valid memory buffer.
+ ///
+ /// It shoud always be true that a bit denoting a configured memory buffer
+ // is associated with a non-0 \a baseAddress and vice-versa.
+ uint32_t config;
+
+ // Digital Thermal Sensor configuration bitmap.
+ // use CONFIG_UBDTS0(n) CONFIG_MEMDTS0(n) CONFIG_MEMDTS1(n) to set/test
+ uint32_t dts_config;
+
+ uint32_t reserved; // Keep structure size multiple of 8
+
+ /// The final return code from gpe_*_configuration_create().
+ /// @see MemBufConfigurationCreateRc
+ /// If initialization fails then this value can be used to diagnose what
+ /// happend. This field should be statically initialized to a non-0 value
+ /// (MEMBUF_NOT_CONFIGURED) and can then be checked against 0 to
+ /// determine if the structure has been correctly initialized.
+ int32_t configRc;
+
+} MemBufConfiguration_t __attribute__((aligned(8)));
+
+
+typedef struct
+{
+ union
+ {
+ struct
+ {
+ uint32_t scom;
+ uint8_t reserved;
+ uint8_t errorFlags;
+ uint8_t instanceNumber;
+ uint8_t commandType;
+ };
+ uint64_t command;
+ };
+ uint64_t mask;
+ union
+ {
+ uint64_t data;
+ struct
+ {
+ uint32_t unused;
+ uint64_t* pData;
+ };
+ };
+} scomList_t;
+
+
+// Inband Scom Return Codes
+enum
+{
+ // rc 1 - 7 reserved from scom rc
+ INBAND_ACCESS_INACTIVE = 98,
+ INBAND_ACCESS_IN_PROGRESS = 99,
+ MEMBUF_INVALID_SCOM = 100,
+ MEMBUF_GET_MEM_DATA_COLLECT_INVALID = 200,
+ MEMBUF_GET_MEM_DATA_UPDATE_INVALID = 201,
+ MEMBUF_GET_MEM_DATA_DIED = 202,
+ MEMBUF_CHANNEL_CHECKSTOP = 203,
+ MEMBUF_SCACHE_ERROR = 204,
+};
+
+// Inband Scom Operations
+typedef enum
+{
+ /// No operation
+ MEMBUF_SCOM_NOP,
+
+ /// Read from SCOM, depositing read data into the \a data field of the
+ /// scomList_t.
+ MEMBUF_SCOM_READ,
+
+ /// Write to SCOM, taking write data from the \a data field of the scomList_t.
+ MEMBUF_SCOM_WRITE,
+
+ /// Read-Modify-Write.
+ ///
+ /// This operation first reads the SCOM. Bits under the \a mask field of the
+ /// scomList_t are then cleared in the read data. The masked read data is then
+ /// ORed with the contents of the \a data field of the scomList_t and the
+ /// result is written back to the SCOM address.
+ ///
+ /// \note This command \e does \e not apply the mask to the data from the \a
+ /// data field of the scomList_t. The caller should do this (if necessary)
+ /// when setting up the scomList_t.
+ ///
+ /// \note The procedures do not provide a way to distinguish errors that may
+ /// have occurred on the initial read vs. those that may have occurred on the
+ /// subsequenct write.
+ MEMBUF_SCOM_RMW,
+
+ /// The \a data field of the scomList_t contains a
+ /// 32-bit pointer (cast to a uint64_t) to an array of # of MEMBUF uint64_t
+ /// values. SCOM read data for each configured memory buffer module is
+ // deposited in this array. Array entries for unconfigured memory
+ // modules are zeroed.
+ MEMBUF_SCOM_READ_VECTOR,
+
+ /// Write the \a data field of the scomList_t to
+ /// all configured MEMBUFs.
+ MEMBUF_SCOM_WRITE_ALL,
+
+ /// Perform read-modify write for all configured
+ /// MEMBUF.
+ MEMBUF_SCOM_RMW_ALL,
+
+ // Send SYNC to broadcast new throttle values.
+ MEMBUF_SCOM_MEMBUF_SYNC,
+
+} membuf_scom_operation_t;
+
+#define MCS_MCSYNC_SYNC_GO 0x0000800000000000ull
+
+// BAR and PBA_SLAVE assigned to gpe1 membuf
+// - @see POWER Energy Management Hcode/HWP spec
+#define PBA_BAR_MEMBUF 1
+#define PBA_SLAVE_MEMBUF 2
+
+// These are used to setup MemBufConfiguration.config field
+#define CHIP_CONFIG_MCS_BASE 16
+#define CHIP_CONFIG_MCS(n) \
+ ((0x80000000ul >> CHIP_CONFIG_MCS_BASE) >> (n))
+
+#define CHIP_CONFIG_MEMBUF_BASE 24
+#define CHIP_CONFIG_MEMBUF(n) \
+ ((0x80000000ul >> CHIP_CONFIG_MEMBUF_BASE) >> (n))
+
+#define CONFIG_UBDTS0(n) \
+ (0x80000000ul >> (4*n))
+
+#define CONFIG_MEMDTS0(n) \
+ (0x40000000ul >> (4*n))
+
+#define CONFIG_MEMDTS1(n) \
+ (0x20000000ul >> (4*n))
+
+#endif
+
+
diff --git a/src/common/membuf_structs.h b/src/common/membuf_structs.h
new file mode 100644
index 0000000..279af31
--- /dev/null
+++ b/src/common/membuf_structs.h
@@ -0,0 +1,92 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/common/membuf_structs.h $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016,2018 */
+/* [+] 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 */
+
+/* This header file is used by both occ_405 and occ_gpe1. */
+/* Contains common structures and globals. */
+#if !defined(_MEMBUF_STRUCTS_H)
+#define _MEMBUF_STRUCTS_H
+
+#include "stdint.h"
+#include "gpe_export.h"
+#include "membuf_configuration.h"
+
+// IPC message payload for call to gpe_membuf_init()
+typedef struct
+{
+ GpeErrorStruct error;
+ MemBufConfiguration_t * membufConfiguration;
+ uint32_t mem_type;
+
+} MemBufConfigParms_t;
+
+// IPC message payload for call to gpe_membuf_scom()
+typedef struct
+{
+ GpeErrorStruct error;
+
+ /**
+ * Input: The SCOM list
+ * This is a pointer to an array of scomList_t objects
+ * describing the sequence of commands to execute.
+ */
+ scomList_t* scomList;
+
+ /**
+ * Input: The number of entries in the scomList.
+ * @note It is considered an error if \a entries is 0, under the
+ * assumption that the caller must have neglected to initialize the
+ * structure.
+ */
+ int entries;
+
+} MemBufScomParms_t;
+
+// IPC message payload for call to gpe_membuf_data()
+typedef struct
+{
+ GpeErrorStruct error;
+
+ /**
+ * The index (0 .. NMEMBUF - 1) of the MemBuf whose sensor cache
+ * data to collect, or -1 to bypass collection.
+ */
+ int collect;
+
+ /**
+ * The index (0 .. NMEMBUF - 1) of the MemBuf to "poke" to cause it
+ * to begin collecting the next round of data into its sensor cache, or
+ * -1 to bypass updating
+ */
+ int update;
+
+ /**
+ * Pointer to data collected. Needs to be set if collect != -1
+ * otherwise it's not used.
+ */
+ uint64_t * data;
+} MemBufGetMemDataParms_t;
+
+
+#endif
diff --git a/src/common/ocmb_mem_data.h b/src/common/ocmb_mem_data.h
new file mode 100644
index 0000000..4534dc5
--- /dev/null
+++ b/src/common/ocmb_mem_data.h
@@ -0,0 +1,87 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/common/ocmb_mem_data.h $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016,2018 */
+/* [+] 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 */
+
+/* This header file is used by both occ_405 and occ_gpe1. */
+/* Contains common structures and globals. */
+#if !defined(__OCMB_MEM_DATA_H__)
+#define __OCMB_MEM_DATA_H__
+
+typedef union
+{
+ uint16_t value;
+ struct
+ {
+ uint16_t ubdts0_err : 1;
+ uint16_t ubdts0_valid : 1;
+ uint16_t ubdts0_present : 1;
+ uint16_t memdts0_err : 1;
+ uint16_t memdts0_valid : 1;
+ uint16_t memdts0_present : 1;
+ uint16_t memdts1_err : 1;
+ uint16_t memdts1_valid : 1;
+ uint16_t memdts1_present : 1;
+ uint16_t event : 1;
+ uint16_t initial_packet0 : 1;
+ uint16_t reserved : 5;
+
+ } fields;
+} ocmb_status_t;
+
+typedef union
+{
+ uint32_t value;
+ struct
+ {
+ uint32_t initial_packet1 : 1;
+ uint32_t reserved2 : 7;
+ uint32_t reserved1 : 24;
+ } fields;
+} ocmb_pkt1_status_t;
+
+
+typedef struct
+{
+ ocmb_status_t status;
+ uint16_t ubdts0; // Membuf thermal sensor
+ uint16_t memdts[2]; // dimm0/1/ thermal sensor
+ uint32_t mba_rd; // MBA reads
+ uint32_t mba_wr; // MBA writes
+ uint32_t mba_act; // MBA activations
+ uint32_t mba_powerups;
+ uint8_t self_timed_refresh; // lp2_exists
+ uint8_t reserved1;
+ uint16_t reserved2;
+ uint32_t frame_count;
+
+ uint32_t mba_arr_cnt_base;
+ uint32_t mba_arr_cnt_low;
+ uint32_t mba_arr_cnt_med;
+ uint32_t mba_arr_cnt_high;
+ ocmb_pkt1_status_t status1;
+ uint32_t reserved4;
+ uint64_t reserved5;
+} OcmbMemData;
+
+#endif
diff --git a/src/include/registers/ocmb_firmware_registers.h b/src/include/registers/ocmb_firmware_registers.h
new file mode 100644
index 0000000..dabd2d1
--- /dev/null
+++ b/src/include/registers/ocmb_firmware_registers.h
@@ -0,0 +1,93 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/include/registers/ocmb_firmware_registers.h $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2011,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 */
+#ifndef __OCMB_FIRMWARE_REGISTERS_H__
+#define __OCMB_FIRMWARE_REGISTERS_H__
+
+#include <stdint.h>
+
+typedef union ocmb_mmio_merrctl
+{
+ uint64_t value;
+ struct
+ {
+ uint32_t high_order;
+ uint32_t low_order;
+ } words;
+
+ struct
+ {
+ uint64_t dont_care0: 52;
+ uint64_t snsc_master_enable : 1;
+ uint64_t dont_care1: 11;
+ } fields;
+
+} mmio_merrctl_t;
+
+#define SNSC_MASTER_ENABLED 1
+#define SNSC_MASTER_DISABLED 0
+
+typedef union ocmb_mmio_mfir
+{
+ uint64_t value;
+ struct
+ {
+ uint32_t high_order;
+ uint32_t low_order;
+ } words;
+
+ struct
+ {
+ uint64_t dont_care0: 7;
+ uint64_t snsc_both_starts_err: 1;
+ uint64_t snsc_mult_seq_perr: 1;
+ uint64_t snsc_fsm_perr: 1;
+ uint64_t snsc_reg_perr: 1;
+ uint64_t dont_care1: 53;
+ } fields;
+} mmio_mfir_t;
+
+typedef union ocmb_mba_farb3q
+{
+ uint64_t value;
+ struct
+ {
+ uint32_t high_order;
+ uint32_t low_order;
+ } words;
+
+ struct
+ {
+ uint64_t cfg_nm_n_per_slot: 15; //mba
+ uint64_t cfg_nm_n_per_port: 16; //chip
+ uint64_t cfg_nm_m: 14;
+ uint64_t cfg_nm_ras_weight: 3;
+ uint64_t cfg_nm_cas_weight: 3;
+ uint64_t reserved0: 2;
+ uint64_t cfg_nm_change_after_sync: 1;
+ uint64_t reserved1: 10;
+ } fields;
+} ocmb_mba_farb3q_t;
+
+#endif
diff --git a/src/include/registers/ocmb_register_addresses.h b/src/include/registers/ocmb_register_addresses.h
new file mode 100644
index 0000000..fb3070a
--- /dev/null
+++ b/src/include/registers/ocmb_register_addresses.h
@@ -0,0 +1,39 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/include/registers/ocmb_register_addresses.h $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2011,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 */
+#ifndef __OCMB_REGISTER_ADDRESSES_H__
+#define __OCMB_REGISTER_ADDRESSES_H__
+
+
+#define MMIO_MERRCTL 0x080108ea
+#define MMIO_MFIR 0x08010870
+#define MMIO_MFIR_AND 0x08010871
+
+// N/M Throtling Control
+#define OCMB_MBA_FARB3Q 0x08011418
+
+#define OCMB_IB_SENSOR_CACHE_ADDR (0x40084200 >> 3)
+#define OCMB_IB_BAR_B_BIT (0x0000000080000000ull)
+
+#endif
diff --git a/src/include/registers/p9a_firmware_registers.h b/src/include/registers/p9a_firmware_registers.h
new file mode 100644
index 0000000..98c1bcd
--- /dev/null
+++ b/src/include/registers/p9a_firmware_registers.h
@@ -0,0 +1,79 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/include/registers/p9a_firmware_registers.h $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016,2018 */
+/* [+] 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 */
+
+/* This header file is used by both occ_405 and occ_gpe1. */
+/* Contains common structures and globals. */
+#if !defined(__P9A_FIRMWARE_REGISTERS_H__)
+#define __P9A_FIRMWARE_REGISTERS_H__
+
+typedef union mcfgpr
+{
+ uint64_t value;
+ struct
+ {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct
+ {
+#ifdef _BIG_ENDIAN
+ uint64_t config_valid : 1;
+ uint64_t mmio_valid : 1;
+ uint64_t config_group_addr : 31;
+ uint64_t mmio_group_base_addr : 31;
+#else
+ uint64_t mmio_group_base_addr : 31;
+ uint64_t config_group_addr : 31;
+ uint64_t mmio_valid : 1;
+ uint64_t config_valid : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} mcfgpr_t;
+
+
+typedef union
+{
+ uint64_t value;
+ struct
+ {
+#ifdef _BIG_ENDIAN
+ uint64_t dont_care : 56;
+ uint64_t addr_extension_group_id : 4;
+ uint64_t addr_extension_chip_id : 3;
+ uint64_t dont_care1 : 1;
+#else
+ uint64_t dont_care1 : 1;
+ uint64_t addr_extension_chip_id : 3;
+ uint64_t addr_extension_group_id : 4;
+ uint64_t dont_care : 56;
+#endif
+ } fields;
+} pb_mode_t;
+#endif
diff --git a/src/include/registers/p9a_misc_scom_addresses.h b/src/include/registers/p9a_misc_scom_addresses.h
new file mode 100644
index 0000000..6a6975e
--- /dev/null
+++ b/src/include/registers/p9a_misc_scom_addresses.h
@@ -0,0 +1,43 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/include/registers/p9a_misc_scom_addresses.h $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2011,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 */
+// Axone MC Primary Memory Configuration Register, Inband
+#define P9A_MI_0_MCFGPR0 0x0501080C
+#define P9A_MI_1_MCFGPR0 0x0501088C
+#define P9A_MI_2_MCFGPR0 0x0301080C
+#define P9A_MI_3_MCFGPR0 0x0301088C
+
+#define P9A_MI_0_MCFGPR1 0x0501080D
+#define P9A_MI_1_MCFGPR1 0x0501088D
+#define P9A_MI_2_MCFGPR1 0x0301080D
+#define P9A_MI_3_MCFGPR1 0x0301088D
+
+// Axone MC Sync Command Register
+#define P9A_MI_0_MCSYNC 0x05010815
+#define P9A_MI_1_MCSYNC 0x05010895
+#define P9A_MI_2_MCSYNC 0x03010815
+#define P9A_MI_3_MCSYNC 0x03010895
+
+// Axone PB Mode register
+#define P9A_PU_NMMU_MMCQ_PB_MODE_REG 0x05012C15
diff --git a/src/occ_405/amec/amec_sensors_ocmb.c b/src/occ_405/amec/amec_sensors_ocmb.c
new file mode 100644
index 0000000..3e57266
--- /dev/null
+++ b/src/occ_405/amec/amec_sensors_ocmb.c
@@ -0,0 +1,634 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/occ_405/amec/amec_sensors_centaur.c $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2011,2018 */
+/* [+] 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 */
+
+/******************************************************************************/
+/* includes */
+/******************************************************************************/
+#include <occ_common.h>
+#include <ssx.h>
+#include <errl.h> // Error logging
+#include "sensor.h"
+#include "rtls.h"
+#include "occ_sys_config.h"
+#include "occ_service_codes.h" // for SSX_GENERIC_FAILURE
+#include "dcom.h"
+#include "memory.h"
+#include "centaur_data.h"
+#include "amec_smh.h"
+#include "amec_slave_smh.h"
+#include <trac.h>
+#include "amec_sys.h"
+#include "sensor_enum.h"
+#include "amec_service_codes.h"
+#include "amec_sensors_ocmb.h"
+#include "ocmb_mem_data.h"
+
+/******************************************************************************/
+/* Globals */
+/******************************************************************************/
+extern dimm_sensor_flags_t G_dimm_overtemp_bitmap;
+extern dimm_sensor_flags_t G_dimm_temp_updated_bitmap;
+extern uint8_t G_cent_overtemp_bitmap;
+extern uint8_t G_cent_temp_updated_bitmap;
+extern uint8_t G_centaur_needs_recovery;
+extern uint64_t G_inject_dimm;
+extern uint32_t G_inject_dimm_trace[MAX_NUM_OCMBS][NUM_DIMMS_PER_OCMB];
+
+uint32_t amec_diff_adjust_for_overflow(uint32_t i_new_value, uint32_t i_old_value);
+
+/******************************************************************************/
+/* Forward Declarations */
+/******************************************************************************/
+void amec_update_ocmb_dimm_dts_sensors(OcmbMemData * i_sensor_cache, uint8_t i_membuf);
+void amec_update_ocmb_dts_sensors(OcmbMemData * i_sensor_cache, uint8_t i_membuf);
+void amec_perfcount_ocmb_getmc( OcmbMemData * i_sensor_cache, uint8_t i_membuf);
+
+/******************************************************************************/
+/* Code */
+/******************************************************************************/
+
+// Function Specification
+//
+// Name: amec_update_ocmb_dimm_dts_sensors
+//
+// Description: Updates sensors that have data grabbed by the fast core data
+// task.
+//
+// Thread: RealTime Loop
+//
+// End Function Specification
+void amec_update_ocmb_sensors(uint8_t i_membuf)
+{
+ if(CENTAUR_PRESENT(i_membuf))
+ {
+ OcmbMemData * l_sensor_cache =
+ (OcmbMemData *)cent_get_centaur_data_ptr(i_membuf);
+ if(CENTAUR_UPDATED(i_membuf))
+ {
+ amec_update_ocmb_dimm_dts_sensors(l_sensor_cache, i_membuf);
+ amec_update_ocmb_dts_sensors(l_sensor_cache, i_membuf);
+ amec_perfcount_ocmb_getmc(l_sensor_cache, i_membuf);
+ }
+ CLEAR_CENTAUR_UPDATED(i_membuf);
+ }
+}
+
+// Function Specification
+//
+// Name: amec_update_ocmb_dimm_dts_sensors
+//
+// Description: Updates sensors that have data from the membuf sensor cache
+//
+// Thread: RealTime Loop
+//
+// Note: The ocmb cache data uses the same space as the Centaur
+// membuf cache data, so some of the centaur attributes apply to
+// Ocmb data as well as Centaur.
+//
+// End Function Specification
+void amec_update_ocmb_dimm_dts_sensors(OcmbMemData * i_sensor_cache, uint8_t i_membuf)
+{
+#define MIN_VALID_DIMM_TEMP 1
+#define MAX_VALID_DIMM_TEMP 125 //according to Mike Pardiek 04/23/2019
+#define MAX_MEM_TEMP_CHANGE 2
+
+ uint32_t k, l_hottest_dimm_temp;
+ uint16_t l_dts[NUM_DIMMS_PER_OCMB] = {0};
+ uint32_t l_hottest_dimm_loc = NUM_DIMMS_PER_OCMB;
+ int32_t l_dimm_temp, l_prev_temp;
+ static uint8_t L_ran_once[MAX_NUM_OCMBS] = {FALSE};
+
+ // Harvest thermal data for all dimms
+ for(k=0; k < NUM_DIMMS_PER_OCMB; k++)
+ {
+ if(!CENTAUR_SENSOR_ENABLED(i_membuf, k))
+ {
+ continue;
+ }
+
+#ifdef __INJECT_DIMM__
+ if (g_amec->proc[0].memctl[i_membuf].centaur.dimm_temps[k].temp_sid) // DIMM has sensor ID
+ {
+ if ((G_inject_dimm & ((uint64_t)1 << ((i_membuf * 8) + k))) == 0)
+ {
+ if (G_inject_dimm_trace[i_membuf][k] != 0)
+ {
+ TRAC_INFO("amec_update_ocmb_dimm_dts_sensors: stopping injection of errors for DIMM%04X", (i_membuf<<8)|k);
+ G_inject_dimm_trace[i_membuf][k] = 0;
+ }
+ }
+ else
+ {
+ if (G_inject_dimm_trace[i_membuf][k] == 0)
+ {
+ TRAC_INFO("amec_update_ocmb_dimm_dts_sensors: injecting errors for DIMM%04X", (i_membuf<<8)|k);
+ G_inject_dimm_trace[i_membuf][k] = 1;
+ }
+ continue; // Skip this DIMM
+ }
+ }
+#endif
+
+ fru_temp_t* l_fru = &g_amec->proc[0].memctl[i_membuf].centaur.dimm_temps[k];
+
+ l_dimm_temp = i_sensor_cache->memdts[k];
+ l_prev_temp = l_fru->cur_temp;
+ if(!l_prev_temp)
+ {
+ l_prev_temp = l_dimm_temp;
+ }
+
+ //Check DTS status bits. VALID NEW if valid and !err
+ if((k == 0 &&
+ i_sensor_cache->status.fields.memdts0_valid &&
+ (!i_sensor_cache->status.fields.memdts0_err)) ||
+ (k == 1 &&
+ i_sensor_cache->status.fields.memdts1_valid &&
+ (!i_sensor_cache->status.fields.memdts1_err)))
+ {
+ //make sure temperature is within a 'reasonable' range.
+ if(l_dimm_temp < MIN_VALID_DIMM_TEMP ||
+ l_dimm_temp > MAX_VALID_DIMM_TEMP)
+ {
+ //set a flag so that if we end up logging an error we have something to debug why
+ l_fru->flags |= FRU_TEMP_OUT_OF_RANGE;
+ l_dts[k] = l_prev_temp;
+ }
+ else
+ {
+ //don't allow temp to change more than is reasonable for 2ms
+ if(l_dimm_temp > (l_prev_temp + MAX_MEM_TEMP_CHANGE))
+ {
+ l_dts[k] = l_prev_temp + MAX_MEM_TEMP_CHANGE;
+ if(!l_fru->flags)
+ {
+ TRAC_INFO("dimm temp rose faster than reasonable: membuf[%d] dimm[%d] prev[%d] cur[%d]",
+ i_membuf, k, l_prev_temp, l_dimm_temp);
+ l_fru->flags |= FRU_TEMP_FAST_CHANGE;
+ }
+ }
+ else if (l_dimm_temp < (l_prev_temp - MAX_MEM_TEMP_CHANGE))
+ {
+ l_dts[k] = l_prev_temp - MAX_MEM_TEMP_CHANGE;
+ if(!l_fru->flags)
+ {
+ TRAC_INFO("dimm temp fell faster than reasonable: membuf[%d] dimm[%d] prev[%d] cur[%d]",
+ i_membuf, k, l_prev_temp, l_dimm_temp);
+ l_fru->flags |= FRU_TEMP_FAST_CHANGE;
+ }
+ }
+ else //reasonable amount of change occurred
+ {
+ l_dts[k] = l_dimm_temp;
+ l_fru->flags &= ~FRU_TEMP_FAST_CHANGE;
+ }
+
+ //Notify thermal thread that temperature has been updated
+ G_dimm_temp_updated_bitmap.bytes[i_membuf] |= DIMM_SENSOR0 >> k;
+
+ //clear error flags
+ l_fru->flags &= FRU_TEMP_FAST_CHANGE;
+ }
+ }
+ else //status was VALID_OLD or ERROR
+ {
+ //convert status number to a flag
+ uint8_t l_status_flag = 0;
+ if((k == 0 && i_sensor_cache->status.fields.memdts0_err) ||
+ (k == 1 && i_sensor_cache->status.fields.memdts1_err))
+ {
+ l_status_flag = FRU_SENSOR_STATUS_ERROR;
+ }
+ else
+ {
+ l_status_flag = FRU_SENSOR_STATUS_VALID_OLD;
+ }
+
+ if(L_ran_once[i_membuf])
+ {
+ //Trace the error if we haven't traced it already for this sensor
+ if((l_status_flag != FRU_SENSOR_STATUS_VALID_OLD) &&
+ !(l_status_flag & l_fru->flags))
+ {
+ TRAC_ERR("Membuf %d dimm sensor%d reported an error.", i_membuf, k);
+ }
+
+ l_fru->flags |= l_status_flag;
+ }
+
+ //use last temperature
+ l_dts[k] = l_prev_temp;
+
+ //request recovery (disable and re-enable sensor cache collection)
+ if(i_sensor_cache->status.fields.memdts0_err ||
+ i_sensor_cache->status.fields.memdts1_err)
+ {
+ G_centaur_needs_recovery |= CENTAUR0_PRESENT_MASK >> i_membuf;
+ }
+ }
+
+ //Check if at or above the error temperature
+ if(l_dts[k] >= g_amec->thermaldimm.ot_error)
+ {
+ //Set a bit so that this dimm can be called out by the thermal thread
+ G_dimm_overtemp_bitmap.bytes[i_membuf] |= 1 << k;
+ }
+ }
+
+ // Find hottest temperature from all DIMMs for this centaur
+ for(l_hottest_dimm_temp = 0, k = 0; k < NUM_DIMMS_PER_OCMB; k++)
+ {
+ if(l_dts[k] > l_hottest_dimm_temp)
+ {
+ l_hottest_dimm_temp = l_dts[k];
+ l_hottest_dimm_loc = k;
+ }
+ g_amec->proc[0].memctl[i_membuf].centaur.dimm_temps[k].cur_temp = l_dts[k];
+ }
+
+ amec_centaur_t* l_centaur_ptr = &g_amec->proc[0].memctl[i_membuf].centaur;
+
+ //only update location if hottest dimm temp is greater than previous maximum
+ if(l_hottest_dimm_temp > l_centaur_ptr->tempdimmax.sample_max)
+ {
+ sensor_update(&l_centaur_ptr->locdimmax, l_hottest_dimm_loc);
+ }
+
+ //update the max dimm temperature sensor for this centaur
+ sensor_update(&l_centaur_ptr->tempdimmax, l_hottest_dimm_temp);
+
+ L_ran_once[i_membuf] = TRUE;
+ AMEC_DBG("Centaur[%d]: HotDimm=%d\n",i_membuf,l_hottest_dimm_temp);
+}
+
+// Function Specification
+//
+// Name: amec_update_ocmb_dts_sensors
+//
+// Description: Updates sensors that have data grabbed by the fast core data
+//
+// Thread: RealTime Loop
+//
+// End Function Specification
+void amec_update_ocmb_dts_sensors(OcmbMemData * i_sensor_cache, uint8_t i_membuf)
+{
+#define MIN_VALID_MEMBUF_TEMP 1
+#define MAX_VALID_MEMBUF_TEMP 125 //according to Mike Pardiek
+
+ uint16_t l_dts;
+ uint16_t l_sens_temp;
+ int32_t l_prev_temp;
+ static uint8_t L_ran_once[MAX_NUM_OCMBS] = {FALSE};
+
+ l_sens_temp = i_sensor_cache->ubdts0;
+
+ fru_temp_t* l_fru = &g_amec->proc[0].memctl[i_membuf].centaur.centaur_hottest;
+
+ l_prev_temp = l_fru->cur_temp;
+ if(!l_prev_temp)
+ {
+ l_prev_temp = l_sens_temp;
+ }
+
+ //Check DTS status bits
+ if(i_sensor_cache->status.fields.ubdts0_valid &&
+ (!i_sensor_cache->status.fields.ubdts0_err))
+ {
+ //make sure temperature is within a 'reasonable' range.
+ if(l_sens_temp < MIN_VALID_MEMBUF_TEMP ||
+ l_sens_temp > MAX_VALID_MEMBUF_TEMP)
+ {
+ //set a flag so that if we end up logging an error we have something to debug why
+ l_fru->flags |= FRU_TEMP_OUT_OF_RANGE;
+ l_dts = l_prev_temp;
+ }
+ else
+ {
+ //don't allow temp to change more than is reasonable for 2ms
+ if(l_sens_temp > (l_prev_temp + MAX_MEM_TEMP_CHANGE))
+ {
+ l_dts = l_prev_temp + MAX_MEM_TEMP_CHANGE;
+ if(!l_fru->flags)
+ {
+ TRAC_INFO("membuf temp rose faster than reasonable: membuf[%d] prev[%d] cur[%d]",
+ i_membuf, l_prev_temp, l_sens_temp);
+ l_fru->flags |= FRU_TEMP_FAST_CHANGE;
+ }
+ }
+ else if (l_sens_temp < (l_prev_temp - MAX_MEM_TEMP_CHANGE))
+ {
+ l_dts = l_prev_temp - MAX_MEM_TEMP_CHANGE;
+ if(!l_fru->flags)
+ {
+ TRAC_INFO("membuf temp fell faster than reasonable: cent[%d] prev[%d] cur[%d]",
+ i_membuf, l_prev_temp, l_sens_temp);
+ l_fru->flags |= FRU_TEMP_FAST_CHANGE;
+ }
+ }
+ else //reasonable amount of change occurred
+ {
+ l_dts = l_sens_temp;
+ l_fru->flags &= ~FRU_TEMP_FAST_CHANGE;
+ }
+
+ //Notify thermal thread that temperature has been updated
+ G_cent_temp_updated_bitmap |= CENTAUR0_PRESENT_MASK >> i_membuf;
+
+ //clear error flags
+ l_fru->flags &= FRU_TEMP_FAST_CHANGE;
+ }
+ }
+ else //status was INVALID
+ {
+ if(L_ran_once[i_membuf])
+ {
+ //Trace the error if we haven't traced it already for this sensor
+ if(!(l_fru->flags & FRU_SENSOR_STATUS_INVALID) &&
+ i_sensor_cache->status.fields.ubdts0_err)
+ {
+ TRAC_ERR("Membuf %d temp sensor error.", i_membuf);
+ }
+
+ l_fru->flags |= FRU_SENSOR_STATUS_INVALID;
+ }
+
+ //use last temperature
+ l_dts = l_prev_temp;
+ }
+
+ L_ran_once[i_membuf] = TRUE;
+
+ //Check if at or above the error temperature
+ if(l_dts >= g_amec->thermalcent.ot_error)
+ {
+ //Set a bit so that this dimm can be called out by the thermal thread
+ G_cent_overtemp_bitmap |= (CENTAUR0_PRESENT_MASK >> i_membuf);
+ }
+
+ // Update Interim Data - later this will get picked up to form centaur sensor
+ g_amec->proc[0].memctl[i_membuf].centaur.centaur_hottest.cur_temp = l_dts;
+
+ AMEC_DBG("Membuf[%d]: HotMembuf=%d\n",i_membuf,l_dts);
+}
+
+// Function Specification
+//
+// Name: amec_update_ocmb_temp_sensors
+//
+// Description: Updates thermal sensors that have data grabbed by the centaur.
+//
+// Thread: RealTime Loop
+//
+// End Function Specification
+void amec_update_ocmb_temp_sensors(void)
+{
+ uint32_t k;
+ uint32_t l_hot_dimm = 0;
+ uint32_t l_hot_mb = 0;
+
+ // -----------------------------------------------------------
+ // Find hottest temperature from all membufs for this Proc chip
+ // Find hottest temperature from all DIMMs for this Proc chip
+ // -----------------------------------------------------------
+ for(k=0; k < MAX_NUM_OCMBS; k++)
+ {
+ if(g_amec->proc[0].memctl[k].centaur.centaur_hottest.cur_temp > l_hot_mb)
+ {
+ l_hot_mb = g_amec->proc[0].memctl[k].centaur.centaur_hottest.cur_temp;
+ }
+ if(g_amec->proc[0].memctl[k].centaur.tempdimmax.sample > l_hot_dimm)
+ {
+ l_hot_dimm = g_amec->proc[0].memctl[k].centaur.tempdimmax.sample;
+ }
+ }
+ sensor_update(&g_amec->proc[0].temp2mscent,l_hot_mb);
+ AMEC_DBG("HotMembuf=%d\n",l_hot_mb);
+
+ sensor_update(&g_amec->proc[0].tempdimmthrm,l_hot_dimm);
+ AMEC_DBG("HotDimm=%d\n",l_hot_dimm);
+
+}
+
+
+// Function Specification
+//
+// Name: amec_perfcount_ocmb_getmc
+//
+// Description: Updates performance sensors that have data grabbed by the
+// centaur.
+//
+// Thread: RealTime Loop
+//
+// End Function Specification
+
+void amec_perfcount_ocmb_getmc( OcmbMemData * i_sensor_cache,
+ uint8_t i_membuf)
+{
+ /*------------------------------------------------------------------------*/
+ /* Local Variables */
+ /*------------------------------------------------------------------------*/
+ uint32_t tempu = 0;
+ uint32_t templ = 0;
+ uint32_t temp32new = 0;
+ uint32_t temp32 = 0;
+ uint32_t tempreg = 0;
+
+ #define AMECSENSOR_PORTPAIR_PTR(sensor_base,idx,idx2) \
+ (&(g_amec->proc[0].memctl[idx].centaur.portpair[idx2].sensor_base))
+
+ /*------------------------------------------------------------------------*/
+ /* Code */
+ /*------------------------------------------------------------------------*/
+
+ OcmbMemData * l_sensor_cache = i_sensor_cache;
+
+ tempu = l_sensor_cache->mba_rd;
+ templ = l_sensor_cache->mba_wr;
+
+ // ---------------------------------------------------------------------------
+ // Interim Calculation: MWRMx (0.01 Mrps) Memory write requests per sec
+ // ---------------------------------------------------------------------------
+
+ // Extract write bandwidth
+ temp32new = (templ);
+
+ temp32 = g_amec->proc[0].memctl[i_membuf].centaur.portpair[0].perf.wr_cnt_accum;
+ temp32 = amec_diff_adjust_for_overflow(temp32new, temp32);
+ g_amec->proc[0].memctl[i_membuf].centaur.portpair[0].perf.wr_cnt_accum = temp32new; // Save latest accumulator away for next time
+
+ // Read every 8 ms....to convert to 0.01 Mrps = ((8ms read * 125)/10000)
+ tempreg = ((temp32*125)/10000);
+
+ g_amec->proc[0].memctl[i_membuf].centaur.portpair[0].perf.memwrite2ms = tempreg;
+
+ // -------------------------------------------------------------------------
+ // Interim Calculation: MRDMx (0.01 Mrps) Memory read requests per sec
+ // -------------------------------------------------------------------------
+
+ // Extract read bandwidth
+ temp32new = (tempu);
+
+ temp32 = g_amec->proc[0].memctl[i_membuf].centaur.portpair[0].perf.rd_cnt_accum;
+ temp32 = amec_diff_adjust_for_overflow(temp32new, temp32);
+ g_amec->proc[0].memctl[i_membuf].centaur.portpair[0].perf.rd_cnt_accum = temp32new; // Save latest accumulator away for next time
+
+ // Read every 8 ms....to convert to 0.01 Mrps = ((8ms read * 125)/10000)
+ tempreg = ((temp32*125)/10000);
+
+ g_amec->proc[0].memctl[i_membuf].centaur.portpair[0].perf.memread2ms = tempreg;
+
+ // Go after second MC performance counter (power ups and activations)
+ tempu = l_sensor_cache->mba_act;
+ templ = l_sensor_cache->mba_powerups;
+
+ // ----------------------------------------------------------------
+ // Sensor: MPUMx (0.01 Mrps) Memory power-up requests per sec
+ // ----------------------------------------------------------------
+ // Extract power up count
+ temp32new = (templ); // left shift into top 20 bits of 32 bits
+
+ // For DD1.0, we only have 1 channel field that we use; DD2.0 we need to add another channel
+ temp32 = g_amec->proc[0].memctl[i_membuf].centaur.portpair[0].perf.pwrup_cnt_accum;
+ temp32 = amec_diff_adjust_for_overflow(temp32new, temp32);
+ g_amec->proc[0].memctl[i_membuf].centaur.portpair[0].perf.pwrup_cnt_accum = temp32new; // Save latest accumulator away for next time
+ tempreg=(uint16_t)(temp32>>12); // Select upper 20 bits
+ g_amec->proc[0].memctl[i_membuf].centaur.portpair[0].perf.pwrup_cnt=(uint16_t)tempreg;
+ sensor_update(AMECSENSOR_PORTPAIR_PTR(mpu2ms,i_membuf,0), tempreg);
+
+ // -------------------------------------------------------------------
+ // Sensor: MACMx (0.01 Mrps) Memory activation requests per sec
+ // -------------------------------------------------------------------
+ // Extract activation count
+ temp32 = templ;
+ temp32 += tempu;
+
+ temp32new = (temp32); // left shift into top 20 bits of 32 bits
+ // For DD1.0, we only have 1 channel field that we use; DD2.0 we need to add another channel
+ temp32 = g_amec->proc[0].memctl[i_membuf].centaur.portpair[0].perf.act_cnt_accum;
+ temp32 = amec_diff_adjust_for_overflow(temp32new, temp32);
+ g_amec->proc[0].memctl[i_membuf].centaur.portpair[0].perf.act_cnt_accum = temp32new; // Save latest accumulator away for next time
+ tempreg=(uint16_t)(temp32>>12); // Select lower 16 of 20 bits
+ g_amec->proc[0].memctl[i_membuf].centaur.portpair[0].perf.act_cnt=(uint16_t)tempreg;
+ sensor_update(AMECSENSOR_PORTPAIR_PTR(mac2ms,i_membuf,0), tempreg);
+
+ // --------------------------------------------------------------------------
+ // Sensor: MTS (count) Last received Timestamp (frame count) from Centaur
+ // --------------------------------------------------------------------------
+ // Extract framecount (clock is 266.6666666MHz * 0.032 / 4096)=2083.
+ temp32new = l_sensor_cache->frame_count;
+
+ temp32 = g_amec->proc[0].memctl[i_membuf].centaur.portpair[0].perf.fr2_cnt_accum;
+ temp32 = amec_diff_adjust_for_overflow(temp32new, temp32);
+ g_amec->proc[0].memctl[i_membuf].centaur.portpair[0].perf.fr2_cnt_accum = temp32new; // Save latest accumulator away for next time
+ tempreg=(uint16_t)(temp32>>12); // Select upper 20 bits
+
+ g_amec->proc[0].memctl[i_membuf].centaur.portpair[0].perf.fr2_cnt=(uint16_t)tempreg;
+ sensor_update(AMECSENSOR_PORTPAIR_PTR(mts2ms,i_membuf,0), tempreg);
+
+ // ------------------------------------------------------------------------------
+ // Sensor: MIRB (0.01 Mevents/s) Memory Inter-request arrival idle intervals
+ // ------------------------------------------------------------------------------
+ temp32new = l_sensor_cache->mba_arr_cnt_base;
+ temp32 = g_amec->proc[0].memctl[i_membuf].centaur.portpair[0].perf.intreq_base_accum;
+ temp32 = amec_diff_adjust_for_overflow(temp32new, temp32);
+ g_amec->proc[0].memctl[i_membuf].centaur.portpair[0].perf.intreq_base_accum = temp32new; // Save latest accumulator away for next time
+
+ // Read every 8 ms....to convert to 0.01 Mrps = ((8ms read * 125)/10000)
+ tempreg = ((temp32*125)/10000);
+ g_amec->proc[0].memctl[i_membuf].centaur.portpair[0].perf.mirb2ms = tempreg;
+ sensor_update(AMECSENSOR_PORTPAIR_PTR(mirb2ms,i_membuf,0), tempreg);
+
+ // --------------------------------------------------------------------------------------------------------
+ // Sensor: MIRL (0.01 Mevents/s) Memory Inter-request arrival idle intervals longer than low threshold
+ // --------------------------------------------------------------------------------------------------------
+ temp32new = l_sensor_cache->mba_arr_cnt_low;
+ temp32 = g_amec->proc[0].memctl[i_membuf].centaur.portpair[0].perf.intreq_low_accum;
+ temp32 = amec_diff_adjust_for_overflow(temp32new, temp32);
+ g_amec->proc[0].memctl[i_membuf].centaur.portpair[0].perf.intreq_low_accum = temp32new; // Save latest accumulator away for next time
+
+ // Read every 8 ms....to convert to 0.01 Mrps = ((8ms read * 125)/10000)
+ tempreg = ((temp32*125)/10000);
+ g_amec->proc[0].memctl[i_membuf].centaur.portpair[0].perf.mirl2ms = tempreg;
+ sensor_update(AMECSENSOR_PORTPAIR_PTR(mirl2ms,i_membuf,0), tempreg);
+
+ // -----------------------------------------------------------------------------------------------------------
+ // Sensor: MIRM (0.01 Mevents/s) Memory Inter-request arrival idle intervals longer than medium threshold
+ // -----------------------------------------------------------------------------------------------------------
+ temp32new = l_sensor_cache->mba_arr_cnt_med;
+ temp32 = g_amec->proc[0].memctl[i_membuf].centaur.portpair[0].perf.intreq_med_accum;
+ temp32 = amec_diff_adjust_for_overflow(temp32new, temp32);
+ g_amec->proc[0].memctl[i_membuf].centaur.portpair[0].perf.intreq_med_accum = temp32new; // Save latest accumulator away for next time
+
+ // Read every 8 ms....to convert to 0.01 Mrps = ((8ms read * 125)/10000)
+ tempreg = ((temp32*125)/10000);
+ g_amec->proc[0].memctl[i_membuf].centaur.portpair[0].perf.mirm2ms = tempreg;
+ sensor_update(AMECSENSOR_PORTPAIR_PTR(mirm2ms,i_membuf,0), tempreg);
+
+ // ---------------------------------------------------------------------------------------------------------
+ // Sensor: MIRH (0.01 Mevents/s) Memory Inter-request arrival idle intervals longer than high threshold
+ // ---------------------------------------------------------------------------------------------------------
+ temp32new = l_sensor_cache->mba_arr_cnt_high;
+ temp32 = g_amec->proc[0].memctl[i_membuf].centaur.portpair[0].perf.intreq_high_accum;
+ temp32 = amec_diff_adjust_for_overflow(temp32new, temp32);
+ g_amec->proc[0].memctl[i_membuf].centaur.portpair[0].perf.intreq_high_accum = temp32new; // Save latest accumulator away for next time
+
+ // Read every 8 ms....to convert to 0.01 Mrps = ((8ms read * 125)/10000)
+ tempreg = ((temp32*125)/10000);
+ g_amec->proc[0].memctl[i_membuf].centaur.portpair[0].perf.mirh2ms = tempreg;
+ sensor_update(AMECSENSOR_PORTPAIR_PTR(mirh2ms,i_membuf,0), tempreg);
+
+ // ----------------------------------------------------
+ // Sensor: MLP2 (events/s) Number of LP2 exits
+ // ----------------------------------------------------
+ temp32new = l_sensor_cache->self_timed_refresh;
+ temp32 = g_amec->proc[0].memctl[i_membuf].centaur.perf.lp2exit_accum;
+ temp32 = amec_diff_adjust_for_overflow(temp32new, temp32);
+ g_amec->proc[0].memctl[i_membuf].centaur.perf.lp2exit_accum = temp32new; // Save latest accumulator away for next time
+
+ // Read every 8 ms....to convert to 0.01 Mrps = ((8ms read * 125)/10000)
+ tempreg = ((temp32*125)/10000);
+ g_amec->proc[0].memctl[i_membuf].centaur.perf.mlp2_2ms = tempreg;
+ sensor_update((&(g_amec->proc[0].memctl[i_membuf].centaur.mlp2ms)), tempreg);
+
+ // ------------------------------------------------------------
+ // Sensor: MRDMx (0.01 Mrps) Memory read requests per sec
+ // ------------------------------------------------------------
+ tempreg = g_amec->proc[0].memctl[i_membuf].centaur.portpair[0].perf.memread2ms;
+ tempreg += g_amec->proc[0].memctl[i_membuf].centaur.portpair[1].perf.memread2ms;
+ sensor_update( (&(g_amec->proc[0].memctl[i_membuf].mrd)), tempreg);
+
+ // -------------------------------------------------------------
+ // Sensor: MWRMx (0.01 Mrps) Memory write requests per sec
+ // -------------------------------------------------------------
+ tempreg = g_amec->proc[0].memctl[i_membuf].centaur.portpair[0].perf.memwrite2ms;
+ tempreg += g_amec->proc[0].memctl[i_membuf].centaur.portpair[1].perf.memwrite2ms;
+ sensor_update( (&(g_amec->proc[0].memctl[i_membuf].mwr)), tempreg);
+
+ return;
+}
+
+/*----------------------------------------------------------------------------*/
+/* End */
+/*----------------------------------------------------------------------------*/
diff --git a/src/occ_405/amec/amec_sensors_ocmb.h b/src/occ_405/amec/amec_sensors_ocmb.h
new file mode 100644
index 0000000..c290a3d
--- /dev/null
+++ b/src/occ_405/amec/amec_sensors_ocmb.h
@@ -0,0 +1,36 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/occ_405/amec/amec_sensors_ocmb.h $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2018 */
+/* [+] 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 */
+
+#ifndef _AMEC_SENSORS_OCMB_H
+#define _AMEC_SENSORS_OCMB_H
+
+//*************************************************************************
+// Function Prototypes
+//*************************************************************************
+void amec_update_ocmb_sensors(uint8_t i_membuf);
+void amec_update_ocmb_temp_sensors(void);
+
+#endif
+
diff --git a/src/occ_405/amec/amec_slave_smh.c b/src/occ_405/amec/amec_slave_smh.c
index 8c34a8a..5293f2f 100755
--- a/src/occ_405/amec/amec_slave_smh.c
+++ b/src/occ_405/amec/amec_slave_smh.c
@@ -46,6 +46,7 @@
#include <amec_sensors_power.h>
#include <memory.h>
#include <amec_sensors_centaur.h>
+#include <amec_sensors_ocmb.h>
#include <amec_sensors_fw.h>
#include <amec_freq.h>
#include <amec_data.h>
@@ -502,8 +503,14 @@ void amec_slv_state_0(void)
//-------------------------------------------------------
// Update Centaur sensors (for this tick)
//-------------------------------------------------------
- if (MEM_TYPE_CUMULUS == G_sysConfigData.mem_type)
+ if(MEM_TYPE_CUMULUS == G_sysConfigData.mem_type)
+ {
amec_update_centaur_sensors(CENTAUR_0);
+ }
+ else if(MEM_TYPE_OCM == G_sysConfigData.mem_type)
+ {
+ amec_update_ocmb_sensors(CENTAUR_0);
+ }
//-------------------------------------------------------
// Update vector sensors
@@ -531,20 +538,24 @@ void amec_slv_state_0(void)
// End Function Specification
void amec_slv_state_1(void)
{
- AMEC_DBG("\tAMEC Slave State 1\n");
-
- //-------------------------------------------------------
- // Update Centaur sensors (for this tick)
- //-------------------------------------------------------
- if (MEM_TYPE_CUMULUS == G_sysConfigData.mem_type)
- {
- amec_update_centaur_sensors(CENTAUR_1);
+ AMEC_DBG("\tAMEC Slave State 1\n");
+ if(MEM_TYPE_CUMULUS == G_sysConfigData.mem_type)
+ {
+ //-------------------------------------------------------
+ // Update Centaur sensors (for this tick)
+ //-------------------------------------------------------
+ amec_update_centaur_sensors(CENTAUR_1);
- //-------------------------------------------------------
- // Update Proc Level Centaur/DIMM Temperature sensors
- //-------------------------------------------------------
- amec_update_centaur_temp_sensors();
- }
+ //-------------------------------------------------------
+ // Update Proc Level Centaur/DIMM Temperature sensors
+ //-------------------------------------------------------
+ amec_update_centaur_temp_sensors();
+ }
+ else if(MEM_TYPE_OCM == G_sysConfigData.mem_type)
+ {
+ amec_update_ocmb_sensors(CENTAUR_1);
+ amec_update_ocmb_temp_sensors();
+ }
}
@@ -562,8 +573,14 @@ void amec_slv_state_2(void)
//-------------------------------------------------------
// Update Centaur sensors (for this tick)
//-------------------------------------------------------
- if (MEM_TYPE_CUMULUS == G_sysConfigData.mem_type)
+ if(MEM_TYPE_CUMULUS == G_sysConfigData.mem_type)
+ {
amec_update_centaur_sensors(CENTAUR_2);
+ }
+ else if(MEM_TYPE_OCM == G_sysConfigData.mem_type)
+ {
+ amec_update_ocmb_sensors(CENTAUR_2);
+ }
// Call VRM Vdd thermal controller
amec_controller_vrm_vdd_thermal();
@@ -586,8 +603,14 @@ void amec_slv_state_3(void)
//-------------------------------------------------------
// Update Centaur sensors (for this tick)
//-------------------------------------------------------
- if (MEM_TYPE_CUMULUS == G_sysConfigData.mem_type)
+ if(MEM_TYPE_CUMULUS == G_sysConfigData.mem_type)
+ {
amec_update_centaur_sensors(CENTAUR_3);
+ }
+ else if(MEM_TYPE_OCM == G_sysConfigData.mem_type)
+ {
+ amec_update_ocmb_sensors(CENTAUR_3);
+ }
}
@@ -602,13 +625,19 @@ void amec_slv_state_3(void)
// End Function Specification
void amec_slv_state_4(void)
{
- AMEC_DBG("\tAMEC Slave State 4\n");
+ AMEC_DBG("\tAMEC Slave State 4\n");
//-------------------------------------------------------
// Update Centaur sensors (for this tick)
//-------------------------------------------------------
- if (MEM_TYPE_CUMULUS == G_sysConfigData.mem_type)
+ if(MEM_TYPE_CUMULUS == G_sysConfigData.mem_type)
+ {
amec_update_centaur_sensors(CENTAUR_4);
+ }
+ else if(MEM_TYPE_OCM == G_sysConfigData.mem_type)
+ {
+ amec_update_ocmb_sensors(CENTAUR_4);
+ }
//-------------------------------------------------------
// Run WOF Algorithm if we are NOT getting readings from PGPE
@@ -638,8 +667,14 @@ void amec_slv_state_5(void)
//-------------------------------------------------------
// Update Centaur sensors (for this tick)
//-------------------------------------------------------
- if (MEM_TYPE_CUMULUS == G_sysConfigData.mem_type)
+ if(MEM_TYPE_CUMULUS == G_sysConfigData.mem_type)
+ {
amec_update_centaur_sensors(CENTAUR_5);
+ }
+ else if(MEM_TYPE_OCM == G_sysConfigData.mem_type)
+ {
+ amec_update_ocmb_sensors(CENTAUR_5);
+ }
//-------------------------------------------------------
// Update partition sensors for DPS algorithms (for this tick)
@@ -665,8 +700,14 @@ void amec_slv_state_6(void)
//-------------------------------------------------------
// Update Centaur sensors (for this tick)
//-------------------------------------------------------
- if (MEM_TYPE_CUMULUS == G_sysConfigData.mem_type)
+ if(MEM_TYPE_CUMULUS == G_sysConfigData.mem_type)
+ {
amec_update_centaur_sensors(CENTAUR_6);
+ }
+ else if(MEM_TYPE_OCM == G_sysConfigData.mem_type)
+ {
+ amec_update_ocmb_sensors(CENTAUR_6);
+ }
}
@@ -684,8 +725,14 @@ void amec_slv_state_7(void)
//-------------------------------------------------------
// Update Centaur sensors (for this tick)
//-------------------------------------------------------
- if (MEM_TYPE_CUMULUS == G_sysConfigData.mem_type)
+ if(MEM_TYPE_CUMULUS == G_sysConfigData.mem_type)
+ {
amec_update_centaur_sensors(CENTAUR_7);
+ }
+ else if(MEM_TYPE_OCM == G_sysConfigData.mem_type)
+ {
+ amec_update_ocmb_sensors(CENTAUR_7);
+ }
}
// Function Specification
diff --git a/src/occ_405/cent/centaur_control.c b/src/occ_405/cent/centaur_control.c
index 407bbdd..dd3fb7f 100755
--- a/src/occ_405/cent/centaur_control.c
+++ b/src/occ_405/cent/centaur_control.c
@@ -39,7 +39,7 @@
#include "rtls.h"
#include "apss.h"
#include "state.h"
-#include "centaur_structs.h"
+#include "membuf_structs.h"
#include "centaur_firmware_registers.h"
#include "centaur_register_addresses.h"
#include "amec_sys.h"
@@ -64,7 +64,7 @@ typedef enum
NM_THROTTLE_MBA23 = 1,
MBS_THROTTLE_SYNC = 2,
NUM_CENT_THROTTLE_SCOMS = 3,
-} eCentaurThrottleRegs;
+} eMemBufThrottleRegs;
//*************************************************************************/
@@ -78,9 +78,9 @@ typedef enum
//Pore flex request for the GPE job that is used for centaur init.
GpeRequest G_centaur_control_request;
-// @see CentaurScomParms in centaur_structs.h
-GPE_BUFFER(CentaurScomParms_t G_centaur_control_reg_parms);
-// scomList_t @see centaur_configuration.h
+// @see CentaurScomParms in membuf_structs.h
+GPE_BUFFER(MemBufScomParms_t G_membuf_control_reg_parms);
+// scomList_t @see membuf_configuration.h
GPE_BUFFER(scomList_t G_centaurThrottle[NUM_CENT_THROTTLE_SCOMS]);
//bitmap of configured MBA's (2 per centaur, lsb is centaur 0/mba 0)
@@ -244,8 +244,8 @@ bool centaur_control( memory_control_task_t * i_memControlTask )
amec_centaur_t *l_cent_ptr = NULL;
int l_cent = i_memControlTask->curMemIndex;
- CentaurScomParms_t * l_parms =
- (CentaurScomParms_t *)(i_memControlTask->gpe_req.cmd_data);
+ MemBufScomParms_t * l_parms =
+ (MemBufScomParms_t *)(i_memControlTask->gpe_req.cmd_data);
do
{
@@ -292,7 +292,7 @@ bool centaur_control( memory_control_task_t * i_memControlTask )
if(MBA_CONFIGURED(l_cent, 0))
{
/// [0]: Set up N/M throttle MBA01
- G_centaurThrottle[NM_THROTTLE_MBA01].commandType = CENTAUR_SCOM_RMW;
+ G_centaurThrottle[NM_THROTTLE_MBA01].commandType = MEMBUF_SCOM_RMW;
G_centaurThrottle[NM_THROTTLE_MBA01].instanceNumber = l_cent;
// Set up value to be written
l_mbafarbq.fields.cfg_nm_n_per_mba = l_mba01_n_per_mba;
@@ -301,14 +301,14 @@ bool centaur_control( memory_control_task_t * i_memControlTask )
}
else
{
- G_centaurThrottle[NM_THROTTLE_MBA01].commandType = CENTAUR_SCOM_NOP;
+ G_centaurThrottle[NM_THROTTLE_MBA01].commandType = MEMBUF_SCOM_NOP;
}
//only write to MBA23 if configured
if(MBA_CONFIGURED(l_cent, 1))
{
/// [1]: Set up N/M throttle MBA23
- G_centaurThrottle[NM_THROTTLE_MBA23].commandType = CENTAUR_SCOM_RMW;
+ G_centaurThrottle[NM_THROTTLE_MBA23].commandType = MEMBUF_SCOM_RMW;
G_centaurThrottle[NM_THROTTLE_MBA23].instanceNumber = l_cent;
// Set up value to be written
l_mbafarbq.fields.cfg_nm_n_per_mba = l_mba23_n_per_mba;
@@ -317,10 +317,10 @@ bool centaur_control( memory_control_task_t * i_memControlTask )
}
else
{
- G_centaurThrottle[NM_THROTTLE_MBA23].commandType = CENTAUR_SCOM_NOP;
+ G_centaurThrottle[NM_THROTTLE_MBA23].commandType = MEMBUF_SCOM_NOP;
}
- G_centaurThrottle[MBS_THROTTLE_SYNC].commandType = CENTAUR_SCOM_CENTAUR_SYNC;
+ G_centaurThrottle[MBS_THROTTLE_SYNC].commandType = MEMBUF_SCOM_MEMBUF_SYNC;
/// Set up GPE parameters
l_parms->scomList = G_centaurThrottle;
@@ -377,9 +377,9 @@ void centaur_control_init( void )
G_centaurThrottle[NM_THROTTLE_MBA23].mask = l_mbafarbq.value;
// Set up GPE parameters
- G_centaur_control_reg_parms.error.ffdc = 0;
- G_centaur_control_reg_parms.entries = 0;
- G_centaur_control_reg_parms.scomList = &G_centaurThrottle[0];
+ G_membuf_control_reg_parms.error.ffdc = 0;
+ G_membuf_control_reg_parms.entries = 0;
+ G_membuf_control_reg_parms.scomList = &G_centaurThrottle[0];
//--------------------------------------------------
// Initializes GPE Centaur Control Task, but
@@ -388,8 +388,8 @@ void centaur_control_init( void )
l_rc_gpe = gpe_request_create(
&G_memory_control_task.gpe_req, // gpe_req for the task
&G_async_gpe_queue1, // queue
- IPC_ST_CENTAUR_SCOM_FUNCID, // Function ID
- &G_centaur_control_reg_parms, // parm for the task
+ IPC_ST_MEMBUF_SCOM_FUNCID, // Function ID
+ &G_membuf_control_reg_parms, // parm for the task
SSX_WAIT_FOREVER, //
NULL, // callback
NULL, // callback argument
@@ -429,7 +429,7 @@ void centaur_control_init( void )
);
addUsrDtlsToErrl(l_err, //io_err
- (uint8_t *) &G_centaur_control_request.ffdc, //i_dataPtr,
+ (uint8_t *) &G_memory_control_task.gpe_req.ffdc, //i_dataPtr,
sizeof(GpeFfdc), //i_size
ERRL_USR_DTL_STRUCT_VERSION_1, //version
ERRL_USR_DTL_BINARY_DATA); //type
diff --git a/src/occ_405/cent/centaur_data.c b/src/occ_405/cent/centaur_data.c
index ec27b9d..3ccd7bf 100755
--- a/src/occ_405/cent/centaur_data.c
+++ b/src/occ_405/cent/centaur_data.c
@@ -38,10 +38,11 @@
#include "apss.h"
#include "state.h"
#include "occhw_scom.h"
-#include "centaur_structs.h"
+#include "membuf_structs.h"
#include "centaur_mem_data.h"
#include "centaur_firmware_registers.h"
#include "centaur_register_addresses.h"
+#include "dimm.h" // MEM_TYPE_
//*************************************************************************/
// Externs
@@ -111,19 +112,19 @@ GPE_BUFFER(CentaurMemData G_centaur_data[NUM_CENTAUR_DATA_BUFF +
//pore request for scoming centaur registers
GpeRequest G_cent_scom_req; // p8/working/procedures/ssx/pgp/pgp_async.h
-//input/output parameters for IPC_ST_CENTAUR_SCOM()
-GPE_BUFFER(CentaurScomParms_t G_cent_scom_gpe_parms);
+//input/output parameters for IPC_ST_MEMBUF_SCOM()
+GPE_BUFFER(MemBufScomParms_t G_cent_scom_gpe_parms);
//scom command list entry
GPE_BUFFER(scomList_t G_cent_scom_list_entry[NUM_CENT_OPS]);
-//buffer for storing output from running IPC_ST_CENTAUR_SCOM()
+//buffer for storing output from running IPC_ST_MEMBUF_SCOM()
GPE_BUFFER(uint64_t G_cent_scom_data[MAX_NUM_CENTAURS]) = {0};
-// parms for call to IPC_ST_CENTAUR_INIT_FUNCID
-GPE_BUFFER(CentaurConfigParms_t G_gpe_centaur_config_args);
+// parms for call to IPC_ST_MEMBUF_INIT_FUNCID
+GPE_BUFFER(MemBufConfigParms_t G_gpe_centaur_config_args);
-GPE_BUFFER(CentaurConfiguration_t G_centaurConfiguration);
+GPE_BUFFER(MemBufConfiguration_t G_membufConfiguration);
//Global array of centaur data pointers
CentaurMemData * G_centaur_data_ptrs[MAX_NUM_CENTAURS] = { &G_centaur_data[0],
&G_centaur_data[1], &G_centaur_data[2], &G_centaur_data[3],
@@ -131,18 +132,18 @@ CentaurMemData * G_centaur_data_ptrs[MAX_NUM_CENTAURS] = { &G_centaur_data[0],
&G_centaur_data[7]};
//Global structures for gpe get mem data parms
-GPE_BUFFER(CentaurGetMemDataParms_t G_centaur_data_parms);
+GPE_BUFFER(MemBufGetMemDataParms_t G_membuf_data_parms);
//Pore flex request for the GPE job that is used for centaur init.
GpeRequest G_centaur_reg_gpe_req;
//Centaur structures used for task data pointers.
-centaur_data_task_t G_centaur_data_task = {
- .start_centaur = 0,
- .current_centaur = 0,
- .end_centaur = 7,
- .prev_centaur = 7,
- .centaur_data_ptr = &G_centaur_data[MAX_NUM_CENTAURS]
+membuf_data_task_t G_membuf_data_task = {
+ .start_membuf = 0,
+ .current_membuf = 0,
+ .end_membuf = 7,
+ .prev_membuf = 7,
+ .membuf_data_ptr = &G_centaur_data[MAX_NUM_CENTAURS]
};
@@ -274,7 +275,7 @@ void cent_recovery(uint32_t i_cent)
{
// Check if the centaur has a channel checkstop. If it does then remove the centaur
// from the enabled sensor bit map and do not log any errors
- if(G_cent_scom_gpe_parms.error.rc == CENTAUR_CHANNEL_CHECKSTOP)
+ if(G_cent_scom_gpe_parms.error.rc == MEMBUF_CHANNEL_CHECKSTOP)
{
cent_chan_checkstop(l_prev_cent);
}
@@ -284,7 +285,7 @@ void cent_recovery(uint32_t i_cent)
L_cent_callouts |= l_cent_mask;
// There was an error doing the recovery scoms
- TRAC_ERR("cent_recovery: IPC_ST_CENTAUR_SCOM failed. rc[0x%08x] cent[%d] entries[%d] errorIndex[0x%08X]",
+ TRAC_ERR("cent_recovery: IPC_ST_MEMBUF_SCOM failed. rc[0x%08x] cent[%d] entries[%d] errorIndex[0x%08X]",
G_cent_scom_gpe_parms.error.rc,
l_prev_cent,
G_cent_scom_gpe_parms.entries,
@@ -449,17 +450,17 @@ void cent_recovery(uint32_t i_cent)
//check if this centaur requires lfir6 recovery
if(G_centaur_nest_lfir6 & l_cent_mask)
{
- //Set the command type from CENTAUR_SCOM_NOP to CENTAUR_SCOM_RMW
+ //Set the command type from MEMBUF_SCOM_NOP to MEMBUF_SCOM_RMW
//these entries will reset the centaur DTS FSM and clear LFIR 6
//if recovery worked, LFIR 6 should remain cleared.
- G_cent_scom_list_entry[RESET_DTS_FSM].commandType = CENTAUR_SCOM_WRITE;
- G_cent_scom_list_entry[CLEAR_NEST_LFIR6].commandType = CENTAUR_SCOM_WRITE;
+ G_cent_scom_list_entry[RESET_DTS_FSM].commandType = MEMBUF_SCOM_WRITE;
+ G_cent_scom_list_entry[CLEAR_NEST_LFIR6].commandType = MEMBUF_SCOM_WRITE;
}
else
{
//these ops aren't needed so disable them
- G_cent_scom_list_entry[RESET_DTS_FSM].commandType = CENTAUR_SCOM_NOP;
- G_cent_scom_list_entry[CLEAR_NEST_LFIR6].commandType = CENTAUR_SCOM_NOP;
+ G_cent_scom_list_entry[RESET_DTS_FSM].commandType = MEMBUF_SCOM_NOP;
+ G_cent_scom_list_entry[CLEAR_NEST_LFIR6].commandType = MEMBUF_SCOM_NOP;
}
//Decrement the delay counter for centaur i2c recovery
@@ -489,13 +490,13 @@ void cent_recovery(uint32_t i_cent)
//clear the request for i2c recovery here
G_centaur_needs_recovery &= ~l_cent_mask;
- //Set the command type from CENTAUR_SCOM_NOP to CENTAUR_SCOM_RMW
+ //Set the command type from MEMBUF_SCOM_NOP to MEMBUF_SCOM_RMW
//this entry will disable the centaur sensor cache and
//set a flag to finish the recovery in a later call of this
//function (cent_recovery for a given centaur is called every
//2 msec)
- G_cent_scom_list_entry[DISABLE_SC].commandType = CENTAUR_SCOM_RMW;
- G_cent_scom_list_entry[ENABLE_SC].commandType = CENTAUR_SCOM_NOP;
+ G_cent_scom_list_entry[DISABLE_SC].commandType = MEMBUF_SCOM_RMW;
+ G_cent_scom_list_entry[ENABLE_SC].commandType = MEMBUF_SCOM_NOP;
L_i2c_finish_recovery[i_cent] = TRUE;
}
}
@@ -515,8 +516,8 @@ void cent_recovery(uint32_t i_cent)
}
//these ops aren't needed so disable them
- G_cent_scom_list_entry[DISABLE_SC].commandType = CENTAUR_SCOM_NOP;
- G_cent_scom_list_entry[ENABLE_SC].commandType = CENTAUR_SCOM_NOP;
+ G_cent_scom_list_entry[DISABLE_SC].commandType = MEMBUF_SCOM_NOP;
+ G_cent_scom_list_entry[ENABLE_SC].commandType = MEMBUF_SCOM_NOP;
// Finish the i2c recovery if it was started for this centaur
if(L_i2c_finish_recovery[i_cent] == TRUE)
@@ -527,11 +528,11 @@ void cent_recovery(uint32_t i_cent)
//clear the finish_recovery flag for this centaur
L_i2c_finish_recovery[i_cent] = FALSE;
- //Set the command type from CENTAUR_SCOM_NOP to CENTAUR_SCOM_RMW
+ //Set the command type from MEMBUF_SCOM_NOP to MEMBUF_SCOM_RMW
//this entry will re-enable the centaur sensor cache
//which will also cause the i2c master to be reset
- G_cent_scom_list_entry[DISABLE_SC].commandType = CENTAUR_SCOM_NOP;
- G_cent_scom_list_entry[ENABLE_SC].commandType = CENTAUR_SCOM_RMW;
+ G_cent_scom_list_entry[DISABLE_SC].commandType = MEMBUF_SCOM_NOP;
+ G_cent_scom_list_entry[ENABLE_SC].commandType = MEMBUF_SCOM_RMW;
}
}
@@ -596,9 +597,9 @@ void centaur_data( void )
errlHndl_t l_err = NULL; // Error handler
int rc = 0; // Return code
CentaurMemData * l_temp = NULL;
- centaur_data_task_t * l_centaur_data_ptr = &G_centaur_data_task;
- CentaurGetMemDataParms_t * l_parms =
- (CentaurGetMemDataParms_t *)(l_centaur_data_ptr->gpe_req.cmd_data);
+ membuf_data_task_t * l_centaur_data_ptr = &G_membuf_data_task;
+ MemBufGetMemDataParms_t * l_parms =
+ (MemBufGetMemDataParms_t *)(l_centaur_data_ptr->gpe_req.cmd_data);
static bool L_gpe_scheduled = FALSE;
static bool L_gpe_error_logged = FALSE;
static bool L_gpe_had_1_tick = FALSE;
@@ -608,16 +609,16 @@ void centaur_data( void )
// ------------------------------------------
// Centaur Data Task Variable Initial State
// ------------------------------------------
- // ->current_centaur: the one that was just 'written' to last tick to
+ // ->current_membuf: the one that was just 'written' to last tick to
// kick off the sensor cache population in the
- // centaur. It will be 'read from' during this tick.
+ // membuf. It will be 'read from' during this tick.
//
- // ->prev_centaur: the one that was 'read from' during the last tick
+ // ->prev_membuf: the one that was 'read from' during the last tick
// and will be used to update the
// G_updated_centaur_mask during this tick.
//
- // ->centaur_data_ptr: points to G_centaur_data_ptrs[] for
- // the centaur that is referenced by prev_centaur
+ // ->membuf_data_ptr: points to G_centaur_data_ptrs[] for
+ // the centaur that is referenced by prev_membuf
// (the one that was just 'read')
//First, check to see if the previous GPE request still running
@@ -648,7 +649,7 @@ void centaur_data( void )
//Need to complete collecting data for all assigned centaurs from
//previous interval and tick 0 is the current tick before collect data again.
- if( (l_centaur_data_ptr->current_centaur == l_centaur_data_ptr->end_centaur)
+ if( (l_centaur_data_ptr->current_membuf == l_centaur_data_ptr->end_membuf)
&& ((CURRENT_TICK & (MAX_NUM_TICKS - 1)) != 0) )
{
CENT_DBG("Did not collect centaur data. Need to wait for tick.");
@@ -666,11 +667,11 @@ void centaur_data( void )
{
// Check if the centaur has a channel checkstop. If it does then do not
// log any errors, but remove the centaur from the config
- if(l_parms->error.rc == CENTAUR_CHANNEL_CHECKSTOP)
+ if(l_parms->error.rc == MEMBUF_CHANNEL_CHECKSTOP)
{
- cent_chan_checkstop(l_centaur_data_ptr->prev_centaur);
+ cent_chan_checkstop(l_centaur_data_ptr->prev_membuf);
}
- else // log the error if it was not a CENTAUR_CHANNEL_CHECKSTOP
+ else // log the error if it was not a MEMBUF_CHANNEL_CHECKSTOP
{
//log an error the first time this happens but keep on running.
//This should be informational (except mfg) since we are going to retry
@@ -683,8 +684,8 @@ void centaur_data( void )
// There was an error collecting the centaur sensor cache
TRAC_ERR("task_centaur_data: gpe_get_mem_data failed. rc=0x%08x, cur=%d, prev=%d",
l_parms->error.rc,
- l_centaur_data_ptr->current_centaur,
- l_centaur_data_ptr->prev_centaur);
+ l_centaur_data_ptr->current_membuf,
+ l_centaur_data_ptr->prev_membuf);
/* @
* @errortype
* @moduleid CENT_TASK_DATA_MOD
@@ -714,8 +715,16 @@ void centaur_data( void )
ERRL_USR_DTL_STRUCT_VERSION_1, //version
ERRL_USR_DTL_BINARY_DATA); //type
+
+ // Capture the GPE1 trace buffer
+ addUsrDtlsToErrl(l_err,
+ (uint8_t *) G_shared_gpe_data.gpe1_tb_ptr,
+ G_shared_gpe_data.gpe1_tb_sz,
+ ERRL_USR_DTL_STRUCT_VERSION_1,
+ ERRL_USR_DTL_TRACE_DATA);
+
//Callouts depend on the return code of the gpe_get_mem_data procedure
- if(l_parms->error.rc == CENTAUR_GET_MEM_DATA_DIED)
+ if(l_parms->error.rc == MEMBUF_GET_MEM_DATA_DIED)
{
//callout the processor
addCalloutToErrl(l_err,
@@ -723,14 +732,15 @@ void centaur_data( void )
G_sysConfigData.proc_huid,
ERRL_CALLOUT_PRIORITY_LOW);
}
- else if(l_parms->error.rc == CENTAUR_GET_MEM_DATA_SENSOR_CACHE_FAILED)
+ else if(l_parms->error.rc == CENTAUR_GET_MEM_DATA_SENSOR_CACHE_FAILED ||
+ l_parms->error.rc == MEMBUF_SCACHE_ERROR)
{
//callout the previous centaur if present
- if(CENTAUR_PRESENT(l_centaur_data_ptr->prev_centaur))
+ if(CENTAUR_PRESENT(l_centaur_data_ptr->prev_membuf))
{
addCalloutToErrl(l_err,
ERRL_CALLOUT_TYPE_HUID,
- G_sysConfigData.centaur_huids[l_centaur_data_ptr->prev_centaur],
+ G_sysConfigData.centaur_huids[l_centaur_data_ptr->prev_membuf],
ERRL_CALLOUT_PRIORITY_HIGH);
}
@@ -743,11 +753,11 @@ void centaur_data( void )
else if(l_parms->error.rc == CENTAUR_GET_MEM_DATA_UPDATE_FAILED)
{
//callout the current centaur if present
- if(CENTAUR_PRESENT(l_centaur_data_ptr->current_centaur))
+ if(CENTAUR_PRESENT(l_centaur_data_ptr->current_membuf))
{
addCalloutToErrl(l_err,
ERRL_CALLOUT_TYPE_HUID,
- G_sysConfigData.centaur_huids[l_centaur_data_ptr->current_centaur],
+ G_sysConfigData.centaur_huids[l_centaur_data_ptr->current_membuf],
ERRL_CALLOUT_PRIORITY_HIGH);
}
@@ -775,18 +785,18 @@ void centaur_data( void )
//If the previous GPE request succeeded then swap l_centaur_data_ptr
//with the global one. The gpe routine will write new data into
//a buffer that is not being accessed by the RTLoop code.
- l_temp = l_centaur_data_ptr->centaur_data_ptr;
- l_centaur_data_ptr->centaur_data_ptr =
- G_centaur_data_ptrs[l_centaur_data_ptr->current_centaur];
- G_centaur_data_ptrs[l_centaur_data_ptr->prev_centaur] = l_temp;
+ l_temp = l_centaur_data_ptr->membuf_data_ptr;
+ l_centaur_data_ptr->membuf_data_ptr =
+ G_centaur_data_ptrs[l_centaur_data_ptr->current_membuf];
+ G_centaur_data_ptrs[l_centaur_data_ptr->prev_membuf] = l_temp;
//Centaur data has been collected so set the bit in global mask.
//AMEC code will know which centaur to update sensors for. AMEC is
//responsible for clearing the bit later on.
// prev centaur is the one that was just 'read from' in the last tick
- if( CENTAUR_PRESENT(l_centaur_data_ptr->prev_centaur) )
+ if( CENTAUR_PRESENT(l_centaur_data_ptr->prev_membuf) )
{
- G_updated_centaur_mask |= CENTAUR_BY_MASK(l_centaur_data_ptr->prev_centaur);
+ G_updated_centaur_mask |= CENTAUR_BY_MASK(l_centaur_data_ptr->prev_membuf);
}
}
}//if(L_gpe_scheduled)
@@ -794,48 +804,48 @@ void centaur_data( void )
// If the centaur is not present, then we need to point to the empty G_centaur_data
// so that we don't use old/stale data from a leftover G_centaur_data
// (this is very handy for debug...)
- if( !CENTAUR_PRESENT(l_centaur_data_ptr->current_centaur))
+ if( !CENTAUR_PRESENT(l_centaur_data_ptr->current_membuf))
{
- G_centaur_data_ptrs[l_centaur_data_ptr->current_centaur] = &G_centaur_data[9];
+ G_centaur_data_ptrs[l_centaur_data_ptr->current_membuf] = &G_centaur_data[9];
}
//Update current centaur
- if ( l_centaur_data_ptr->current_centaur >= l_centaur_data_ptr->end_centaur )
+ if ( l_centaur_data_ptr->current_membuf >= l_centaur_data_ptr->end_membuf )
{
- l_centaur_data_ptr->prev_centaur = l_centaur_data_ptr->current_centaur;
- l_centaur_data_ptr->current_centaur = l_centaur_data_ptr->start_centaur;
+ l_centaur_data_ptr->prev_membuf = l_centaur_data_ptr->current_membuf;
+ l_centaur_data_ptr->current_membuf = l_centaur_data_ptr->start_membuf;
}
else
{
- l_centaur_data_ptr->prev_centaur = l_centaur_data_ptr->current_centaur;
- l_centaur_data_ptr->current_centaur++;
+ l_centaur_data_ptr->prev_membuf = l_centaur_data_ptr->current_membuf;
+ l_centaur_data_ptr->current_membuf++;
}
// ------------------------------------------
- // Centaur Data Task Variable State Changed
+ // Membuf Data Task Variable State Changed
// ------------------------------------------
- // ->current_centaur: the one that will be 'written' to in order to
+ // ->current_membuf: the one that will be 'written' to in order to
// kick off the sensor cache population in the
- // centaur.
+ // membuf.
//
- // ->prev_centaur: the one that will be 'read from', meaning have
- // the sensor cache transferred from the Centaur
- // to l_centaur_data_ptr->centaur_data_ptr
+ // ->prev_membuf: the one that will be 'read from', meaning have
+ // the sensor cache transferred from the membuf
+ // to l_centaur_data_ptr->membuf_data_ptr
//
- // ->centaur_data_ptr: points to G_centaur_data_ptrs[] for
- // the centaur that is referenced by prev_centaur
+ // ->membuf_data_ptr: points to G_centaur_data_ptrs[] for
+ // the centaur that is referenced by prev_membuf
// (the one that will be 'read')
//If centaur is not present then skip it. This task assigned to this centaur will
//be idle during this time it would have collected the data.
- if( CENTAUR_PRESENT(l_centaur_data_ptr->current_centaur)
- || CENTAUR_PRESENT(l_centaur_data_ptr->prev_centaur) )
+ if( CENTAUR_PRESENT(l_centaur_data_ptr->current_membuf)
+ || CENTAUR_PRESENT(l_centaur_data_ptr->prev_membuf) )
{
// Setup the 'get centaur data' parms
// ->config controls which Centaur we are reading from
- if( CENTAUR_PRESENT(l_centaur_data_ptr->prev_centaur) ){
+ if( CENTAUR_PRESENT(l_centaur_data_ptr->prev_membuf) ){
// If prev centaur is present, do the read of the sensor cache
- l_parms->collect = l_centaur_data_ptr->prev_centaur;
+ l_parms->collect = l_centaur_data_ptr->prev_membuf;
}
else{
// If prev centaur is not present, don't do the read of the sensor cache.
@@ -843,16 +853,16 @@ void centaur_data( void )
}
// ->config_update controls which Centaur we are writing to
- if( CENTAUR_PRESENT(l_centaur_data_ptr->current_centaur) ){
+ if( CENTAUR_PRESENT(l_centaur_data_ptr->current_membuf) ){
// If cur centaur is present, do the write to kick off the sensor cache collect
- l_parms->update = l_centaur_data_ptr->current_centaur;
+ l_parms->update = l_centaur_data_ptr->current_membuf;
}
else{
// If cur centaur is not present, don't do the write to kick off the sensor cache collect
l_parms->update = -1;
}
- l_parms->data = (uint64_t *)(l_centaur_data_ptr->centaur_data_ptr);
+ l_parms->data = (uint64_t *)(l_centaur_data_ptr->membuf_data_ptr);
l_parms->error.ffdc = 0;
// Pore flex schedule gpe_get_mem_data
@@ -899,9 +909,12 @@ void centaur_data( void )
while(0);
//handle centaur i2c recovery requests and centaur workaround.
- if(CENTAUR_PRESENT(l_centaur_data_ptr->current_centaur))
+ if(CENTAUR_PRESENT(l_centaur_data_ptr->current_membuf))
{
- cent_recovery(l_centaur_data_ptr->current_centaur);
+ if (MEM_TYPE_CUMULUS == G_sysConfigData.mem_type)
+ {
+ cent_recovery(l_centaur_data_ptr->current_membuf);
+ }
}
return;
}
@@ -923,7 +936,7 @@ int cent_get_enabled_sensors()
{
// Set up scom list entry (there's only 1)
G_cent_scom_list_entry[0].scom = CENTAUR_SENSCACHE_ENABLE; //scom address
- G_cent_scom_list_entry[0].commandType = CENTAUR_SCOM_READ_VECTOR; //scom operation to perform
+ G_cent_scom_list_entry[0].commandType = MEMBUF_SCOM_READ_VECTOR; //scom operation to perform
G_cent_scom_list_entry[0].instanceNumber = 0; //Ignored for READ_VECTOR operation
G_cent_scom_list_entry[0].pData = (uint64_t *) G_cent_scom_data; //scom data will be stored here
@@ -936,7 +949,7 @@ int cent_get_enabled_sensors()
l_rc = gpe_request_create(
&G_cent_scom_req, // gpe_req for the task
&G_async_gpe_queue1, // queue
- IPC_ST_CENTAUR_SCOM_FUNCID, // Function ID
+ IPC_ST_MEMBUF_SCOM_FUNCID, // Function ID
&G_cent_scom_gpe_parms, // parm for the task
SSX_SECONDS(2), // timeout
NULL, // callback
@@ -985,7 +998,7 @@ void centaur_init( void )
int rc = 0; // Return code
int l_jj = 0; // Indexer
static scomList_t L_scomList[2] SECTION_ATTRIBUTE(".noncacheable");
- static CentaurScomParms_t L_centaur_reg_parms SECTION_ATTRIBUTE(".noncacheable");
+ static MemBufScomParms_t L_centaur_reg_parms SECTION_ATTRIBUTE(".noncacheable");
do
{
@@ -998,7 +1011,7 @@ void centaur_init( void )
/// Before anything else, we need to call this procedure to
/// determine which Centaurs are out there, their config info.
/// and Type/EC Level
- rc = centaur_configuration_create(&G_centaurConfiguration);
+ rc = membuf_configuration_create();
if( rc )
{
break;
@@ -1015,14 +1028,13 @@ void centaur_init( void )
if( CENTAUR_BY_MASK(l_jj) )
{
- if( G_centaurConfiguration.baseAddress[l_jj] )
+ if( G_membufConfiguration.baseAddress[l_jj] )
{
// G_cent_ba is != 0, so a valid Bar Address was found
// This means there is a VALID centaur there.
G_present_centaurs |= (CENTAUR0_PRESENT_MASK >> l_jj);
- // Trace out the CFAM Chip ID, which includes Type & EC
- TRAC_INFO("centaur_init: Centaur[%d] Found, Chip Id= 0x%08x",l_jj);
+ TRAC_INFO("centaur_init: Centaur[%d] Found",l_jj);
}
}
}
@@ -1034,49 +1046,49 @@ void centaur_init( void )
// Set up recovery scom list entries
G_cent_scom_list_entry[L4_LINE_DELETE].scom = MBCCFGQ_REG; //scom address
- G_cent_scom_list_entry[L4_LINE_DELETE].commandType = CENTAUR_SCOM_RMW; //scom operation to perform
+ G_cent_scom_list_entry[L4_LINE_DELETE].commandType = MEMBUF_SCOM_RMW; //scom operation to perform
G_cent_scom_list_entry[L4_LINE_DELETE].mask = LINE_DELETE_ON_NEXT_CE; //mask of bits to change
G_cent_scom_list_entry[L4_LINE_DELETE].data = LINE_DELETE_ON_NEXT_CE; //scom data (always set the bit)
//one time init for reading LFIR6
G_cent_scom_list_entry[READ_NEST_LFIR6].scom = CENT_NEST_LFIR_REG; //scom address
- G_cent_scom_list_entry[READ_NEST_LFIR6].commandType = CENTAUR_SCOM_READ; //scom operation to perform
+ G_cent_scom_list_entry[READ_NEST_LFIR6].commandType = MEMBUF_SCOM_READ; //scom operation to perform
G_cent_scom_list_entry[READ_NEST_LFIR6].mask = 0; //mask (not used for reads)
G_cent_scom_list_entry[READ_NEST_LFIR6].data = 0; //scom data (initialize to 0)
//one time init for reading centaur thermal status register
G_cent_scom_list_entry[READ_THERM_STATUS].scom = CENT_THRM_STATUS_REG; //scom address
- G_cent_scom_list_entry[READ_THERM_STATUS].commandType = CENTAUR_SCOM_READ; //scom operation to perform
+ G_cent_scom_list_entry[READ_THERM_STATUS].commandType = MEMBUF_SCOM_READ; //scom operation to perform
G_cent_scom_list_entry[READ_THERM_STATUS].mask = 0; //mask (not used for reads)
G_cent_scom_list_entry[READ_THERM_STATUS].data = 0; //scom data (initialize to 0)
//one time init to reset the centaur dts FSM
G_cent_scom_list_entry[RESET_DTS_FSM].scom = CENT_THRM_CTRL_REG; //scom address
- G_cent_scom_list_entry[RESET_DTS_FSM].commandType = CENTAUR_SCOM_NOP; //init to no-op (only runs if needed)
+ G_cent_scom_list_entry[RESET_DTS_FSM].commandType = MEMBUF_SCOM_NOP; //init to no-op (only runs if needed)
G_cent_scom_list_entry[RESET_DTS_FSM].mask = 0; //mask (not used for writes)
G_cent_scom_list_entry[RESET_DTS_FSM].data = CENT_THRM_CTRL4; //scom data (sets bit4)
//one time init to clear centaur NEST LFIR 6
G_cent_scom_list_entry[CLEAR_NEST_LFIR6].scom = CENT_NEST_LFIR_AND_REG; //scom address
- G_cent_scom_list_entry[CLEAR_NEST_LFIR6].commandType = CENTAUR_SCOM_NOP; //init to no-op (only runs if needed)
+ G_cent_scom_list_entry[CLEAR_NEST_LFIR6].commandType = MEMBUF_SCOM_NOP; //init to no-op (only runs if needed)
G_cent_scom_list_entry[CLEAR_NEST_LFIR6].mask = 0; //mask (not used for writes)
G_cent_scom_list_entry[CLEAR_NEST_LFIR6].data = ~CENT_NEST_LFIR6; //scom data
//one time init to disable centaur sensor cache
G_cent_scom_list_entry[DISABLE_SC].scom = SCAC_CONFIG_REG; //scom address
- G_cent_scom_list_entry[DISABLE_SC].commandType = CENTAUR_SCOM_NOP; //init to no-op (only runs if needed)
+ G_cent_scom_list_entry[DISABLE_SC].commandType = MEMBUF_SCOM_NOP; //init to no-op (only runs if needed)
G_cent_scom_list_entry[DISABLE_SC].mask = SCAC_MASTER_ENABLE; //mask of bits to change
G_cent_scom_list_entry[DISABLE_SC].data = 0; //scom data (disable sensor cache)
//one time init to enable centaur sensor cache
G_cent_scom_list_entry[ENABLE_SC].scom = SCAC_CONFIG_REG; //scom address
- G_cent_scom_list_entry[ENABLE_SC].commandType = CENTAUR_SCOM_NOP; //init to no-op (only runs if needed)
+ G_cent_scom_list_entry[ENABLE_SC].commandType = MEMBUF_SCOM_NOP; //init to no-op (only runs if needed)
G_cent_scom_list_entry[ENABLE_SC].mask = SCAC_MASTER_ENABLE; //mask of bits to change
G_cent_scom_list_entry[ENABLE_SC].data = SCAC_MASTER_ENABLE; //scom data (enable sensor cache)
//one time init for reading centaur sensor cache lfir
G_cent_scom_list_entry[READ_SCAC_LFIR].scom = SCAC_LFIR_REG; //scom address
- G_cent_scom_list_entry[READ_SCAC_LFIR].commandType = CENTAUR_SCOM_READ; //scom operation to perform
+ G_cent_scom_list_entry[READ_SCAC_LFIR].commandType = MEMBUF_SCOM_READ; //scom operation to perform
G_cent_scom_list_entry[READ_SCAC_LFIR].mask = 0; //mask (not used for reads)
G_cent_scom_list_entry[READ_SCAC_LFIR].data = 0; //scom data (initialize to 0)
@@ -1085,7 +1097,7 @@ void centaur_init( void )
/// NOTE: max timeout is about 2 seconds.
L_scomList[0].scom = CENTAUR_MBSCFGQ;
- L_scomList[0].commandType = CENTAUR_SCOM_RMW_ALL;
+ L_scomList[0].commandType = MEMBUF_SCOM_RMW_ALL;
centaur_mbscfgq_t l_mbscfg;
l_mbscfg.value = 0;
@@ -1102,7 +1114,7 @@ void centaur_init( void )
/// [1]: clear the emergency throttle bit
L_scomList[1].scom = CENTAUR_MBSEMERTHROQ;
- L_scomList[1].commandType = CENTAUR_SCOM_RMW_ALL;
+ L_scomList[1].commandType = MEMBUF_SCOM_RMW_ALL;
centaur_mbsemerthroq_t l_mbs_et;
l_mbs_et.value = 0;
@@ -1122,7 +1134,7 @@ void centaur_init( void )
rc = gpe_request_create(
&G_centaur_reg_gpe_req, //gpe_req for the task
&G_async_gpe_queue1, //queue
- IPC_ST_CENTAUR_SCOM_FUNCID, // Function ID
+ IPC_ST_MEMBUF_SCOM_FUNCID, // Function ID
&L_centaur_reg_parms, //parm for the task
SSX_SECONDS(5), //timeout
NULL, //callback
@@ -1140,7 +1152,7 @@ void centaur_init( void )
// Check for errors on Scom
if(rc || L_centaur_reg_parms.error.rc)
{
- TRAC_ERR("centaur_init: IPC_ST_CENTAUR_SCOM failure. rc = 0x%08x, gpe_rc = 0x%08x, address = 0x%08x",
+ TRAC_ERR("centaur_init: IPC_ST_MEMBUF_SCOM failure. rc = 0x%08x, gpe_rc = 0x%08x, address = 0x%08x",
rc,
L_centaur_reg_parms.error.rc,
L_centaur_reg_parms.error.addr);
@@ -1156,17 +1168,17 @@ void centaur_init( void )
/// to gather the 'centaur' data, but we will set them to
/// invalid (-1) until the task sets them up
- G_centaur_data_parms.error.ffdc = 0;
- G_centaur_data_parms.collect = -1;
- G_centaur_data_parms.update = -1;
- G_centaur_data_parms.data = 0;
+ G_membuf_data_parms.error.ffdc = 0;
+ G_membuf_data_parms.collect = -1;
+ G_membuf_data_parms.update = -1;
+ G_membuf_data_parms.data = 0;
//Initializes existing PoreFlex object for centaur data
rc = gpe_request_create(
- &G_centaur_data_task.gpe_req, //gpe_req for the task
+ &G_membuf_data_task.gpe_req, //gpe_req for the task
&G_async_gpe_queue1, //queue
- IPC_ST_CENTAUR_DATA_FUNCID, //Function ID
- &G_centaur_data_parms, //parm for the task
+ IPC_ST_MEMBUF_DATA_FUNCID, //Function ID
+ &G_membuf_data_parms, //parm for the task
SSX_WAIT_FOREVER, //
NULL, //callback
NULL, //callback argument
@@ -1174,7 +1186,7 @@ void centaur_init( void )
if(rc)
{
- TRAC_ERR("centaur_init: gpe_request_create failed for G_centaur_data_task.gpe_req. rc = 0x%08x", rc);
+ TRAC_ERR("centaur_init: gpe_request_create failed for G_membuf_data_task.gpe_req. rc = 0x%08x", rc);
break;
}
@@ -1182,7 +1194,7 @@ void centaur_init( void )
rc = gpe_request_create(
&G_cent_scom_req, // gpe_req for the task
&G_async_gpe_queue1, // queue
- IPC_ST_CENTAUR_SCOM_FUNCID, // entry point
+ IPC_ST_MEMBUF_SCOM_FUNCID, // entry point
&G_cent_scom_gpe_parms, // parm for the task
SSX_WAIT_FOREVER, //
NULL, // callback
@@ -1275,19 +1287,27 @@ CentaurMemData * cent_get_centaur_data_ptr( const uint8_t i_occ_centaur_id )
}
}
-uint32_t centaur_configuration_create( CentaurConfiguration_t * i_centaurConfiguration )
+uint32_t membuf_configuration_create( )
{
bool rc = 0;
GpeRequest l_request;
do
{
- G_gpe_centaur_config_args.centaurConfiguration = i_centaurConfiguration;
+ G_gpe_centaur_config_args.membufConfiguration = &G_membufConfiguration;
+ if(MEM_TYPE_CUMULUS == G_sysConfigData.mem_type)
+ {
+ G_gpe_centaur_config_args.mem_type = MEMTYPE_CENTAUR;
+ }
+ else
+ {
+ G_gpe_centaur_config_args.mem_type = MEMTYPE_OCMB;
+ }
rc = gpe_request_create(
&l_request, // request
&G_async_gpe_queue1, // gpe queue
- IPC_ST_CENTAUR_INIT_FUNCID, // Function Id
+ IPC_ST_MEMBUF_INIT_FUNCID, // Function Id
&G_gpe_centaur_config_args, // GPE arg_ptr
SSX_SECONDS(5), // timeout
NULL, // callback
@@ -1295,22 +1315,22 @@ uint32_t centaur_configuration_create( CentaurConfiguration_t * i_centaurConfigu
ASYNC_REQUEST_BLOCKING);
if( rc )
{
- TRAC_ERR("centaur_configuration_create: gpe_request_create failed for"
- " IPC_ST_CENTAUR_INIT_FUNCID. rc = 0x%08x",rc);
+ TRAC_ERR("membuf_configuration_create: gpe_request_create failed for"
+ " IPC_ST_MEMBUF_INIT_FUNCID. rc = 0x%08x",rc);
break;
}
- TRAC_INFO("centaur_configuration_create: Scheduling request for IPC_ST_CENTAUR_INIT_FUNCID");
+ TRAC_INFO("membuf_configuration_create: Scheduling request for IPC_ST_MEMBUF_INIT_FUNCID");
gpe_request_schedule(&l_request);
- TRAC_INFO("centaur_configuration_create: GPE_centaur_configuration_create w/rc=0x%08x",
+ TRAC_INFO("membuf_configuration_create: GPE_membuf_configuration_create w/rc=0x%08x",
l_request.request.completion_state);
if(ASYNC_REQUEST_STATE_COMPLETE != l_request.request.completion_state)
{
rc = l_request.request.completion_state;
- TRAC_ERR("centaur_configuration_create: IPC_ST_CENTAUR_INIT_FUNCID"
+ TRAC_ERR("membuf_configuration_create: IPC_ST_MEMBUF_INIT_FUNCID"
" request did not complete.");
break;
}
@@ -1318,7 +1338,7 @@ uint32_t centaur_configuration_create( CentaurConfiguration_t * i_centaurConfigu
if (G_gpe_centaur_config_args.error.rc != GPE_RC_SUCCESS)
{
rc = G_gpe_centaur_config_args.error.rc;
- TRAC_ERR("centaur_configuration_create: IPC_ST_CENTAUR_INIT_FUNCID"
+ TRAC_ERR("membuf_configuration_create: IPC_ST_MEMBUF_INIT_FUNCID"
" failed with rc=0x%08x.",
rc);
break;
diff --git a/src/occ_405/cent/centaur_data.h b/src/occ_405/cent/centaur_data.h
index 30c0e0d..2c7e259 100755
--- a/src/occ_405/cent/centaur_data.h
+++ b/src/occ_405/cent/centaur_data.h
@@ -33,7 +33,7 @@
#include <ssx.h>
#include "rtls.h"
#include "centaur_mem_data.h"
-#include "centaur_structs.h"
+#include "membuf_structs.h"
#include "occ_sys_config.h"
#include "memory.h"
@@ -109,15 +109,15 @@ enum eOccCentaurs
//Centaur data collect structures used for task data pointers
-struct centaur_data_task {
- uint8_t start_centaur;
- uint8_t current_centaur;
- uint8_t end_centaur;
- uint8_t prev_centaur;
- CentaurMemData * centaur_data_ptr;
+struct membuf_data_task {
+ uint8_t start_membuf;
+ uint8_t current_membuf;
+ uint8_t end_membuf;
+ uint8_t prev_membuf;
+ CentaurMemData * membuf_data_ptr;
GpeRequest gpe_req;
} __attribute__ ((__packed__));
-typedef struct centaur_data_task centaur_data_task_t;
+typedef struct membuf_data_task membuf_data_task_t;
//*************************************************************************
@@ -125,7 +125,7 @@ typedef struct centaur_data_task centaur_data_task_t;
//*************************************************************************
//Global centaur structures used for task data pointers
-extern centaur_data_task_t G_centaur_data_task;
+extern membuf_data_task_t G_membuf_data_task;
//Global is bitmask of centaurs
extern uint32_t G_present_centaurs;
@@ -158,6 +158,9 @@ extern uint8_t G_cent_temp_updated_bitmap;
//bitmap of configured MBA's (2 per centaur, lsb is centaur0/mba0)
extern uint16_t G_configured_mbas;
+//global Message payload for collecting membuf sensor cache data.
+extern MemBufGetMemDataParms_t G_membuf_data_parms;
+
//*************************************************************************
// Function Prototypes
//*************************************************************************
@@ -176,11 +179,12 @@ void cent_recovery(uint32_t i_cent);
//associated with the specified OCC centaur id.
CentaurMemData * cent_get_centaur_data_ptr( const uint8_t i_centaur_id );
-// Create the centaur configuration object
-uint32_t centaur_configuration_create( CentaurConfiguration_t * i_centaurConfiguration );
+// Create the global membuf configuration object
+uint32_t membuf_configuration_create( );
// Remove centaur from enabled sensor list due to channel checkstop
void cent_chan_checkstop(uint32_t i_cent);
+void ocmb_init(void);
#endif //_CENTAUR_DATA_H
diff --git a/src/occ_405/cent/centaur_data_service_codes.h b/src/occ_405/cent/centaur_data_service_codes.h
index 85515ba..426090e 100755
--- a/src/occ_405/cent/centaur_data_service_codes.h
+++ b/src/occ_405/cent/centaur_data_service_codes.h
@@ -48,6 +48,7 @@ enum centModuleId
CENTAUR_INIT_MOD = CENT_COMP_ID | 0x01,
CENT_CONTROL_MOD = CENT_COMP_ID | 0x02,
CENT_RECOVERY_MOD = CENT_COMP_ID | 0x03,
+ OCMB_INIT_MOD = CENT_COMP_ID | 0x04,
};
//*************************************************************************
diff --git a/src/occ_405/cent/ocmb_control.c b/src/occ_405/cent/ocmb_control.c
new file mode 100644
index 0000000..02be215
--- /dev/null
+++ b/src/occ_405/cent/ocmb_control.c
@@ -0,0 +1,191 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/occ_405/cent/ocmb_control.c $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016,2018 */
+/* [+] 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 <occ_common.h>
+#include "gpe_export.h"
+#include "centaur_data_service_codes.h"
+#include "errl.h"
+#include "trac.h"
+#include "memory.h"
+#include "membuf_structs.h"
+#include "ocmb_firmware_registers.h"
+#include "ocmb_register_addresses.h"
+#include "amec_sys.h"
+
+// These are found in centaur_control.c. They are valid for Ocmb
+extern MemBufScomParms_t G_membuf_control_reg_parms;
+GPE_BUFFER(extern scomList_t *G_centaurThrottle);
+extern memory_control_task_t G_memory_control_task;
+void cent_update_nlimits(uint32_t i_cent);
+uint16_t centaurThrottle_convert2Numerator(uint16_t i_throttle, uint8_t i_cent, uint8_t i_mba);
+
+typedef enum
+{
+ NM_THROTTLE_MBA = 0,
+ NM_THROTTLE_SYNC = 1,
+ NUM_THROTTLE_SCOMS = 2,
+} eOcmbThrottleInfo;
+
+
+void ocmb_control_init( void )
+{
+ errlHndl_t err = NULL;
+ int rc_gpe = 0;
+ ocmb_mba_farb3q_t l_mbafarbq;
+
+ //initialize the active throttle limits
+ memset(G_memoryThrottleLimits, 0, sizeof(G_memoryThrottleLimits));
+
+ // set upt the throttle scom regs. //slot 0, slot1 or per-port
+ G_centaurThrottle[NM_THROTTLE_MBA].scom = OCMB_MBA_FARB3Q;
+ l_mbafarbq.value = 0;
+ l_mbafarbq.fields.cfg_nm_n_per_slot = -1;
+ l_mbafarbq.fields.cfg_nm_n_per_port = -1;
+ G_centaurThrottle[NM_THROTTLE_MBA].mask = l_mbafarbq.value;
+
+ // Set up GPE parameters
+ G_membuf_control_reg_parms.error.ffdc = 0;
+ G_membuf_control_reg_parms.entries = 0;
+ G_membuf_control_reg_parms.scomList = &G_centaurThrottle[0];
+
+ //--------------------------------------------------
+ // Initializes GPE Centaur Control Task, but
+ // doesn't actually run anything until RTL
+ //--------------------------------------------------
+ rc_gpe = gpe_request_create(
+ &G_memory_control_task.gpe_req, // gpe_req for the task
+ &G_async_gpe_queue1, // queue
+ IPC_ST_MEMBUF_SCOM_FUNCID, // Function ID
+ &G_membuf_control_reg_parms, // parm for the task
+ SSX_WAIT_FOREVER, //
+ NULL, // callback
+ NULL, // callback argument
+ ASYNC_CALLBACK_IMMEDIATE ); // options
+
+ if (rc_gpe)
+ {
+ //If fail to create gpe request then there is a problem.
+ TRAC_ERR("ocmb_control_init: Failed to initialize membuf control task [rc_gpe=0x%x]", rc_gpe);
+
+ /* @
+ * @errortype
+ * @moduleid CENTAUR_INIT_MOD
+ * @reasoncode SSX_GENERIC_FAILURE
+ * @userdata1 l_rc_gpe - Return code of failing function
+ * @userdata2 0
+ * @userdata4 ERC_CENTAUR_GPE_REQUEST_CREATE_FAILURE
+ * @devdesc Failed to initialize GPE routine
+ */
+ err = createErrl(
+ OCMB_INIT_MOD, //modId
+ SSX_GENERIC_FAILURE, //reasoncode
+ ERC_CENTAUR_GPE_REQUEST_CREATE_FAILURE, //Extended reason code
+ ERRL_SEV_PREDICTIVE, //Severity
+ NULL, //Trace Buf
+ DEFAULT_TRACE_SIZE, //Trace Size
+ rc_gpe, //userdata1
+ 0 //userdata2
+ );
+
+ addUsrDtlsToErrl(err, //io_err
+ (uint8_t *) &G_memory_control_task.gpe_req.ffdc, //i_dataPtr,
+ sizeof(GpeFfdc), //i_size
+ ERRL_USR_DTL_STRUCT_VERSION_1, //version
+ ERRL_USR_DTL_BINARY_DATA); //type
+
+ REQUEST_RESET(err);
+ }
+}
+
+// Function Specification
+//
+// Name: ocmb_control
+//
+// Description: Performs centaur control.
+// return TRUE settings changed HW needs to be updated.
+// return FALSE settings did not change
+//
+// End Function Specification
+bool ocmb_control( memory_control_task_t * i_memControlTask )
+{
+ bool throttle_updated = TRUE;
+ int l_membuf = i_memControlTask->curMemIndex;
+ amec_centaur_t * l_cent_ptr = NULL;
+
+ MemBufScomParms_t * l_parms =
+ (MemBufScomParms_t *)(i_memControlTask->gpe_req.cmd_data);
+
+ l_cent_ptr = &g_amec->proc[0].memctl[l_membuf].centaur;
+
+ // update min/max settings
+ cent_update_nlimits(l_membuf);
+
+ // calculate new N values
+ ocmb_mba_farb3q_t l_mbafarbq;
+ uint16_t l_mba01_n_per_mba =
+ centaurThrottle_convert2Numerator(g_amec->mem_speed_request, l_membuf, 0);
+
+ uint16_t l_mba01_n_per_chip = G_memoryThrottleLimits[l_membuf][0].max_n_per_chip;
+ amec_cent_mem_speed_t l_mba01_speed;
+
+ //combine port and slot(mba) settings (16 bit) in to a single 32bit value
+ l_mba01_speed.mba_n = l_mba01_n_per_mba;
+ l_mba01_speed.chip_n = l_mba01_n_per_chip;
+
+
+ // Check if the throttle value has been updated since the last
+ // time we sent it. If it has, then send a new value, otherwise
+ // do nothing.
+ if ( l_mba01_speed.word32 != l_cent_ptr->portpair[0].last_mem_speed_sent.word32 )
+ {
+
+ /// Set up Centuar Scom Registers - array of Scoms
+ /// [0]: N/M Throttle MBA
+
+ /// [0]: Set up N/M throttle MBA
+ G_centaurThrottle[NM_THROTTLE_MBA].commandType = MEMBUF_SCOM_RMW;
+ G_centaurThrottle[NM_THROTTLE_MBA].instanceNumber = l_membuf;
+ // Set up value to be written
+ l_mbafarbq.fields.cfg_nm_n_per_slot = l_mba01_n_per_mba;
+ l_mbafarbq.fields.cfg_nm_n_per_port = l_mba01_n_per_chip;
+ G_centaurThrottle[NM_THROTTLE_MBA].data = l_mbafarbq.value;
+
+ G_centaurThrottle[NM_THROTTLE_SYNC].commandType = MEMBUF_SCOM_MEMBUF_SYNC;
+
+ /// Set up GPE parameters
+ l_parms->scomList = G_centaurThrottle;
+ l_parms->entries = NUM_THROTTLE_SCOMS;
+ l_parms->error.ffdc = 0;
+
+ // Update the last sent throttle value, this will get
+ // cleared if the GPE does not complete successfully.
+ l_cent_ptr->portpair[0].last_mem_speed_sent.word32 = l_mba01_speed.word32;
+ }
+ else
+ {
+ throttle_updated = FALSE;
+ }
+
+ return throttle_updated;
+}
diff --git a/src/occ_405/cent/ocmb_data.c b/src/occ_405/cent/ocmb_data.c
new file mode 100644
index 0000000..8599b28
--- /dev/null
+++ b/src/occ_405/cent/ocmb_data.c
@@ -0,0 +1,162 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/occ_405/cent/ocmb_data.c $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016,2018 */
+/* [+] 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 "centaur_data.h"
+#include "ocmb_membuf.h"
+#include "occ_service_codes.h"
+#include "centaur_data_service_codes.h"
+#include "errl.h"
+#include "trac.h"
+#include "membuf_structs.h"
+
+/**
+ * GPE shared data area for gpe0 tracebuffer and size
+ */
+extern gpe_shared_data_t G_shared_gpe_data;
+
+/**
+ * ocmb_init
+ * Initialize environment for collection of ocmb DTS and performance
+ * data.
+ * @post G_membufConfiguration populated
+ * @post G_present_centaurs populated
+ * @post G_dimm_present_sensors
+ * @post G_membuf_data_task populated
+ * @post GPE request to call for recover created ?
+ * @post GPE request to call for throttle conttrol created
+ * @note HW Deadman timer enabled and set to max value
+ * @note HW Any emergency throttle cleared
+*/
+void ocmb_init(void)
+{
+ //errlHndl_t err = NULL;
+ int rc = 0;
+ int membuf_idx = 0;
+ do
+ {
+ TRAC_INFO("ocmb_init: Initializing Memory Data Controller");
+ // Create configuration data use G_membufConfiguration
+ rc = membuf_configuration_create(&G_membufConfiguration);
+ if( rc )
+ {
+ break;
+ }
+
+ // Configure OCC_405 global membuf present and sensor enabled flags
+ G_present_centaurs = 0;
+ for(membuf_idx=0; membuf_idx<MAX_NUM_CENTAURS; ++membuf_idx)
+ {
+ // Check if this membuf is even possible to be present
+ if( CENTAUR_BY_MASK(membuf_idx) )
+ {
+ if( G_membufConfiguration.baseAddress[membuf_idx] )
+ {
+ // A valid inband Bar Address was found
+ G_present_centaurs |= (CENTAUR0_PRESENT_MASK >> membuf_idx);
+
+ if(G_membufConfiguration.dts_config & CONFIG_MEMDTS0(membuf_idx))
+ {
+ G_dimm_enabled_sensors.bytes[membuf_idx] = DIMM_SENSOR0;
+ }
+ if(G_membufConfiguration.dts_config & CONFIG_MEMDTS1(membuf_idx))
+ {
+ G_dimm_enabled_sensors.bytes[membuf_idx] = (DIMM_SENSOR0 >> 1);
+ }
+ TRAC_INFO("ocmb_init: Membuf[%d] Found.",
+ membuf_idx);
+ }
+ }
+ }
+
+ TRAC_IMP("ocmb_init: G_present_centaurs = 0x%08x", G_present_centaurs);
+
+ G_dimm_present_sensors = G_dimm_enabled_sensors;
+
+ TRAC_IMP("bitmap of present dimm temperature sensors: 0x%08X%08X",
+ G_dimm_enabled_sensors.words[0],
+ G_dimm_enabled_sensors.words[1]);
+
+ // Setup the GPE request to do sensor data collection
+ G_membuf_data_parms.error.ffdc = 0;
+ G_membuf_data_parms.collect = -1;
+ G_membuf_data_parms.update = -1;
+ G_membuf_data_parms.data = 0;
+
+ rc = gpe_request_create(
+ &G_membuf_data_task.gpe_req, //gpe_req for the task
+ &G_async_gpe_queue1, //queue
+ IPC_ST_MEMBUF_DATA_FUNCID, //Function ID
+ &G_membuf_data_parms, //parm for the task
+ SSX_WAIT_FOREVER, //
+ NULL, //callback
+ NULL, //callback argument
+ 0 ); //options
+ if( rc )
+ {
+ TRAC_ERR("ocmb_init: gpe_request_create failed for "
+ "G_membuf_data_task.gpe_req. rc = 0x%08x", rc);
+ break;
+ }
+
+ } while(0);
+
+ if( rc )
+ {
+ /* @
+ * @errortype
+ * @moduleid OCMB_INIT_MOD
+ * @reasoncode SSX_GENERIC_FAILURE
+ * @userdata1 rc - Return code of failing function
+ * @userdata4 OCC_NO_EXTENDED_RC
+ * @devdesc Failed to initialize memory buffer sensors
+ */
+ errlHndl_t l_err =
+ createErrl(
+ OCMB_INIT_MOD, //modId
+ SSX_GENERIC_FAILURE, //reasoncode
+ OCC_NO_EXTENDED_RC, //Extended reasoncode
+ ERRL_SEV_PREDICTIVE, //Severity
+ NULL, //Trace Buf
+ DEFAULT_TRACE_SIZE, //Trace Size
+ rc, //userdata1
+ 0 //userdata2
+ );
+
+ // Capture the GPE1 trace buffer
+ addUsrDtlsToErrl(l_err,
+ (uint8_t *) G_shared_gpe_data.gpe1_tb_ptr,
+ G_shared_gpe_data.gpe1_tb_sz,
+ ERRL_USR_DTL_STRUCT_VERSION_1,
+ ERRL_USR_DTL_TRACE_DATA);
+
+
+ REQUEST_RESET(l_err);
+ }
+ else
+ {
+ ocmb_control_init();
+ }
+
+ return;
+}
diff --git a/src/occ_405/cent/ocmb_membuf.h b/src/occ_405/cent/ocmb_membuf.h
new file mode 100644
index 0000000..844974d
--- /dev/null
+++ b/src/occ_405/cent/ocmb_membuf.h
@@ -0,0 +1,47 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/occ/cent/ocmb_membuf.h $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2014,2015 */
+/* [+] 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 */
+#ifndef __OCMB_MEMBUF_H__
+#define __OCMB_MEMBUF_H__
+
+#include "ssx.h"
+#include "memory.h"
+#include "membuf_structs.h"
+
+
+extern MemBufConfiguration_t G_membufConfiguration;
+
+/**
+ * Control ocmb memory buffer thottling
+ * @param[in] The memroy control task
+ * @return TRUE if throttle values changed, otherwise FALSE.
+ */
+bool ocmb_control( memory_control_task_t * i_memControlTask );
+
+/**
+ * Initialize structures for throttle control on ocmb memory data buffer
+ */
+void ocmb_control_init( void );
+
+#endif
diff --git a/src/occ_405/dimm/dimm.c b/src/occ_405/dimm/dimm.c
index 56d36dd..fd8e6e3 100755
--- a/src/occ_405/dimm/dimm.c
+++ b/src/occ_405/dimm/dimm.c
@@ -1031,7 +1031,7 @@ void task_dimm_sm(struct task *i_self)
}
}
}
- else // G_sysConfigData.mem_type is Centaur
+ else // G_sysConfigData.mem_type is Cumulus(Centaur) or Axone(Ocmb)
{
centaur_data();
}
diff --git a/src/occ_405/mem/memory.c b/src/occ_405/mem/memory.c
index 111407d..1ab7277 100644
--- a/src/occ_405/mem/memory.c
+++ b/src/occ_405/mem/memory.c
@@ -30,8 +30,9 @@
#include "memory_power_control.h"
#include "dimm_control.h"
#include "centaur_control.h"
+#include "ocmb_membuf.h"
#include "centaur_data.h"
-#include "centaur_structs.h"
+#include "membuf_structs.h"
#include "memory_service_codes.h"
#include <occ_service_codes.h> // for SSX_GENERIC_FAILURE
#include "amec_sys.h"
@@ -41,7 +42,7 @@ extern dimm_control_args_t G_dimm_control_args;
extern task_t G_task_table[TASK_END];
-extern CentaurScomParms_t G_centaur_control_reg_parms;
+extern MemBufScomParms_t G_membuf_control_reg_parms;
// This array identifies dimm throttle limits for both Centaurs (Cumulus) and
// rdimms (Nimbus) based systems.
@@ -105,7 +106,11 @@ void task_memory_control( task_t * i_task )
}
else if (MEM_TYPE_CUMULUS == G_sysConfigData.mem_type)
{
- gpe_rc = G_centaur_control_reg_parms.error.rc;
+ gpe_rc = G_membuf_control_reg_parms.error.rc;
+ }
+ else if (MEM_TYPE_OCM == G_sysConfigData.mem_type)
+ {
+ gpe_rc = G_membuf_control_reg_parms.error.rc;
}
do
@@ -148,7 +153,7 @@ void task_memory_control( task_t * i_task )
{
// ignore error and stop monitoring this centaur if there is a channel checkstop
if( (MEM_TYPE_CUMULUS == G_sysConfigData.mem_type) &&
- (gpe_rc == CENTAUR_CHANNEL_CHECKSTOP) )
+ (gpe_rc == MEMBUF_CHANNEL_CHECKSTOP) )
{
// Remove the centaur sensor and all dimm sensors behind it.
cent_chan_checkstop(memControlTask->curMemIndex);
@@ -224,6 +229,16 @@ void task_memory_control( task_t * i_task )
}
rc = centaur_control(memControlTask); // Control one centaur
}
+ else if (MEM_TYPE_OCM == G_sysConfigData.mem_type)
+ {
+ // We use the same macros for Ocmb and Centaur
+ if(!CENTAUR_PRESENT(memIndex) ||
+ (!MBA_CONFIGURED(memIndex, 0) && !MBA_CONFIGURED(memIndex, 1)))
+ {
+ break;
+ }
+ rc = ocmb_control(memControlTask);
+ }
if(rc)
{
@@ -237,7 +252,7 @@ void task_memory_control( task_t * i_task )
}
else if (MEM_TYPE_CUMULUS == G_sysConfigData.mem_type)
{
- gpe_rc = G_centaur_control_reg_parms.error.rc;
+ gpe_rc = G_membuf_control_reg_parms.error.rc;
}
//Error in schedule gpe memory (dimm/centaur) control
@@ -361,11 +376,18 @@ void memory_init()
// Init DIMM state manager IPC request
memory_nimbus_init();
}
- else
+ else if (MEM_TYPE_CUMULUS == G_sysConfigData.mem_type)
{
- TRAC_INFO("memory_init: calling centaur_init()");
centaur_init(); //no rc, handles errors internally
}
+ else if (MEM_TYPE_OCM == G_sysConfigData.mem_type)
+ {
+ ocmb_init();
+ }
+ else
+ {
+ TRAC_ERR("memory_init: Uknown memory type");
+ }
// check if the init resulted in a reset
if(isSafeStateRequested())
diff --git a/src/occ_405/occLinkInputFile b/src/occ_405/occLinkInputFile
index 97f2f9a..f34fde3 100644
--- a/src/occ_405/occLinkInputFile
+++ b/src/occ_405/occLinkInputFile
@@ -15,6 +15,7 @@ INPUT ( amec_amester.o
amec_sensors_fw.o
amec_sensors_power.o
amec_sensors_centaur.o
+ amec_sensors_ocmb.o
amec_sensors_core.o
amec_slave_smh.o
amec_tasks.o
@@ -22,6 +23,8 @@ INPUT ( amec_amester.o
avsbus.o
centaur_control.o
centaur_data.o
+ ocmb_control.o
+ ocmb_data.o
chom.o
cmdh_dbug_cmd.o
cmdh_fsp_cmds_datacnfg.o
diff --git a/src/occ_405/occbuildname.c b/src/occ_405/occbuildname.c
index 1f73927..b3e3a04 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_190424a\0" /*</BuildName>*/ ;
+volatile const char G_occ_buildname[16] __attribute__((section(".buildname"))) = /*<BuildName>*/ "op_occ_190426a\0" /*</BuildName>*/ ;
#endif
diff --git a/src/occ_405/topfiles.mk b/src/occ_405/topfiles.mk
index 7d98dbc..94dadfd 100644
--- a/src/occ_405/topfiles.mk
+++ b/src/occ_405/topfiles.mk
@@ -39,12 +39,15 @@ TOP-C-SOURCES = amec/amec_controller.c \
amec/amec_sensors_fw.c \
amec/amec_sensors_power.c \
amec/amec_sensors_centaur.c \
+ amec/amec_sensors_ocmb.c \
amec/amec_sensors_core.c \
amec/amec_slave_smh.c \
amec/amec_tasks.c \
amec/sensor_power.c \
cent/centaur_control.c \
cent/centaur_data.c \
+ cent/ocmb_control.c \
+ cent/ocmb_data.c \
cmdh/cmdh_dbug_cmd.c \
cmdh/cmdh_fsp_cmds_datacnfg.c \
cmdh/cmdh_fsp_cmds.c \
diff --git a/src/occ_gpe0/firdata/firData.c b/src/occ_gpe0/firdata/firData.c
index 5e35056..fc827b0 100644
--- a/src/occ_gpe0/firdata/firData.c
+++ b/src/occ_gpe0/firdata/firData.c
@@ -971,9 +971,9 @@ void FirData_addTrgtsToPnor( FirData_t * io_fd )
ADD_SUBUNITS_TO_PNOR( omicMask, MC, OMIC )
END_UNIT_LOOP
}
- else if ( HOMER_CHIP_EXPLORER == chipHdr->chipType )
+ else if ( HOMER_CHIP_OCMB == chipHdr->chipType )
{
- // NOTE: The Explorer chip does not have any unit data.
+ // NOTE: The Ocmb chip does not have any unit data.
isM = false; // processor chips only.
@@ -1136,9 +1136,9 @@ int32_t FirData_init( FirData_t * io_fd,
{
reglist += sizeof(HOMER_ChipAxone_t);
}
- else if (HOMER_CHIP_EXPLORER == l_chiptPtr->chipType)
+ else if (HOMER_CHIP_OCMB == l_chiptPtr->chipType)
{
- // There is no chip unit data for Explorer.
+ // There is no chip unit data for Ocmb.
}
else
{
diff --git a/src/occ_gpe0/firdata/homerData_common.h b/src/occ_gpe0/firdata/homerData_common.h
index e661467..0d1a3cc 100644
--- a/src/occ_gpe0/firdata/homerData_common.h
+++ b/src/occ_gpe0/firdata/homerData_common.h
@@ -142,7 +142,7 @@ typedef enum
{
HOMER_CHIP_NIMBUS, /** P9 Nimbus processor chip */
HOMER_CHIP_AXONE, /** P9 Axone processor chip */
- HOMER_CHIP_EXPLORER, /** Explorer memory buffer chip */
+ HOMER_CHIP_OCMB, /** OCMB memory buffer chip */
HOMER_CHIP_INVALID = 0xff, /** Invalid chip */
diff --git a/src/occ_gpe1/gpe1_main.c b/src/occ_gpe1/gpe1_main.c
index 2385ac9..2115f39 100644
--- a/src/occ_gpe1/gpe1_main.c
+++ b/src/occ_gpe1/gpe1_main.c
@@ -33,7 +33,12 @@
#include "pk_trace.h"
#include "ipc_api.h"
#include "gpe_export.h"
-#include "gpe_centaur.h"
+#include "gpe_membuf.h"
+
+#if defined(__OCMB_UNIT_TEST__)
+#include "membuf_structs.h"
+#include "ocmb_mem_data.h"
+#endif
#define KERNEL_STACK_SIZE 1024
@@ -47,6 +52,18 @@ gpe_shared_data_t * G_gpe_shared_data = (gpe_shared_data_t*) GPE_SHARED_DATA_ADD
extern PkTraceBuffer* g_pk_trace_buf_ptr;
+#if defined(__OCMB_UNIT_TEST__)
+MemBufGetMemDataParms_t G_dataParms;
+MemBufConfiguration_t G_membufConfiguration;
+OcmbMemData G_escache;
+
+extern MemBufConfiguration_t * G_membuf_config;
+
+int gpe_ocmb_configuration_create(MemBufConfiguration_t* o_config);
+int get_ocmb_sensorcache(MemBufConfiguration_t* i_config,
+ MemBufGetMemDataParms_t* i_parms);
+#endif
+
// The main function is called by the boot code (after initializing some
// registers)
int main(int argc, char **argv)
@@ -87,7 +104,17 @@ int main(int argc, char **argv)
PK_TRACE("ipc_enable failed with rc = 0x%08x", rc);
pk_halt();
}
+#if defined(__OCMB_UNIT_TEST__)
+ G_dataParms.error.rc = 0;
+ G_dataParms.collect = 0;
+ G_dataParms.update = -1;
+ G_dataParms.data = (uint64_t*)(&G_escache);
+ G_membuf_config = &G_membufConfiguration;
+
+ rc = get_ocmb_sensorcache(&G_membufConfiguration, &G_dataParms);
+ PK_TRACE("get_ocmb_sensorcache rc = %x",rc);
+#endif
return 0;
}
diff --git a/src/occ_gpe1/gpe_centaur.c b/src/occ_gpe1/gpe_centaur.c
index d492133..6c17878 100644
--- a/src/occ_gpe1/gpe_centaur.c
+++ b/src/occ_gpe1/gpe_centaur.c
@@ -1,102 +1,706 @@
-#include "gpe_centaur.h"
-#include "ipc_async_cmd.h"
-#include "gpe_util.h"
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: chips/p9/procedures/lib/pm/centaur_thermal_access.c $ */
+/* */
+/* IBM CONFIDENTIAL */
+/* */
+/* EKB Project */
+/* */
+/* COPYRIGHT 2017 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* The source code for this program is not published or otherwise */
+/* divested of its trade secrets, irrespective of what has been */
+/* deposited with the U.S. Copyright Office. */
+/* */
+/* IBM_PROLOG_END_TAG */
+/**
+ * @briefcentaur_thermal_access
+ */
-CentaurConfiguration_t * G_centaur_config = NULL;
+#include "gpe_membuf.h"
+#include "ppe42_scom.h"
+#include "pk.h"
+#include "p9_misc_scom_addresses.h"
+#include "mcs_firmware_registers.h"
+#include "pba_firmware_constants.h"
+#include "pba_register_addresses.h"
+#include "centaur_register_addresses.h"
+#include "ppe42_msr.h"
+#include "occhw_pba_common.h"
-void gpe_centaur_init(ipc_msg_t* i_cmd, void* i_arg)
+// Power Bus Address bit that configures centaur for HOST/OCC P9=bit(38)
+#define PBA_HOST_OCC_CFG 0x0000000002000000ull;
+
+
+const uint32_t MCFGPR[OCCHW_N_MEMBUF] =
+{
+ MCS_0_MCRSVDE,
+ MCS_0_MCRSVDF,
+ MCS_1_MCRSVDE,
+ MCS_1_MCRSVDF,
+ MCS_2_MCRSVDE,
+ MCS_2_MCRSVDF,
+ MCS_3_MCRSVDE,
+ MCS_3_MCRSVDF
+};
+
+const uint32_t MCSYNC[OCCHW_N_MEMBUF/2] =
+{
+ MCS_0_MCSYNC,
+ MCS_1_MCSYNC,
+ MCS_2_MCSYNC,
+ MCS_3_MCSYNC
+};
+
+const uint32_t MCCHIFIR[OCCHW_N_MEMBUF] =
+{
+ MCP_CHAN0_CHI_FIR,
+ MCP_CHAN1_CHI_FIR,
+ MCP_CHAN2_CHI_FIR,
+ MCP_CHAN3_CHI_FIR,
+ MCP_CHAN4_CHI_FIR,
+ MCP_CHAN5_CHI_FIR,
+ MCP_CHAN6_CHI_FIR,
+ MCP_CHAN7_CHI_FIR
+};
+
+const uint32_t MCMCICFG1Q[OCCHW_N_MEMBUF] =
{
- int rc;
- ipc_async_cmd_t *async_cmd = (ipc_async_cmd_t*)i_cmd;
- CentaurConfigParms_t* payload = (CentaurConfigParms_t*)async_cmd->cmd_data;
+ MCP_CHAN0_CHI_MCICFG1Q,
+ MCP_CHAN1_CHI_MCICFG1Q,
+ MCP_CHAN2_CHI_MCICFG1Q,
+ MCP_CHAN3_CHI_MCICFG1Q,
+ MCP_CHAN4_CHI_MCICFG1Q,
+ MCP_CHAN5_CHI_MCICFG1Q,
+ MCP_CHAN6_CHI_MCICFG1Q,
+ MCP_CHAN7_CHI_MCICFG1Q
+};
+
+///////////////////////////////////////////////////////////////
+// These are PPE specific PBA routines.
+//////////////////////////////////////////////////////////////
+int
+gpe_pba_parms_create(GpePbaParms* parms,
+ int slave,
+ int write_ttype,
+ int write_tsize,
+ int read_ttype)
+{
+ pba_slvctln_t* slvctl, *mask;
+ pba_slvrst_t* slvrst;
+ pba_slvrst_t* slvrst_in_progress;
+ uint64_t all1 = 0xffffffffffffffffull;
+
+ parms->slave_id = slave;
+
+ slvctl = &(parms->slvctl);
+ mask = &(parms->mask);
+ slvrst = &(parms->slvrst);
+ slvrst_in_progress = &(parms->slvrst_in_progress);
+
+ parms->slvctl_address = PBA_SLVCTLN(slave);
+
+ slvrst->value = 0;
+ slvrst->fields.set = PBA_SLVRST_SET(slave);
+
+ slvrst_in_progress->value = 0;
+ slvrst_in_progress->fields.in_prog = PBA_SLVRST_IN_PROG(slave);
+
+ slvctl->value = 0;
+ mask->value = 0;
- CentaurConfiguration_t * config = payload->centaurConfiguration;
- G_centaur_config = config;
+ slvctl->fields.enable = 1;
+ mask->fields.enable = all1;
- payload->error.error = 0;
- payload->error.ffdc = 0;
+ slvctl->fields.mid_match_value = OCI_MASTER_ID_GPE1;
+ mask->fields.mid_match_value = all1;
- if(G_centaur_config == NULL)
+ slvctl->fields.mid_care_mask = all1;
+ mask->fields.mid_care_mask = all1;
+
+ slvctl->fields.write_ttype = write_ttype;
+ mask->fields.write_ttype = all1;
+
+ slvctl->fields.write_tsize = write_tsize;
+ mask->fields.write_tsize = all1;
+
+ slvctl->fields.read_ttype = read_ttype;
+ mask->fields.read_ttype = all1;
+
+ slvctl->fields.buf_alloc_a = 1;
+ slvctl->fields.buf_alloc_b = 1;
+ slvctl->fields.buf_alloc_c = 1;
+ slvctl->fields.buf_alloc_w = 1;
+ mask->fields.buf_alloc_a = 1;
+ mask->fields.buf_alloc_b = 1;
+ mask->fields.buf_alloc_c = 1;
+ mask->fields.buf_alloc_w = 1;
+
+ if (read_ttype == PBA_READ_TTYPE_CI_PR_RD)
{
- PK_TRACE("gpe_centaur_init: centaurConfiguration data ptr is NULL!");
- rc = GPE_RC_CONFIG_DATA_NULL_PTR;
+
+ slvctl->fields.buf_invalidate_ctl = 1;
+ mask->fields.buf_invalidate_ctl = all1;
+
+ slvctl->fields.read_prefetch_ctl = PBA_READ_PREFETCH_NONE;
+ mask->fields.read_prefetch_ctl = all1;
+
}
else
{
- PK_TRACE("Centaur_configuration. MSR:%08x",mfmsr());
- rc = gpe_centaur_configuration_create(G_centaur_config);
+
+ slvctl->fields.buf_invalidate_ctl = 0;
+ mask->fields.buf_invalidate_ctl = all1;
}
- payload->error.rc = rc;
+ mask->value = ~(mask->value);
+
+ return 0;
+}
+
+
+////////////////////////////////////////////////
+// Centaur specific routines
+////////////////////////////////////////////////
+int gpe_centaur_configuration_create(MemBufConfiguration_t* o_config)
+{
+ int rc = 0;
+ unsigned int i = 0;
+ mcfgpr_t mcfgpr;
+ uint64_t* ptr = (uint64_t*)o_config;
+ int designated_sync = -1;
+
+ // Prevent unwanted interrupts from scom errors
+ const uint32_t orig_msr = mfmsr();
+ mtmsr((orig_msr & ~(MSR_SIBRC | MSR_SIBRCA)) | MSR_SEM);
- // Send response
- rc = ipc_send_rsp(i_cmd, IPC_RC_SUCCESS);
- if(rc)
+ for(i = 0; i < sizeof(MemBufConfiguration_t) / 8; ++i)
{
- PK_TRACE("gpe_centaur_init: Failed to send response. rc = %x. Halting GPE1.",
- rc);
+ *ptr++ = 0ull;
+ }
+
+ o_config->configRc = MEMBUF_NOT_CONFIGURED;
+
+ do
+ {
+ // Create the PBASLV configurations for the GPE procedures.
+ // The 'dataParms' define the PBASLV setup needed to access the
+ // Centaur sensor cache. The 'scomParms' define the PBASLV setup
+ // needed to access the Centaur SCOMs.
+
+ rc = gpe_pba_parms_create(&(o_config->dataParms),
+ PBA_SLAVE_MEMBUF,
+ PBA_WRITE_TTYPE_CI_PR_W,
+ PBA_WRITE_TTYPE_DC,
+ PBA_READ_TTYPE_CL_RD_NC);
+
+ if (rc)
+ {
+ rc = MEMBUF_DATA_SETUP_ERROR;
+ break;
+ }
+
+ rc = gpe_pba_parms_create(&(o_config->scomParms),
+ PBA_SLAVE_MEMBUF,
+ PBA_WRITE_TTYPE_CI_PR_W,
+ PBA_WRITE_TTYPE_DC,
+ PBA_READ_TTYPE_CI_PR_RD);
+
+ if (rc)
+ {
+ rc = MEMBUF_SCOM_SETUP_ERROR;
+ break;
+ }
+
+ // Iterate through each MCS on the chip and check configuration.
+
+ // Note that the code uniformly treats SCOM failures of the MCFGPR
+ // registers as an unconfigured Centaur. This works both for real
+ // hardware, as well as for our VBU models where some of the "valid"
+ // MCS are not in the simulation models.
+
+ for (i = 0; i < OCCHW_N_MEMBUF; ++i)
+ {
+ // check for channel checkstop
+ rc = check_centaur_channel_chkstp(i);
+ if (rc)
+ {
+ // If scom failed OR there is a channel checkstop then
+ // Centaur is not usable.
+ rc = 0;
+ continue;
+ }
+
+ // Verify that inband scom has been setup. If not then
+ // assume the centaur is either non-existant or not configured.
+ // Setup is provided by HWP p9c_set_inband_addr.C
+ rc = getscom_abs(MCFGPR[i], &(mcfgpr.value));
+
+ if (rc)
+ {
+ // ignore if can't be scomed.
+ rc = 0;
+ continue;
+ }
+
+ // If inband scom is not configured then assume the centaur does not exist
+ if (!mcfgpr.fields.mcfgprq_valid)
+ {
+ continue;
+ }
+
+
+ // The 31-bit base-address (inband scom BAR) corresponds to bits [8:38] in the
+ // 64-bit PowerBus address.
+ // Set the HOST/OCC bit in the address.
+ o_config->baseAddress[i] =
+ ((uint64_t)(mcfgpr.fields.mcfgprq_base_address) << 25) | PBA_HOST_OCC_CFG;
+
+ PK_TRACE_DBG("Centar[%d] Base Address: %016llx",i,o_config->baseAddress[i]);
+
+ // Add the Centaur to the configuration
+ o_config->config |= (CHIP_CONFIG_MCS(i) | CHIP_CONFIG_MEMBUF(i));
+ }
+
+ if (rc)
+ {
+ break;
+ }
+
+ // Find the designated sync
+ for (i = 0; i < (OCCHW_N_MEMBUF/2); ++i)
+ {
+ uint64_t mcsync;
+ rc = getscom_abs(MCSYNC[i], &mcsync);
+ if (rc)
+ {
+ PK_TRACE("getscom failed on MCSYNC, rc = %d. The first configured MC will be"
+ " the designated sync",rc);
+ rc = 0;
+ }
+ if (mcsync != 0)
+ {
+ designated_sync = i;
+ // There can only be one sync, so stop searching.
+ break;
+ }
+ }
+
+ if (designated_sync < 0)
+ {
+ designated_sync = cntlz32(o_config->config << CHIP_CONFIG_MCS_BASE);
+ PK_TRACE("No designated sync found, using MCS(%d)",designated_sync);
+ }
+
+ o_config->mcSyncAddr = MCSYNC[designated_sync];
+
+
+ rc = configure_pba_bar_for_inband_access(o_config);
+ if( rc )
+ {
+ break;
+ }
+ // At this point the structure is initialized well-enough that it can
+ // be used by gpe_inband_scom().
+
+
+ o_config->configRc = 0;
+
+ if (o_config->config == 0)
+ {
+ break;
+ }
+
+
+ // Get Device ID from each centaur
+ membuf_get_scom_vector(o_config,
+ CENTAUR_DEVICE_ID,
+ (uint64_t*)(&(o_config->deviceId[0])));
- gpe_set_ffdc(&(payload->error), 0x00, GPE_RC_IPC_SEND_FAILED, rc);
- pk_halt();
}
+ while(0);
+
+ o_config->configRc = rc;
+
+ mtmsr(orig_msr);
+
+ return rc;
}
-void gpe_centaur_scom(ipc_msg_t* i_cmd, void* i_arg)
+int configure_pba_bar_for_inband_access(MemBufConfiguration_t * i_config)
{
- static int g_log_once = 0;
- int rc;
- ipc_async_cmd_t *async_cmd = (ipc_async_cmd_t*)i_cmd;
- CentaurScomParms_t * scomParms = (CentaurScomParms_t*)async_cmd->cmd_data;
+ uint64_t bar = 0;
+ uint64_t barMsk = PBA_BARMSKN_MASK_MASK;
+ uint64_t mask = 0;
+ int i = 0;
+ int rc = 0;
- if(g_log_once == 0)
+ do
{
- g_log_once = 1;
- PK_TRACE("Centaur Scom. MSR:%08x",mfmsr());
- }
- gpe_scom_centaur(G_centaur_config, scomParms);
+ // Configure the PBA BAR and PBA BARMSK.
+ // Set the BARMSK bits such that:
+ // -PBA[8:22] are provided by the PBABAR.
+ // -PBA[23:36] are provided by the PBASLVCTL ExtrAddr field
+ // -PBA[37:43] are provided by the OCI addr[5:11]
+ // PBA[44:63] will always come from the OCI addr[12:31]
+ // Note: This code should no longer be needed when the BAR/BARMSK is set
+ // by PHYP.
+ if (i_config->config != 0)
+ {
+
+ for (i = 0; i < OCCHW_N_MEMBUF; ++i)
+ {
+ bar |= i_config->baseAddress[i];
+ }
+
+ bar &= ~barMsk;
+
+ PK_TRACE_DBG("PBABAR(%d): %016llx", PBA_BAR_MEMBUF, bar);
+ PK_TRACE_DBG("PBABARMSK: %016llx", barMsk);
+
+ rc = putscom_abs(PBA_BARMSKN(PBA_BAR_MEMBUF), barMsk);
+
+ if (rc)
+ {
+ PK_TRACE_DBG("Unexpected rc = 0x%08x SCOMing PBA_BARMSKN(%d)\n",
+ (uint32_t)rc, PBA_BAR_MEMBUF);
+ rc = MEMBUF_BARMSKN_PUTSCOM_FAILURE;
+ break;
+ }
+
+ rc = putscom_abs(PBA_BARN(PBA_BAR_MEMBUF), bar);
+ if (rc)
+ {
+ PK_TRACE_DBG("Unexpected rc = 0x%08x SCOMing PBA_BARN(%d)\n",
+ (uint32_t)rc, PBA_BAR_MEMBUF);
+ rc = MEMBUF_BARN_PUTSCOM_FAILURE;
+ break;
+ }
+ }
+
+ // Do an independent check that every Centaur base address
+ // can be generated by the combination of the current BAR and
+ // BAR Mask, along with the initial requirement that the mask must
+ // include at least bits 38:43.
+
+ if (i_config->config != 0)
+ {
+ rc = getscom_abs(PBA_BARN(PBA_BAR_MEMBUF), &bar);
+
+ if (rc)
+ {
+ PK_TRACE_DBG("Unexpected rc = 0x%08x SCOMing PBA_BARN(%d)\n",
+ (uint32_t)rc, PBA_BAR_MEMBUF);
+ rc = MEMBUF_BARN_GETSCOM_FAILURE;
+ break;
+ }
+
+ rc = getscom_abs(PBA_BARMSKN(PBA_BAR_MEMBUF), &mask);
+
+ if (rc)
+ {
+ PK_TRACE_DBG("Unexpected rc = 0x%08x SCOMing PBA_BARMSKN(%d)\n",
+ (uint32_t)rc, PBA_BAR_MEMBUF);
+ rc = MEMBUF_BARMSKN_GETSCOM_FAILURE;
+ break;
+ }
+
+ bar = bar & PBA_BARN_ADDR_MASK;
+ mask = mask & PBA_BARMSKN_MASK_MASK;
+
+ if ((mask & 0x0000000003f00000ull) != 0x0000000003f00000ull)
+ {
- // Send response
- rc = ipc_send_rsp(i_cmd, IPC_RC_SUCCESS);
- if(rc)
+ PK_TRACE("PBA BAR mask (%d) does not cover bits 38:43\n", PBA_BAR_MEMBUF);
+ rc = MEMBUF_MASK_ERROR;
+ break;
+ }
+
+ for (i = 0; i < OCCHW_N_MEMBUF; ++i)
+ {
+ if (i_config->baseAddress[i] != 0)
+ {
+ if ((i_config->baseAddress[i] & ~mask) !=
+ (bar & ~mask))
+ {
+
+ PK_TRACE("BAR/Mask (%d) error for MCS/Centaur %d",
+ PBA_BAR_MEMBUF, i);
+
+ PK_TRACE(" base = 0x%08x%08x",
+ (uint32_t)(i_config->baseAddress[i]>>32),
+ (uint32_t)(i_config->baseAddress[i]));
+
+ PK_TRACE(" bar = 0x%08x%08x"
+ " mask = 0x%08x%08x",
+ (uint32_t)(bar >> 32),
+ (uint32_t)(bar),
+ (uint32_t)(mask >> 32),
+ (uint32_t)(mask));
+
+ rc = MEMBUF_BAR_MASK_ERROR;
+ break;
+ }
+ }
+ }
+ }
+ } while(0);
+ return rc;
+}
+
+
+
+int check_centaur_channel_chkstp(unsigned int i_centaur)
+{
+ int rc = 0;
+ mcchifir_t chifir;
+ mcmcicfg_t chicfg;
+
+ do
{
- PK_TRACE("gpe_centaur_scom: Failed to send response. rc = %x. Halting GPE1.",
- rc);
+ rc = getscom_abs(MCCHIFIR[i_centaur], &(chifir.value));
+ if (rc)
+ {
+ PK_TRACE("MCCHIFIR scom failed. rc = %d",rc);
+ break;
+ }
- gpe_set_ffdc(&(scomParms->error), 0x00, GPE_RC_IPC_SEND_FAILED, rc);
- pk_halt();
- }
+ if(chifir.fields.fir_dsrc_no_forward_progress ||
+ chifir.fields.fir_dmi_channel_fail ||
+ chifir.fields.fir_channel_init_timeout ||
+ chifir.fields.fir_channel_interlock_err ||
+ chifir.fields.fir_replay_buffer_ue ||
+ chifir.fields.fir_replay_buffer_overrun ||
+ chifir.fields.fir_df_sm_perr ||
+ chifir.fields.fir_cen_checkstop ||
+ chifir.fields.fir_dsff_tag_overrun ||
+ chifir.fields.fir_dsff_mca_async_cmd_error ||
+ chifir.fields.fir_dsff_seq_error ||
+ chifir.fields.fir_dsff_timeout)
+ {
+ PK_TRACE("MCCHIFIR: %08x%08x for channel %d",
+ chifir.words.high_order,
+ chifir.words.low_order,
+ i_centaur);
+ rc = getscom_abs(MCMCICFG1Q[i_centaur], &(chicfg.value));
+ if (rc)
+ {
+ PK_TRACE("MCMCICFG scom failed. rc = %d",rc);
+ break;
+ }
+ PK_TRACE("MCMCICFG1Q %08x%08x",
+ chicfg.words.high_order,
+ chicfg.words.low_order);
+
+ rc = MEMBUF_CHANNEL_CHECKSTOP;
+ }
+ } while(0);
+
+ return rc;
}
-void gpe_centaur_data(ipc_msg_t* i_cmd, void* i_arg)
+int centaur_throttle_sync(MemBufConfiguration_t* i_config)
{
- static int g_log_once = 0;
- int rc;
- ipc_async_cmd_t *async_cmd = (ipc_async_cmd_t*)i_cmd;
+ uint64_t data;
+ int rc = 0;
+ do
+ {
+ rc = getscom_abs(i_config->mcSyncAddr,&data);
+ if (rc)
+ {
+ PK_TRACE("centaur_throttle_sync: getscom failed. rc = %d",rc);
+ break;
+ }
- CentaurGetMemDataParms_t * dataParms =
- (CentaurGetMemDataParms_t *)async_cmd->cmd_data;
+ data &= ~MCS_MCSYNC_SYNC_GO;
- if(g_log_once == 0)
+ rc = putscom_abs(i_config->mcSyncAddr, data);
+ if (rc)
+ {
+ PK_TRACE("centaur_throttle_sync: reset sync putscom failed. rc = %d",rc);
+ break;
+ }
+
+ data |= MCS_MCSYNC_SYNC_GO;
+
+ rc = putscom_abs(i_config->mcSyncAddr, data);
+ if (rc)
+ {
+ PK_TRACE("centaur_throttle_sync: set sync putscom failed. rc = %d",rc);
+ break;
+ }
+ } while (0);
+
+ return rc;
+}
+
+int centaur_sensorcache_setup(MemBufConfiguration_t* i_config,
+ uint32_t i_centaur_instance,
+ uint32_t * o_oci_addr)
+{
+ int rc = 0;
+#if defined(__USE_PBASLV__)
+ pba_slvctln_t slvctln;
+#endif
+ uint64_t pb_addr = i_config->baseAddress[i_centaur_instance];
+
+ // bit 38 set OCI master, bits 39,40 Centaur thermal sensors '10'b
+ pb_addr |= 0x0000000003000000ull;
+
+#if defined(__USE_PBASLV__)
+ PPE_LVD((i_config->dataParms).slvctl_address, slvctln.value);
+ slvctln.fields.extaddr = pb_addr >> 27;
+ PPE_STVD((i_config->dataParms).slvctl_address, slvctln.value);
+#else
{
- g_log_once = 1;
- PK_TRACE("Centaur Data. MSR:%08x",mfmsr());
+ // HW bug workaround - don't use extaddr - use pbabar.
+ uint64_t barMsk = 0;
+
+ // Mask SIB from generating mck
+ mtmsr(mfmsr() | MSR_SEM);
+
+ // put the PBA in the BAR
+ rc = putscom_abs(PBA_BARN(PBA_BAR_MEMBUF), pb_addr);
+ if (rc)
+ {
+ PK_TRACE("centaur_sensorcache_setup: putscom fail on PBABAR,"
+ " rc = %d",rc);
+ }
+ else
+ {
+ rc = putscom_abs(PBA_BARMSKN(PBA_BAR_MEMBUF), barMsk);
+ if (rc)
+ {
+ PK_TRACE("centaur_sensrocache_setup: putscom fail on"
+ " PBABARMSK, rc = %d",rc);
+ }
+ }
}
- rc = centaur_get_mem_data(G_centaur_config, dataParms);
+#endif
+ // make oci address
+ *o_oci_addr = (uint32_t)(pb_addr & 0x07ffffffull);
+
+ // PBA space bits[0:1] = '10' bar select bits[3:4]
+ *o_oci_addr |= ((PBA_BAR_MEMBUF | 0x8) << 28);
+
+ return rc;
+}
+
+
+// read centaur data sensor cache
+int get_centaur_sensorcache(MemBufConfiguration_t* i_config,
+ MemBufGetMemDataParms_t* i_parms)
+{
+ int rc = 0;
+ uint32_t oci_addr = 0;
+ uint64_t pba_slvctln_save;
+ uint64_t data64 = 0;
+
+ i_parms->error.rc = MEMBUF_GET_MEM_DATA_DIED;
- dataParms->error.rc = rc;
+ pbaslvctl_reset(&(i_config->dataParms));
+ pba_slvctln_save = pbaslvctl_setup(&(i_config->dataParms));
- // Send response
- rc = ipc_send_rsp(i_cmd, IPC_RC_SUCCESS);
- if(rc)
+ // Clear SIB error accumulator bits & mask SIB errors from
+ // generating machine checks
+ mtmsr((mfmsr() & ~(MSR_SIBRC | MSR_SIBRCA)) | MSR_SEM);
+
+ if(i_parms->collect != -1)
{
- PK_TRACE("gpe_centaur_init: Failed to send response. rc = %x. Halting GPE1.",
- rc);
+ if((i_parms->collect >= OCCHW_N_MEMBUF) ||
+ (0 == (CHIP_CONFIG_MEMBUF(i_parms->collect) & (i_config->config))))
+ {
+ rc = MEMBUF_GET_MEM_DATA_COLLECT_INVALID;
+ }
+ else
+ {
+ rc = centaur_sensorcache_setup(i_config, i_parms->collect,&oci_addr);
+
+ if(!rc)
+ {
+ uint32_t org_msr = mfmsr();
+ mtmsr(org_msr | MSR_SEM); // Mask off SIB errors from gen mck
+ g_inband_access_state = INBAND_ACCESS_IN_PROGRESS;
+ // Read 128 bytes from centaur cache
+ int i;
+ for(i = 0; i < 128; i += 8)
+ {
+ PPE_LVDX(oci_addr, i, data64);
+ PPE_STVDX((i_parms->data), i, data64);
+ }
- gpe_set_ffdc(&(dataParms->error), 0x00, GPE_RC_IPC_SEND_FAILED, rc);
- pk_halt();
+ // Poll for SIB errors or machine check
+ if((mfmsr() & MSR_SIBRC) ||
+ g_inband_access_state != INBAND_ACCESS_IN_PROGRESS)
+ {
+ // Take centaur out of config list
+ PK_TRACE("Removing Membuf %d from list of configured Membufs",
+ i_parms->collect);
+ i_config->config &= ~(CHIP_CONFIG_MEMBUF(i_parms->collect));
+
+ // This rc will cause the 405 to remove this centaur sensor
+ rc = MEMBUF_CHANNEL_CHECKSTOP;
+ }
+ mtmsr(org_msr);
+ g_inband_access_state = INBAND_ACCESS_INACTIVE;
+ }
+ }
}
+
+ if(i_parms->update != -1)
+ {
+ int update_rc = 0;
+ if((i_parms->update >= OCCHW_N_MEMBUF) ||
+ (0 == (CHIP_CONFIG_MEMBUF(i_parms->update) & (i_config->config))))
+ {
+ update_rc = MEMBUF_GET_MEM_DATA_UPDATE_INVALID;
+ }
+ else
+ {
+ update_rc = centaur_sensorcache_setup(i_config, i_parms->update,&oci_addr);
+
+ if(!update_rc)
+ {
+ // Writing a zero to this address tells the centaur to update
+ // the sensor cache for the next centaur.
+ data64 = 0;
+ update_rc = inband_access(i_config,
+ i_parms->update,
+ oci_addr,
+ &data64,
+ INBAND_ACCESS_WRITE);
+ }
+ }
+ if(!rc && update_rc)
+ {
+ rc = update_rc;
+ }
+ }
+
+ pbaslvctl_reset(&(i_config->dataParms));
+ PPE_STVD((i_config->dataParms).slvctl_address, pba_slvctln_save);
+
+ if(!rc)
+ {
+ int instance = i_parms->collect;
+ if(instance == -1)
+ {
+ instance = i_parms->update;
+ }
+ if (instance != -1)
+ {
+ rc = check_centaur_channel_chkstp(instance);
+ }
+ }
+
+ i_parms->error.rc = rc;
+ return rc;
}
+
diff --git a/src/occ_gpe1/gpe_centaur.h b/src/occ_gpe1/gpe_centaur.h
deleted file mode 100644
index 482af22..0000000
--- a/src/occ_gpe1/gpe_centaur.h
+++ /dev/null
@@ -1,61 +0,0 @@
-#if !defined(_GPE_CENTAUR_H)
-#define _GPE_CENTAUR_H
-
-#include "ipc_structs.h"
-#include "centaur_structs.h"
-
-// IPC interface
-void gpe_centaur_scom(ipc_msg_t* i_cmd, void* i_arg);
-void gpe_centaur_data(ipc_msg_t* i_cmd, void* i_arg);
-void gpe_centaur_init(ipc_msg_t* i_cmd, void* i_arg);
-
-// HCODE interface
-/**
- * Populate a CentaurConfiguration object
- * @param[out] 8 byte aligned pointer to the CentaurConfiguration object.
- * @return [0 | return code]
- * @note The CentaurConfiguration object is shared with the 405 so
- * it needs to be in non-cacheable sram.
- */
-int gpe_centaur_configuration_create(CentaurConfiguration_t * o_config);
-
-/**
- * Scom all of the centaurs with the same SCOM address.
- * @param[in] The CentaurConfig object
- * @param[in] The SCOM address
- * @param[out] The array of data collected. Must be large enough to hold
- * uint64_t data from each centaur.
- * @return [0 | return code]
- */
-int centaur_get_scom_vector(CentaurConfiguration_t* i_config,
- uint32_t i_scom_address,
- uint64_t* o_data);
-
-/**
- * Scom one or more centaurs
- * @param[in] The CentaurConfig object
- * @param[in/out] The Centaur Scom Parms object
- * @return The return code is part of the Centaur Scom Parms object
- */
-void gpe_scom_centaur(CentaurConfiguration_t* i_config,
- CentaurScomParms_t* i_parms);
-
-
-/**
- * Collect the centaur thermal data
- * @param[in] The CentaurConfig object
- * @param[in/out] The Centaur data parm object
- * @return [0 | return code]
- */
-int centaur_get_mem_data(CentaurConfiguration_t* i_config,
- CentaurGetMemDataParms_t* i_parms);
-
-/**
- * Check for channel checkstop
- * @param[in] The ordinal centaur number
- * @return [0 | return code]
- */
-int check_channel_chkstp(unsigned int i_centaur);
-
-extern uint32_t g_centaur_access_state;
-#endif
diff --git a/src/occ_gpe1/gpe_centaur_configuration.c b/src/occ_gpe1/gpe_centaur_configuration.c
deleted file mode 100644
index b9866bb..0000000
--- a/src/occ_gpe1/gpe_centaur_configuration.c
+++ /dev/null
@@ -1,497 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: chips/p9/procedures/lib/pm/centaur_thermal_access.c $ */
-/* */
-/* IBM CONFIDENTIAL */
-/* */
-/* EKB Project */
-/* */
-/* COPYRIGHT 2017 */
-/* [+] International Business Machines Corp. */
-/* */
-/* */
-/* The source code for this program is not published or otherwise */
-/* divested of its trade secrets, irrespective of what has been */
-/* deposited with the U.S. Copyright Office. */
-/* */
-/* IBM_PROLOG_END_TAG */
-/**
- * @briefcentaur_thermal_access
- */
-
-#include "gpe_centaur.h"
-#include "ppe42_scom.h"
-#include "pk.h"
-#include "p9_misc_scom_addresses.h"
-#include "mcs_firmware_registers.h"
-#include "pba_firmware_constants.h"
-#include "pba_register_addresses.h"
-#include "centaur_register_addresses.h"
-#include "ppe42_msr.h"
-#include "occhw_pba_common.h"
-
-// Which GPE controls the PBASLAVE
-#define OCI_MASTER_ID_GPE1 1
-
-// Power Bus Address bit that configures centaur for HOST/OCC P9=bit(38)
-#define PBA_HOST_OCC_CFG 0x0000000002000000ull;
-
-
-const uint32_t MCFGPR[OCCHW_NCENTAUR] =
-{
- MCS_0_MCRSVDE,
- MCS_0_MCRSVDF,
- MCS_1_MCRSVDE,
- MCS_1_MCRSVDF,
- MCS_2_MCRSVDE,
- MCS_2_MCRSVDF,
- MCS_3_MCRSVDE,
- MCS_3_MCRSVDF
-};
-
-const uint32_t MCSYNC[OCCHW_NCENTAUR/2] =
-{
- MCS_0_MCSYNC,
- MCS_1_MCSYNC,
- MCS_2_MCSYNC,
- MCS_3_MCSYNC
-};
-
-const uint32_t MCCHIFIR[OCCHW_NCENTAUR] =
-{
- MCP_CHAN0_CHI_FIR,
- MCP_CHAN1_CHI_FIR,
- MCP_CHAN2_CHI_FIR,
- MCP_CHAN3_CHI_FIR,
- MCP_CHAN4_CHI_FIR,
- MCP_CHAN5_CHI_FIR,
- MCP_CHAN6_CHI_FIR,
- MCP_CHAN7_CHI_FIR
-};
-
-const uint32_t MCMCICFG1Q[OCCHW_NCENTAUR] =
-{
- MCP_CHAN0_CHI_MCICFG1Q,
- MCP_CHAN1_CHI_MCICFG1Q,
- MCP_CHAN2_CHI_MCICFG1Q,
- MCP_CHAN3_CHI_MCICFG1Q,
- MCP_CHAN4_CHI_MCICFG1Q,
- MCP_CHAN5_CHI_MCICFG1Q,
- MCP_CHAN6_CHI_MCICFG1Q,
- MCP_CHAN7_CHI_MCICFG1Q
-};
-
-///////////////////////////////////////////////////////////////
-// These are PPE specific PBA routines.
-//////////////////////////////////////////////////////////////
-int
-gpe_pba_parms_create(GpePbaParms* parms,
- int slave,
- int write_ttype,
- int write_tsize,
- int read_ttype)
-{
- pba_slvctln_t* slvctl, *mask;
- pba_slvrst_t* slvrst;
- pba_slvrst_t* slvrst_in_progress;
- uint64_t all1 = 0xffffffffffffffffull;
-
- parms->slave_id = slave;
-
- slvctl = &(parms->slvctl);
- mask = &(parms->mask);
- slvrst = &(parms->slvrst);
- slvrst_in_progress = &(parms->slvrst_in_progress);
-
- parms->slvctl_address = PBA_SLVCTLN(slave);
-
- slvrst->value = 0;
- slvrst->fields.set = PBA_SLVRST_SET(slave);
-
- slvrst_in_progress->value = 0;
- slvrst_in_progress->fields.in_prog = PBA_SLVRST_IN_PROG(slave);
-
- slvctl->value = 0;
- mask->value = 0;
-
- slvctl->fields.enable = 1;
- mask->fields.enable = all1;
-
- slvctl->fields.mid_match_value = OCI_MASTER_ID_GPE1;
- mask->fields.mid_match_value = all1;
-
- slvctl->fields.mid_care_mask = all1;
- mask->fields.mid_care_mask = all1;
-
- slvctl->fields.write_ttype = write_ttype;
- mask->fields.write_ttype = all1;
-
- slvctl->fields.write_tsize = write_tsize;
- mask->fields.write_tsize = all1;
-
- slvctl->fields.read_ttype = read_ttype;
- mask->fields.read_ttype = all1;
-
- slvctl->fields.buf_alloc_a = 1;
- slvctl->fields.buf_alloc_b = 1;
- slvctl->fields.buf_alloc_c = 1;
- slvctl->fields.buf_alloc_w = 1;
- mask->fields.buf_alloc_a = 1;
- mask->fields.buf_alloc_b = 1;
- mask->fields.buf_alloc_c = 1;
- mask->fields.buf_alloc_w = 1;
-
- if (read_ttype == PBA_READ_TTYPE_CI_PR_RD)
- {
-
- slvctl->fields.buf_invalidate_ctl = 1;
- mask->fields.buf_invalidate_ctl = all1;
-
- slvctl->fields.read_prefetch_ctl = PBA_READ_PREFETCH_NONE;
- mask->fields.read_prefetch_ctl = all1;
-
- }
- else
- {
-
- slvctl->fields.buf_invalidate_ctl = 0;
- mask->fields.buf_invalidate_ctl = all1;
- }
-
- mask->value = ~(mask->value);
-
- return 0;
-}
-
-
-////////////////////////////////////////////////
-// Centaur specific routines
-////////////////////////////////////////////////
-int gpe_centaur_configuration_create(CentaurConfiguration_t* o_config)
-{
- int rc = 0;
- unsigned int i = 0;
- mcfgpr_t mcfgpr;
- uint64_t bar = 0;
- uint64_t mask = 0;
- uint64_t* ptr = (uint64_t*)o_config;
- int designated_sync = -1;
-
- // Prevent unwanted interrupts from scom errors
- const uint32_t orig_msr = mfmsr() & MSR_SEM;
- mtmsr((orig_msr & ~(MSR_SIBRC | MSR_SIBRCA)) | MSR_SEM);
-
- for(i = 0; i < sizeof(CentaurConfiguration_t) / 8; ++i)
- {
- *ptr++ = 0ull;
- }
-
- o_config->configRc = CENTAUR_NOT_CONFIGURED;
-
- do
- {
- // Create the PBASLV configurations for the GPE procedures.
- // The 'dataParms' define the PBASLV setup needed to access the
- // Centaur sensor cache. The 'scomParms' define the PBASLV setup
- // needed to access the Centaur SCOMs.
-
- rc = gpe_pba_parms_create(&(o_config->dataParms),
- PBA_SLAVE_CENTAUR,
- PBA_WRITE_TTYPE_CI_PR_W,
- PBA_WRITE_TTYPE_DC,
- PBA_READ_TTYPE_CL_RD_NC);
-
- if (rc)
- {
- rc = CENTAUR_DATA_SETUP_ERROR;
- break;
- }
-
- rc = gpe_pba_parms_create(&(o_config->scomParms),
- PBA_SLAVE_CENTAUR,
- PBA_WRITE_TTYPE_CI_PR_W,
- PBA_WRITE_TTYPE_DC,
- PBA_READ_TTYPE_CI_PR_RD);
-
- if (rc)
- {
- rc = CENTAUR_SCOM_SETUP_ERROR;
- break;
- }
-
- // Iterate through each MCS on the chip and check configuration.
-
- // Note that the code uniformly treats SCOM failures of the MCFGPR
- // registers as an unconfigured Centaur. This works both for real
- // hardware, as well as for our VBU models where some of the "valid"
- // MCS are not in the simulation models.
-
- for (i = 0; i < OCCHW_NCENTAUR; ++i)
- {
- // check for channel checkstop
- rc = check_channel_chkstp(i);
- if (rc)
- {
- // If scom failed OR there is a channel checkstop then
- // Centaur is not usable.
- rc = 0;
- continue;
- }
-
- // Verify that inband scom has been setup. If not then
- // assume the centaur is either non-existant or not configured.
- // Setup is provided by HWP p9c_set_inband_addr.C
- rc = getscom_abs(MCFGPR[i], &(mcfgpr.value));
-
- if (rc)
- {
- // ignore if can't be scomed.
- rc = 0;
- continue;
- }
-
- // If inband scom is not configured then assume the centaur does not exist
- if (!mcfgpr.fields.mcfgprq_valid)
- {
- continue;
- }
-
-
- // The 31-bit base-address (inband scom BAR) corresponds to bits [8:38] in the
- // 64-bit PowerBus address.
- // Set the HOST/OCC bit in the address.
- o_config->baseAddress[i] =
- ((uint64_t)(mcfgpr.fields.mcfgprq_base_address) << 25) | PBA_HOST_OCC_CFG;
-
- PK_TRACE_DBG("Centar[%d] Base Address: %016llx",i,o_config->baseAddress[i]);
-
- // Add the Centaur to the configuration
- o_config->config |= (CHIP_CONFIG_MCS(i) | CHIP_CONFIG_CENTAUR(i));
- }
-
- if (rc)
- {
- break;
- }
-
- // Find the designated sync
- for (i = 0; i < (OCCHW_NCENTAUR/2); ++i)
- {
- uint64_t mcsync;
- rc = getscom_abs(MCSYNC[i], &mcsync);
- if (rc)
- {
- PK_TRACE("getscom failed on MCSYNC, rc = %d. The first configured MC will be the designated sync",rc);
- rc = 0;
- }
- if (mcsync != 0)
- {
- designated_sync = i;
- // There can only be one sync, so stop searching.
- break;
- }
- }
-
- if (designated_sync < 0)
- {
- designated_sync = cntlz32(o_config->config << CHIP_CONFIG_MCS_BASE);
- PK_TRACE("No designated sync found, using MCS(%d)",designated_sync);
- }
-
- o_config->mcSyncAddr = MCSYNC[designated_sync];
-
-
- // Configure the PBA BAR and PBA BARMSK.
- // Set the BARMSK bits such that:
- // -PBA[8:22] are provided by the PBABAR.
- // -PBA[23:36] are provided by the PBASLVCTL ExtrAddr field
- // -PBA[37:43] are provided by the OCI addr[5:11]
- // PBA[44:63] will always come from the OCI addr[12:31]
- // Note: This code should no longer be needed when the BAR/BARMSK is set
- // by PHYP.
- if (o_config->config != 0)
- {
- uint64_t bar = 0;
- uint64_t barMsk = PBA_BARMSKN_MASK_MASK;
-
- for (i = 0; i < OCCHW_NCENTAUR; ++i)
- {
- bar |= o_config->baseAddress[i];
- }
-
- bar &= ~barMsk;
-
- PK_TRACE_DBG("PBABAR(%d): %016llx", PBA_BAR_CENTAUR, bar);
- PK_TRACE_DBG("PBABARMSK: %016llx", barMsk);
-
- rc = putscom_abs(PBA_BARMSKN(PBA_BAR_CENTAUR), barMsk);
-
- if (rc)
- {
- PK_TRACE_DBG("Unexpected rc = 0x%08x SCOMing PBA_BARMSKN(%d)\n",
- (uint32_t)rc, PBA_BAR_CENTAUR);
- rc = CENTAUR_BARMSKN_PUTSCOM_FAILURE;
- break;
- }
-
- rc = putscom_abs(PBA_BARN(PBA_BAR_CENTAUR), bar);
- if (rc)
- {
- PK_TRACE_DBG("Unexpected rc = 0x%08x SCOMing PBA_BARN(%d)\n",
- (uint32_t)rc, PBA_BAR_CENTAUR);
- rc = CENTAUR_BARN_PUTSCOM_FAILURE;
- break;
- }
- }
-
- // Do an independent check that every Centaur base address
- // can be generated by the combination of the current BAR and
- // BAR Mask, along with the initial requirement that the mask must
- // include at least bits 38:43.
-
- if (o_config->config != 0)
- {
- rc = getscom_abs(PBA_BARN(PBA_BAR_CENTAUR), &bar);
-
- if (rc)
- {
- PK_TRACE_DBG("Unexpected rc = 0x%08x SCOMing PBA_BARN(%d)\n",
- (uint32_t)rc, PBA_BAR_CENTAUR);
- rc = CENTAUR_BARN_GETSCOM_FAILURE;
- break;
- }
-
- rc = getscom_abs(PBA_BARMSKN(PBA_BAR_CENTAUR), &mask);
-
- if (rc)
- {
- PK_TRACE_DBG("Unexpected rc = 0x%08x SCOMing PBA_BARMSKN(%d)\n",
- (uint32_t)rc, PBA_BAR_CENTAUR);
- rc = CENTAUR_BARMSKN_GETSCOM_FAILURE;
- break;
- }
-
- bar = bar & PBA_BARN_ADDR_MASK;
- mask = mask & PBA_BARMSKN_MASK_MASK;
-
- if ((mask & 0x0000000003f00000ull) != 0x0000000003f00000ull)
- {
-
- PK_TRACE("PBA BAR mask (%d) does not cover bits 38:43\n", PBA_BAR_CENTAUR);
- rc = CENTAUR_MASK_ERROR;
- break;
- }
-
- for (i = 0; i < OCCHW_NCENTAUR; ++i)
- {
- if (o_config->baseAddress[i] != 0)
- {
- if ((o_config->baseAddress[i] & ~mask) !=
- (bar & ~mask))
- {
-
- PK_TRACE("BAR/Mask (%d) error for MCS/Centaur %d",
- PBA_BAR_CENTAUR, i);
-
- PK_TRACE(" base = 0x%08x%08x",
- (uint32_t)(o_config->baseAddress[i]>>32),
- (uint32_t)(o_config->baseAddress[i]));
-
- PK_TRACE(" bar = 0x%08x%08x"
- " mask = 0x%08x%08x",
- (uint32_t)(bar >> 32),
- (uint32_t)(bar),
- (uint32_t)(mask >> 32),
- (uint32_t)(mask));
-
- rc = CENTAUR_BAR_MASK_ERROR;
- break;
- }
- }
- }
-
- if (rc)
- {
- break;
- }
- }
-
-
- // At this point the structure is initialized well-enough that it can
- // be used by gpe_scom_centaur().
-
-
- o_config->configRc = 0;
-
- if (o_config->config == 0)
- {
- break;
- }
-
-
- // Get Device ID from each centaur
- centaur_get_scom_vector(o_config,
- CENTAUR_DEVICE_ID,
- (uint64_t*)(&(o_config->deviceId[0])));
-
- }
- while(0);
-
- o_config->configRc = rc;
-
- mtmsr(orig_msr);
-
- return rc;
-}
-
-int check_channel_chkstp(unsigned int i_centaur)
-{
- int rc = 0;
- mcchifir_t chifir;
- mcmcicfg_t chicfg;
-
- do
- {
- rc = getscom_abs(MCCHIFIR[i_centaur], &(chifir.value));
- if (rc)
- {
- PK_TRACE("MCCHIFIR scom failed. rc = %d",rc);
- break;
- }
-
- if(chifir.fields.fir_dsrc_no_forward_progress ||
- chifir.fields.fir_dmi_channel_fail ||
- chifir.fields.fir_channel_init_timeout ||
- chifir.fields.fir_channel_interlock_err ||
- chifir.fields.fir_replay_buffer_ue ||
- chifir.fields.fir_replay_buffer_overrun ||
- chifir.fields.fir_df_sm_perr ||
- chifir.fields.fir_cen_checkstop ||
- chifir.fields.fir_dsff_tag_overrun ||
- chifir.fields.fir_dsff_mca_async_cmd_error ||
- chifir.fields.fir_dsff_seq_error ||
- chifir.fields.fir_dsff_timeout)
- {
- PK_TRACE("MCCHIFIR: %08x%08x for channel %d",
- chifir.words.high_order,
- chifir.words.low_order,
- i_centaur);
-
- rc = getscom_abs(MCMCICFG1Q[i_centaur], &(chicfg.value));
- if (rc)
- {
- PK_TRACE("MCMCICFG scom failed. rc = %d",rc);
- break;
- }
-
- PK_TRACE("MCMCICFG1Q %08x%08x",
- chicfg.words.high_order,
- chicfg.words.low_order);
-
- rc = CENTAUR_CHANNEL_CHECKSTOP;
- }
- } while(0);
-
- return rc;
-}
diff --git a/src/occ_gpe1/gpe_centaur_scom.c b/src/occ_gpe1/gpe_centaur_scom.c
deleted file mode 100644
index edee857..0000000
--- a/src/occ_gpe1/gpe_centaur_scom.c
+++ /dev/null
@@ -1,762 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: chips/p9/procedures/lib/pm/centaur_scom.c $ */
-/* */
-/* IBM CONFIDENTIAL */
-/* */
-/* EKB Project */
-/* */
-/* COPYRIGHT 2017 */
-/* [+] International Business Machines Corp. */
-/* */
-/* */
-/* The source code for this program is not published or otherwise */
-/* divested of its trade secrets, irrespective of what has been */
-/* deposited with the U.S. Copyright Office. */
-/* */
-/* IBM_PROLOG_END_TAG */
-#include <stdint.h>
-#include "gpe_centaur.h"
-#include "gpe_pba_cntl.h"
-#include "ppe42_scom.h"
-#include "ppe42.h"
-#include "pba_register_addresses.h"
-#include "ppe42_msr.h"
-
-#define CENTAUR_ACCESS_READ 1
-#define CENTAUR_ACCESS_WRITE 2
-
-/**
- * @file centaur_scom
- * @brief scom access from gpe to a centaur
- */
-
-uint32_t g_centaur_access_state = CENTAUR_ACCESS_INACTIVE;
-
-int centaur_access(CentaurConfiguration_t* i_config,
- uint32_t i_instance,
- uint32_t i_oci_addr,
- uint64_t * io_data,
- int i_read_write)
-{
- int rc = 0;
- uint32_t org_msr = mfmsr();
- uint32_t msr = org_msr | MSR_SEM; // Mask off SIB from generating mck.
-
- g_centaur_access_state = CENTAUR_ACCESS_IN_PROGRESS;
-
- if(i_read_write == CENTAUR_ACCESS_READ)
- {
- mtmsr(msr);
- sync();
- PPE_LVD(i_oci_addr, *io_data);
- }
- else
- {
- // Set PPE to precise mode for stores so that in the case of a machine
- // check, there is a predictable instruction address to resume on.
- msr &= ~MSR_IPE;
- mtmsr(msr);
- sync();
-
- PPE_STVD(i_oci_addr, *io_data);
- }
-
- // Poll SIB error or machine check
- if((mfmsr() & MSR_SIBRC) ||
- g_centaur_access_state != CENTAUR_ACCESS_IN_PROGRESS)
- {
- // Take centaur out of config
- PK_TRACE("Removing Centaur %d from list of configured Centaurs",
- i_instance);
-
- i_config->config &= ~(CHIP_CONFIG_CENTAUR(i_instance));
-
- // This will cause the 405 to remove the centaur sensor.
- rc = CENTAUR_CHANNEL_CHECKSTOP;
- }
- g_centaur_access_state = CENTAUR_ACCESS_INACTIVE;
- mtmsr(org_msr);
- return rc;
-}
-
-/**
- * Setup the PBASLVCTLN extended address and calculate the OCI scom address
- * @param[in] PBA base address
- * @param[in] The Centaur scom address
- * @returns the OCI address to scom the centaur
- * @Post The extended address field in the PBASLVCNT is set
- */
-int centaur_scom_setup(CentaurConfiguration_t* i_config,
- uint32_t i_centaur_instance,
- uint32_t i_scom_address,
- uint32_t *o_oci_addr)
-{
- int rc = 0;
-#if defined(__USE_PBASLV__)
- pba_slvctln_t slvctln;
-#endif
- uint64_t pb_addr = i_config->baseAddress[i_centaur_instance];
-
- // Break address into componets
- uint32_t local = i_scom_address & 0x00001fff;
- uint32_t port = i_scom_address & 0x000f0000;
- uint32_t slave = i_scom_address & 0x03000000;
- uint32_t multi = i_scom_address & 0xc0000000;
-
- // compress to 21 bits for P9
- uint32_t scom_address =
- local +
- (port >> 3) +
- (slave >> 7) +
- (multi >> 11);
-
- // P9: Turn on bit 38 to indicate OCC
- pb_addr |= 0x0000000002000000ull;
- pb_addr |= ((uint64_t)scom_address << 3);
-
-#if defined(__USE_PBASLV__)
- // put bits 23:36 of address into slvctln extended addr
- PPE_LVD((i_config->scomParms).slvctl_address, slvctln.value);
- slvctln.fields.extaddr = pb_addr >> 27;
- PPE_STVD((i_config->scomParms).slvctl_address, slvctln.value);
-#else
- // HW bug work-around
- {
- // workaround - don't use extraddr - use pbabar.
- uint64_t barMsk = 0;
-
- // Mask SIB from generating mck
- mtmsr(mfmsr() | MSR_SEM);
-
- // put the PBA in the BAR
- rc = putscom_abs(PBA_BARN(PBA_BAR_CENTAUR), pb_addr);
- if(rc)
- {
- PK_TRACE("centaur_scom_setup. putscom fail on PBABAR."
- " rc = %d",rc);
- }
- else
- {
- rc = putscom_abs(PBA_BARMSKN(PBA_BAR_CENTAUR), barMsk);
- if(rc)
- {
- PK_TRACE("centaur_scom_setup. putscom fail on PBABARMSK"
- " rc = %d",rc);
- }
- }
- }
-#endif
- // make oci address
- *o_oci_addr = (uint32_t)(pb_addr & 0x07ffffffull);
-
- // upper nibble is PBA region and BAR_SELECT
- *o_oci_addr |= ((PBA_BAR_CENTAUR | 0x8) << 28);
- PK_TRACE_DBG("Centaur OCI scom addr: %08x",*o_oci_addr);
- return rc;
-}
-
-int centaur_sensorcache_setup(CentaurConfiguration_t* i_config,
- uint32_t i_centaur_instance,
- uint32_t * o_oci_addr)
-{
- int rc = 0;
-#if defined(__USE_PBASLV__)
- pba_slvctln_t slvctln;
-#endif
- uint64_t pb_addr = i_config->baseAddress[i_centaur_instance];
-
- // bit 38 set OCI master, bits 39,40 Centaur thermal sensors '10'b
- pb_addr |= 0x0000000003000000ull;
-
-#if defined(__USE_PBASLV__)
- PPE_LVD((i_config->dataParms).slvctl_address, slvctln.value);
- slvctln.fields.extaddr = pb_addr >> 27;
- PPE_STVD((i_config->dataParms).slvctl_address, slvctln.value);
-#else
- {
- // HW bug workaround - don't use extaddr - use pbabar.
- uint64_t barMsk = 0;
-
- // Mask SIB from generating mck
- mtmsr(mfmsr() | MSR_SEM);
-
- // put the PBA in the BAR
- rc = putscom_abs(PBA_BARN(PBA_BAR_CENTAUR), pb_addr);
- if (rc)
- {
- PK_TRACE("centaur_sensorcache_setup: putscom fail on PBABAR,"
- " rc = %d",rc);
- }
- else
- {
- rc = putscom_abs(PBA_BARMSKN(PBA_BAR_CENTAUR), barMsk);
- if (rc)
- {
- PK_TRACE("centaur_sensrocache_setup: putscom fail on"
- " PBABARMSK, rc = %d",rc);
- }
- }
- }
-#endif
- // make oci address
- *o_oci_addr = (uint32_t)(pb_addr & 0x07ffffffull);
-
- // PBA space bits[0:1] = '10' bar select bits[3:4]
- *o_oci_addr |= ((PBA_BAR_CENTAUR | 0x8) << 28);
-
- return rc;
-}
-
-void pbaslvctl_reset(GpePbaParms* i_pba_parms)
-{
- uint64_t val = 0;
-
- do
- {
- PPE_STVD(PBA_SLVRST, i_pba_parms->slvrst.value);
- PPE_LVD(PBA_SLVRST, val);
- val &= i_pba_parms->slvrst_in_progress.value;
- }
- while(val != 0);
-}
-
-uint64_t pbaslvctl_setup(GpePbaParms* i_pba_parms)
-{
- uint64_t slvctl_val;
- uint64_t slvctl_val_org;
- PPE_LVD(i_pba_parms->slvctl_address, slvctl_val_org);
- slvctl_val = slvctl_val_org;
- slvctl_val &= i_pba_parms->mask.value;
- slvctl_val |= i_pba_parms->slvctl.value;
- PPE_STVD(i_pba_parms->slvctl_address, slvctl_val);
- return slvctl_val_org;
-}
-
-// Get data from each existing centaur.
-int centaur_get_scom_vector(CentaurConfiguration_t* i_config,
- uint32_t i_scom_address,
- uint64_t* o_data)
-{
- int rc = 0;
- int access_rc = 0;
- int pba_rc = 0;
- int instance = 0;
- uint64_t pba_slvctln_save;
-
- pbaslvctl_reset(&(i_config->scomParms));
- pba_slvctln_save = pbaslvctl_setup(&(i_config->scomParms));
-
- // clear SIB errors in MSR
- mtmsr((mfmsr() & ~(MSR_SIBRC | MSR_SIBRCA)));
-
- for(instance = 0; instance < OCCHW_NCENTAUR; ++instance)
- {
- if( CHIP_CONFIG_CENTAUR(instance) & (i_config->config))
- {
- uint32_t oci_addr;
- pba_rc = centaur_scom_setup(i_config,
- instance,
- i_scom_address,
- &oci_addr);
-
- if(pba_rc)
- {
- rc = pba_rc;
- // Already traced.
- // Trumps any access error
- *o_data = 0;
- }
-
- // read centaur scom
- access_rc = centaur_access(i_config,
- instance,
- oci_addr,
- o_data,
- CENTAUR_ACCESS_READ);
- if(!rc && access_rc)
- {
- // not critical, but don't touch this centaur again.
- rc = access_rc;
- *o_data = 0;
- // continue
- }
- }
- else
- {
- *o_data = 0;
- }
-
- ++o_data;
- }
-
- // gpe_pba_cntl function?
- pbaslvctl_reset(&(i_config->scomParms));
- PPE_STVD((i_config->scomParms).slvctl_address, pba_slvctln_save);
-
- return rc;
-}
-
-int centaur_get_scom(CentaurConfiguration_t* i_config,
- int i_centaur_instance,
- uint32_t i_scom_address,
- uint64_t* o_data)
-{
- int rc = 0;
- uint32_t oci_addr;
- uint64_t pba_slvctln_save;
-
- pbaslvctl_reset(&(i_config->scomParms));
- pba_slvctln_save = pbaslvctl_setup(&(i_config->scomParms));
-
- rc = centaur_scom_setup(i_config,
- i_centaur_instance,
- i_scom_address,
- &oci_addr);
-
- if( !rc && (CHIP_CONFIG_CENTAUR(i_centaur_instance) & (i_config->config)))
- {
- // read centaur scom
- rc = centaur_access(i_config,
- i_centaur_instance,
- oci_addr,
- o_data,
- CENTAUR_ACCESS_READ);
- }
- else
- {
- *o_data = 0;
- }
-
- // gpe_pba_cntl function?
- pbaslvctl_reset(&(i_config->scomParms));
- PPE_STVD((i_config->scomParms).slvctl_address, pba_slvctln_save);
-
- return rc;
-}
-
-
-// Write all configured centaur with the same data
-int centaur_put_scom_all(CentaurConfiguration_t* i_config,
- uint32_t i_scom_address,
- uint64_t i_data)
-{
- int rc = 0;
- int pba_rc = 0;
- int access_rc = 0;
- int instance = 0;
- uint64_t pba_slvctln_save;
-
- pbaslvctl_reset(&(i_config->scomParms));
- pba_slvctln_save = pbaslvctl_setup(&(i_config->scomParms));
-
- for(instance = 0; instance < OCCHW_NCENTAUR; ++instance)
- {
- if( CHIP_CONFIG_CENTAUR(instance) & (i_config->config))
- {
- uint32_t oci_addr;
- pba_rc = centaur_scom_setup(i_config,
- instance,
- i_scom_address,
- &oci_addr);
-
- if(pba_rc)
- {
- // Already traced in centaur_scom_setup
- // Trumps access_rc
- rc = pba_rc;
- }
-
- // centaur scom
- access_rc = centaur_access(i_config,
- instance,
- oci_addr,
- &i_data,
- CENTAUR_ACCESS_WRITE);
- if(!rc && access_rc)
- {
- // Centaur won't be touched again.
- rc = access_rc;
- // continue
- }
- }
- }
-
- // reset pba slave
- pbaslvctl_reset(&(i_config->scomParms));
- PPE_STVD((i_config->scomParms).slvctl_address, pba_slvctln_save);
-
- return rc;
-}
-
-int centaur_put_scom(CentaurConfiguration_t* i_config,
- int i_centaur_instance,
- uint32_t i_scom_address,
- uint64_t i_data)
-{
- int rc = 0;
- uint32_t oci_addr;
- uint64_t pba_slvctln_save;
-
- pbaslvctl_reset(&(i_config->scomParms));
- pba_slvctln_save = pbaslvctl_setup(&(i_config->scomParms));
-
- rc = centaur_scom_setup(i_config,
- i_centaur_instance,
- i_scom_address,
- &oci_addr);
-
- if(!rc)
- {
- if(CHIP_CONFIG_CENTAUR(i_centaur_instance) & (i_config->config))
- {
- // write centaur scom
- rc = centaur_access(i_config,
- i_centaur_instance,
- oci_addr,
- &i_data,
- CENTAUR_ACCESS_WRITE);
- }
- }
-
- // reset pba slave
- pbaslvctl_reset(&(i_config->scomParms));
- PPE_STVD((i_config->scomParms).slvctl_address, pba_slvctln_save);
-
- return rc;
-}
-
-// write x
-int centaur_scom_rmw(CentaurConfiguration_t* i_config,
- int i_centaur_instance,
- uint32_t i_scom_address,
- uint64_t i_mask,
- uint64_t* i_data)
-{
- int rc = 0;
- uint32_t oci_addr;
- uint64_t pba_slvctln_save;
- uint64_t data64;
-
- pbaslvctl_reset(&(i_config->scomParms));
- pba_slvctln_save = pbaslvctl_setup(&(i_config->scomParms));
-
- rc = centaur_scom_setup(i_config,
- i_centaur_instance,
- i_scom_address,
- &oci_addr);
- if(!rc)
- {
-
- rc = centaur_access(i_config,
- i_centaur_instance,
- oci_addr,
- &data64,
- CENTAUR_ACCESS_READ);
-
- if(!rc)
- {
- data64 &= (i_mask ^ 0xffffffffffffffffull);
- data64 |= *i_data;
-
- rc = centaur_access(i_config,
- i_centaur_instance,
- oci_addr,
- &data64,
- CENTAUR_ACCESS_WRITE);
- }
- }
-
- pbaslvctl_reset(&(i_config->scomParms));
- PPE_STVD((i_config->scomParms).slvctl_address, pba_slvctln_save);
-
- return rc;
-}
-
-
-int centaur_scom_rmw_all(CentaurConfiguration_t* i_config,
- uint32_t i_scom_address,
- uint64_t i_mask,
- uint64_t i_data)
-{
- int rc = 0;
- int pba_rc = 0;
- int access_rc = 0;
- int instance = 0;
- uint64_t pba_slvctln_save;
-
- pbaslvctl_reset(&(i_config->scomParms));
- pba_slvctln_save = pbaslvctl_setup(&(i_config->scomParms));
-
- for(instance = 0; (instance < OCCHW_NCENTAUR); ++instance)
- {
- if( CHIP_CONFIG_CENTAUR(instance) & (i_config->config))
- {
- uint64_t data64;
- uint32_t oci_addr;
- pba_rc = centaur_scom_setup(i_config,
- instance,
- i_scom_address,
- &oci_addr);
- if(pba_rc)
- {
- rc = pba_rc;
- // Already traced in centaur_scom_setup
- // Trumps any access_rc
- }
- if(!pba_rc)
- {
-
- access_rc = centaur_access(i_config,
- instance,
- oci_addr,
- &data64,
- CENTAUR_ACCESS_READ);
-
- if(!access_rc)
- {
- data64 &= (i_mask ^ 0xffffffffffffffffull);
- data64 |= i_data;
-
- access_rc = centaur_access(i_config,
- instance,
- oci_addr,
- &data64,
- CENTAUR_ACCESS_WRITE);
- }
- }
- if(!rc && access_rc)
- {
- rc = access_rc;
- }
-
- pbaslvctl_reset(&(i_config->scomParms));
- }
- }
-
- PPE_STVD((i_config->scomParms).slvctl_address, pba_slvctln_save);
-
- return rc;
-}
-
-
-// read centaur data sensor cache
-int centaur_get_mem_data(CentaurConfiguration_t* i_config,
- CentaurGetMemDataParms_t* i_parms)
-{
- int rc = 0;
- uint32_t oci_addr = 0;
- uint64_t pba_slvctln_save;
- uint64_t data64 = 0;
-
- i_parms->error.rc = CENTAUR_GET_MEM_DATA_DIED;
-
- pbaslvctl_reset(&(i_config->dataParms));
- pba_slvctln_save = pbaslvctl_setup(&(i_config->dataParms));
-
- // Clear SIB error accumulator bits & mask SIB errors from
- // generating machine checks
- mtmsr((mfmsr() & ~(MSR_SIBRC | MSR_SIBRCA)) | MSR_SEM);
-
- if(i_parms->collect != -1)
- {
- if((i_parms->collect >= OCCHW_NCENTAUR) ||
- (0 == (CHIP_CONFIG_CENTAUR(i_parms->collect) & (i_config->config))))
- {
- rc = CENTAUR_GET_MEM_DATA_COLLECT_INVALID;
- }
- else
- {
- rc = centaur_sensorcache_setup(i_config, i_parms->collect,&oci_addr);
-
- if(!rc)
- {
- uint32_t org_msr = mfmsr();
- mtmsr(org_msr | MSR_SEM); // Mask off SIB errors from gen mck
- g_centaur_access_state = CENTAUR_ACCESS_IN_PROGRESS;
- // Read 128 bytes from centaur cache
- int i;
- for(i = 0; i < 128; i += 8)
- {
- PPE_LVDX(oci_addr, i, data64);
- PPE_STVDX((i_parms->data), i, data64);
- }
-
- // Poll for SIB errors or machine check
- if((mfmsr() & MSR_SIBRC) ||
- g_centaur_access_state != CENTAUR_ACCESS_IN_PROGRESS)
- {
- // Take centaur out of config list
- PK_TRACE("Removing Centaur %d from list of configured Centaurs",
- i_parms->collect);
- i_config->config &= ~(CHIP_CONFIG_CENTAUR(i_parms->collect));
-
- // This rc will cause the 405 to remove this centaur sensor
- rc = CENTAUR_CHANNEL_CHECKSTOP;
- }
- mtmsr(org_msr);
- g_centaur_access_state = CENTAUR_ACCESS_INACTIVE;
- }
- }
- }
-
- if(i_parms->update != -1)
- {
- int update_rc = 0;
- if((i_parms->update >= OCCHW_NCENTAUR) ||
- (0 == (CHIP_CONFIG_CENTAUR(i_parms->update) & (i_config->config))))
- {
- update_rc = CENTAUR_GET_MEM_DATA_UPDATE_INVALID;
- }
- else
- {
- update_rc = centaur_sensorcache_setup(i_config, i_parms->update,&oci_addr);
-
- if(!update_rc)
- {
- // Writing a zero to this address tells the centaur to update
- // the sensor cache for the next centaur.
- data64 = 0;
- update_rc = centaur_access(i_config,
- i_parms->update,
- oci_addr,
- &data64,
- CENTAUR_ACCESS_WRITE);
- }
- }
- if(!rc && update_rc)
- {
- rc = update_rc;
- }
- }
-
- pbaslvctl_reset(&(i_config->dataParms));
- PPE_STVD((i_config->dataParms).slvctl_address, pba_slvctln_save);
-
- if(!rc)
- {
- int instance = i_parms->collect;
- if(instance == -1)
- {
- instance = i_parms->update;
- }
- if (instance != -1)
- {
- rc = check_channel_chkstp(instance);
- }
- }
-
-
- i_parms->error.rc = rc;
- return rc;
-}
-
-
-int centaur_scom_sync(CentaurConfiguration_t* i_config)
-{
- uint64_t data;
- int rc = 0;
- do
- {
- rc = getscom_abs(i_config->mcSyncAddr,&data);
- if (rc)
- {
- PK_TRACE("centaur_scom_sync: getscom failed. rc = %d",rc);
- break;
- }
-
- data &= ~MCS_MCSYNC_SYNC_GO;
-
- rc = putscom_abs(i_config->mcSyncAddr, data);
- if (rc)
- {
- PK_TRACE("centaur_scom_sync: reset sync putscom failed. rc = %d",rc);
- break;
- }
-
- data |= MCS_MCSYNC_SYNC_GO;
-
- rc = putscom_abs(i_config->mcSyncAddr, data);
- if (rc)
- {
- PK_TRACE("centaur_scom_sync: set sync putscom failed. rc = %d",rc);
- break;
- }
- } while (0);
-
- return rc;
-}
-
-
-// CentaurConfiguration needs to be setup before this is called
-void gpe_scom_centaur(CentaurConfiguration_t* i_config,
- CentaurScomParms_t* i_parms)
-{
- int i;
- int rc = 0;
- mtmsr((mfmsr() & ~(MSR_SIBRC | MSR_SIBRCA)) | MSR_SEM);
-
- for(i = 0; i < i_parms->entries; ++i)
- {
- switch(i_parms->scomList[i].commandType)
- {
- case CENTAUR_SCOM_NOP:
- break;
-
- case CENTAUR_SCOM_READ:
- rc =centaur_get_scom(i_config,
- i_parms->scomList[i].instanceNumber,
- i_parms->scomList[i].scom,
- &(i_parms->scomList[i].data));
- break;
-
- case CENTAUR_SCOM_WRITE:
- rc = centaur_put_scom(i_config,
- i_parms->scomList[i].instanceNumber,
- i_parms->scomList[i].scom,
- i_parms->scomList[i].data);
- break;
-
- case CENTAUR_SCOM_RMW:
- rc = centaur_scom_rmw(i_config,
- i_parms->scomList[i].instanceNumber,
- i_parms->scomList[i].scom,
- i_parms->scomList[i].mask,
- &(i_parms->scomList[i].data));
- break;
-
- case CENTAUR_SCOM_READ_VECTOR:
- rc = centaur_get_scom_vector(i_config,
- i_parms->scomList[i].scom,
- i_parms->scomList[i].pData
- );
- break;
-
- case CENTAUR_SCOM_WRITE_ALL:
- rc = centaur_put_scom_all(i_config,
- i_parms->scomList[i].scom,
- i_parms->scomList[i].data);
- break;
-
- case CENTAUR_SCOM_RMW_ALL:
- rc = centaur_scom_rmw_all(i_config,
- i_parms->scomList[i].scom,
- i_parms->scomList[i].mask,
- i_parms->scomList[i].data);
- break;
-
- case CENTAUR_SCOM_CENTAUR_SYNC:
- rc = centaur_scom_sync(i_config);
- break;
-
- default:
- break;
- };
- i_parms->error.rc = rc;
- if (rc)
- {
- break;
- }
- }
-}
diff --git a/src/occ_gpe1/gpe_membuf.c b/src/occ_gpe1/gpe_membuf.c
new file mode 100644
index 0000000..c5f9dd4
--- /dev/null
+++ b/src/occ_gpe1/gpe_membuf.c
@@ -0,0 +1,147 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/occ_gpe1/gpe_membuf.c $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015,2018 */
+/* [+] 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 "gpe_membuf.h"
+#include "ipc_async_cmd.h"
+#include "gpe_util.h"
+
+MemBufConfiguration_t * G_membuf_config = NULL;
+
+void gpe_membuf_init(ipc_msg_t* i_cmd, void* i_arg)
+{
+ int rc;
+ ipc_async_cmd_t *async_cmd = (ipc_async_cmd_t*)i_cmd;
+ MemBufConfigParms_t* payload = (MemBufConfigParms_t*)async_cmd->cmd_data;
+
+ MemBufConfiguration_t * config = payload->membufConfiguration;
+ G_membuf_config = config;
+
+ payload->error.error = 0;
+ payload->error.ffdc = 0;
+
+ if(G_membuf_config == NULL)
+ {
+ PK_TRACE("gpe_membuf_init: membufConfiguration data ptr is NULL!");
+ rc = GPE_RC_CONFIG_DATA_NULL_PTR;
+ }
+ else
+ {
+ if(payload->mem_type == MEMTYPE_CENTAUR)
+ {
+ PK_TRACE("Centaur_configuration. MSR:%08x",mfmsr());
+ rc = gpe_centaur_configuration_create(G_membuf_config);
+ }
+ else if(payload->mem_type == MEMTYPE_OCMB)
+ {
+ PK_TRACE("Ocmb_configuration. MSR:%08x",mfmsr());
+ rc = gpe_ocmb_configuration_create(G_membuf_config);
+ }
+ else
+ {
+ rc = GPE_RC_INVALID_MEMBUF_TYPE;
+ }
+ // Must set membuf_type AFTER config created!
+ G_membuf_config->membuf_type = payload->mem_type;
+ }
+
+ payload->error.rc = rc;
+
+ // Send response
+ rc = ipc_send_rsp(i_cmd, IPC_RC_SUCCESS);
+ if(rc)
+ {
+ PK_TRACE("gpe_membuf_init: Failed to send response. rc = %x. Halting GPE1.",
+ rc);
+
+ gpe_set_ffdc(&(payload->error), 0x00, GPE_RC_IPC_SEND_FAILED, rc);
+ pk_halt();
+ }
+}
+
+void gpe_membuf_scom(ipc_msg_t* i_cmd, void* i_arg)
+{
+ static int g_log_once = 0;
+ int rc;
+ ipc_async_cmd_t *async_cmd = (ipc_async_cmd_t*)i_cmd;
+ MemBufScomParms_t * scomParms = (MemBufScomParms_t*)async_cmd->cmd_data;
+
+ if(g_log_once == 0)
+ {
+ g_log_once = 1;
+ PK_TRACE("gpe_membuf_scom. MSR:%08x",mfmsr());
+ }
+ gpe_inband_scom(G_membuf_config, scomParms);
+
+ // Send response
+ rc = ipc_send_rsp(i_cmd, IPC_RC_SUCCESS);
+ if(rc)
+ {
+ PK_TRACE("gpe_membuf_scom: Failed to send response. rc = %x. Halting GPE1.",
+ rc);
+
+ gpe_set_ffdc(&(scomParms->error), 0x00, GPE_RC_IPC_SEND_FAILED, rc);
+ pk_halt();
+ }
+
+
+}
+
+void gpe_membuf_data(ipc_msg_t* i_cmd, void* i_arg)
+{
+ static int g_log_once = 0;
+ int rc;
+ ipc_async_cmd_t *async_cmd = (ipc_async_cmd_t*)i_cmd;
+
+ MemBufGetMemDataParms_t * dataParms =
+ (MemBufGetMemDataParms_t *)async_cmd->cmd_data;
+
+ if(g_log_once == 0)
+ {
+ g_log_once = 1;
+ PK_TRACE("Centaur Data. MSR:%08x",mfmsr());
+ }
+ if(G_membuf_config->membuf_type == MEMTYPE_CENTAUR)
+ {
+ rc = get_centaur_sensorcache(G_membuf_config, dataParms);
+ }
+ else
+ {
+ rc = get_ocmb_sensorcache(G_membuf_config, dataParms);
+ }
+
+ dataParms->error.rc = rc;
+
+ // Send response
+ rc = ipc_send_rsp(i_cmd, IPC_RC_SUCCESS);
+ if(rc)
+ {
+ PK_TRACE("gpe_membuf_data: Failed to send response. rc = %x. Halting GPE1.",
+ rc);
+
+ gpe_set_ffdc(&(dataParms->error), 0x00, GPE_RC_IPC_SEND_FAILED, rc);
+ pk_halt();
+ }
+}
+
+
diff --git a/src/occ_gpe1/gpe_membuf.h b/src/occ_gpe1/gpe_membuf.h
new file mode 100644
index 0000000..39a4f53
--- /dev/null
+++ b/src/occ_gpe1/gpe_membuf.h
@@ -0,0 +1,177 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/occ_gpe1/gpe_membuf.h $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015,2018 */
+/* [+] 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 */
+#if !defined(_GPE_MEMBUF_H)
+#define _GPE_MEMBUF_H
+
+#include "ipc_structs.h"
+#include "membuf_structs.h"
+
+
+// Which GPE controls the PBASLAVE
+#define OCI_MASTER_ID_GPE1 1
+
+
+#define INBAND_ACCESS_READ 1
+#define INBAND_ACCESS_WRITE 2
+
+
+// IPC interface
+void gpe_membuf_scom(ipc_msg_t* i_cmd, void* i_arg);
+void gpe_membuf_data(ipc_msg_t* i_cmd, void* i_arg);
+void gpe_membuf_init(ipc_msg_t* i_cmd, void* i_arg);
+
+// HCODE interfaces
+/**
+ * Reset the PBA slave controller
+ * @param[in] pba_parms
+ */
+void pbaslvctl_reset(GpePbaParms* i_pba_parms);
+
+/**
+ * Configure the PBA Slave
+ * @param[in] pba_parms
+ */
+uint64_t pbaslvctl_setup(GpePbaParms* i_pba_parms);
+
+
+/**
+ * Access the MEMBUF mmio over the PBA slave.
+ * @param[in] Memory buffer configuration
+ * @param[in] The membuf ordinal number
+ * @param[in] The OCI mapped address
+ * @param[io] The data to move
+ * @param[in] The operation to perform
+ */
+int inband_access(MemBufConfiguration_t* i_config,
+ uint32_t i_instance,
+ uint32_t i_oci_addr,
+ uint64_t * io_data,
+ int i_read_write);
+
+/**
+ * Populate the MemBufConfiguration object for Centaur
+ * @param[out] 8 byte aligned pointer to the CentaurConfiguration object.
+ * @return [0 | return code]
+ * @note The CentaurConfiguration object is shared with the 405 so
+ * it needs to be in non-cacheable sram.
+ */
+int gpe_centaur_configuration_create(MemBufConfiguration_t * o_config);
+
+/**
+ * Scom all of the membufs with the same SCOM address.
+ * @param[in] The CentaurConfig object
+ * @param[in] The SCOM address
+ * @param[out] The array of data collected. Must be large enough to hold
+ * uint64_t data from each membuf.
+ * @return [0 | return code]
+ */
+int membuf_get_scom_vector(MemBufConfiguration_t* i_config,
+ uint32_t i_scom_address,
+ uint64_t* o_data);
+
+/**
+ * Scom one or more membuf modules
+ * @param[in] The MemBufConfiguration object
+ * @param[in/out] The Scom Parms object
+ * @return The return code is part of the MemBufScomParms object
+ */
+void gpe_inband_scom(MemBufConfiguration_t* i_config,
+ MemBufScomParms_t* i_parms);
+
+
+/**
+ * Collect the centaur thermal data
+ * @param[in] The CentaurConfig object
+ * @param[in/out] The Centaur data parm object
+ * @return [0 | return code]
+ */
+int get_centaur_sensorcache(MemBufConfiguration_t* i_config,
+ MemBufGetMemDataParms_t* i_parms);
+
+/**
+ * Check for channel checkstop
+ * @param[in] The ordinal centaur number
+ * @return [0 | return code]
+ */
+int check_centaur_channel_chkstp(unsigned int i_centaur);
+
+/**
+ * Send SYNC to centaur to effectuate the thottle values
+ * @param[in] the membuf configuration
+ */
+int centaur_throttle_sync(MemBufConfiguration_t* i_config);
+
+/**
+ * Create PBA slave configuration parameters.
+ * @param[in] ptr tor param data area to be filled out.
+ * @param[in] PBA slave to use.
+ * @param[in] write ttype (@see occhw_pba_common.h)
+ * @param[in] write tsize (@see occhw_pba_common.h)
+ * @param[in] read_ttype (@see occhw_pba_common.h)
+ * @return [SUCCESS | return code]
+ */
+int gpe_pba_parms_create(GpePbaParms* parms,
+ int slave,
+ int write_ttype,
+ int write_tsize,
+ int read_ttype);
+
+/**
+ * Configure the PBABAR for inband access
+ * @param[in] Configuration information
+ */
+int configure_pba_bar_for_inband_access(MemBufConfiguration_t * i_config);
+
+
+extern uint32_t g_inband_access_state;
+
+/**
+ * Populate a CentaurConfiguration object for ocmb
+ * @param[out] 8 byte aligned pointer to the CentaurConfiguration object.
+ * @return [0 | return code]
+ * @note The CentaurConfiguration object is shared with the 405 so
+ * it needs to be in non-cacheable sram.
+ */
+int gpe_ocmb_configuration_create(MemBufConfiguration_t * o_config);
+
+/**
+ * Check for OCMBr sensor errors
+ * @param[in] Configuration information
+ * @param[in] The ordinal membuf number
+ * @return [0 | return code]
+ */
+int check_and_reset_mmio_fir(MemBufConfiguration_t * i_config,unsigned int i_membuf);
+
+/**
+ * Send SYNC to ocmb to effectuate the thottle values
+ * @param[in] the membuf configuration
+ */
+int ocmb_throttle_sync(MemBufConfiguration_t* i_config);
+
+int get_ocmb_sensorcache(MemBufConfiguration_t* i_config,
+ MemBufGetMemDataParms_t* i_parms);
+
+
+#endif
diff --git a/src/occ_gpe1/gpe_membuf_scom.c b/src/occ_gpe1/gpe_membuf_scom.c
new file mode 100644
index 0000000..b27ab3f
--- /dev/null
+++ b/src/occ_gpe1/gpe_membuf_scom.c
@@ -0,0 +1,605 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: chips/p9/procedures/lib/pm/membuf_scom.c $ */
+/* */
+/* IBM CONFIDENTIAL */
+/* */
+/* EKB Project */
+/* */
+/* COPYRIGHT 2017 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* The source code for this program is not published or otherwise */
+/* divested of its trade secrets, irrespective of what has been */
+/* deposited with the U.S. Copyright Office. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#include <stdint.h>
+#include "gpe_membuf.h"
+#include "gpe_pba_cntl.h"
+#include "ppe42_scom.h"
+#include "ppe42.h"
+#include "pba_register_addresses.h"
+#include "ppe42_msr.h"
+
+/**
+ * @file gpe_membuf_scom
+ * @brief scom access from gpe to a membuf
+ */
+
+uint32_t g_inband_access_state = INBAND_ACCESS_INACTIVE;
+
+void swap_u64(uint64_t * data64)
+{
+ uint64_t val = *data64;
+ val = ((val << 8) & 0xff00ff00ff00ff00ULL) | ((val >> 8) & 0x00ff00ff00ff00ffULL);
+ val = ((val <<16) & 0xffff0000ffff0000ULL) | ((val >>16) & 0x0000ffff0000ffffULL);
+ *data64 = (val << 32) | (val >> 32);
+}
+
+int inband_access(MemBufConfiguration_t* i_config,
+ uint32_t i_instance,
+ uint32_t i_oci_addr,
+ uint64_t * io_data,
+ int i_read_write)
+{
+ int rc = 0;
+ uint32_t org_msr = mfmsr();
+ uint32_t msr = org_msr | MSR_SEM; // Mask off SIB from generating mck.
+
+ g_inband_access_state = INBAND_ACCESS_IN_PROGRESS;
+
+ if(i_read_write == INBAND_ACCESS_READ)
+ {
+ mtmsr(msr);
+ sync();
+ PPE_LVD(i_oci_addr, *io_data);
+
+ PK_TRACE("inband read %08x%08x from %08x",
+ (uint32_t)((*io_data)>>32),
+ (uint32_t)((*io_data)),
+ i_oci_addr);
+ if(i_config->membuf_type != MEMTYPE_CENTAUR)
+ {
+ swap_u64(io_data);
+ }
+ }
+ else
+ {
+ if(i_config->membuf_type != MEMTYPE_CENTAUR)
+ {
+ swap_u64(io_data);
+ }
+ // Set PPE to precise mode for stores so that in the case of a machine
+ // check, there is a predictable instruction address to resume on.
+
+ msr &= ~MSR_IPE;
+ mtmsr(msr);
+ sync();
+
+ uint64_t data64 = *io_data; //This makes PPE_STVD generate better code
+ PPE_STVD(i_oci_addr, data64);
+
+ PK_TRACE("inband write %08x%08x to %08x",
+ (uint32_t)((*io_data)>>32),
+ (uint32_t)((*io_data)),
+ i_oci_addr);
+ }
+
+ // Poll SIB error or machine check
+ if((mfmsr() & MSR_SIBRC) ||
+ g_inband_access_state != INBAND_ACCESS_IN_PROGRESS)
+ {
+ // Take membuf out of config
+ PK_TRACE("Removing MemBuf %d from list of configured MemBufs",
+ i_instance);
+
+ i_config->config &= ~(CHIP_CONFIG_MEMBUF(i_instance));
+
+ // This will cause the 405 to remove the membuf sensor(s).
+ rc = MEMBUF_CHANNEL_CHECKSTOP;
+ }
+ g_inband_access_state = INBAND_ACCESS_INACTIVE;
+ mtmsr(org_msr);
+ return rc;
+}
+
+/**
+ * Setup the PBASLVCTLN extended address and calculate the OCI scom address
+ * @param[in] PBA base address
+ * @param[in] The inband scom address
+ * @returns the mapped OCI address to scom the membuf
+ * @Post The extended address field in the PBASLVCNT is set
+ */
+int inband_scom_setup(MemBufConfiguration_t* i_config,
+ uint32_t i_membuf_instance,
+ uint32_t i_scom_address,
+ uint32_t *o_oci_addr)
+{
+ int rc = 0;
+ uint32_t scom_address = i_scom_address;
+ // TODO use PBASLV in P10
+#if defined(__USE_PBASLV__)
+ pba_slvctln_t slvctln;
+#endif
+ uint64_t pb_addr = i_config->baseAddress[i_membuf_instance];
+
+ if(i_config->membuf_type == MEMTYPE_CENTAUR)
+ {
+ // Break address into componets
+ uint32_t local = i_scom_address & 0x00001fff;
+ uint32_t port = i_scom_address & 0x000f0000;
+ uint32_t slave = i_scom_address & 0x03000000;
+ uint32_t multi = i_scom_address & 0xc0000000;
+
+ // compress to 21 bits for P9
+ scom_address =
+ local +
+ (port >> 3) +
+ (slave >> 7) +
+ (multi >> 11);
+ // P9: Turn on bit 38 to indicate OCC
+ pb_addr |= 0x0000000002000000ull;
+ }
+ pb_addr |= ((uint64_t)scom_address << 3);
+
+#if defined(__USE_PBASLV__)
+ // put bits 23:36 of address into slvctln extended addr
+ PPE_LVD((i_config->scomParms).slvctl_address, slvctln.value);
+ slvctln.fields.extaddr = pb_addr >> 27;
+ PPE_STVD((i_config->scomParms).slvctl_address, slvctln.value);
+#else
+ // TODO P9 HW bug work-around - Use PBASLV in P10
+ {
+ // workaround - don't use extraddr - use pbabar.
+ uint64_t barMsk = 0;
+
+ // Mask SIB from generating mck
+ mtmsr(mfmsr() | MSR_SEM);
+
+ // put the PBA in the BAR
+ rc = putscom_abs(PBA_BARN(PBA_BAR_MEMBUF), pb_addr & 0x00fffffffff00000ull);
+ if(rc)
+ {
+ PK_TRACE("inband_scom_setup. putscom fail on PBABAR."
+ " rc = %d",rc);
+ }
+ else
+ {
+ rc = putscom_abs(PBA_BARMSKN(PBA_BAR_MEMBUF), barMsk);
+ if(rc)
+ {
+ PK_TRACE("inband_scom_setup. putscom fail on PBABARMSK"
+ " rc = %d",rc);
+ }
+ }
+ }
+#endif
+ // make oci address
+ *o_oci_addr = (uint32_t)(pb_addr & 0x07ffffffull);
+
+ // upper nibble is PBA region and BAR_SELECT
+ *o_oci_addr |= ((PBA_BAR_MEMBUF | 0x8) << 28);
+ PK_TRACE_DBG("OCI mapped scom addr: %08x",*o_oci_addr);
+ return rc;
+}
+
+void pbaslvctl_reset(GpePbaParms* i_pba_parms)
+{
+ uint64_t val = 0;
+
+ do
+ {
+ PPE_STVD(PBA_SLVRST, i_pba_parms->slvrst.value);
+ PPE_LVD(PBA_SLVRST, val);
+ val &= i_pba_parms->slvrst_in_progress.value;
+ }
+ while(val != 0);
+}
+
+uint64_t pbaslvctl_setup(GpePbaParms* i_pba_parms)
+{
+ uint64_t slvctl_val;
+ uint64_t slvctl_val_org;
+ PPE_LVD(i_pba_parms->slvctl_address, slvctl_val_org);
+ slvctl_val = slvctl_val_org;
+ slvctl_val &= i_pba_parms->mask.value;
+ slvctl_val |= i_pba_parms->slvctl.value;
+ PPE_STVD(i_pba_parms->slvctl_address, slvctl_val);
+ return slvctl_val_org;
+}
+
+// Get data from each existing membuf.
+int membuf_get_scom_vector(MemBufConfiguration_t* i_config,
+ uint32_t i_scom_address,
+ uint64_t* o_data)
+{
+ int rc = 0;
+ int access_rc = 0;
+ int pba_rc = 0;
+ int instance = 0;
+ uint64_t pba_slvctln_save;
+
+ pbaslvctl_reset(&(i_config->scomParms));
+ pba_slvctln_save = pbaslvctl_setup(&(i_config->scomParms));
+
+ // clear SIB errors in MSR
+ mtmsr((mfmsr() & ~(MSR_SIBRC | MSR_SIBRCA)));
+
+ for(instance = 0; instance < OCCHW_N_MEMBUF; ++instance)
+ {
+ if( CHIP_CONFIG_MEMBUF(instance) & (i_config->config))
+ {
+ uint32_t oci_addr;
+ pba_rc = inband_scom_setup(i_config,
+ instance,
+ i_scom_address,
+ &oci_addr);
+
+ if(pba_rc)
+ {
+ rc = pba_rc;
+ // Already traced.
+ // Trumps any access error
+ *o_data = 0;
+ }
+ else
+ {
+ // inband scom read
+ access_rc = inband_access(i_config,
+ instance,
+ oci_addr,
+ o_data,
+ INBAND_ACCESS_READ);
+ // only set access_rc if rc not already set.
+ if(!rc && access_rc)
+ {
+ // not critical, but don't access this membuf again.
+ rc = access_rc;
+ *o_data = 0;
+ // continue with next instance
+ }
+ }
+ }
+ else
+ {
+ *o_data = 0;
+ }
+
+ ++o_data;
+ }
+
+ // gpe_pba_cntl function?
+ pbaslvctl_reset(&(i_config->scomParms));
+ PPE_STVD((i_config->scomParms).slvctl_address, pba_slvctln_save);
+
+ return rc;
+}
+
+int membuf_get_scom(MemBufConfiguration_t* i_config,
+ int i_membuf_instance,
+ uint32_t i_scom_address,
+ uint64_t* o_data)
+{
+ int rc = 0;
+ uint32_t oci_addr;
+ uint64_t pba_slvctln_save;
+
+ pbaslvctl_reset(&(i_config->scomParms));
+ pba_slvctln_save = pbaslvctl_setup(&(i_config->scomParms));
+
+ rc = inband_scom_setup(i_config,
+ i_membuf_instance,
+ i_scom_address,
+ &oci_addr);
+
+ if( !rc && (CHIP_CONFIG_MEMBUF(i_membuf_instance) & (i_config->config)))
+ {
+ // read membuf scom
+ rc = inband_access(i_config,
+ i_membuf_instance,
+ oci_addr,
+ o_data,
+ INBAND_ACCESS_READ);
+ }
+ else
+ {
+ *o_data = 0;
+ }
+
+ // gpe_pba_cntl function?
+ pbaslvctl_reset(&(i_config->scomParms));
+ PPE_STVD((i_config->scomParms).slvctl_address, pba_slvctln_save);
+
+ return rc;
+}
+
+
+// Write all configured membuf with the same data
+int membuf_put_scom_all(MemBufConfiguration_t* i_config,
+ uint32_t i_scom_address,
+ uint64_t i_data)
+{
+ int rc = 0;
+ int pba_rc = 0;
+ int access_rc = 0;
+ int instance = 0;
+ uint64_t pba_slvctln_save;
+
+ pbaslvctl_reset(&(i_config->scomParms));
+ pba_slvctln_save = pbaslvctl_setup(&(i_config->scomParms));
+
+ for(instance = 0; instance < OCCHW_N_MEMBUF; ++instance)
+ {
+ if( CHIP_CONFIG_MEMBUF(instance) & (i_config->config))
+ {
+ uint32_t oci_addr;
+ pba_rc = inband_scom_setup(i_config,
+ instance,
+ i_scom_address,
+ &oci_addr);
+
+ if(pba_rc)
+ {
+ // Already traced in inband_scom_setup
+ // Trumps access_rc
+ rc = pba_rc;
+ }
+ else
+ {
+ // membuf scom
+ access_rc = inband_access(i_config,
+ instance,
+ oci_addr,
+ &i_data,
+ INBAND_ACCESS_WRITE);
+ // Only set access_rc if rc not already set
+ if(!rc && access_rc)
+ {
+ // This MemBuf won't be touched again.
+ rc = access_rc;
+ // continue with next instance
+ }
+ }
+ }
+ }
+
+ // reset pba slave
+ pbaslvctl_reset(&(i_config->scomParms));
+ PPE_STVD((i_config->scomParms).slvctl_address, pba_slvctln_save);
+
+ return rc;
+}
+
+int membuf_put_scom(MemBufConfiguration_t* i_config,
+ int i_membuf_instance,
+ uint32_t i_scom_address,
+ uint64_t i_data)
+{
+ int rc = 0;
+ uint32_t oci_addr;
+ uint64_t pba_slvctln_save;
+
+ pbaslvctl_reset(&(i_config->scomParms));
+ pba_slvctln_save = pbaslvctl_setup(&(i_config->scomParms));
+
+ rc = inband_scom_setup(i_config,
+ i_membuf_instance,
+ i_scom_address,
+ &oci_addr);
+
+ if(!rc)
+ {
+ if(CHIP_CONFIG_MEMBUF(i_membuf_instance) & (i_config->config))
+ {
+ // write membuf scom
+ rc = inband_access(i_config,
+ i_membuf_instance,
+ oci_addr,
+ &i_data,
+ INBAND_ACCESS_WRITE);
+ }
+ }
+
+ // reset pba slave
+ pbaslvctl_reset(&(i_config->scomParms));
+ PPE_STVD((i_config->scomParms).slvctl_address, pba_slvctln_save);
+
+ return rc;
+}
+
+// write x
+int membuf_scom_rmw(MemBufConfiguration_t* i_config,
+ int i_membuf_instance,
+ uint32_t i_scom_address,
+ uint64_t i_mask,
+ uint64_t* i_data)
+{
+ int rc = 0;
+ uint32_t oci_addr;
+ uint64_t pba_slvctln_save;
+ uint64_t data64;
+
+ pbaslvctl_reset(&(i_config->scomParms));
+ pba_slvctln_save = pbaslvctl_setup(&(i_config->scomParms));
+
+ rc = inband_scom_setup(i_config,
+ i_membuf_instance,
+ i_scom_address,
+ &oci_addr);
+ if(!rc)
+ {
+
+ rc = inband_access(i_config,
+ i_membuf_instance,
+ oci_addr,
+ &data64,
+ INBAND_ACCESS_READ);
+
+ if(!rc)
+ {
+ data64 &= (i_mask ^ 0xffffffffffffffffull);
+ data64 |= *i_data;
+
+ rc = inband_access(i_config,
+ i_membuf_instance,
+ oci_addr,
+ &data64,
+ INBAND_ACCESS_WRITE);
+ }
+ }
+
+ pbaslvctl_reset(&(i_config->scomParms));
+ PPE_STVD((i_config->scomParms).slvctl_address, pba_slvctln_save);
+
+ return rc;
+}
+
+
+int membuf_scom_rmw_all(MemBufConfiguration_t* i_config,
+ uint32_t i_scom_address,
+ uint64_t i_mask,
+ uint64_t i_data)
+{
+ int rc = 0;
+ int pba_rc = 0;
+ int access_rc = 0;
+ int instance = 0;
+ uint64_t pba_slvctln_save;
+
+ pbaslvctl_reset(&(i_config->scomParms));
+ pba_slvctln_save = pbaslvctl_setup(&(i_config->scomParms));
+
+ for(instance = 0; (instance < OCCHW_N_MEMBUF); ++instance)
+ {
+ if( CHIP_CONFIG_MEMBUF(instance) & (i_config->config))
+ {
+ uint64_t data64;
+ uint32_t oci_addr;
+ pba_rc = inband_scom_setup(i_config,
+ instance,
+ i_scom_address,
+ &oci_addr);
+ if(pba_rc)
+ {
+ rc = pba_rc;
+ // Already traced in inband_scom_setup
+ // Trumps any access_rc
+ }
+ if(!pba_rc)
+ {
+
+ access_rc = inband_access(i_config,
+ instance,
+ oci_addr,
+ &data64,
+ INBAND_ACCESS_READ);
+
+ if(!access_rc)
+ {
+ data64 &= (i_mask ^ 0xffffffffffffffffull);
+ data64 |= i_data;
+
+ access_rc = inband_access(i_config,
+ instance,
+ oci_addr,
+ &data64,
+ INBAND_ACCESS_WRITE);
+ }
+ }
+ if(!rc && access_rc)
+ {
+ rc = access_rc;
+ }
+
+ pbaslvctl_reset(&(i_config->scomParms));
+ }
+ }
+
+ PPE_STVD((i_config->scomParms).slvctl_address, pba_slvctln_save);
+
+ return rc;
+}
+
+
+
+// MemBufConfiguration needs to be setup before this is called
+void gpe_inband_scom(MemBufConfiguration_t* i_config,
+ MemBufScomParms_t* i_parms)
+{
+ int i;
+ int rc = 0;
+ mtmsr((mfmsr() & ~(MSR_SIBRC | MSR_SIBRCA)) | MSR_SEM);
+
+ for(i = 0; i < i_parms->entries; ++i)
+ {
+ switch(i_parms->scomList[i].commandType)
+ {
+ case MEMBUF_SCOM_NOP:
+ break;
+
+ case MEMBUF_SCOM_READ:
+ rc =membuf_get_scom(i_config,
+ i_parms->scomList[i].instanceNumber,
+ i_parms->scomList[i].scom,
+ &(i_parms->scomList[i].data));
+ break;
+
+ case MEMBUF_SCOM_WRITE:
+ rc = membuf_put_scom(i_config,
+ i_parms->scomList[i].instanceNumber,
+ i_parms->scomList[i].scom,
+ i_parms->scomList[i].data);
+ break;
+
+ case MEMBUF_SCOM_RMW:
+ rc = membuf_scom_rmw(i_config,
+ i_parms->scomList[i].instanceNumber,
+ i_parms->scomList[i].scom,
+ i_parms->scomList[i].mask,
+ &(i_parms->scomList[i].data));
+ break;
+
+ case MEMBUF_SCOM_READ_VECTOR:
+ rc = membuf_get_scom_vector(i_config,
+ i_parms->scomList[i].scom,
+ i_parms->scomList[i].pData
+ );
+ break;
+
+ case MEMBUF_SCOM_WRITE_ALL:
+ rc = membuf_put_scom_all(i_config,
+ i_parms->scomList[i].scom,
+ i_parms->scomList[i].data);
+ break;
+
+ case MEMBUF_SCOM_RMW_ALL:
+ rc = membuf_scom_rmw_all(i_config,
+ i_parms->scomList[i].scom,
+ i_parms->scomList[i].mask,
+ i_parms->scomList[i].data);
+ break;
+
+ case MEMBUF_SCOM_MEMBUF_SYNC:
+ if( i_config->membuf_type == MEMTYPE_CENTAUR)
+ {
+ rc = centaur_throttle_sync(i_config);
+ }
+ else
+ {
+ rc = ocmb_throttle_sync(i_config);
+ }
+ break;
+
+ default:
+ break;
+ };
+ if (rc)
+ {
+ break;
+ }
+ }
+ i_parms->error.rc = rc;
+}
diff --git a/src/occ_gpe1/gpe_ocmb.c b/src/occ_gpe1/gpe_ocmb.c
new file mode 100644
index 0000000..dfe7d89
--- /dev/null
+++ b/src/occ_gpe1/gpe_ocmb.c
@@ -0,0 +1,630 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/occ_gpe1/gpe_ocmb.c $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016,2018 */
+/* [+] 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 "gpe_membuf.h"
+#include "ppe42_scom.h"
+#include "pk.h"
+#include "ppe42_msr.h"
+#include "occhw_pba_common.h"
+#include "p9a_misc_scom_addresses.h"
+#include "p9a_firmware_registers.h"
+#include "ocmb_register_addresses.h"
+#include "ocmb_firmware_registers.h"
+#include "ocmb_mem_data.h"
+
+const uint32_t AXONE_MCFGPR[OCCHW_N_MEMBUF] =
+{
+ P9A_MI_0_MCFGPR0,
+ P9A_MI_0_MCFGPR1,
+ P9A_MI_1_MCFGPR0,
+ P9A_MI_1_MCFGPR1,
+ P9A_MI_2_MCFGPR0,
+ P9A_MI_2_MCFGPR1,
+ P9A_MI_3_MCFGPR0,
+ P9A_MI_3_MCFGPR1
+};
+
+const uint32_t AXONE_MCSYNC[OCCHW_N_MEMBUF/2] =
+{
+ P9A_MI_0_MCSYNC,
+ P9A_MI_1_MCSYNC,
+ P9A_MI_2_MCSYNC,
+ P9A_MI_3_MCSYNC
+};
+
+// This table was taken from ekb p9a_omi_setup_bars.C
+const int NUM_EXT_MASKS = 20;
+const uint8_t EXT_MASK_REORDER[][9] = // Workbook table 7
+{
+ // B 6 7 8 9 10 11 12 13
+ { 0x00, 15, 18, 16, 17, 21, 20, 19, 14 },
+ { 0x04, 15, 18, 16, 17, 21, 20, 14, 19 },
+ { 0x06, 15, 18, 16, 17, 21, 14, 20, 19 },
+ { 0x07, 15, 18, 16, 17, 14, 21, 20, 19 },
+ { 0x80, 15, 18, 16, 17, 21, 20, 19, 14 },
+ { 0x84, 15, 18, 16, 17, 21, 20, 14, 19 },
+ { 0x86, 15, 18, 16, 17, 21, 14, 20, 19 },
+ { 0x87, 15, 18, 16, 17, 14, 21, 20, 19 },
+ { 0xC0, 15, 21, 17, 18, 20, 19, 14, 16 },
+ { 0xC4, 15, 21, 17, 18, 20, 14, 19, 16 },
+ { 0xC6, 15, 21, 17, 18, 14, 20, 19, 16 },
+ { 0xC7, 15, 14, 17, 18, 21, 20, 19, 16 },
+ { 0xE0, 15, 20, 18, 21, 19, 14, 17, 16 },
+ { 0xE4, 15, 20, 18, 21, 14, 19, 17, 16 },
+ { 0xE6, 15, 14, 18, 21, 20, 19, 17, 16 },
+ { 0xE7, 15, 21, 18, 14, 20, 19, 17, 16 },
+ { 0xF0, 15, 19, 21, 20, 14, 18, 17, 16 },
+ { 0xF4, 15, 14, 21, 20, 19, 18, 17, 16 },
+ { 0xF6, 15, 20, 21, 14, 19, 18, 17, 16 },
+ { 0xF7, 15, 20, 14, 21, 19, 18, 17, 16 }
+};
+
+int inband_scom_setup(MemBufConfiguration_t* i_config,
+ uint32_t i_membuf_instance,
+ uint32_t i_scom_address,
+ uint32_t *o_oci_addr);
+
+int membuf_get_scom(MemBufConfiguration_t* i_config,
+ int i_membuf_instance,
+ uint32_t i_scom_address,
+ uint64_t* o_data);
+
+int membuf_put_scom(MemBufConfiguration_t* i_config,
+ int i_membuf_instance,
+ uint32_t i_scom_address,
+ uint64_t i_data);
+
+void swap_u32(uint32_t * data32)
+{
+ uint32_t val = *data32;
+ val = ((val << 8) & 0xff00ff00) | ((val >> 8) & 0x00ff00ff);
+ *data32 = (val << 16) | (val >> 16);
+}
+
+
+int ocmb_check_sensor_cache_enabled(MemBufConfiguration_t * i_config,
+ int i_instance)
+{
+ int rc = 0;
+ mmio_merrctl_t merrctl;
+
+ rc = membuf_get_scom(i_config,
+ i_instance,
+ MMIO_MERRCTL,
+ &(merrctl.value));
+ if(rc)
+ {
+ PK_TRACE("OCMB MERRCTL getscom failed. rc = %d",
+ (uint16_t)rc);
+ }
+ else
+ {
+ //PK_TRACE("1MERRCTL: %08x%08x",
+ // merrctl.words.high_order,
+ // merrctl.words.low_order);
+ if(merrctl.fields.snsc_master_enable == SNSC_MASTER_DISABLED)
+ {
+ // attempted to enable it
+ merrctl.fields.snsc_master_enable = SNSC_MASTER_ENABLED;
+ rc = membuf_put_scom(i_config,
+ i_instance,
+ MMIO_MERRCTL,
+ merrctl.value);
+ if(rc)
+ {
+ PK_TRACE("OCMB MERRCTL putscom failed. rc = %d",
+ (uint16_t)rc);
+ }
+ //PK_TRACE("2MERRCTL: %08x%08x",
+ // merrctl.words.high_order,
+ // merrctl.words.low_order);
+ }
+
+ }
+ return rc;
+}
+
+int gpe_ocmb_configuration_create(MemBufConfiguration_t* o_config)
+{
+ int rc = 0;
+ int i = 0;
+ int l_rule = 0;
+ int l_ext_addr_mask = 0;
+ int designated_sync = -1;
+ mcfgpr_t mcfgpr;
+ pb_mode_t pb_mode;
+ uint64_t* ptr = (uint64_t*)o_config;
+
+ // Prevent unwanted interrupts from scom errors
+ // Enable store Gathering, and Icache prefetch for performance.
+ const uint32_t orig_msr = mfmsr();
+ mtmsr((orig_msr & ~(MSR_SIBRC | MSR_SIBRCA)) | MSR_SEM | MSR_IS1 | MSR_IS2 );
+ sync();
+
+ for(i = 0; i < sizeof(MemBufConfiguration_t) / 8; ++i)
+ {
+ *ptr++ = 0ull;
+ }
+
+ o_config->configRc = MEMBUF_NOT_CONFIGURED;
+ o_config->membuf_type = MEMTYPE_OCMB;
+
+ do
+ {
+ // Create the PBASLV configuration for collecting sensor data.
+ rc = gpe_pba_parms_create(&(o_config->dataParms),
+ PBA_SLAVE_MEMBUF,
+ PBA_WRITE_TTYPE_CI_PR_W,
+ PBA_WRITE_TTYPE_DC,
+ PBA_READ_TTYPE_CI_PR_RD);
+
+ if (rc)
+ {
+ rc = MEMBUF_DATA_SETUP_ERROR;
+ break;
+ }
+
+ // create the PBASLV configuration for doing inband scoms.
+ rc = gpe_pba_parms_create(&(o_config->scomParms),
+ PBA_SLAVE_MEMBUF,
+ PBA_WRITE_TTYPE_CI_PR_W,
+ PBA_WRITE_TTYPE_DC,
+ PBA_READ_TTYPE_CI_PR_RD);
+ if (rc)
+ {
+ rc = MEMBUF_SCOM_SETUP_ERROR;
+ break;
+ }
+
+ // On Ocmb the mmio bar value has been swizzled
+ // Need to un-swizzle
+ rc = getscom_abs(P9A_PU_NMMU_MMCQ_PB_MODE_REG, &(pb_mode.value));
+ if( rc )
+ {
+ PK_TRACE("Scom failed on PB_MODE_REG. rc = %d",
+ rc);
+ rc = MEMBUF_PBMODE_GETSCOM_FAILURE;
+ break;
+ }
+
+ l_ext_addr_mask = pb_mode.fields.addr_extension_group_id << 4;
+ l_ext_addr_mask |= pb_mode.fields.addr_extension_chip_id;
+
+ // bits [6:13] in mmio bar have been rearranged - look up translation
+ // rule.
+ for(l_rule = 0; l_rule < NUM_EXT_MASKS; ++l_rule)
+ {
+ if(EXT_MASK_REORDER[l_rule][0] == l_ext_addr_mask) // found
+ {
+ break;
+ }
+ }
+
+ if(l_rule == NUM_EXT_MASKS) // rule not found.
+ {
+ PK_TRACE("Failed to find match for %x in EXT_MASK_REORDER",
+ l_ext_addr_mask);
+ rc = MEMBUF_PMODE_DATA_MISMATCH;
+ break;
+ }
+
+ // Find all configured MEMBUFs
+ for (i = 0; i < OCCHW_N_MEMBUF; ++i)
+ {
+ uint64_t l_pba_addr = 0;
+ uint32_t l_mmio_bar = 0;
+
+ rc = getscom_abs(AXONE_MCFGPR[i], &(mcfgpr.value));
+
+ if( rc )
+ {
+ rc = 0; // Can't be scommed then ignore this MEMBUF
+ continue;
+ }
+
+ if(!mcfgpr.fields.mmio_valid)
+ {
+ continue; // MEMBUF MMIOBAR not configured, ignore MEMBUF
+ }
+
+ l_mmio_bar =
+ (uint32_t)(mcfgpr.fields.mmio_group_base_addr) << 1;
+ PK_TRACE("Ocmb[%d] MMIO Bar: %08x", i, l_mmio_bar);
+
+ // The mmio bar has been swizzled, It needs to be unswizzled.
+ // Make this easy for PPE 32 bit arch.
+
+ uint32_t l_mask = 0x02000000; //Start bit 6
+ uint32_t l_reordered = 0;
+ int l_col;
+
+ for(l_col = 1; l_col < 9; ++l_col)
+ {
+ if((l_mask & l_mmio_bar) != 0)
+ {
+ uint32_t l_setbit = 0x80000000 >>
+ EXT_MASK_REORDER[l_rule][l_col];
+ l_reordered |= l_setbit;
+ }
+
+ l_mask >>= 1;
+ }
+ l_mmio_bar &= 0xfc03ffff; //mask off bits 6-13
+ l_mmio_bar |= (l_reordered << 8);
+
+ l_pba_addr = (uint64_t)(l_mmio_bar) << 32;
+
+ // The 31-bit base-address (inband scom BAR) corresponds
+ // to bits [8:38] of the Power Bus addresss
+ l_pba_addr >>= 8;
+
+ if((i % 2) != 0)
+ {
+ l_pba_addr |= OCMB_IB_BAR_B_BIT;
+ }
+
+ PK_TRACE("MMIO Base Address: 0x%08x%08x on ocmb %d",
+ (uint32_t)(l_pba_addr >> 32),
+ (uint32_t)(l_pba_addr),
+ i);
+
+ o_config->baseAddress[i] = l_pba_addr;
+ // Add this membuf to the configuration
+ o_config->config |= (CHIP_CONFIG_MCS(i) | CHIP_CONFIG_MEMBUF(i));
+ }
+
+ if( rc )
+ {
+ break;
+ }
+
+ // Find the designated sync.
+ // Find the register that HWPs used to sync the throttle n/m values
+ // accross all membufs. Only one register should be setup.
+ for (i = 0; i < (OCCHW_N_MEMBUF/2); ++i)
+ {
+ uint64_t mcsync;
+ rc = getscom_abs(AXONE_MCSYNC[i], &mcsync);
+ if (rc)
+ {
+ PK_TRACE("getscom failed on MCSYNC, rc = %d. The first configured "
+ "MC will be the designated sync",rc);
+ rc = 0;
+ }
+ if (mcsync != 0)
+ {
+ designated_sync = i;
+ // There can only be one sync, so stop searching.
+ break;
+ }
+ }
+
+ if (designated_sync < 0)
+ {
+ // Leave mcSyncAddr zero.
+ PK_TRACE("No designated sync found. Ocmb sync disabled.");
+ }
+ else
+ {
+ o_config->mcSyncAddr = AXONE_MCSYNC[designated_sync];
+ }
+
+ if(o_config->config != 0)
+ {
+ rc = configure_pba_bar_for_inband_access(o_config);
+
+ if( rc )
+ {
+ break;
+ }
+ }
+
+ if(!rc)
+ {
+ for(i = 0; i < OCCHW_N_MEMBUF; ++i)
+ {
+ if( CHIP_CONFIG_MEMBUF(i) & (o_config->config))
+ {
+ // Attempt to reset any SCACHE FIR errors
+ // and insure the SCACHE is enabled
+ check_and_reset_mmio_fir(o_config, i);
+ ocmb_check_sensor_cache_enabled(o_config,i);
+ }
+ }
+
+ // Find out which DTS are present
+ OcmbMemData escache;
+ MemBufGetMemDataParms_t l_parms;
+
+ l_parms.update = -1;
+ l_parms.data = (uint64_t *)(&escache);
+
+ for(i = 0; i < OCCHW_N_MEMBUF; ++i)
+ {
+ if( CHIP_CONFIG_MEMBUF(i) & (o_config->config))
+ {
+ l_parms.collect = i;
+ rc = get_ocmb_sensorcache(o_config, &l_parms);
+ if( rc )
+ {
+ PK_TRACE("gpe_ocmb_configuration_create failed to"
+ " get sensorcache for MEMBUF %d, rc = %d.",
+ i, rc);
+ continue; // Thermal sensors not available.
+ }
+
+ if(escache.status.fields.ubdts0_present)
+ {
+ o_config->dts_config |= CONFIG_UBDTS0(i);
+ }
+ if(escache.status.fields.memdts0_present)
+ {
+ o_config->dts_config |= CONFIG_MEMDTS0(i);
+ }
+ if(escache.status.fields.memdts1_present)
+ {
+ o_config->dts_config |= CONFIG_MEMDTS1(i);
+ }
+ PK_TRACE("Ocmb dts_config: %08x",o_config->dts_config);
+ }
+ }
+ }
+
+ }
+ while( 0 );
+
+ o_config->configRc = rc;
+
+ mtmsr(orig_msr);
+
+ return rc;
+}
+
+int check_and_reset_mmio_fir(MemBufConfiguration_t* i_config, unsigned int i_membuf)
+{
+ int rc = 0;
+ mmio_mfir_t mfir;
+
+ rc = membuf_get_scom(i_config, i_membuf, MMIO_MFIR, &(mfir.value));
+ if(rc)
+ {
+ PK_TRACE("check_and_reset_mmio_fir mmio scom fail. rc = %d",rc);
+ }
+ else
+ {
+
+ // Check for bits 7,8,9,10
+ if(mfir.fields.snsc_both_starts_err ||
+ mfir.fields.snsc_mult_seq_perr ||
+ mfir.fields.snsc_fsm_perr ||
+ mfir.fields.snsc_reg_perr)
+ {
+ PK_TRACE("ocmb mmio fir: 0x%08x%08x",
+ mfir.words.high_order,
+ mfir.words.low_order);
+
+ rc = MEMBUF_SCACHE_ERROR;
+
+ mfir.value = 0xffffffffffffffffull;
+ mfir.fields.snsc_both_starts_err = 0;
+ mfir.fields.snsc_mult_seq_perr = 0;
+ mfir.fields.snsc_fsm_perr = 0;
+ mfir.fields.snsc_reg_perr = 0;
+ membuf_put_scom(i_config, i_membuf, MMIO_MFIR_AND, mfir.value);
+ }
+ }
+
+ return rc;
+}
+
+int ocmb_throttle_sync(MemBufConfiguration_t* i_config)
+{
+ // see
+ // https://farm3802.rtp.stglabs.ibm.com/regdb/entire_table.php?db=FIGDB_cb1_25_36_DB&name=MB_SIM.SRQ.MBA_FARB3Q
+ // SYNC only needed if OCMB_MBA_FARB3Q bit cfg_nm_change_after_sync is set.
+ // HWP programs this.
+ // Ocmb may not need to sync as it only has one FARB3Q reg to write.
+ uint64_t data;
+ int rc = 0;
+ do
+ {
+ // No designated sync addr, therefore Sync not needed.
+ if(i_config->mcSyncAddr == 0)
+ {
+ break;
+ }
+
+ rc = getscom_abs(i_config->mcSyncAddr,&data);
+ if (rc)
+ {
+ PK_TRACE("ocmb_throttle_sync: getscom failed. rc = %d",rc);
+ break;
+ }
+
+ data &= ~MCS_MCSYNC_SYNC_GO;
+
+ rc = putscom_abs(i_config->mcSyncAddr, data);
+ if (rc)
+ {
+ PK_TRACE("ocmb_throttle_sync: reset sync putscom failed. rc = %d",rc);
+ break;
+ }
+
+ data |= MCS_MCSYNC_SYNC_GO;
+
+ rc = putscom_abs(i_config->mcSyncAddr, data);
+ if (rc)
+ {
+ PK_TRACE("ocmb_throttle_sync: set sync putscom failed. rc = %d",rc);
+ break;
+ }
+ } while (0);
+
+ return rc;
+}
+
+void extract_32b(uint32_t oci_addr, uint64_t * i_dest_addr)
+{
+ typedef union
+ {
+ uint64_t v;
+ struct
+ {
+ uint32_t h;
+ uint32_t l;
+ } w;
+ } data64_t;
+
+ data64_t data64;
+ uint32_t * dest_addr = (uint32_t *)i_dest_addr;
+ PkMachineContext ctx;
+
+ pk_critical_section_enter(&ctx);
+ // Invalidate the cache block at oci_addr
+ asm volatile ("dcbi 0, %0" : : "r" (oci_addr) : "memory");
+
+ // The first load causes the PBA bridge to fetch the 32 byte sensor cache
+ // and place it in the PPE42 data cache. The PPE42 cache must not be
+ // invalidated by any other load(s) until all 32 bytes have been read.
+ // Note: A store does a store-through and won't invalidate the data cache.
+
+ asm volatile ("lvd %[d], 0(%[a])\n" : [d]"=r"(data64.v) : [a]"b"(oci_addr));
+ dest_addr[7] = data64.w.h;
+ dest_addr[6] = data64.w.l;
+
+ asm volatile ("lvd %[d], 8(%[a])\n" : [d]"=r"(data64.v) : [a]"b"(oci_addr));
+ dest_addr[5] = data64.w.h;
+ dest_addr[4] = data64.w.l;
+
+ asm volatile ("lvd %[d], 16(%[a])\n" : [d]"=r"(data64.v) : [a]"b"(oci_addr));
+ dest_addr[3] = data64.w.h;
+ dest_addr[2] = data64.w.l;
+
+ asm volatile ("lvd %[d], 24(%[a])\n" : [d]"=r"(data64.v) : [a]"b"(oci_addr));
+ dest_addr[1] = data64.w.h;
+ dest_addr[0] = data64.w.l;
+ sync();
+ pk_critical_section_exit(&ctx);
+}
+
+int get_ocmb_sensorcache(MemBufConfiguration_t* i_config,
+ MemBufGetMemDataParms_t* i_parms)
+{
+ int rc = 0;
+ uint64_t pba_slvctln_save;
+
+ i_parms->error.rc = MEMBUF_GET_MEM_DATA_DIED;
+
+ pbaslvctl_reset(&(i_config->dataParms));
+ pba_slvctln_save = pbaslvctl_setup(&(i_config->dataParms));
+
+ // Clear SIB error accumulator bits & mask SIB errors from
+ // generating machine checks
+ mtmsr((mfmsr() & ~(MSR_SIBRC | MSR_SIBRCA)) | MSR_SEM);
+
+ //collect has the ordinal # of the membuf from which to collect the
+ //sensor cache.
+ if(i_parms->collect != -1)
+ {
+ if((i_parms->collect >= OCCHW_N_MEMBUF) ||
+ (0 == (CHIP_CONFIG_MEMBUF(i_parms->collect) & (i_config->config))))
+ {
+ rc = MEMBUF_GET_MEM_DATA_COLLECT_INVALID;
+ }
+ else
+ {
+ uint32_t oci_addr = 0;
+
+ int rc1 = check_and_reset_mmio_fir(i_config, i_parms->collect);
+ int rc2 = ocmb_check_sensor_cache_enabled(i_config,
+ i_parms->collect);
+
+ if(rc2)
+ {
+ rc = rc2; // mmio scom fail
+ }
+ else if (rc1)
+ {
+ rc = rc1; //mmio scom fail or MEMBUF_SCACHE_ERROR;
+ }
+ else
+ {
+
+ // NOTE: inband_scom_setup can be used to map the oci_addr so
+ // long as i_config->dataParms and i_config->scomParms are the,
+ // same, which for ocmb is currently true.
+ rc = inband_scom_setup(i_config,
+ i_parms->collect,
+ OCMB_IB_SENSOR_CACHE_ADDR,
+ &oci_addr);
+
+ if(!rc)
+ {
+ uint32_t org_msr = mfmsr();
+ // Mask off SIB errors from gen mck and set data cache enable,
+ // Enable Store Gathering, and Icache prefetch
+ mtmsr(org_msr | MSR_SEM | MSR_IS0 | MSR_IS1 | MSR_IS2);
+ sync();
+ g_inband_access_state = INBAND_ACCESS_IN_PROGRESS;
+
+ extract_32b(oci_addr,(i_parms->data)); //packet0
+ extract_32b(oci_addr + 32, (i_parms->data) + 4); //packet1
+
+ // Poll for SIB errors or machine check
+ if((mfmsr() & MSR_SIBRC) ||
+ g_inband_access_state != INBAND_ACCESS_IN_PROGRESS)
+ {
+ // Take membuf out of config list
+ PK_TRACE("Removing Membuf %d from list of configured Membufs",
+ i_parms->collect);
+ i_config->config &= ~(CHIP_CONFIG_MEMBUF(i_parms->collect));
+
+ // This rc will cause the 405 to remove this centaur sensor
+ rc = MEMBUF_CHANNEL_CHECKSTOP;
+ }
+ mtmsr(org_msr);
+ g_inband_access_state = INBAND_ACCESS_INACTIVE;
+
+ // Finish making data big-endian
+ uint32_t * p = (uint32_t *)(i_parms->data);
+ int i;
+ for(i=0; i < 16; ++i)
+ {
+ swap_u32(p);
+ ++p;
+ }
+ }
+ }
+ }
+ }
+ // if(i_parms->update != -1) {} -- not used for Ocmb
+
+ pbaslvctl_reset(&(i_config->dataParms));
+ PPE_STVD((i_config->dataParms).slvctl_address, pba_slvctln_save);
+
+ i_parms->error.rc = rc;
+ return rc;
+}
+
+
diff --git a/src/occ_gpe1/ipc_func_tables.c b/src/occ_gpe1/ipc_func_tables.c
index abc1575..8ee7cd0 100644
--- a/src/occ_gpe1/ipc_func_tables.c
+++ b/src/occ_gpe1/ipc_func_tables.c
@@ -26,7 +26,7 @@
#include "ipc_async_cmd.h"
#include "gpe1_dimm.h"
#include "gpu_structs.h"
-#include "gpe_centaur.h"
+#include "gpe_membuf.h"
void gpe_dimm_control(ipc_msg_t* cmd, void* arg);
void gpe1_nop(ipc_msg_t* cmd, void* arg);
@@ -86,9 +86,9 @@ IPC_HANDLER(gpe_24x7, 0) // 4 - IPC_ST_24_X_7_FUNCID
IPC_HANDLER(gpe_mem_power_control, 0) // 5 - IPC_ST_MEM_POWER_CONTROL_FUNCID
IPC_HANDLER(gpe_gpu_sm, 0) // 6 - IPC_ST_GPU_SM_FUNCID
IPC_HANDLER(gpe_gpu_init, 0) // 7 - IPC_ST_GPE_GPU_INIT_FUNCID
-IPC_HANDLER(gpe_centaur_scom, 0) // 8 - IPC_ST_CENTAUR_SCOM_FUNCID
-IPC_HANDLER(gpe_centaur_data, 0) // 9 - IPC_ST_CENTAUR_DATA_FUNCID
-IPC_HANDLER(gpe_centaur_init, 0) // 10 -IPC_ST_CENTAUR_INIT_FUNCID
+IPC_HANDLER(gpe_membuf_scom, 0) // 8 - IPC_ST_MEMBUF_SCOM_FUNCID
+IPC_HANDLER(gpe_membuf_data, 0) // 9 - IPC_ST_MEMBUF_DATA_FUNCID
+IPC_HANDLER(gpe_membuf_init, 0) // 10 -IPC_ST_MEMBUF_INIT_FUNCID
IPC_HANDLER(gpe_scom_nvdimms_nimbus, 0) // 11 -IPC_ST_EPOW_GPIO_ASSERT_FUNCID
IPC_HANDLER_DEFAULT // 12
IPC_HANDLER_DEFAULT // 13
diff --git a/src/occ_gpe1/link.cmd b/src/occ_gpe1/link.cmd
index ae41e28..67de73f 100644
--- a/src/occ_gpe1/link.cmd
+++ b/src/occ_gpe1/link.cmd
@@ -27,7 +27,7 @@
#undef powerpc
#ifndef INITIAL_STACK_SIZE
-#define INITIAL_STACK_SIZE 256
+#define INITIAL_STACK_SIZE 512
#endif
OUTPUT_FORMAT(elf32-powerpc);
diff --git a/src/occ_gpe1/occ_gpe1_machine_check_handler.c b/src/occ_gpe1/occ_gpe1_machine_check_handler.c
index 33424c6..53780f7 100644
--- a/src/occ_gpe1/occ_gpe1_machine_check_handler.c
+++ b/src/occ_gpe1/occ_gpe1_machine_check_handler.c
@@ -1,5 +1,29 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/occ_gpe1/occ_gpe1_machine_check_handler.c $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016,2018 */
+/* [+] 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_panic_codes.h"
-#include "gpe_centaur.h"
+#include "gpe_membuf.h"
#include "pk.h"
#define OCI_ADDR_BAR_MASK 0xf0000000
@@ -8,7 +32,7 @@
extern uint32_t gpe1_machine_check_handler(uint32_t srr0,
uint32_t srr1,
uint32_t edr);
-extern uint32_t g_centaur_access_state;
+extern uint32_t g_inband_access_state;
uint32_t gpe1_machine_check_handler(uint32_t srr0,
uint32_t srr1,
@@ -20,15 +44,15 @@ uint32_t gpe1_machine_check_handler(uint32_t srr0,
edr);
// It's possible to get back-to-back machine checks for the same condition
- // so CENTAUR_CHANNEL_CHECKSTOP may already be set. Also check that the
- // machine check was due to a Centaur Access (PBABAR1)
- if((g_centaur_access_state == CENTAUR_ACCESS_IN_PROGRESS ||
- g_centaur_access_state == CENTAUR_CHANNEL_CHECKSTOP) &&
+ // so MEMBUF_CHANNEL_CHECKSTOP may already be set. Also check that the
+ // machine check was due to a MEMBUF PBA Access (PBABAR1)
+ if((g_inband_access_state == INBAND_ACCESS_IN_PROGRESS ||
+ g_inband_access_state == MEMBUF_CHANNEL_CHECKSTOP) &&
((edr & OCI_ADDR_BAR_MASK) == OCI_ADDR_BAR1))
{
// Returning this to OCC405 will cause sensor to be removed from
// active list
- g_centaur_access_state = CENTAUR_CHANNEL_CHECKSTOP;
+ g_inband_access_state = MEMBUF_CHANNEL_CHECKSTOP;
// The instruction that caused the machine check should
// be a double word load or store.
diff --git a/src/occ_gpe1/topfiles.mk b/src/occ_gpe1/topfiles.mk
index 53d35b5..5a0095f 100644
--- a/src/occ_gpe1/topfiles.mk
+++ b/src/occ_gpe1/topfiles.mk
@@ -26,8 +26,9 @@
TOP-C-SOURCES = gpe1_main.c gpe1_dimm_read.c gpe1_dimm_reset.c nop.c \
pk_app_irq_table.c ipc_func_tables.c gpe1_dimm_control.c \
gpe1_24x7.c gpe1_memory_power_control.c gpe_gpu_init.c \
- gpe_centaur_scom.c gpe_centaur_configuration.c \
- gpe_centaur.c occ_gpe1_machine_check_handler.c
+ gpe_membuf_scom.c gpe_centaur.c \
+ gpe_membuf.c occ_gpe1_machine_check_handler.c \
+ gpe_ocmb.c
TOP-S-SOURCES = occ_gpe1_mck_handler.S
OpenPOWER on IntegriCloud