summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorWael El-Essawy <welessa@us.ibm.com>2016-04-27 14:38:10 -0500
committerWael El-Essawy <welessa@us.ibm.com>2016-05-03 18:23:13 -0400
commit8a7f3c6739f022df1c128b9d5a479e7abfac0ec1 (patch)
treedcecbff7b4739d6fd53566d7eab0848a4e36f6cf /src
parent0773d5a096886bd01a25ae28480a54b213179899 (diff)
downloadtalos-occ-8a7f3c6739f022df1c128b9d5a479e7abfac0ec1.tar.gz
talos-occ-8a7f3c6739f022df1c128b9d5a479e7abfac0ec1.zip
Empath counters collection PPE code
Change-Id: Ic17691020a66dffd92e9a685616092043ff05476 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/23976 Tested-by: FSP CI Jenkins Reviewed-by: William A. Bryan <wilbryan@us.ibm.com> Reviewed-by: Douglas R. Gilbert <dgilbert@us.ibm.com> Reviewed-by: Wael El-Essawy <welessa@us.ibm.com>
Diffstat (limited to 'src')
-rw-r--r--src/include/core_data.h93
-rw-r--r--src/include/p9_config.h76
-rw-r--r--src/occ_gpe0/core_data.c180
3 files changed, 223 insertions, 126 deletions
diff --git a/src/include/core_data.h b/src/include/core_data.h
index 3a8ce66..96455e8 100644
--- a/src/include/core_data.h
+++ b/src/include/core_data.h
@@ -7,7 +7,7 @@
/* */
/* EKB Project */
/* */
-/* COPYRIGHT 2015 */
+/* COPYRIGHT 2015,2016 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -35,7 +35,38 @@
#include <stdint.h>
#define THERM_DTS_RESULT 0x00050000
-
+#define PC_OCC_SPRC 0x00010A82
+#define PC_OCC_SPRD 0x00010A83
+#define TOD_VALUE_REG 0x00040020
+
+#define CORE_RAW_CYCLES 0x200
+#define CORE_RUN_CYCLES 0x208
+#define CORE_WORKRATE_BUSY 0x210
+#define CORE_WORKRATE_FINISH 0x218
+#define CORE_MEM_HIER_A_LATENCY 0x220
+#define CORE_MEM_HIER_B_LATENCY 0x228
+#define CORE_MEM_HIER_C_ACCESS 0x230
+#define THREAD0_RUN_CYCLES 0x238
+#define THREAD0_INST_DISP_UTIL 0x240
+#define THREAD0_INST_COMP_UTIL 0x248
+#define THREAD0_MEM_HIER_C_ACCESS 0x250
+#define THREAD1_RUN_CYCLES 0x258
+#define THREAD1_INST_DISP_UTIL 0x260
+#define THREAD1_INST_COMP_UTIL 0x268
+#define THREAD1_MEM_HEIR_C_ACCESS 0x270
+#define THREAD2_RUN_CYCLES 0x278
+#define THREAD2_INST_DISP_UTIL 0x280
+#define THREAD2_INST_COMP_UTIL 0x288
+#define THREAD2_MEM_HEIR_C_ACCESS 0x290
+#define THREAD3_RUN_CYCLES 0x298
+#define THREAD3_INST_DISP_UTIL 0x2A0
+#define THREAD3_INST_COMP_UTIL 0x2A8
+#define THREAD3_MEM_HEIR_C_ACCESS 0x2B0
+#define IFU_THROTTLE_BLOCK_FETCH 0x2B8
+#define IFU_THROTTLE_ACTIVE 0x2C0
+#define VOLT_DROOP_THROTTLE_ACTIVE 0x2C8
+
+#define EMPATH_CORE_THREADS 4
typedef union dts_sensor_result_reg
{
@@ -49,47 +80,35 @@ typedef union dts_sensor_result_reg
} dts_sensor_result_reg_t;
-typedef struct //40 bytes
+typedef struct
{
- uint32_t unused;
uint32_t tod_2mhz;
- uint32_t dispatch;
- uint32_t completion;
- uint32_t freq_sens_busy;
- uint32_t freq_sens_finish;
- uint32_t run_cycles;
- uint32_t raw_cycles;
- uint32_t mem_a; // not used in P8
- uint32_t mem_b; // not used in P8
-} CoreDataEmpath;
-
+ uint32_t raw_cycles; // 0x200
+ uint32_t run_cycles; // 0x208
+ uint32_t freq_sens_busy; // 0x210 Core workrate busy counter
+ uint32_t freq_sens_finish; // 0x218 Core workrate finish counter
+ uint32_t mem_latency_a;
+ uint32_t mem_latency_b;
+ uint32_t mem_access_c;
-// \todo (RTC 137031) : should seriously question the need for this
-typedef struct //24 bytes
-{
- uint32_t raw_cycles;
- uint32_t tod_2mhz;
- uint32_t count[4]; // research prototype use
-} CoreDataPerPartitionMemory;
+} CoreDataEmpath;
typedef struct
{
- uint32_t raw_cycles;
- uint32_t tod_2mhz;
uint32_t ifu_throttle;
- uint32_t isu_throttle;
+ //uint32_t isu_throttle; // No longer exists
uint32_t ifu_active;
uint32_t undefined;
-} CoreDataThrottle; // not used in P8
+ uint32_t v_droop; // new for p9
+} CoreDataThrottle;
typedef struct
{
- uint32_t raw_cycles; // used in P8
- uint32_t tod_2mhz;
- uint32_t run_cycles; // used in P8
+ uint32_t run_cycles;
+ uint32_t dispatch; // new for p9
uint32_t completion;
- uint32_t mem_a;
- uint32_t mem_b;
+ uint32_t mem_c; // was mem_a
+ // uint32_t mem_b; // No longer exists in p9
} CoreDataPerThread;
typedef union sensor_result
@@ -107,8 +126,6 @@ typedef union sensor_result
typedef struct
{
- uint32_t unused;
- uint32_t tod_2mhz;
sensor_result_t core[2];
sensor_result_t cache;
sensor_result_t reserved;
@@ -118,13 +135,12 @@ typedef struct
//
// The instance of this data object must be 8 byte aligned
//
-typedef struct
+typedef struct // 120
{
- CoreDataEmpath empath; //40
- CoreDataPerPartitionMemory per_partition_memory; //24
- CoreDataThrottle throttle; //24
- CoreDataPerThread per_thread[8]; //24 * 8
- CoreDataDts dts; //16
+ CoreDataEmpath empath; //32
+ CoreDataThrottle throttle; //16
+ CoreDataPerThread per_thread[EMPATH_CORE_THREADS]; // 64
+ CoreDataDts dts; //8
} CoreData;
#ifdef __cplusplus
@@ -144,4 +160,3 @@ uint32_t get_core_data(uint32_t i_core, CoreData* o_data);
};
#endif
#endif /* __GPE_CORE_DATA_H__ */
-
diff --git a/src/include/p9_config.h b/src/include/p9_config.h
index 0e259a0..1136008 100644
--- a/src/include/p9_config.h
+++ b/src/include/p9_config.h
@@ -1,25 +1,19 @@
/* IBM_PROLOG_BEGIN_TAG */
/* This is an automatically generated prolog. */
/* */
-/* $Source: src/include/p9_config.h $ */
+/* $Source: chips/p9/procedures/lib/pm/p9_config.h $ */
/* */
-/* OpenPOWER OnChipController Project */
-/* */
-/* Contributors Listed Below - COPYRIGHT 2015 */
-/* [+] International Business Machines Corp. */
+/* IBM CONFIDENTIAL */
/* */
+/* EKB Project */
/* */
-/* 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 */
+/* COPYRIGHT 2015,2016 */
+/* [+] International Business Machines Corp. */
/* */
-/* 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. */
+/* 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 */
@@ -38,60 +32,8 @@
#include <stdint.h>
-// TODO is any of the "Config" needed in P9?
-//
-/// A bitmask defining a chip configuration
-///
-/// Since we are using the conventional big-endian notation, any use of these
-/// bitmasks requires that the data being tested is of this type - otherwise
-/// the masks won't work.
-///
-/// Layout:
-///
-/// Bits 0:15 - Core chiplet 0..15 is configured
-/// Bits 16:23 - MCS 0..7 is configured
-/// Bits 24:31 - Centaur 0..7 is configured
-
-typedef uint64_t ChipConfig;
-typedef uint16_t ChipConfigCores;
-typedef uint8_t ChipConfigMcs;
-typedef uint8_t ChipConfigCentaur;
-
-
-/// Convert a ChipConfig into a mask suitable for use as the 32-bit chiplet
-/// mask argument of a PORE wakeup program.
-
-static inline uint32_t
-pore_exe_mask(ChipConfig config)
-{
- return (uint32_t)((config >> 32) & 0xffff0000);
-}
-
-/// Left justify and mask core chiplet configuration into a uint32_t
-
-static inline uint32_t
-left_justify_core_config(ChipConfig config)
-{
- return (uint32_t)((config >> 32) & 0xffff0000);
-}
-
-/// Left justify and mask MCS configuration into a uint32_t
-
-static inline uint32_t
-left_justify_mcs_config(ChipConfig config)
-{
- return (uint32_t)((config >> 16) & 0xff000000);
-}
-
-/// Left justify and mask Centaur configuration into a uint32_t
-
-static inline uint32_t
-left_justify_centaur_config(ChipConfig config)
-{
- return (uint32_t)((config >> 8) & 0xff000000);
-}
-/// SCOM address Reanges:
+/// SCOM address Ranges:
// Cores (EX chiplet): 0x20000000 - 0x37000000
// Caches: 0x10000000 - 0x15000000
//
diff --git a/src/occ_gpe0/core_data.c b/src/occ_gpe0/core_data.c
index 7d119a9..8b69ff4 100644
--- a/src/occ_gpe0/core_data.c
+++ b/src/occ_gpe0/core_data.c
@@ -7,7 +7,7 @@
/* */
/* EKB Project */
/* */
-/* COPYRIGHT 2015 */
+/* COPYRIGHT 2015,2016 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -25,8 +25,9 @@
// *HWP Level: 1
// *HWP Consumed by: OCC
#include "core_data.h"
-#include "ppe42_scom.h"
#include "p9_config.h"
+#include "ppe42_msr.h"
+#include "ppe42_scom.h"
uint32_t get_core_data(uint32_t i_core,
CoreData* o_data)
@@ -36,6 +37,8 @@ uint32_t get_core_data(uint32_t i_core,
uint64_t* ptr = (uint64_t*)o_data;
uint32_t coreSelect = CHIPLET_CORE_ID(i_core);
uint32_t quadSelect = CHIPLET_CACHE_ID((i_core / 4));
+ //volatile uint64_t* scom_reg = (uint64_t*)(0);
+ uint64_t value64 = 0;
uint32_t i;
@@ -44,32 +47,169 @@ uint32_t get_core_data(uint32_t i_core,
ptr[i] = 0;
}
- dts_sensor_result_reg_t scom_data;
+ // Turn off MCR bit to prevent machine check on error on scom readings bits 1:7
+ // rc == 1 resource occupied (see ppe42_scom.h) Action: return with rc
+ // rc == 2 Core is fenced, offline Action: return with rc
+ // rc == 3 partial good
+ // rc == 4 address error
+ // rc == 5 clock error
+ // rc == 6 packet error
+ // rc == 7 timeout
+ // ACTIONS:
+ // rc 1,2:- mask the machine check, return rc
+ // 3-7 Leave as machine check (or as it was)
+ uint32_t org_sem = mfmsr() & MSR_SEM;
+
+ // Clear SIBRC and SIBRCA
+ // mask off resource occupied/offline errors - will return these)
+ // SIB rc 3-7 will machine check (unless already masked)
+ mtmsr((mfmsr() & ~(MSR_SIBRC | MSR_SIBRCA))
+ | 0xe0000000); //MASK SIBRC == 1 | SIBRC == 2
- rc = getscom(quadSelect, THERM_DTS_RESULT, &(scom_data.value));
+ dts_sensor_result_reg_t dts_scom_data;
- if(!rc)
+ //scom_reg = (uint64_t*)(quadSelect + THERM_DTS_RESULT);
+ //dts_scom_data.value = *scom_reg;
+ PPE_LVD(quadSelect + THERM_DTS_RESULT, value64);
+ dts_scom_data.value = value64;
+
+ // Pick the sensor reading closest to core
+ // first two cores - use cache dts0
+ // last two cores - use cache dts1
+ if(i_core & 0x00000002)
{
- // Pick the sensor reading closest to core
- // first two cores - use cache dts0
- // last two cores - use cache dts1
- if(i_core & 0x00000002)
- {
- o_data->dts.cache.result = scom_data.half_words.reading[1];
- }
- else
- {
- o_data->dts.cache.result = scom_data.half_words.reading[0];
- }
+ o_data->dts.cache.result = dts_scom_data.half_words.reading[1];
+ }
+ else
+ {
+ o_data->dts.cache.result = dts_scom_data.half_words.reading[0];
+ }
+
+ //scom_reg = (uint64_t*)(coreSelect + THERM_DTS_RESULT);
+ //dts_scom_data.value = *scom_reg;
+ PPE_LVD(coreSelect + THERM_DTS_RESULT, value64);
+ dts_scom_data.value = value64;
+
+ o_data->dts.core[0].result = dts_scom_data.half_words.reading[0];
+ o_data->dts.core[1].result = dts_scom_data.half_words.reading[1];
+
+ // Send command to select which emmpath counter to read
+ uint64_t empath_scom_data = CORE_RAW_CYCLES;
+ //scom_reg = (uint64_t*)(coreSelect + PC_OCC_SPRC);
+ //*scom_reg = empath_scom_data;
+ PPE_STVD(coreSelect + PC_OCC_SPRC, empath_scom_data)
+
+
+ // Read counters.
+ // Counter selected auto increments to the next counter after each read.
+
+ //CORE_RAW_CYCLES
+ //scom_reg = (uint64_t*)(coreSelect + PC_OCC_SPRD);
+ //empath_scom_data = *scom_reg;
+ PPE_LVD(coreSelect + PC_OCC_SPRD, empath_scom_data);
+ o_data->empath.raw_cycles = (uint32_t)empath_scom_data;
+
+ //CORE_RUN_CYCLES
+ //empath_scom_data = *scom_reg;
+ PPE_LVD(coreSelect + PC_OCC_SPRD, empath_scom_data);
+ o_data->empath.run_cycles = (uint32_t)empath_scom_data;
+
+ //CORE_WORKRATE_BUSY
+ //empath_scom_data = *scom_reg;
+ PPE_LVD(coreSelect + PC_OCC_SPRD, empath_scom_data);
+ o_data->empath.freq_sens_busy = (uint32_t)empath_scom_data;
- rc = getscom(coreSelect, THERM_DTS_RESULT, &(scom_data.value));
+ //CORE_WORKRATE_FINISH
+ //empath_scom_data = *scom_reg;
+ PPE_LVD(coreSelect + PC_OCC_SPRD, empath_scom_data);
+ o_data->empath.freq_sens_finish = (uint32_t)empath_scom_data;
- if(!rc)
+ //CORE_MEM_HIER_A_LATENCY
+ // empath_scom_data = *scom_reg;
+ PPE_LVD(coreSelect + PC_OCC_SPRD, empath_scom_data);
+ o_data->empath.mem_latency_a = (uint32_t)empath_scom_data;
+
+ //CORE_MEM_HIER_B_LATENCY
+ // empath_scom_data = *scom_reg;
+ PPE_LVD(coreSelect + PC_OCC_SPRD, empath_scom_data);
+ o_data->empath.mem_latency_b = (uint32_t)empath_scom_data;
+
+ //CORE_MEM_HIER_C_ACCESS
+ //empath_scom_data = *scom_reg;
+ PPE_LVD(coreSelect + PC_OCC_SPRD, empath_scom_data);
+ o_data->empath.mem_access_c = (uint32_t)empath_scom_data;
+
+ int thread = 0;
+
+ for( ; thread < EMPATH_CORE_THREADS; ++thread )
+ {
+ // THREAD_RUN_CYCLES
+ //empath_scom_data = *scom_reg;
+ PPE_LVD(coreSelect + PC_OCC_SPRD, empath_scom_data);
+ o_data->per_thread[thread].run_cycles = (uint32_t)empath_scom_data;
+
+ // THREAD_INST_DISP_UTIL
+ //empath_scom_data = *scom_reg;
+ PPE_LVD(coreSelect + PC_OCC_SPRD, empath_scom_data);
+ o_data->per_thread[thread].dispatch = (uint32_t)empath_scom_data;
+
+ // THREAD_INST_COMP_UTIL
+ //empath_scom_data = *scom_reg;
+ PPE_LVD(coreSelect + PC_OCC_SPRD, empath_scom_data);
+ o_data->per_thread[thread].completion = (uint32_t)empath_scom_data;
+
+ // THREAD_MEM_HEIR_C_ACCESS
+ //empath_scom_data = *scom_reg;
+ PPE_LVD(coreSelect + PC_OCC_SPRD, empath_scom_data);
+ o_data->per_thread[thread].mem_c = (uint32_t)empath_scom_data;
+ }
+
+ //IFU_THROTTLE_BLOCK_FETCH
+ //empath_scom_data = *scom_reg;
+ PPE_LVD(coreSelect + PC_OCC_SPRD, empath_scom_data);
+ o_data->throttle.ifu_throttle = (uint32_t)empath_scom_data;
+
+ //IFU_THROTTLE_ACTIVE
+ //empath_scom_data = *scom_reg;
+ PPE_LVD(coreSelect + PC_OCC_SPRD, empath_scom_data);
+ o_data->throttle.ifu_active = (uint32_t)empath_scom_data;
+
+ //VOLT_DROOP_THROTTLE_ACTIVE
+ //empath_scom_data = *scom_reg;
+ PPE_LVD(coreSelect + PC_OCC_SPRD, empath_scom_data);
+ o_data->throttle.v_droop = (uint32_t)empath_scom_data;
+
+ // TOD value
+ //scom_reg = (uint64_t*)TOD_VALUE_REG;
+ PPE_LVD(TOD_VALUE_REG, empath_scom_data);
+ //empath_scom_data = *scom_reg;
+ o_data->empath.tod_2mhz = (uint32_t)(empath_scom_data >> 8); //[24..56]
+
+ // Check rc accumulated - ignore rc == 0
+ uint32_t sibrca = (mfmsr() & 0x0000007f);
+
+ if(sibrca)
+ {
+ // Report most severe error in rc
+ rc = 7;
+ uint32_t mask = 1;
+
+ for(; mask != 0x00000080; mask <<= 1)
{
- o_data->dts.core[0].result = scom_data.half_words.reading[0];
- o_data->dts.core[1].result = scom_data.half_words.reading[1];
+ if( mask & sibrca )
+ {
+ break;
+ }
+
+ --rc;
}
}
+ // Clear masks SIB masks (MSR_SEM)
+ // Clear SIBRC and SIMBRCA
+ // Restore any SIB masks that may have been on before.
+ mtmsr((mfmsr() & ~(MSR_SEM | MSR_SIBRC | MSR_SIBRCA))
+ | (org_sem & MSR_SEM));
+
return rc;
}
OpenPOWER on IntegriCloud