diff options
author | Wael El-Essawy <welessa@us.ibm.com> | 2016-04-27 14:38:10 -0500 |
---|---|---|
committer | Wael El-Essawy <welessa@us.ibm.com> | 2016-05-03 18:23:13 -0400 |
commit | 8a7f3c6739f022df1c128b9d5a479e7abfac0ec1 (patch) | |
tree | dcecbff7b4739d6fd53566d7eab0848a4e36f6cf /src | |
parent | 0773d5a096886bd01a25ae28480a54b213179899 (diff) | |
download | talos-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.h | 93 | ||||
-rw-r--r-- | src/include/p9_config.h | 76 | ||||
-rw-r--r-- | src/occ_gpe0/core_data.c | 180 |
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; } |