diff options
author | William Bryan <wilbryan@us.ibm.com> | 2018-01-03 12:30:29 -0600 |
---|---|---|
committer | William A. Bryan <wilbryan@us.ibm.com> | 2018-03-27 11:57:42 -0400 |
commit | bd605ba0a030b3490f0edebd8fb704722b6eab0d (patch) | |
tree | 34fc7b10f06fef7baf9d101f78b816a6129753d8 | |
parent | c8538f3c894d5f28f688f7a081507c3ef14d6c24 (diff) | |
download | talos-occ-bd605ba0a030b3490f0edebd8fb704722b6eab0d.tar.gz talos-occ-bd605ba0a030b3490f0edebd8fb704722b6eab0d.zip |
Memory Throttle Sensors
RTC:131184
Change-Id: I2582a1eb9d599f700182f17047cc95accad03725
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/51407
Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com>
Reviewed-by: Andres A. Lugo-Reyes <aalugore@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/dimm_structs.h | 24 | ||||
-rw-r--r-- | src/common/mca_addresses.h | 64 | ||||
-rwxr-xr-x | src/occ_405/amec/amec_analytics.c | 6 | ||||
-rw-r--r-- | src/occ_405/amec/amec_init.c | 13 | ||||
-rw-r--r-- | src/occ_405/amec/amec_sensors_centaur.c | 6 | ||||
-rwxr-xr-x | src/occ_405/amec/amec_sys.h | 13 | ||||
-rwxr-xr-x | src/occ_405/dcom/dcom.h | 4 | ||||
-rw-r--r-- | src/occ_405/dimm/dimm_control.c | 58 | ||||
-rw-r--r-- | src/occ_405/mem/memory.c | 37 | ||||
-rwxr-xr-x | src/occ_405/rtls/rtls_tables.c | 14 | ||||
-rwxr-xr-x | src/occ_405/sensor/sensor_enum.h | 45 | ||||
-rwxr-xr-x | src/occ_405/sensor/sensor_info.c | 18 | ||||
-rw-r--r-- | src/occ_405/sensor/sensor_main_memory.c | 21 | ||||
-rwxr-xr-x | src/occ_405/sensor/sensor_table.c | 21 | ||||
-rwxr-xr-x | src/occ_405/thread/chom.c | 4 | ||||
-rwxr-xr-x | src/occ_405/timer/timer.c | 51 | ||||
-rw-r--r-- | src/occ_gpe1/gpe1_dimm_control.c | 54 |
17 files changed, 314 insertions, 139 deletions
diff --git a/src/common/dimm_structs.h b/src/common/dimm_structs.h index b6f11f9..3302845 100644 --- a/src/common/dimm_structs.h +++ b/src/common/dimm_structs.h @@ -1,11 +1,11 @@ /* IBM_PROLOG_BEGIN_TAG */ /* This is an automatically generated prolog. */ /* */ -/* $Source: src/dimm_structs.h $ */ +/* $Source: src/common/dimm_structs.h $ */ /* */ /* OpenPOWER OnChipController Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2016 */ +/* Contributors Listed Below - COPYRIGHT 2016,2018 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -77,6 +77,11 @@ typedef union }; } dimm_n_value_t; +typedef struct +{ + uint32_t m_value; + uint32_t need_m; +} dimm_m_value_t; typedef struct { @@ -84,13 +89,28 @@ typedef struct uint8_t mc; uint8_t port; dimm_n_value_t dimmNumeratorValues; + dimm_m_value_t dimmDenominatorValues; + uint32_t need_run; } dimm_control_args_t; +typedef struct +{ + uint32_t mba_read_cnt; + uint32_t mba_write_cnt; +} perf_mon_count0_t; + +typedef struct +{ + uint32_t med_idle_cnt; + uint32_t high_idle_cnt; +} perf_mon_counts_t; typedef struct { GpeErrorStruct error; uint8_t mca; + perf_mon_count0_t rd_wr_counts; + perf_mon_counts_t idle_counts; } reset_mem_deadman_args_t; #endif // _DIMM_STRUCTS_H diff --git a/src/common/mca_addresses.h b/src/common/mca_addresses.h index 0417419..d6eced3 100644 --- a/src/common/mca_addresses.h +++ b/src/common/mca_addresses.h @@ -5,7 +5,7 @@ /* */ /* OpenPOWER OnChipController Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2015,2017 */ +/* Contributors Listed Below - COPYRIGHT 2015,2018 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -31,32 +31,35 @@ #define NUM_NIMBUS_MCAS (MAX_NUM_MCU_PORTS * NUM_NIMBUS_MC_PAIRS) // Base Address of NIMBUS MCA. -#define DIMM_MCA_BASE_ADDRESS 0x07010800 +#define DIMM_MCA_BASE_ADDRESS 0x07010800 -#define MCA_MCPAIR_SPACE 0x01000000 -#define MCA_PORT_SPACE 0x40 -#define MC_PORT_SPACE(mc,port) ((MCA_MCPAIR_SPACE * (mc)) + ( MCA_PORT_SPACE * (port))) +#define MCA_MCPAIR_SPACE 0x01000000 +#define MCA_PORT_SPACE 0x40 +#define MC_PORT_SPACE(mc,port) ((MCA_MCPAIR_SPACE * (mc)) + ( MCA_PORT_SPACE * (port))) -#define POWER_CTRL_REG0_OFFSET 0x0134 -#define POWER_CTRL_REG0_ADDRESS (DIMM_MCA_BASE_ADDRESS + POWER_CTRL_REG0_OFFSET) +#define POWER_CTRL_REG0_OFFSET 0x0134 +#define POWER_CTRL_REG0_ADDRESS (DIMM_MCA_BASE_ADDRESS + POWER_CTRL_REG0_OFFSET) -#define STR_REG0_OFFSET 0x0135 -#define STR_REG0_ADDRESS (DIMM_MCA_BASE_ADDRESS + STR_REG0_OFFSET) +#define STR_REG0_OFFSET 0x0135 +#define STR_REG0_ADDRESS (DIMM_MCA_BASE_ADDRESS + STR_REG0_OFFSET) -#define N_M_TCR_OFFSET 0x0116 -#define N_M_TCR_ADDRESS (DIMM_MCA_BASE_ADDRESS + N_M_TCR_OFFSET) +#define PERF_MON_COUNTS0_OFFSET 0x0137 +#define PERF_MON_COUNTS0_ADDRESS (DIMM_MCA_BASE_ADDRESS + PERF_MON_COUNTS0_OFFSET) -#define DEADMAN_TIMER_OFFSET 0x013C -#define DEADMAN_TIMER_ADDRESS (DIMM_MCA_BASE_ADDRESS + DEADMAN_TIMER_OFFSET) +#define N_M_TCR_OFFSET 0x0116 +#define N_M_TCR_ADDRESS (DIMM_MCA_BASE_ADDRESS + N_M_TCR_OFFSET) -#define EMERGENCY_THROTTLE_OFFSET 0x0125 -#define EMERGENCY_THROTTLE_ADDRESS (DIMM_MCA_BASE_ADDRESS + EMERGENCY_THROTTLE_OFFSET) -#define ER_THROTTLE_IN_PROGRESS_MASK 0x8000000000000000 +#define PERF_MON_COUNTS_IDLE_OFFSET 0x013C +#define PERF_MON_COUNTS_IDLE_ADDRESS (DIMM_MCA_BASE_ADDRESS + PERF_MON_COUNTS_IDLE_OFFSET) -#define MCA_CAL_FIR_OFFSET 0x0100 -#define MCA_CAL_FIR_ADDRESS (DIMM_MCA_BASE_ADDRESS + MCA_CAL_FIR_OFFSET) -#define MCA_FIR_THROTTLE_ENGAGED_MASK 0x0200000000000000 +#define EMERGENCY_THROTTLE_OFFSET 0x0125 +#define EMERGENCY_THROTTLE_ADDRESS (DIMM_MCA_BASE_ADDRESS + EMERGENCY_THROTTLE_OFFSET) +#define ER_THROTTLE_IN_PROGRESS_MASK 0x8000000000000000 + +#define MCA_CAL_FIR_OFFSET 0x0100 +#define MCA_CAL_FIR_ADDRESS (DIMM_MCA_BASE_ADDRESS + MCA_CAL_FIR_OFFSET) +#define MCA_FIR_THROTTLE_ENGAGED_MASK 0x0200000000000000 // Memory Power Control @@ -101,7 +104,7 @@ mc23.port3 0x080108C0 + 0x00000116 = 0x080109D6 #define N_M_DIMM_TCR(mc,port) (N_M_TCR_ADDRESS + MC_PORT_SPACE(mc,port)) /* -MC/Port Address MCA Port Address Deadman Offset SCOM Address +MC/Port Address MCA Port Address "Deadman" Offset SCOM Address mc01.port0 0x07010800 + 0x0000013C = 0x0701093C mc01.port1 0x07010840 + 0x0000013C = 0x0701097C mc01.port2 0x07010880 + 0x0000013C = 0x070109BC @@ -112,8 +115,25 @@ mc23.port2 0x08010880 + 0x0000013C = 0x080109BC mc23.port3 0x080108C0 + 0x0000013C = 0x080109FC */ -// NIMBUS DIMM Deadman SCOM Register Addresses macro -#define DEADMAN_TIMER_MCA(mca) (DEADMAN_TIMER_ADDRESS + MC_PORT_SPACE((mca>>2),(mca&3))) +// NIMBUS DIMM Performance Monitor -- Idle Threshold Counter +// This register effectively acts as a deadman register. +// Reading it will reset the deadman counter. +#define PERF_MON_COUNTS_IDLE_MCA(mca) (PERF_MON_COUNTS_IDLE_ADDRESS + MC_PORT_SPACE((mca>>2),(mca&3))) + +/* +MC/Port Address MCA Port Address "Deadman" Offset SCOM Address +mc01.port0 0x07010800 + 0x00000137 = 0x07010937 +mc01.port1 0x07010840 + 0x00000137 = 0x07010977 +mc01.port2 0x07010880 + 0x00000137 = 0x070109B7 +mc01.port3 0x070108C0 + 0x00000137 = 0x070109F7 +mc23.port0 0x08010800 + 0x00000137 = 0x08010937 +mc23.port1 0x08010840 + 0x00000137 = 0x08010977 +mc23.port2 0x08010880 + 0x00000137 = 0x080109B7 +mc23.port3 0x080108C0 + 0x00000137 = 0x080109F7 + */ + +// NIMBUS DIMM Performance Monitor -- Read/Write Count +#define PERF_MON_COUNTS0_MCA(mca) (PERF_MON_COUNTS0_ADDRESS + MC_PORT_SPACE((mca>>2),(mca&3))) // Emergency Mode Throttle Register /* diff --git a/src/occ_405/amec/amec_analytics.c b/src/occ_405/amec/amec_analytics.c index 9cca40d..d715a72 100755 --- a/src/occ_405/amec/amec_analytics.c +++ b/src/occ_405/amec/amec_analytics.c @@ -5,7 +5,7 @@ /* */ /* OpenPOWER OnChipController Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2011,2016 */ +/* Contributors Listed Below - COPYRIGHT 2011,2018 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -307,13 +307,13 @@ void amec_analytics_main(void) for (j=0; j<8; j++) // Group 45 supports all 8 Centaurs per OCC { g_amec->g44_avg[(i*MSA)+l] = g_amec->g44_avg[(i*MSA)+l] + - (UINT32)(g_amec->proc[i].memctl[j].mrd2ms.sample/78); // memory read bandwidth + (UINT32)(g_amec->proc[i].memctl[j].mrd.sample/78); // memory read bandwidth l=l+1; } for (j=0; j<8; j++) // Group 45 supports all 8 Centaurs per OCC { g_amec->g44_avg[(i*MSA)+l] = g_amec->g44_avg[(i*MSA)+l] + - (UINT32)(g_amec->proc[i].memctl[j].mwr2ms.sample/78); // memory write bandwidth + (UINT32)(g_amec->proc[i].memctl[j].mwr.sample/78); // memory write bandwidth l=l+1; } diff --git a/src/occ_405/amec/amec_init.c b/src/occ_405/amec/amec_init.c index 9f57117..3d82ac0 100644 --- a/src/occ_405/amec/amec_init.c +++ b/src/occ_405/amec/amec_init.c @@ -5,7 +5,7 @@ /* */ /* OpenPOWER OnChipController Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2011,2017 */ +/* Contributors Listed Below - COPYRIGHT 2011,2018 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -229,7 +229,7 @@ void amec_init_gamec_struct(void) /* Local Variables */ /*------------------------------------------------------------------------*/ uint16_t l_idx = 0; - + uint16_t l_idx2 = 0; /*------------------------------------------------------------------------*/ /* Code */ /*------------------------------------------------------------------------*/ @@ -344,6 +344,15 @@ void amec_init_gamec_struct(void) // Initialize to no VRM faults g_amec->sys.vrm_fault_status = 0; + // Initialize saying we need the M value + for(l_idx=0; l_idx < NUM_NIMBUS_MC_PAIRS; l_idx++) + { + for(l_idx2=0; l_idx2 < MAX_NUM_MCU_PORTS; l_idx2++) + { + g_amec->sys.dimm_m_values[l_idx][l_idx2].need_m = TRUE; + } + } + // Initialize wof_disabled g_amec->wof.wof_disabled = WOF_RC_OCC_WOF_DISABLED; diff --git a/src/occ_405/amec/amec_sensors_centaur.c b/src/occ_405/amec/amec_sensors_centaur.c index 9749a3f..8cd50c3 100644 --- a/src/occ_405/amec/amec_sensors_centaur.c +++ b/src/occ_405/amec/amec_sensors_centaur.c @@ -5,7 +5,7 @@ /* */ /* OpenPOWER OnChipController Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2011,2017 */ +/* Contributors Listed Below - COPYRIGHT 2011,2018 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -472,7 +472,7 @@ void amec_perfcount_getmc( MemData * i_sensor_cache, // --------------------------------------------------------------------------- // Extract write bandwidth - temp32new = (templ); // left shift into top 20 bits of 32 bits + temp32new = (templ); temp32 = temp32new - g_amec->proc[0].memctl[i_centaur].centaur.portpair[i_mc_id].perf.wr_cnt_accum; g_amec->proc[0].memctl[i_centaur].centaur.portpair[i_mc_id].perf.wr_cnt_accum = temp32new; // Save latest accumulator away for next time @@ -487,7 +487,7 @@ void amec_perfcount_getmc( MemData * i_sensor_cache, // ------------------------------------------------------------------------- // Extract read bandwidth - temp32new = (tempu); // left shift into top 20 bits of 32 bits + temp32new = (tempu); temp32 = temp32new - g_amec->proc[0].memctl[i_centaur].centaur.portpair[i_mc_id].perf.rd_cnt_accum; g_amec->proc[0].memctl[i_centaur].centaur.portpair[i_mc_id].perf.rd_cnt_accum = temp32new; // Save latest accumulator away for next time diff --git a/src/occ_405/amec/amec_sys.h b/src/occ_405/amec/amec_sys.h index bcb11b8..95260d6 100755 --- a/src/occ_405/amec/amec_sys.h +++ b/src/occ_405/amec/amec_sys.h @@ -5,7 +5,7 @@ /* */ /* OpenPOWER OnChipController Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2011,2017 */ +/* Contributors Listed Below - COPYRIGHT 2011,2018 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -254,9 +254,11 @@ typedef struct // Sub-structures under MemCtl amec_centaur_t centaur; - // Sensors - sensor_t mrd2ms; - sensor_t mwr2ms; + // Performance Sensors + sensor_t mrd; + sensor_t mwr; + sensor_t memspstat; + sensor_t memsp; } amec_memctl_t; @@ -390,6 +392,9 @@ typedef struct // Memory Throttle Sent Last time to DIMM Throttle Register dimm_n_value_t current_dimm_n_values[NUM_NIMBUS_MC_PAIRS][MAX_NUM_MCU_PORTS]; + // M Values for NM Throttling Control (counts DRAM clock cycles) + dimm_m_value_t dimm_m_values[NUM_NIMBUS_MC_PAIRS][MAX_NUM_MCU_PORTS]; + // Current Memory Power Control values (applied last through GPE1) uint8_t current_mem_pwr_ctl; diff --git a/src/occ_405/dcom/dcom.h b/src/occ_405/dcom/dcom.h index 7235b5c..c5ffc16 100755 --- a/src/occ_405/dcom/dcom.h +++ b/src/occ_405/dcom/dcom.h @@ -215,8 +215,8 @@ typedef struct __attribute__ ((packed)) uint16_t utilcy[MAX_CORES]; // [176] uint16_t tempvdd; // [224] uint16_t reserved2; // [226] - uint16_t mrd2msp0mx[MAX_NUM_MEM_CONTROLLERS]; // [228] - uint16_t mwr2msp0mx[MAX_NUM_MEM_CONTROLLERS]; // [244] + uint16_t mrd[MAX_NUM_MEM_CONTROLLERS]; // [228] + uint16_t mwr[MAX_NUM_MEM_CONTROLLERS]; // [244] uint16_t coreReserved[MAX_CORES]; // [260] uint16_t todclock[NUM_TOD_SENSORS]; // [308] uint16_t temp2mscent; // [314] diff --git a/src/occ_405/dimm/dimm_control.c b/src/occ_405/dimm/dimm_control.c index 6bdb94f..934513f 100644 --- a/src/occ_405/dimm/dimm_control.c +++ b/src/occ_405/dimm/dimm_control.c @@ -79,16 +79,49 @@ bool dimm_control(uint8_t mc, uint8_t port) // GPE1 G_dimm_control_args.dimmNumeratorValues struct // and populate G_dimm_control_args.mc/port values // corresponding to dimm to be throttled. - G_dimm_control_args.dimmNumeratorValues.new_n = FALSE; // Reset New N Value Flag prior to calling + + // Reset New N Value Flag prior to calling + G_dimm_control_args.dimmNumeratorValues.new_n = FALSE; populate_dimm_control_args(g_amec->mem_speed_request, mc, port, &G_dimm_control_args); + // Only need to update the static throttle sensors once + static bool L_mem_static_throttle_update[NUM_NIMBUS_MC_PAIRS][MAX_NUM_MCU_PORTS] = {{0}}; + + // Update memory throttle sensors + if( (g_amec->sys.dimm_m_values[mc][port].need_m != TRUE) && + (g_amec->sys.dimm_m_values[mc][port].m_value != 0) ) + { + uint32_t l_nm_val, l_sensor_offset = 0; + l_sensor_offset = (mc * MAX_NUM_MCU_PORTS) + port; + + // Update current memory throttle + l_nm_val = g_amec->sys.current_dimm_n_values[mc][port].slot_n * 4000; + l_nm_val /= g_amec->sys.dimm_m_values[mc][port].m_value; + + sensor_update( AMECSENSOR_ARRAY_PTR(MEMSPM0,l_sensor_offset), l_nm_val); + + if(!L_mem_static_throttle_update[mc][port]) + { + // Update static memory throttle + l_nm_val = G_sysConfigData.mem_throt_limits[mc][port].nom_n_per_mba * 4000; + l_nm_val /= g_amec->sys.dimm_m_values[mc][port].m_value; + + sensor_update( AMECSENSOR_ARRAY_PTR(MEMSPSTATM0,l_sensor_offset), l_nm_val); + + L_mem_static_throttle_update[mc][port] = TRUE; + } + } + // 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(G_dimm_control_args.dimmNumeratorValues.new_n) + if(G_dimm_control_args.need_run) { - DIMM_DBG("dimm throttle control changed: MC=%d. port=%d , Throttle=%d", - mc, port, g_amec->mem_speed_request); + if(G_dimm_control_args.dimmNumeratorValues.new_n) + { + DIMM_DBG("dimm throttle control changed: MC=%d. port=%d , Throttle=%d", + mc, port, g_amec->mem_speed_request); + } return TRUE; } @@ -197,7 +230,6 @@ void dimm_update_nlimits(uint8_t mc, uint8_t port) // Thread: RTL // // End Function Specification - #define DIMM_THROTTLE_100_PERCENT_VALUE 1000 void populate_dimm_control_args(uint16_t i_throttle, uint8_t mc, uint8_t port, dimm_control_args_t * dimm_control_args) @@ -226,9 +258,23 @@ void populate_dimm_control_args(uint16_t i_throttle, uint8_t mc, uint8_t port, dimm_control_args->dimmNumeratorValues.word32 = dimm_nvalue.word32; g_amec->sys.current_dimm_n_values[mc][port].word32 = dimm_nvalue.word32; - dimm_control_args->dimmNumeratorValues.new_n = 1; + dimm_control_args->dimmNumeratorValues.new_n = TRUE; + } + + // Indicate if we need the M value + dimm_control_args->dimmDenominatorValues.need_m = + g_amec->sys.dimm_m_values[mc][port].need_m; + + if(dimm_control_args->dimmDenominatorValues.need_m || + dimm_control_args->dimmNumeratorValues.new_n) + { dimm_control_args->mc = mc; dimm_control_args->port = port; + dimm_control_args->need_run = TRUE; + } + else + { + dimm_control_args->need_run = FALSE; } } } diff --git a/src/occ_405/mem/memory.c b/src/occ_405/mem/memory.c index bf739f4..4f0e9c6 100644 --- a/src/occ_405/mem/memory.c +++ b/src/occ_405/mem/memory.c @@ -5,7 +5,7 @@ /* */ /* OpenPOWER OnChipController Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2014,2017 */ +/* Contributors Listed Below - COPYRIGHT 2014,2018 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -33,6 +33,7 @@ #include "centaur_data.h" #include "memory_service_codes.h" #include <occ_service_codes.h> // for SSX_GENERIC_FAILURE +#include "amec_sys.h" extern bool G_mem_monitoring_allowed; extern dimm_control_args_t G_dimm_control_args; @@ -50,17 +51,7 @@ extern task_t G_task_table[TASK_END]; // // For Cumulus systems, only the first two columns (corresponding to the two mba // pairs mba01 and mba23) are used. -memory_throttle_t G_memoryThrottleLimits[MAX_NUM_MEM_CONTROLLERS][MAX_NUM_MCU_PORTS] = -{ - {{0}, {0}, {0}, {0}}, - {{0}, {0}, {0}, {0}}, - {{0}, {0}, {0}, {0}}, - {{0}, {0}, {0}, {0}}, - {{0}, {0}, {0}, {0}}, - {{0}, {0}, {0}, {0}}, - {{0}, {0}, {0}, {0}}, - {{0}, {0}, {0}, {0}} -}; +memory_throttle_t G_memoryThrottleLimits[MAX_NUM_MEM_CONTROLLERS][MAX_NUM_MCU_PORTS] = {{{0}}}; //Memory structure used for task data pointers in both Cumulus (Centaur) //and Nimbus (RDIMM) systems. @@ -102,6 +93,9 @@ void task_memory_control( task_t * i_task ) uint32_t gpe_rc = 0; + uint8_t mc = 0; + uint8_t port = 0; + // Pointer to the task data structure memory_control_task_t* memControlTask = (memory_control_task_t*) i_task->data_ptr; @@ -119,6 +113,8 @@ void task_memory_control( task_t * i_task ) do { memIndex = memControlTask->curMemIndex; + mc = memIndex>>2; + port = memIndex&3; //First, check to see if the previous GPE request still running //A request is considered idle if it is not attached to any of the @@ -177,13 +173,21 @@ void task_memory_control( task_t * i_task ) { //request completed successfully. reset the timeout. L_scom_timeout[memIndex] = 0; + + // Store M value if needed + if(G_dimm_control_args.dimmDenominatorValues.need_m) + { + g_amec->sys.dimm_m_values[mc][port].m_value = + G_dimm_control_args.dimmDenominatorValues.m_value; + g_amec->sys.dimm_m_values[mc][port].need_m = FALSE; + TRAC_INFO("M Value for MC%d P%d is 0x%08X", mc, port, g_amec->sys.dimm_m_values[mc][port].m_value); + } } }//if(L_gpe_scheduled) - //The previous GPE job completed. Now get ready for the next job. + //The previous GPE job completed, get ready for the next job. L_gpe_scheduled = FALSE; - //Update current dimm/centaur index if we didn't fail memControlTask->prevMemIndex = memIndex; if ( memIndex >= memControlTask->endMemIndex ) @@ -196,7 +200,6 @@ void task_memory_control( task_t * i_task ) } memControlTask->curMemIndex = memIndex; - if (MEM_TYPE_NIMBUS == G_sysConfigData.mem_type) { if(!NIMBUS_DIMM_INDEX_THROTTLING_CONFIGURED(memIndex)) @@ -205,8 +208,8 @@ void task_memory_control( task_t * i_task ) } // control dimm specified by mc,port - uint8_t mc = memIndex>>2; - uint8_t port = memIndex&3; + mc = memIndex>>2; + port = memIndex&3; // Do the update_nlimit, calculate new N values, check whether throttle values // were updated, then Schedule GPE request, rc if problem, else L_gpe_schedule diff --git a/src/occ_405/rtls/rtls_tables.c b/src/occ_405/rtls/rtls_tables.c index 9d1f18e..5c880e9 100755 --- a/src/occ_405/rtls/rtls_tables.c +++ b/src/occ_405/rtls/rtls_tables.c @@ -5,7 +5,7 @@ /* */ /* OpenPOWER OnChipController Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2011,2017 */ +/* Contributors Listed Below - COPYRIGHT 2011,2018 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -143,6 +143,7 @@ const uint8_t G_tick0_seq[] = { TASK_ID_MEMORY_CONTROL, TASK_ID_CORE_DATA_CONTROL, TASK_ID_24X7, + TASK_ID_POKE_WDT, TASK_ID_GPE_TIMINGS, TASK_ID_DCOM_WAIT_4_MSTR, TASK_ID_DCOM_RX_INBX, @@ -190,6 +191,7 @@ const uint8_t G_tick2_seq[] = { TASK_ID_MEMORY_CONTROL, TASK_ID_CORE_DATA_CONTROL, TASK_ID_24X7, + TASK_ID_POKE_WDT, TASK_ID_GPE_TIMINGS, TASK_ID_DCOM_WAIT_4_MSTR, TASK_ID_DCOM_RX_INBX, @@ -213,6 +215,7 @@ const uint8_t G_tick3_seq[] = { TASK_ID_MEMORY_CONTROL, TASK_ID_CORE_DATA_CONTROL, TASK_ID_24X7, + TASK_ID_POKE_WDT, TASK_ID_GPE_TIMINGS, TASK_ID_DCOM_WAIT_4_MSTR, TASK_ID_DCOM_RX_INBX, @@ -237,6 +240,7 @@ const uint8_t G_tick4_seq[] = { TASK_ID_MEMORY_CONTROL, TASK_ID_CORE_DATA_CONTROL, TASK_ID_24X7, + TASK_ID_POKE_WDT, TASK_ID_GPE_TIMINGS, TASK_ID_DCOM_WAIT_4_MSTR, TASK_ID_DCOM_RX_INBX, @@ -284,6 +288,7 @@ const uint8_t G_tick6_seq[] = { TASK_ID_MEMORY_CONTROL, TASK_ID_CORE_DATA_CONTROL, TASK_ID_24X7, + TASK_ID_POKE_WDT, TASK_ID_GPE_TIMINGS, TASK_ID_DCOM_WAIT_4_MSTR, TASK_ID_DCOM_RX_INBX, @@ -306,6 +311,7 @@ const uint8_t G_tick7_seq[] = { TASK_ID_MEMORY_CONTROL, TASK_ID_CORE_DATA_CONTROL, TASK_ID_24X7, + TASK_ID_POKE_WDT, TASK_ID_GPE_TIMINGS, TASK_ID_DCOM_WAIT_4_MSTR, TASK_ID_DCOM_RX_INBX, @@ -330,6 +336,7 @@ const uint8_t G_tick8_seq[] = { TASK_ID_MEMORY_CONTROL, TASK_ID_CORE_DATA_CONTROL, TASK_ID_24X7, + TASK_ID_POKE_WDT, TASK_ID_GPE_TIMINGS, TASK_ID_DCOM_WAIT_4_MSTR, TASK_ID_DCOM_RX_INBX, @@ -377,6 +384,7 @@ const uint8_t G_tick10_seq[] = { TASK_ID_MEMORY_CONTROL, TASK_ID_CORE_DATA_CONTROL, TASK_ID_24X7, + TASK_ID_POKE_WDT, TASK_ID_GPE_TIMINGS, TASK_ID_DCOM_WAIT_4_MSTR, TASK_ID_DCOM_RX_INBX, @@ -399,6 +407,7 @@ const uint8_t G_tick11_seq[] = { TASK_ID_MEMORY_CONTROL, TASK_ID_CORE_DATA_CONTROL, TASK_ID_24X7, + TASK_ID_POKE_WDT, TASK_ID_GPE_TIMINGS, TASK_ID_DCOM_WAIT_4_MSTR, TASK_ID_DCOM_RX_INBX, @@ -423,6 +432,7 @@ const uint8_t G_tick12_seq[] = { TASK_ID_MEMORY_CONTROL, TASK_ID_CORE_DATA_CONTROL, TASK_ID_24X7, + TASK_ID_POKE_WDT, TASK_ID_GPE_TIMINGS, TASK_ID_DCOM_WAIT_4_MSTR, TASK_ID_DCOM_RX_INBX, @@ -470,6 +480,7 @@ const uint8_t G_tick14_seq[] = { TASK_ID_MEMORY_CONTROL, TASK_ID_CORE_DATA_CONTROL, TASK_ID_24X7, + TASK_ID_POKE_WDT, TASK_ID_GPE_TIMINGS, TASK_ID_DCOM_WAIT_4_MSTR, TASK_ID_DCOM_RX_INBX, @@ -492,6 +503,7 @@ const uint8_t G_tick15_seq[] = { TASK_ID_MEMORY_CONTROL, TASK_ID_CORE_DATA_CONTROL, TASK_ID_24X7, + TASK_ID_POKE_WDT, TASK_ID_GPE_TIMINGS, TASK_ID_DCOM_WAIT_4_MSTR, TASK_ID_DCOM_RX_INBX, diff --git a/src/occ_405/sensor/sensor_enum.h b/src/occ_405/sensor/sensor_enum.h index 433530e..51439b1 100755 --- a/src/occ_405/sensor/sensor_enum.h +++ b/src/occ_405/sensor/sensor_enum.h @@ -5,7 +5,7 @@ /* */ /* OpenPOWER OnChipController Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2011,2017 */ +/* Contributors Listed Below - COPYRIGHT 2011,2018 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -351,31 +351,6 @@ enum e_gsid NUTILC22, NUTILC23, - MSTLC0, - MSTLC1, - MSTLC2, - MSTLC3, - MSTLC4, - MSTLC5, - MSTLC6, - MSTLC7, - MSTLC8, - MSTLC9, - MSTLC10, - MSTLC11, - MSTLC12, - MSTLC13, - MSTLC14, - MSTLC15, - MSTLC16, - MSTLC17, - MSTLC18, - MSTLC19, - MSTLC20, - MSTLC21, - MSTLC22, - MSTLC23, - TEMPC0, TEMPC1, TEMPC2, @@ -497,6 +472,24 @@ enum e_gsid MWRM6, MWRM7, + MEMSPM0, + MEMSPM1, + MEMSPM2, + MEMSPM3, + MEMSPM4, + MEMSPM5, + MEMSPM6, + MEMSPM7, + + MEMSPSTATM0, + MEMSPSTATM1, + MEMSPSTATM2, + MEMSPSTATM3, + MEMSPSTATM4, + MEMSPSTATM5, + MEMSPSTATM6, + MEMSPSTATM7, + MIRCM0, MIRCM1, MIRCM2, diff --git a/src/occ_405/sensor/sensor_info.c b/src/occ_405/sensor/sensor_info.c index 06f3ff1..98d6b1a 100755 --- a/src/occ_405/sensor/sensor_info.c +++ b/src/occ_405/sensor/sensor_info.c @@ -5,7 +5,7 @@ /* */ /* OpenPOWER OnChipController Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2011,2017 */ +/* Contributors Listed Below - COPYRIGHT 2011,2018 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -65,21 +65,17 @@ [sensor_name] = {.name = #sensor_name, \ .sensor = { units, type, location, number, frequency, scaleFactor },} -// This will paste a number onto a sensor name base to create the full enum +// These will paste a number onto a sensor name base to create the full enum // representation of the sensor name #define SENSOR_W_NUM(sensor_name, num) sensor_name##num -// This will paste a number onto a sensor name base to create the full enum -// representation of the sensor name #define SENSOR_W_CENTAUR_NUM_HELPER(sensor_name, memc,centL,cent,ppL,pp) sensor_name##memc##centL##cent##ppL##pp #define SENSOR_W_CENTAUR_NUM(sensor_name, memc,cent,pp) SENSOR_W_CENTAUR_NUM_HELPER(sensor_name,memc,C,cent,P,pp) -// This will stringify the enum so to create the sensor name. This will help +// These will stringify the enum so to create the sensor name. This will help // save keystrokes, as well as reduce typos & copy paste errors. #define SENSOR_STRING(sensor_name) #sensor_name -// This will stringify the enum so to create the sensor name. This will help -// save keystrokes, as well as reduce typos & copy paste errors. #define CENTAUR_SENSOR_STRING_HELPER(sensor_name, memc,centL,cent,ppL,pp) SENSOR_STRING(sensor_name##memc##centL##cent##ppL##pp) #define CENTAUR_SENSOR_STRING(sensor_name,memc,cent,pp) CENTAUR_SENSOR_STRING_HELPER(sensor_name, memc,C,cent,P,pp) @@ -175,7 +171,6 @@ [SENSOR_W_NUM(sensor_name,7)] = {.name = SENSOR_STRING(sensor_name ## 7), \ .sensor = { units, type, location, number, frequency, scaleFactor },} - // This will create a set of 16 sensor entries into the sensor list table. // (one for each DIMM...) The base name of the sensor enum must be passed // and this macro will take care of the paste & stringify operations. @@ -351,15 +346,16 @@ const sensor_info_t G_sensor_info[] = SENS_CORE_ENTRY_SET( TEMPPROCTHRMC, "C\0", AMEC_SENSOR_TYPE_TEMP, AMEC_SENSOR_LOC_CORE, AMEC_SENSOR_NONUM, AMEEFP_EVERY_16TH_TICK_HZ, AMEFP( 1, 0) ), SENS_CORE_ENTRY_SET( UTILC, "%\0", AMEC_SENSOR_TYPE_UTIL, AMEC_SENSOR_LOC_CORE, AMEC_SENSOR_NONUM, AMEEFP_EVERY_16TH_TICK_HZ, AMEFP( 1,-2) ), SENS_CORE_ENTRY_SET( NUTILC, "%\0", AMEC_SENSOR_TYPE_UTIL, AMEC_SENSOR_LOC_CORE, AMEC_SENSOR_NONUM, AMEEFP_3S_IN_HZ, AMEFP( 1,-2) ), - SENS_CORE_ENTRY_SET( MSTLC, "cpi\0", AMEC_SENSOR_TYPE_PERF, AMEC_SENSOR_LOC_CORE, AMEC_SENSOR_NONUM, AMEEFP_EVERY_8TH_TICK_HZ, AMEFP( 1, 0) ), SENS_CORE_ENTRY_SET( TEMPC, "C\0", AMEC_SENSOR_TYPE_TEMP, AMEC_SENSOR_LOC_CORE, AMEC_SENSOR_NONUM, AMEEFP_EVERY_16TH_TICK_HZ, AMEFP( 1, 0) ), SENS_CORE_ENTRY_SET( STOPDEEPREQC, "ss\0", AMEC_SENSOR_TYPE_PERF, AMEC_SENSOR_LOC_CORE, AMEC_SENSOR_NONUM, AMEEFP_EVERY_16TH_TICK_HZ, AMEFP( 1, 0) ), SENS_CORE_ENTRY_SET( STOPDEEPACTC, "ss\0", AMEC_SENSOR_TYPE_PERF, AMEC_SENSOR_LOC_CORE, AMEC_SENSOR_NONUM, AMEEFP_EVERY_16TH_TICK_HZ, AMEFP( 1, 0) ), SENS_CORE_ENTRY_SET( VOLTDROOPCNTC, "#\0",AMEC_SENSOR_TYPE_VOLTAGE, AMEC_SENSOR_LOC_CORE, AMEC_SENSOR_NONUM, AMEEFP_EVERY_16TH_TICK_HZ, AMEFP( 1, 0) ), /* ==MemSensors== NameString Units Type Location Number Freq ScaleFactor */ - SENS_MEMC_ENTRY_SET( MRDM, "GBs\0", AMEC_SENSOR_TYPE_PERF, AMEC_SENSOR_LOC_MEM, AMEC_SENSOR_NONUM, AMEEFP_EVERY_8TH_TICK_HZ, AMEFP( 128, -5) ), - SENS_MEMC_ENTRY_SET( MWRM, "GBs\0", AMEC_SENSOR_TYPE_PERF, AMEC_SENSOR_LOC_MEM, AMEC_SENSOR_NONUM, AMEEFP_EVERY_8TH_TICK_HZ, AMEFP( 128, -5) ), + SENS_MEMC_ENTRY_SET( MRDM, "GBs\0", AMEC_SENSOR_TYPE_PERF, AMEC_SENSOR_LOC_MEM, AMEC_SENSOR_NONUM, AMEEFP_EVERY_8TH_TICK_HZ, AMEFP( 64, -5) ), + SENS_MEMC_ENTRY_SET( MWRM, "GBs\0", AMEC_SENSOR_TYPE_PERF, AMEC_SENSOR_LOC_MEM, AMEC_SENSOR_NONUM, AMEEFP_EVERY_8TH_TICK_HZ, AMEFP( 64, -5) ), + SENS_MEMC_ENTRY_SET( MEMSPM, "%\0", AMEC_SENSOR_TYPE_UTIL, AMEC_SENSOR_LOC_MEM, AMEC_SENSOR_NONUM, AMEEFP_EVERY_8TH_TICK_HZ, AMEFP( 1, -1) ), + SENS_MEMC_ENTRY_SET( MEMSPSTATM, "%\0", AMEC_SENSOR_TYPE_UTIL, AMEC_SENSOR_LOC_MEM, AMEC_SENSOR_NONUM, AMEEFP_EVERY_8TH_TICK_HZ, AMEFP( 1, -1) ), SENS_MEMC_ENTRY_SET( MIRCM, "eps\0", AMEC_SENSOR_TYPE_PERF, AMEC_SENSOR_LOC_MEM, AMEC_SENSOR_NONUM, AMEEFP_EVERY_8TH_TICK_HZ, AMEFP( 1, 0) ), SENS_MEMC_ENTRY_SET( MLP2M, "eps\0", AMEC_SENSOR_TYPE_PERF, AMEC_SENSOR_LOC_MEM, AMEC_SENSOR_NONUM, AMEEFP_EVERY_8TH_TICK_HZ, AMEFP( 1, 0) ), SENS_DIMM_ENTRY_SET( TEMPDIMM, "C\0", AMEC_SENSOR_TYPE_TEMP, AMEC_SENSOR_LOC_MEM, AMEC_SENSOR_NONUM, AMEEFP_EVERY_128TH_TICK_HZ, AMEFP( 1, 0) ), diff --git a/src/occ_405/sensor/sensor_main_memory.c b/src/occ_405/sensor/sensor_main_memory.c index d0fa338..41b8d6c 100644 --- a/src/occ_405/sensor/sensor_main_memory.c +++ b/src/occ_405/sensor/sensor_main_memory.c @@ -5,7 +5,7 @@ /* */ /* OpenPOWER OnChipController Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2017,2017 */ +/* Contributors Listed Below - COPYRIGHT 2017,2018 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -134,6 +134,19 @@ typedef struct __attribute__ ((packed)) MAIN_MEM_SENSOR(gsid_prefix##15 , smf_mode, master_only) /** + * Macro to build main_mem_sensor_t instances for all memory controllers. + */ +#define MAIN_MEM_MEMORY_SENSORS(gsid_prefix, smf_mode, master_only) \ + MAIN_MEM_SENSOR(gsid_prefix##0 , smf_mode, master_only) , \ + MAIN_MEM_SENSOR(gsid_prefix##1 , smf_mode, master_only) , \ + MAIN_MEM_SENSOR(gsid_prefix##2 , smf_mode, master_only) , \ + MAIN_MEM_SENSOR(gsid_prefix##3 , smf_mode, master_only) , \ + MAIN_MEM_SENSOR(gsid_prefix##4 , smf_mode, master_only) , \ + MAIN_MEM_SENSOR(gsid_prefix##5 , smf_mode, master_only) , \ + MAIN_MEM_SENSOR(gsid_prefix##6 , smf_mode, master_only) , \ + MAIN_MEM_SENSOR(gsid_prefix##7 , smf_mode, master_only) + +/** * Macro to build main_mem_sensor_t instances for all APSS channels. */ #define MAIN_MEM_APSSCH_SENSORS(gsid_prefix, smf_mode, master_only) \ @@ -222,7 +235,11 @@ main_mem_sensor_t G_main_mem_sensors[] = MAIN_MEM_SENSOR (PROCPWRTHROT, false, false), MAIN_MEM_SENSOR (PROCOTTHROT, false, false), MAIN_MEM_SENSOR (MEMPWRTHROT, false, false), - MAIN_MEM_SENSOR (MEMOTTHROT, false, false) + MAIN_MEM_SENSOR (MEMOTTHROT, false, false), + MAIN_MEM_MEMORY_SENSORS (MRDM, false, false), + MAIN_MEM_MEMORY_SENSORS (MWRM, false, false), + MAIN_MEM_MEMORY_SENSORS (MEMSPSTATM, true, false), + MAIN_MEM_MEMORY_SENSORS (MEMSPM, false, false), }; /** diff --git a/src/occ_405/sensor/sensor_table.c b/src/occ_405/sensor/sensor_table.c index 9538958..ed21237 100755 --- a/src/occ_405/sensor/sensor_table.c +++ b/src/occ_405/sensor/sensor_table.c @@ -5,7 +5,7 @@ /* */ /* OpenPOWER OnChipController Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2011,2017 */ +/* Contributors Listed Below - COPYRIGHT 2011,2018 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -38,7 +38,7 @@ extern amec_sys_t g_amec_sys; // Will paste number onto enum 'sensor base name' #define SENSOR_W_NUM(sensor,num) sensor##num -// This will paste a number onto a sensor name base to create the full enum +// These will paste a number onto a sensor name base to create the full enum // representation of the sensor name #define SENSOR_W_CENTAUR_NUM_HELPER(sensor_name, memc,centL,cent,ppL,pp) sensor_name##memc##centL##cent##ppL##pp #define SENSOR_W_CENTAUR_NUM(sensor_name, memc,cent,pp) SENSOR_W_CENTAUR_NUM_HELPER(sensor_name,memc,C,cent,P,pp) @@ -115,7 +115,7 @@ extern amec_sys_t g_amec_sys; [SENSOR_W_NUM(sensor, 15)] = ptrbase.ptrmember[15] // Will define a set of "centaur_port_pair sensor pointers" by passing in -// base sensor nameand ptr to [0] entry of array of 16 memcontroller sensors +// base sensor name and ptr to [0] entry of array of 16 memcontroller sensors #define PORTPAIR_SENSOR_PTRS(sensor,ptrbase,ptrmember,ptrsnsr) \ [SENSOR_W_CENTAUR_NUM(sensor, 0, 0, 0)] = ptrbase[0].ptrmember[0].ptrsnsr, \ [SENSOR_W_CENTAUR_NUM(sensor, 0, 0, 1)] = ptrbase[0].ptrmember[1].ptrsnsr, \ @@ -134,7 +134,6 @@ extern amec_sys_t g_amec_sys; [SENSOR_W_CENTAUR_NUM(sensor, 7, 0, 0)] = ptrbase[7].ptrmember[0].ptrsnsr, \ [SENSOR_W_CENTAUR_NUM(sensor, 7, 0, 1)] = ptrbase[7].ptrmember[1].ptrsnsr - // Will create an entry in the G_amec_mini_sensor_list with a pointer at // the sensor index (gsid) passed in by "sensor" #define MINI_SENSOR_PTR(sensor,ptr) [sensor] = ptr @@ -391,7 +390,6 @@ const sensor_ptr_t G_amec_sensor_list[] = CORE_SENSOR_PTRS( TEMPPROCTHRMC , &g_amec_sys.proc[0].core, tempprocthermal), CORE_SENSOR_PTRS( UTILC , &g_amec_sys.proc[0].core, util), CORE_SENSOR_PTRS( NUTILC , &g_amec_sys.proc[0].core, nutil3s), - CORE_SENSOR_PTRS( MSTLC , &g_amec_sys.proc[0].core, mstl2ms), CORE_SENSOR_PTRS( TEMPC, &g_amec_sys.proc[0].core, tempc), CORE_SENSOR_PTRS( STOPDEEPREQC, &g_amec_sys.proc[0].core, stopdeepreqc), CORE_SENSOR_PTRS( STOPDEEPACTC, &g_amec_sys.proc[0].core, stopdeepactc), @@ -400,8 +398,10 @@ const sensor_ptr_t G_amec_sensor_list[] = // ------------------------------------------------------ // Memory Sensors // ------------------------------------------------------ - MEMCONTROL_SENSOR_PTRS(MRDM, &g_amec_sys.proc[0].memctl, mrd2ms), - MEMCONTROL_SENSOR_PTRS(MWRM, &g_amec_sys.proc[0].memctl, mwr2ms), + MEMCONTROL_SENSOR_PTRS(MRDM, &g_amec_sys.proc[0].memctl, mrd), + MEMCONTROL_SENSOR_PTRS(MWRM, &g_amec_sys.proc[0].memctl, mwr), + MEMCONTROL_SENSOR_PTRS(MEMSPM, &g_amec_sys.proc[0].memctl, memsp), + MEMCONTROL_SENSOR_PTRS(MEMSPSTATM, &g_amec_sys.proc[0].memctl, memspstat), MEMCONTROL_SENSOR_PTRS(MIRCM, &g_amec_sys.proc[0].memctl, centaur.mirc2ms), MEMCONTROL_SENSOR_PTRS(MLP2M, &g_amec_sys.proc[0].memctl, centaur.mlp2ms), DIMM_SENSOR_PTRS(TEMPDIMM, &g_amec_sys.proc[0], tempdimm), @@ -572,7 +572,6 @@ const minisensor_ptr_t G_amec_mini_sensor_list[] INIT_SECTION = CORE_MINI_SENSOR_PTRS_NULL( TEMPPROCTHRMC ), CORE_MINI_SENSOR_PTRS( UTILC, &G_dcom_slv_outbox_tx.utilcy ), CORE_MINI_SENSOR_PTRS( NUTILC, &G_dcom_slv_outbox_tx.nutil3sp0cy ), - CORE_MINI_SENSOR_PTRS_NULL( MSTLC ), CORE_MINI_SENSOR_PTRS_NULL( TEMPC ), CORE_MINI_SENSOR_PTRS_NULL( STOPDEEPREQC ), CORE_MINI_SENSOR_PTRS_NULL( STOPDEEPACTC ), @@ -582,8 +581,10 @@ const minisensor_ptr_t G_amec_mini_sensor_list[] INIT_SECTION = // Memory Sensors // ------------------------------------------------------ - MEMCONTROL_MINI_SENSOR_PTRS(MRDM, &G_dcom_slv_outbox_tx.mrd2msp0mx), // - MEMCONTROL_MINI_SENSOR_PTRS(MWRM, &G_dcom_slv_outbox_tx.mwr2msp0mx), // + MEMCONTROL_MINI_SENSOR_PTRS(MRDM, &G_dcom_slv_outbox_tx.mrd), + MEMCONTROL_MINI_SENSOR_PTRS(MWRM, &G_dcom_slv_outbox_tx.mwr), + MEMCONTROL_MINI_SENSOR_PTRS_NULL(MEMSPM), + MEMCONTROL_MINI_SENSOR_PTRS_NULL(MEMSPSTATM), MEMCONTROL_MINI_SENSOR_PTRS_NULL(MIRCM), MEMCONTROL_MINI_SENSOR_PTRS_NULL(MLP2M), diff --git a/src/occ_405/thread/chom.c b/src/occ_405/thread/chom.c index 24f849a..2b6dd75 100755 --- a/src/occ_405/thread/chom.c +++ b/src/occ_405/thread/chom.c @@ -279,8 +279,8 @@ void chom_update_sensors() // update memory bandwidth for ( j = 0; j < MAX_NUM_MEM_CONTROLLERS; j++) { - l_mem_rw = G_dcom_slv_outbox_rx[i].mrd2msp0mx[j] + - G_dcom_slv_outbox_rx[i].mwr2msp0mx[j]; + l_mem_rw = G_dcom_slv_outbox_rx[i].mrd[j] + + G_dcom_slv_outbox_rx[i].mwr[j]; // If l_mem_rw == 0, do not add to sensor if(l_mem_rw != 0) diff --git a/src/occ_405/timer/timer.c b/src/occ_405/timer/timer.c index 2729e41..17194b2 100755 --- a/src/occ_405/timer/timer.c +++ b/src/occ_405/timer/timer.c @@ -5,7 +5,7 @@ /* */ /* OpenPOWER OnChipController Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2011,2017 */ +/* Contributors Listed Below - COPYRIGHT 2011,2018 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -36,6 +36,7 @@ #include <dimm_structs.h> #include <occ_sys_config.h> #include <pgpe_shared.h> +#include <sensor.h> //*************************************************************************/ // Externs @@ -216,7 +217,7 @@ void init_mem_deadman_reset_task(void) // // Name: task_poke_watchdogs // -// Description: Called every 2ms on both master and slaves while in observation +// Description: Called every 500us on both master and slaves while in observation // and active state. It performs the following: // 1. Enable/Reset the OCC heartbeat, setting the count to 8ms. // 2. Reset memory deadman timer for 1 MCA (by a GPE1 IPC task). @@ -226,10 +227,11 @@ void init_mem_deadman_reset_task(void) // to the PGPE Beacon count then log an error and request reset. // // End Function Specification +#define TASK_PGPE_BEACON_RUN_TICK_COUNT 8 void task_poke_watchdogs(struct task * i_self) { ocb_occhbr_t hbr; // OCC heart beat register - static bool L_check_pgpe_beacon = false; // Check GPE beacon this time? + static int L_check_pgpe_beacon_count = 0; // Check GPE beacon this time? // 1. Enable OCC heartbeat @@ -246,18 +248,20 @@ void task_poke_watchdogs(struct task * i_self) // 3. Verify PGPE Beacon is not frozen for 8 ms if there are cores configured if(G_present_cores != 0) { - if(true == L_check_pgpe_beacon) + if(L_check_pgpe_beacon_count >= TASK_PGPE_BEACON_RUN_TICK_COUNT) { - // Examine pgpe Beacon every other call (every 4ms) + // Examine pgpe Beacon every 4ms if(!G_simics_environment) // PGPE Beacon is not implemented in simics { check_pgpe_beacon(); } + L_check_pgpe_beacon_count = 0; + } + else + { + L_check_pgpe_beacon_count++; } - // toggle pgpe beacon check flag, check only once every other call (every 4ms) - L_check_pgpe_beacon = !L_check_pgpe_beacon; } - } // Function Specification @@ -266,14 +270,15 @@ void task_poke_watchdogs(struct task * i_self) // // Description: Verify that if a memory deadman_task was scheduled on GPE1 last cycle // then it is completed. Then if there is a new task to be scheduled -// for this cycle, then schedule it on the GPE1 engine. -// Called every 2ms. +// for this cycle, then schedule it on the GPE1 engine. This task +// is also used to collect memory performance measurements. +// Called every 500us. // // End Function Specification // MAX number of timeout cycles allowed for memory deadman IPC task // before logging an error -#define MEM_DEADMAN_TASK_TIMEOUT 2 +#define MEM_DEADMAN_TASK_TIMEOUT 8 void manage_mem_deadman_task(void) { @@ -289,6 +294,11 @@ void manage_mem_deadman_task(void) static bool L_gpe_timeout_logged = false; static bool L_gpe_had_1_tick = false; + // There is no way to synchronously start or stop the counter, so must + // take the difference between two readings. + static perf_mon_count0_t L_last_reading[NUM_NIMBUS_MCAS] = {{0}}; + uint32_t l_rd_wr_diff = 0; + uint32_t gpe_rc = G_gpe_reset_mem_deadman_args.error.rc; // IPC task rc do @@ -337,6 +347,19 @@ void manage_mem_deadman_task(void) { //Reset the timeout. L_scom_timeout[mca] = 0; + + // Update read/write sensors + l_rd_wr_diff = G_gpe_reset_mem_deadman_args.rd_wr_counts.mba_read_cnt + - L_last_reading[mca].mba_read_cnt; + l_rd_wr_diff = ((l_rd_wr_diff*25)/1000); + sensor_update(AMECSENSOR_ARRAY_PTR(MRDM0,mca), l_rd_wr_diff); + + l_rd_wr_diff = G_gpe_reset_mem_deadman_args.rd_wr_counts.mba_write_cnt + - L_last_reading[mca].mba_write_cnt; + l_rd_wr_diff = ((l_rd_wr_diff*25)/1000); + sensor_update(AMECSENSOR_ARRAY_PTR(MWRM0,mca), l_rd_wr_diff); + // Update last read/write measurement + L_last_reading[mca] = G_gpe_reset_mem_deadman_args.rd_wr_counts; } } @@ -345,17 +368,13 @@ void manage_mem_deadman_task(void) //We didn't fail, update mca (irrespective of whether it will be scheduled) + mca++; if ( mca >= NUM_NIMBUS_MCAS ) { mca = 0; } - else - { - mca++; - } G_gpe_reset_mem_deadman_args.mca = mca; - // If the MCA is not configured, break if(!NIMBUS_DIMM_INDEX_THROTTLING_CONFIGURED(mca)) { diff --git a/src/occ_gpe1/gpe1_dimm_control.c b/src/occ_gpe1/gpe1_dimm_control.c index 0437216..4ba1287 100644 --- a/src/occ_gpe1/gpe1_dimm_control.c +++ b/src/occ_gpe1/gpe1_dimm_control.c @@ -5,7 +5,7 @@ /* */ /* OpenPOWER OnChipController Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2015,2016 */ +/* Contributors Listed Below - COPYRIGHT 2015,2018 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -47,7 +47,6 @@ * * End Function Specification */ - void gpe_dimm_control(ipc_msg_t* cmd, void* arg) { // Note: arg was set to 0 in ipc func table (ipc_func_tables.c), so don't use it. @@ -79,6 +78,18 @@ void gpe_dimm_control(ipc_msg_t* cmd, void* arg) break; } + // Store the M values if needed + if( args->dimmDenominatorValues.need_m ) + { + args->dimmDenominatorValues.m_value = ((regValue & 0x1FFF80000) >> 19); + } + + // If this isn't set, we didn't need to set the N value, just needed M + if(!args->dimmNumeratorValues.new_n) + { + break; + } + // Clear old N values for slot and port regValue &= 0x1FFFFFFFF; // copy slot and port N values (31 bits) from passed dimmNumeratorValues @@ -121,7 +132,7 @@ void gpe_dimm_control(ipc_msg_t* cmd, void* arg) * * Name: gpe_reset_mem_deadman * - * Description: Read memory deadman timer for one MCA + * Description: Read memory performance counter for one MCA. * This effectively resets the memory deadman timer * * Inputs: cmd is a pointer to IPC msg's cmd and cmd_data struct @@ -176,7 +187,7 @@ void gpe_reset_mem_deadman(ipc_msg_t* cmd, void* arg) if(rc) { - PK_TRACE("gpe_reset_mem_deadman: Failed to program deadman timer" + PK_TRACE("gpe_reset_mem_deadman: Failed to program deadman timer (STR REG0)" " MCA:0x%08x, Data:0x%08x, rc:0x%08x", mca, (uint32_t)regValue, rc); gpe_set_ffdc(&(args->error), STR_REG0_MCA(mca), @@ -185,18 +196,23 @@ void gpe_reset_mem_deadman(ipc_msg_t* cmd, void* arg) } } - // read Deadman timer's SCOM Register for specified MCA to reset the timer - rc = getscom_abs(DEADMAN_TIMER_MCA(mca), ®Value); + // The "Deadman" timer is reset by reading from this performance monitor counts register + rc = getscom_abs(PERF_MON_COUNTS_IDLE_MCA(mca), ®Value); if(rc) { - PK_TRACE("gpe_reset_mem_deadman: Deadman timer read failed" + PK_TRACE("gpe_reset_mem_deadman: Performance Monitor Counts read failed" " MCA:0x%08x, Address:0x%08x, rc:0x%08x", - mca, DEADMAN_TIMER_MCA(mca), rc); + mca, PERF_MON_COUNTS_IDLE_MCA(mca), rc); - gpe_set_ffdc(&(args->error), DEADMAN_TIMER_MCA(mca), + gpe_set_ffdc(&(args->error), PERF_MON_COUNTS_IDLE_MCA(mca), GPE_RC_SCOM_GET_FAILED, rc); break; } + else + { + args->idle_counts.med_idle_cnt = ((regValue & 0xFFFFFFFF00000000) >> 32); + args->idle_counts.high_idle_cnt = (regValue & 0xFFFFFFFF); + } // Now that we are poking the deadman timer as second part of init check for and clear // any previous emergency throttle that may have happened from the last time OCC was running @@ -217,7 +233,7 @@ void gpe_reset_mem_deadman(ipc_msg_t* cmd, void* arg) } // clear Emergency Throttle In-Progress bit if set, this is indication that OCC has been - // re-started from permanent safe mode without an IPL + // re-started from permanent safe mode without an IPL if(regValue & ER_THROTTLE_IN_PROGRESS_MASK) { PK_TRACE("gpe_reset_mem_deadman: Enabled timer and clearing throttle for MCA:0x%08x", mca); @@ -267,6 +283,24 @@ void gpe_reset_mem_deadman(ipc_msg_t* cmd, void* arg) } } // if !L_init_complete + // In addition to resetting the "deadman" counter, get some performance information + rc = getscom_abs(PERF_MON_COUNTS0_MCA(mca), ®Value); + if(rc) + { + PK_TRACE("gpe_reset_mem_deadman: Performance Monitor Counts0 read failed" + " MCA:0x%08x, Address:0x%08x, rc:0x%08x", + mca, PERF_MON_COUNTS0_MCA(mca), rc); + + gpe_set_ffdc(&(args->error), PERF_MON_COUNTS0_MCA(mca), + GPE_RC_SCOM_GET_FAILED, rc); + break; + } + else + { + args->rd_wr_counts.mba_read_cnt = ((regValue & 0xFFFFFFFF00000000) >> 32); + args->rd_wr_counts.mba_write_cnt = (regValue & 0xFFFFFFFF); + } + } while(0); // send back a response, IPC success even if ffdc/rc are non zeros |