summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWilliam Bryan <wilbryan@us.ibm.com>2018-01-03 12:30:29 -0600
committerWilliam A. Bryan <wilbryan@us.ibm.com>2018-03-27 11:57:42 -0400
commitbd605ba0a030b3490f0edebd8fb704722b6eab0d (patch)
tree34fc7b10f06fef7baf9d101f78b816a6129753d8
parentc8538f3c894d5f28f688f7a081507c3ef14d6c24 (diff)
downloadtalos-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.h24
-rw-r--r--src/common/mca_addresses.h64
-rwxr-xr-xsrc/occ_405/amec/amec_analytics.c6
-rw-r--r--src/occ_405/amec/amec_init.c13
-rw-r--r--src/occ_405/amec/amec_sensors_centaur.c6
-rwxr-xr-xsrc/occ_405/amec/amec_sys.h13
-rwxr-xr-xsrc/occ_405/dcom/dcom.h4
-rw-r--r--src/occ_405/dimm/dimm_control.c58
-rw-r--r--src/occ_405/mem/memory.c37
-rwxr-xr-xsrc/occ_405/rtls/rtls_tables.c14
-rwxr-xr-xsrc/occ_405/sensor/sensor_enum.h45
-rwxr-xr-xsrc/occ_405/sensor/sensor_info.c18
-rw-r--r--src/occ_405/sensor/sensor_main_memory.c21
-rwxr-xr-xsrc/occ_405/sensor/sensor_table.c21
-rwxr-xr-xsrc/occ_405/thread/chom.c4
-rwxr-xr-xsrc/occ_405/timer/timer.c51
-rw-r--r--src/occ_gpe1/gpe1_dimm_control.c54
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), &regValue);
+ // The "Deadman" timer is reset by reading from this performance monitor counts register
+ rc = getscom_abs(PERF_MON_COUNTS_IDLE_MCA(mca), &regValue);
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), &regValue);
+ 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
OpenPOWER on IntegriCloud