From 6089fe0e7580b1c5030d1f380b1bc91c293e8bb9 Mon Sep 17 00:00:00 2001 From: Chris Cain Date: Tue, 10 Jan 2017 14:32:13 -0600 Subject: AVS Bus divider, loadline and misc changes - validate CRC in cmd response - read current / voltage on alternating ticks (commands on both bus for each tick) - calculate chip power (with loadline) and power for each tick - update divider value for bus speed - add error history counters and add them to logs Change-Id: I33bce916dc2dffef6a6d616633a5f1266d7baa7e RTC: 163992 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/34947 Tested-by: FSP CI Jenkins Reviewed-by: Martha Broyles Reviewed-by: Christopher J. Cain --- src/occ_405/amec/amec_sensors_power.c | 213 +++++++++++++++++----- src/occ_405/amec/amec_sys.h | 2 + src/occ_405/cmdh/cmdh_fsp_cmds.c | 8 + src/occ_405/cmdh/cmdh_fsp_cmds_datacnfg.c | 10 +- src/occ_405/cmdh/cmdh_fsp_cmds_datacnfg.h | 4 +- src/occ_405/dimm/dimm.c | 9 + src/occ_405/errl/errl.c | 66 ++++++- src/occ_405/errl/errl.h | 21 +++ src/occ_405/main.c | 8 +- src/occ_405/occ_service_codes.h | 1 + src/occ_405/pss/avsbus.c | 290 ++++++++++++++++++++---------- src/occ_405/pss/avsbus.h | 11 +- src/occ_405/sensor/sensor_enum.h | 3 + src/occ_405/sensor/sensor_info.c | 2 + src/occ_405/sensor/sensor_table.c | 5 +- 15 files changed, 497 insertions(+), 156 deletions(-) (limited to 'src') diff --git a/src/occ_405/amec/amec_sensors_power.c b/src/occ_405/amec/amec_sensors_power.c index 570ea34..5b98877 100755 --- a/src/occ_405/amec/amec_sensors_power.c +++ b/src/occ_405/amec/amec_sensors_power.c @@ -405,78 +405,159 @@ void amec_update_apss_sensors(void) } +// Read the current from AVS Bus and update sensors +void process_avsbus_current() +{ + if (G_avsbus_vdd_monitoring) + { + // Read Vdd current (returns 10mA) + uint32_t current = avsbus_read(AVSBUS_VDD, AVSBUS_CURRENT); + if (current != 0) + { + // Current value stored in the sensor should be in 10mA (scale -2) + sensor_update(AMECSENSOR_PTR(CURVDD), (uint16_t)current); + } + } + if (G_avsbus_vdn_monitoring) + { + // Read Vdn current (returns 10mA) + uint32_t current = avsbus_read(AVSBUS_VDN, AVSBUS_CURRENT); + if (current != 0) + { + // Current value stored in the sensor should be in 10mA (scale -2) + sensor_update(AMECSENSOR_PTR(CURVDN), (uint16_t)current); + } + } +} + + +// Read the voltage from AVS Bus and update sensors +void process_avsbus_voltage() +{ + if (G_avsbus_vdd_monitoring) + { + // Read Vdd voltage (returns mV) + uint32_t voltage = avsbus_read(AVSBUS_VDD, AVSBUS_VOLTAGE); + if (voltage != 0) + { + // Voltage value stored in the sensor should be in 100mV (scale -1) + voltage /= 100; + sensor_update(AMECSENSOR_PTR(VOLTVDD), (uint16_t)voltage); + } + } + if (G_avsbus_vdn_monitoring) + { + // Read Vdn voltage (returns mV) + uint32_t voltage = avsbus_read(AVSBUS_VDN, AVSBUS_VOLTAGE); + if (voltage != 0) + { + // Voltage value stored in the sensor should be in 100mV (scale -1) + voltage /= 100; + sensor_update(AMECSENSOR_PTR(VOLTVDN), (uint16_t)voltage); + } + } +} + + +// Calculate chip voltage and power and update sensors void update_avsbus_power_sensors(const avsbus_type_e i_type) { static bool L_throttle_vdd = FALSE; static bool L_throttle_vdn = FALSE; bool * L_throttle = &L_throttle_vdd; - uint16_t l_loadline = G_sysConfigData.avsbus_vdd.loadline; - uint32_t l_voltageSensor = VOLTVDD; + // TODO: RTC 130216 : read loadline and distloss from Pstate Super Structure + uint16_t l_loadline = 0x61AB; // OCCPstateParmBlock.vdd_sysparm.loadline_uohm + uint16_t l_distloss = 0x0000; // OCCPstateParmBlock.vdd_sysparm.distloss_uohm uint32_t l_currentSensor = CURVDD; + uint32_t l_voltageSensor = VOLTVDD; + uint32_t l_voltageChip = VOLTVDDSENSE; uint32_t l_powerSensor = PWRVDD; if (AVSBUS_VDN == i_type) { L_throttle = &L_throttle_vdn; - l_loadline = G_sysConfigData.avsbus_vdn.loadline; - l_voltageSensor = VOLTVDN; + l_loadline = 0x6BA8; // OCCPstateParmBlock.vdn_sysparm.loadline_uohm + l_distloss = 0x0000; // OCCPstateParmBlock.vdn_sysparm.distloss_uohm l_currentSensor = CURVDN; + l_voltageSensor = VOLTVDN; + l_voltageChip = VOLTVDNSENSE; l_powerSensor = PWRVDN; } - // Read AVS Bus current - uint32_t l_current_10ma = avsbus_read(i_type, AVSBUS_CURRENT); - if (l_current_10ma != 0) + // Read latest voltage/current sensors + const sensor_t *volt = getSensorByGsid(l_voltageSensor); + const uint32_t l_voltage_100mv = volt->sample; + const sensor_t *curr = getSensorByGsid(l_currentSensor); + const uint32_t l_current_10ma = curr->sample; + +#ifdef AVSDEBUG + // TODO: RTC 130216 : REMOVE AFTER VERIFYING loadline/distlost from Pstate Super Structure + static uint8_t L_traceCount = 0; + if (L_traceCount < 4) { - // Current value stored in the sensor should be in 10mA (scale -2) - sensor_update(AMECSENSOR_PTR(l_currentSensor), (uint16_t)l_current_10ma); + TRAC_INFO("update_avsbus_power_sensors: #%d Vd%c=%dx100mV, I=%dx10mA", L_traceCount, (i_type==AVSBUS_VDD)?'d':'n', + l_voltage_100mv, l_current_10ma); + TRAC_INFO("update_avsbus_power_sensors: #%d Vd%c Rloadline=%d, Rdistloss=%d", L_traceCount, (i_type==AVSBUS_VDD)?'d':'n', + l_loadline, l_distloss); } +#endif - // Read AVS Bus voltage - uint32_t l_voltage_mv = avsbus_read(i_type, AVSBUS_VOLTAGE); - if (l_voltage_mv != 0) + if ((l_voltage_100mv != 0) && (l_current_10ma != 0)) { // Calculate voltage on just processor package (need to take load-line into account) // Voltage value stored in the sensor should be in 100mV (scale -1) // (current is in 10mA units, and load-line is in tenth of microOhms) - // v(V) = i(10mA)*(1 A/1000 mA) * r(1/10u Ohm)*(1 Ohm/1,000,000 uOhm) - // = i * (1 A/100) * r * (1 Ohm/10,000,000) - // = i * r / 1,000,000,000 + // v(V) = i(10mA)*(1 A/1000 mA) * r(1 uOhm)*(1 Ohm/1,000,000 uOhm) + // = i * (1 A/100) * r * (1 Ohm/1,000,000) + // = i * r / 100,000,000 // v(mV) = v(V) * 1,000 // v(100mV) = v(mV) / 100 // = (v(V) * 1,000) / 100 = v(V) * 10 - // = (i * r / 1,000,000,000) * 10 = i * r / 100,000,000 - const uint64_t l_volt_drop_100mv = (l_current_10ma * l_loadline) / 100000000; - // TODO: RTC163992 - Confirm loadline calculation (chip package load line vs regulator load line) - // Convert voltage to 100mv units and subtract the drop: - int32_t l_voltage_100mv = (l_voltage_mv / 100) - l_volt_drop_100mv; - if ((l_voltage_100mv <= 0) || (l_voltage_100mv > 0xFFFF)) + // = (i * r / 100,000,000) * 10 = i * r / 10,000,000 + // NOTE: distloss is the same as Rpath in the WOF algorithm + const uint64_t l_volt_drop_100mv = (l_current_10ma * (l_loadline+l_distloss)) / 10000000; + // Calculate chip voltage + int32_t l_chip_voltage_100mv = l_voltage_100mv - l_volt_drop_100mv; + if ((l_chip_voltage_100mv <= 0) || (l_chip_voltage_100mv > 0xFFFF)) { - // Voltage out of range, write 0 + // Voltage out of range, do not write sensors if (!*L_throttle) { - TRAC_ERR("update_avsbus_power_sensors: Voltage out of range! %dmV - %d(100mV) = %d(100mV)", - l_voltage_mv, WORD_LOW(l_volt_drop_100mv), l_voltage_100mv); + TRAC_ERR("update_avsbus_power_sensors: chip voltage out of range! %dmV - %d(100mV) = %d(100mV)", + l_voltage_100mv, WORD_LOW(l_volt_drop_100mv), l_chip_voltage_100mv); *L_throttle = TRUE; } - l_voltage_100mv = 0; } else { *L_throttle = FALSE; - } - sensor_update(AMECSENSOR_PTR(l_voltageSensor), (uint16_t)l_voltage_100mv); - if (l_current_10ma != 0) - { + // Update chip voltage (remote sense adjusted for loadline) (100mV units) + sensor_update(AMECSENSOR_PTR(l_voltageChip), (uint16_t)l_chip_voltage_100mv); + // Power value stored in the sensor should be in W (scale 0) // p(W) = v(V) * i(A) = v(100mV)*100/1000 * i(10mA)*10/1000 // = v(100mV)/10 * i(10mA)/100 // = v(100mv) * i(10mA) / 1000 - const uint32_t l_power = l_voltage_100mv * l_current_10ma / 1000; + const uint32_t l_power = l_chip_voltage_100mv * l_current_10ma / 1000; sensor_update(AMECSENSOR_PTR(l_powerSensor), (uint16_t)l_power); } + +#ifdef AVSDEBUG + // TODO: RTC 130216 : REMOVE AFTER VERIFYING loadline/distlost from Pstate Super Structure + if (L_traceCount < 4) + { + const sensor_t *power = getSensorByGsid(l_powerSensor); + TRAC_INFO("update_avsbus_power_sensors: #%d Vd%cs=%dx100mV, P=%dW", L_traceCount, (i_type==AVSBUS_VDD)?'d':'n', + l_chip_voltage_100mv, power->sample); + } +#endif } +#ifdef AVSDEBUG + // TODO: RTC 130216 : REMOVE AFTER VERIFYING loadline/distlost from Pstate Super Structure + ++L_traceCount; +#endif + } // end update_avsbus_power_sensors() @@ -484,34 +565,74 @@ void update_avsbus_power_sensors(const avsbus_type_e i_type) // // Name: amec_update_avsbus_sensors // -// Description: Read AVS Bus data and update sensors +// Description: Read AVS Bus data and update sensors (called every tick) +// The very first tick kicks off a read of the currents for both buses (Vdd/Vdn). +// The next tick will process the currents and then start a read of the voltages. +// The next tick will process the voltages and then start a read of the currents. +// (readings for each bus will essentially be updated every 2 ticks) // // Thread: RealTime Loop // // End Function Specification void amec_update_avsbus_sensors(void) { - static bool L_vdd_state = TRUE; - if (L_vdd_state) + static enum { + AVSBUS_STATE_DISABLED = 0, + AVSBUS_STATE_INITIATE_READ = 1, + AVSBUS_STATE_PROCESS_CURRENT = 2, + AVSBUS_STATE_PROCESS_VOLTAGE = 3 + } L_avsbus_state = AVSBUS_STATE_INITIATE_READ; + + if (isSafeStateRequested()) { - // If AVS Bus Vdd config data was received, update sensors - if (G_avsbus_vdd_monitoring) - { - update_avsbus_power_sensors(AVSBUS_VDD); - } + L_avsbus_state = AVSBUS_STATE_DISABLED; + G_avsbus_vdd_monitoring = FALSE; + G_avsbus_vdn_monitoring = FALSE; } - else + + switch (L_avsbus_state) { - // If AVS Bus Vdn config data was received, update sensors - if (G_avsbus_vdn_monitoring) - { - update_avsbus_power_sensors(AVSBUS_VDN); - } + case AVSBUS_STATE_INITIATE_READ: + // Start first AVS Bus read of current + initiate_avsbus_reads(AVSBUS_CURRENT); + L_avsbus_state = AVSBUS_STATE_PROCESS_CURRENT; + break; + + case AVSBUS_STATE_PROCESS_CURRENT: + // Process the current readings + process_avsbus_current(); + // Initiate read of voltages + initiate_avsbus_reads(AVSBUS_VOLTAGE); + L_avsbus_state = AVSBUS_STATE_PROCESS_VOLTAGE; + break; + + case AVSBUS_STATE_PROCESS_VOLTAGE: + // Process the voltage readings + process_avsbus_voltage(); + // Initiate read of currents + initiate_avsbus_reads(AVSBUS_CURRENT); + L_avsbus_state = AVSBUS_STATE_PROCESS_CURRENT; + break; + + case AVSBUS_STATE_DISABLED: + break; + + default: + TRAC_ERR("amec_update_avsbus_sensors: INVALID AVSBUS STATE 0x%02X", L_avsbus_state); + L_avsbus_state = AVSBUS_STATE_INITIATE_READ; + break; } - // Alternate between Vdd/Vdn readings - L_vdd_state = !L_vdd_state; + // Update the chip voltage and power sensors after every reading + if (G_avsbus_vdd_monitoring) + { + update_avsbus_power_sensors(AVSBUS_VDD); + } + if (G_avsbus_vdn_monitoring) + { + update_avsbus_power_sensors(AVSBUS_VDN); + } } // end amec_update_avsbus_sensors() diff --git a/src/occ_405/amec/amec_sys.h b/src/occ_405/amec/amec_sys.h index f741d53..d298c7f 100755 --- a/src/occ_405/amec/amec_sys.h +++ b/src/occ_405/amec/amec_sys.h @@ -79,6 +79,8 @@ typedef struct sensor_t gpetickdur[NUM_GPE_ENGINES]; sensor_t prcdupdatedur; sensor_t probe250us[NUM_AMEC_FW_PROBES]; + sensor_t voltvddsense; + sensor_t voltvdnsense; // DPS update flag // 8 bit flag: =1, no updating allowed; =0, updating is allowed diff --git a/src/occ_405/cmdh/cmdh_fsp_cmds.c b/src/occ_405/cmdh/cmdh_fsp_cmds.c index 0f09151..dbdd75a 100755 --- a/src/occ_405/cmdh/cmdh_fsp_cmds.c +++ b/src/occ_405/cmdh/cmdh_fsp_cmds.c @@ -1160,6 +1160,14 @@ errlHndl_t cmdh_tmgt_setmodestate(const cmdh_fsp_cmd_t * i_cmd_ptr, break; } + // Verify not in safe state + if ((TRUE == isSafeStateRequested()) || (CURRENT_STATE() == OCC_STATE_SAFE)) + { + CMDH_TRAC_ERR("OCC in safe state, rejecting mode change request"); + l_rc = ERRL_RC_INVALID_STATE; + break; + } + // ------------------------------------------------- // Act on State & Mode Changes // ------------------------------------------------- diff --git a/src/occ_405/cmdh/cmdh_fsp_cmds_datacnfg.c b/src/occ_405/cmdh/cmdh_fsp_cmds_datacnfg.c index b0d4cd2..d3e9a3f 100755 --- a/src/occ_405/cmdh/cmdh_fsp_cmds_datacnfg.c +++ b/src/occ_405/cmdh/cmdh_fsp_cmds_datacnfg.c @@ -1001,9 +1001,8 @@ errlHndl_t data_store_avsbus_config(const cmdh_fsp_cmd_t * i_cmd_ptr, G_avsbus_vdd_monitoring = TRUE; G_sysConfigData.avsbus_vdd.bus = l_cmd_ptr->vdd_bus; G_sysConfigData.avsbus_vdd.rail = l_cmd_ptr->vdd_rail; - G_sysConfigData.avsbus_vdd.loadline = l_cmd_ptr->vdd_loadline; - CNFG_DBG("data_store_avsbus_config: Vdd bus[%d] rail[%d] loadline[0x%02X]", - G_sysConfigData.avsbus_vdd.bus, G_sysConfigData.avsbus_vdd.rail, G_sysConfigData.avsbus_vdd.loadline); + CNFG_DBG("data_store_avsbus_config: Vdd bus[%d] rail[%d]", + G_sysConfigData.avsbus_vdd.bus, G_sysConfigData.avsbus_vdd.rail); } else { @@ -1035,9 +1034,8 @@ errlHndl_t data_store_avsbus_config(const cmdh_fsp_cmd_t * i_cmd_ptr, G_avsbus_vdn_monitoring = TRUE; G_sysConfigData.avsbus_vdn.bus = l_cmd_ptr->vdn_bus; G_sysConfigData.avsbus_vdn.rail = l_cmd_ptr->vdn_rail; - G_sysConfigData.avsbus_vdn.loadline = l_cmd_ptr->vdn_loadline; - CNFG_DBG("data_store_avsbus_config: Vdn bus[%d] rail[%d] loadline[0x%02X]", - G_sysConfigData.avsbus_vdn.bus, G_sysConfigData.avsbus_vdn.rail, G_sysConfigData.avsbus_vdn.loadline); + CNFG_DBG("data_store_avsbus_config: Vdn bus[%d] rail[%d]", + G_sysConfigData.avsbus_vdn.bus, G_sysConfigData.avsbus_vdn.rail); if (G_avsbus_vdd_monitoring && (G_sysConfigData.avsbus_vdd.bus == G_sysConfigData.avsbus_vdn.bus)) diff --git a/src/occ_405/cmdh/cmdh_fsp_cmds_datacnfg.h b/src/occ_405/cmdh/cmdh_fsp_cmds_datacnfg.h index 1a71b8c..b3c2cb3 100755 --- a/src/occ_405/cmdh/cmdh_fsp_cmds_datacnfg.h +++ b/src/occ_405/cmdh/cmdh_fsp_cmds_datacnfg.h @@ -140,10 +140,10 @@ typedef struct __attribute__ ((packed)) uint8_t version; uint8_t vdd_bus; uint8_t vdd_rail; - uint16_t vdd_loadline; + uint16_t reserved1; uint8_t vdn_bus; uint8_t vdn_rail; - uint16_t vdn_loadline; + uint16_t reserved2; }cmdh_avsbus_config_t; // Used by TMGT to send OCC the PCAP config data. diff --git a/src/occ_405/dimm/dimm.c b/src/occ_405/dimm/dimm.c index 567fca5..fb62d6b 100755 --- a/src/occ_405/dimm/dimm.c +++ b/src/occ_405/dimm/dimm.c @@ -281,6 +281,15 @@ void mark_dimm_failed() g_amec->proc[0].memctl[port].centaur.dimm_temps[dimm].flags |= FRU_SENSOR_STATUS_ERROR; + if (port == 0) + { + INCREMENT_ERR_HISTORY(ERR_DIMM_I2C_PORT0); + } + else + { + INCREMENT_ERR_HISTORY(ERR_DIMM_I2C_PORT1); + } + if (++G_dimm[port][dimm].errorCount > MAX_CONSECUTIVE_DIMM_RESETS) { // Disable collection on this DIMM, collect FFDC and log error diff --git a/src/occ_405/errl/errl.c b/src/occ_405/errl/errl.c index a309279..07b5e6e 100755 --- a/src/occ_405/errl/errl.c +++ b/src/occ_405/errl/errl.c @@ -61,6 +61,9 @@ errlHndl_t G_occErrSlots[ERRL_MAX_SLOTS] = { (errlHndl_t) G_callslot }; +// Array of error counters that are only cleared on OCC reset +uint8_t G_error_history[ERR_HISTORY_SIZE] = {0}; + extern uint8_t G_occ_interrupt_type; extern bool G_fir_collection_required; @@ -305,6 +308,9 @@ errlHndl_t createErrl( // add trace addTraceToErrl( i_trace, i_traceSz, l_rc ); + // add error history + addErrHistory( l_rc ); + // save off entry Id l_rc->iv_entryId = l_id; @@ -518,6 +524,64 @@ void addTraceToErrl( } + + +// Function Specification +// +// Name: addErrHistory +// +// Description: Add error trace history to log +// +// End Function Specification +void addErrHistory(errlHndl_t io_err) +{ + // 1. Check if error log is not null + // 2. error log is not invalid + // 3. error log has not been commited + // 4. free space is enough (to hold new user detail header + data) + if( (io_err != NULL) && + (io_err != INVALID_ERR_HNDL) && + (io_err->iv_userDetails.iv_committed == 0) && + ((io_err->iv_userDetails.iv_entrySize + sizeof(ErrlUserDetailsEntry_t) + sizeof(G_error_history)) < MAX_ERRL_ENTRY_SZ ) ) + { + void * l_errPtr = io_err; + ErrlUserDetailsEntry_t l_usrDtlsEntry; + const uint16_t l_usrDtlsHeaderSz = sizeof(l_usrDtlsEntry); + + // io_err |-----------------------------------------| + // | ErrlEntry_t | + // | {iv_userDetails.iv_userDetailEntrySize, | <== elog header and optional user details sections, need to add length + // | ... other elements ... }| of new usrdtl section(ErrlUserDetailsEntry_t + data len) + // |-----------------------------------------| + // | ErrlUserDetailsEntry_t | <== new user detail header (l_usrDtlsEntry) + // |-----------------------------------------| + // | data ... | <== new user detail data (G_error_history) + // | ... | + + l_usrDtlsEntry.iv_size = sizeof(G_error_history); + l_usrDtlsEntry.iv_type = (uint8_t) ERRL_USR_DTL_HISTORY_DATA; + l_usrDtlsEntry.iv_version = 1; + + // Calculate trace data address (err address + sizeof(ErrlEntry_t + existing usrDtls) + sizeof(ErrlUserDetailsEntry_t)) + void * l_dataAddr = l_errPtr + io_err->iv_userDetails.iv_entrySize + l_usrDtlsHeaderSz; + memcpy(l_dataAddr, G_error_history, sizeof(G_error_history)); + + // Calculate entire data length including usrDtl header. + const uint16_t l_sizeOfUsrDtls = l_usrDtlsHeaderSz + l_usrDtlsEntry.iv_size; + + // Copy new user details header into log + memcpy(l_errPtr+((io_err->iv_userDetails.iv_entrySize)), &l_usrDtlsEntry, l_usrDtlsHeaderSz); + + //update master user details size with new data + io_err->iv_userDetails.iv_userDetailEntrySize += l_sizeOfUsrDtls; + + //update error log with new size + io_err->iv_userDetails.iv_entrySize += l_sizeOfUsrDtls; + } + +} // end addErrHistory() + + // Function Specification // // Name: reportErrorLog @@ -571,7 +635,7 @@ void commitErrl( errlHndl_t *io_err ) if (l_oisr0_status.fields.check_stop_ppc405) { - TRAC_IMP("addTraceToErrl: System checkstop detected: ppc405, OISR0[0x%08x]", + TRAC_IMP("commitErrl: System checkstop detected: ppc405, OISR0[0x%08x]", l_oisr0_status.value); //Go to the reset state to minimize errors reset_state_request(RESET_REQUESTED_DUE_TO_ERROR); diff --git a/src/occ_405/errl/errl.h b/src/occ_405/errl/errl.h index 217dde2..fcfb83b 100755 --- a/src/occ_405/errl/errl.h +++ b/src/occ_405/errl/errl.h @@ -110,6 +110,7 @@ typedef enum ERRL_USR_DTL_TRACE_DATA = 0x01, ERRL_USR_DTL_CALLHOME_DATA = 0x02, ERRL_USR_DTL_BINARY_DATA = 0x03, + ERRL_USR_DTL_HISTORY_DATA = 0x04, } ERRL_USR_DETAIL_TYPE; // These are the possible OCC States. @@ -265,6 +266,23 @@ extern uint8_t G_occErrIdCounter; extern errlHndl_t G_occErrSlots[ERRL_MAX_SLOTS]; +// Array of error counters that are only cleared on OCC reset +#define ERR_HISTORY_SIZE 32 +extern uint8_t G_error_history[ERR_HISTORY_SIZE]; +typedef enum { + ERR_AVSBUS_VDD_CURRENT = 1, + ERR_AVSBUS_VDD_VOLTAGE = 2, + ERR_AVSBUS_VDN_CURRENT = 3, + ERR_AVSBUS_VDN_VOLTAGE = 4, + ERR_DIMM_I2C_PORT0 = 5, + ERR_DIMM_I2C_PORT1 = 6 +} ERR_HISTORY_INDEX; +#define INCREMENT_ERR_HISTORY(errorIndex) { \ + if ((errorIndex < ERR_HISTORY_SIZE) && (G_error_history[errorIndex] < 255)) { \ + ++G_error_history[errorIndex]; \ + } \ +} + // Globals used by testcases extern uint8_t G_errslot1[MAX_ERRL_ENTRY_SZ]; extern uint8_t G_errslot2[MAX_ERRL_ENTRY_SZ]; @@ -296,6 +314,9 @@ void addTraceToErrl( errlHndl_t io_errl ); +// Add Error history data to the Error Log +void addErrHistory(errlHndl_t io_err); + /* Commit the Error Log */ void commitErrl( errlHndl_t * io_err ); diff --git a/src/occ_405/main.c b/src/occ_405/main.c index 7023233..fdbe9f3 100755 --- a/src/occ_405/main.c +++ b/src/occ_405/main.c @@ -110,6 +110,9 @@ bool G_fir_collection_required = FALSE; // Global flag indicating we are running on Simics bool G_simics_environment = FALSE; +// Nest frequency in MHz +uint32_t G_nest_frequency_mhz; + extern uint8_t g_trac_inf_buffer[]; extern uint8_t g_trac_imp_buffer[]; extern uint8_t g_trac_err_buffer[]; @@ -1261,14 +1264,14 @@ int main(int argc, char **argv) // all HOMER versions. uint32_t l_tb_freq_hz = 0; l_homerrc2 = homer_hd_map_read_unmap(HOMER_NEST_FREQ, - &l_tb_freq_hz, + &G_nest_frequency_mhz, &l_ssxrc2); if ((HOMER_SUCCESS == l_homerrc2) || (HOMER_SSX_UNMAP_ERR == l_homerrc2)) { // Data is in Mhz upon return and needs to be converted to Hz and then // quartered. - l_tb_freq_hz = (l_tb_freq_hz * 1000000)/4; + l_tb_freq_hz = G_nest_frequency_mhz * (1000000 / 4); // @TODO: this parameter should be passsed to all the GPEs/CMEs/etc // Can be stored in GPE accessible SRAM areas. @@ -1277,6 +1280,7 @@ int main(int argc, char **argv) else { l_tb_freq_hz = PPC405_TIMEBASE_HZ; + G_nest_frequency_mhz = (l_tb_freq_hz * 4) / 1000000; } CHECKPOINT(SSX_STARTING); diff --git a/src/occ_405/occ_service_codes.h b/src/occ_405/occ_service_codes.h index 2654851..b96ff0d 100644 --- a/src/occ_405/occ_service_codes.h +++ b/src/occ_405/occ_service_codes.h @@ -79,6 +79,7 @@ enum occReasonCode CENT_LFIR_ERROR = 0x42, AVSBUS_TIMEOUT = 0x50, AVSBUS_ERROR = 0x51, + AVSBUS_CRC_ERROR = 0x52, /// Throttle in nominal or turbo mode due to the bulk power limit being reached with both power supplies good PCAP_THROTTLE_POWER_LIMIT = 0x61, /// Firmware Failure: equivalent to assertion failures diff --git a/src/occ_405/pss/avsbus.c b/src/occ_405/pss/avsbus.c index b958271..6b76379 100644 --- a/src/occ_405/pss/avsbus.c +++ b/src/occ_405/pss/avsbus.c @@ -43,20 +43,16 @@ #define AVS_DBG(frmt,args...) #endif - // AVS Bus usage will be determined after receiving config data from TMGT bool G_avsbus_vdd_monitoring = FALSE; bool G_avsbus_vdn_monitoring = FALSE; -// The following constants are used after a command is put on the bus. -// The code will wait for the o2s_ongoing bit to change (which indicates cmd completion). -// Max wait time will be: O2S_ONGOING_CHECK_ATTEMPTS * O2S_ONGOING_CHECK_DELAY_NS (in nanoseconds) -const uint32_t O2S_ONGOING_CHECK_ATTEMPTS = 10; -const uint32_t O2S_ONGOING_CHECK_DELAY_NS = 100; +extern uint32_t G_nest_frequency_mhz; +#define AVSBUS_FREQUENCY_MHZ 10 // Number of read failures allowed before elog is created and reset requested. // This should be no longer than 4ms (or it will impact WOF calculations) -// (readings are taken every 500ms => 500us * 8 = 4ms) +// (readings are taken every 500us => 500us * 8 = 4ms) const uint8_t MAX_READ_ATTEMPTS = 8; // NOTE: OCC must use Bridge B, because Bridge A is reserved for PGPE @@ -142,13 +138,14 @@ void avsbus_init() // 2 o2s_cpol = 0 (positive active clock) // 3 o2s_cpha = 0 (first edge data launch/sample) // 4:13 o2s_clock_divider = set based on the nest frequency for the desired frequency of 10MHz (assumed speed) per O2SCTRL1_[a][n] description. - // = (nest_freq / (SPI_freq*8))-1 = (500M/(10M*8))-1 = 5.25 // 14:16 reserved // 17 o2s_nr_of_frames = 1 (2 frames to account for the first and second frames of an AVSBus command) // 18:63 reserved // 1r00DDDD DDDDDDrr r1rrrrrr rrrrrrrrr - value = 0x8014400000000000; - // TODO: RTC163992 - Determine correct o2s_clock_divider based on nest freq + value = 0x8000400000000000; + // calculate o2s_clock_divider based on nest freq and target bus freq + const uint64_t divider = (G_nest_frequency_mhz / (AVSBUS_FREQUENCY_MHZ * 8)) - 1; + value |= (divider << 50); if (bus0_monitoring) { out64(OCB_O2SCTRL10B, value); @@ -160,27 +157,29 @@ void avsbus_init() } -// Calculate and update command with correct CRC +// Calculate CRC for specified AVS Bus command // Function which generates a 3 bit CRC value for 29 bit data // from: ekb/chips/p9/procedures/hwp/lib/p9_avsbus_lib.C +// (CRC is bits 29:31 in the AVS bus command) +#define AVS_CRC_MASK 0x0000000700000000 #define AVS_CRC_DATA_MASK 0xFFFFFFF800000000 -void avs_crc_update(uint64_t *io_avs_cmd) +uint64_t avs_crc_calculate(const uint64_t i_avs_cmd) { //Polynomial= x^3 + x^1 + x^0 = 1*x^3 + 0*x^2 + 1*x^1 + 1*x^0 = divisor(1011) - uint64_t l_crc_value = 0; + uint64_t o_crc_value = 0; uint64_t l_polynomial = 0xB000000000000000; uint64_t l_msb = 0x8000000000000000; - l_crc_value = *io_avs_cmd & AVS_CRC_DATA_MASK; + o_crc_value = i_avs_cmd & AVS_CRC_DATA_MASK; - while (l_crc_value & AVS_CRC_DATA_MASK) + while (o_crc_value & AVS_CRC_DATA_MASK) { - if (l_crc_value & l_msb) + if (o_crc_value & l_msb) { //if l_msb is 1'b1, divide by l_polynomial and shift l_polynomial // to the right - l_crc_value = l_crc_value ^ l_polynomial; + o_crc_value = o_crc_value ^ l_polynomial; l_polynomial = l_polynomial >> 1; } else @@ -192,26 +191,22 @@ void avs_crc_update(uint64_t *io_avs_cmd) l_msb = l_msb >> 1; } - // Add CRC to avs command (lower 3 bits of cmd) - *io_avs_cmd |= l_crc_value; + return o_crc_value; } #define ERRORCOUNT_MAXTYPES 2 #define ERRORCOUNT_MAXCMDS 2 -// Read and return the voltage or current for specified rail -// (voltage units are mV, current units are in 10mA) -uint16_t avsbus_read(const avsbus_type_e i_type, - const avsbus_cmdtype_e i_cmdtype) +// Initiate read for specified type (Vdd/Vdn) and cmd (Voltage/Current) +void avsbus_read_start(const avsbus_type_e i_type, + const avsbus_cmdtype_e i_cmdtype) { if (isSafeStateRequested()) { // No need to attempt read if OCC will be reset - return 0; + return; } - uint16_t o_reading = 0; - bool l_failure = FALSE; avsbusData_t l_data; // Create error array for each type (Vdd/Vdn) and command (Voltage/Current) @@ -222,8 +217,6 @@ uint16_t avsbus_read(const avsbus_type_e i_type, l_cmd_index = 1; l_trace_cmd = 'C'; } - static uint32_t L_error_count[ERRORCOUNT_MAXTYPES][ERRORCOUNT_MAXCMDS] = {{0}}; - uint32_t * l_error_count = &L_error_count[i_type][l_cmd_index]; char l_trace_type = 'd'; if (AVSBUS_VDD == i_type) @@ -237,11 +230,12 @@ uint16_t avsbus_read(const avsbus_type_e i_type, } #ifdef AVSDEBUG - static bool L_traced[ERRORCOUNT_MAXTYPES][ERRORCOUNT_MAXCMDS] = {{0}}; - bool * l_traced = &L_traced[i_type][l_cmd_index]; - if (!*l_traced) + static uint32_t L_trace_count[ERRORCOUNT_MAXTYPES][ERRORCOUNT_MAXCMDS] = {{0}}; + uint32_t * l_trace_count = &L_trace_count[i_type][l_cmd_index]; + uint32_t DEBUG_TRACE_MAX = 2; + if (*l_trace_count < DEBUG_TRACE_MAX) { - TRAC_INFO("avsbus_read: Vd%c %c - bus[%d] rail[%d]", + TRAC_INFO("avsbus_read_start: Vd%c %c - bus[%d] rail[%d]", l_trace_type, l_trace_cmd, l_data.bus, l_data.rail); } #endif @@ -249,14 +243,10 @@ uint16_t avsbus_read(const avsbus_type_e i_type, // Determine register based on the bus number uint32_t o2scmd_reg = OCB_O2SCMD0B; uint32_t o2swd_reg = OCB_O2SWD0B; - uint32_t o2sst_reg = OCB_O2SST0B; - uint32_t o2srd_reg = OCB_O2SRD0B; if (1 == l_data.bus) { o2scmd_reg = OCB_O2SCMD1B; o2swd_reg = OCB_O2SWD1B; - o2sst_reg = OCB_O2SST1B; - o2srd_reg = OCB_O2SRD1B; } // Write O2SCMD[a][n] @@ -277,16 +267,87 @@ uint16_t avsbus_read(const avsbus_type_e i_type, // 29:31 CRC // 01110DDD DRRRR111 11111111 11111CCC value = 0x7007FFF800000000 | ((uint64_t) i_cmdtype << 55) | ((uint64_t)l_data.rail << 51); - avs_crc_update(&value); + // Calculate/add CRC + value |= avs_crc_calculate(value); out64(o2swd_reg, value); + // Read has been started so now just wait for HW to complete + // HW: Wait for bus op to complete // HW: arbitration between two bridges // HW: o2s_ongoning: 0 -> 1 // HW: execution completes // HW: o2s_ongoing 1 -> 0 - // Poll waiting for o2s_ongoing to change to 0 or an error bit is set +#ifdef AVSDEBUG + ++*l_trace_count; // DEBUG +#endif + +} // end avsbus_read_start() + + +// Read and return the voltage or current for specified rail +// (voltage units are mV, current units are in 10mA) +uint16_t avsbus_read(const avsbus_type_e i_type, + const avsbus_cmdtype_e i_cmdtype) +{ + if (isSafeStateRequested()) + { + // No need to attempt read if OCC will be reset + return 0; + } + + uint16_t o_reading = 0; + bool l_failure = FALSE; + + uint8_t l_cmd_index = 0; + char l_trace_cmd = 'V'; + if (i_cmdtype == AVSBUS_CURRENT) + { + l_cmd_index = 1; + l_trace_cmd = 'C'; + } + + // Static error counters for each type (Vdd/Vdn) and command (Voltage/Current) + static uint32_t L_error_count[ERRORCOUNT_MAXTYPES][ERRORCOUNT_MAXCMDS] = {{0}}; + uint32_t * l_error_count = &L_error_count[i_type][l_cmd_index]; + + char l_trace_type = 'd'; + avsbusData_t l_data = G_sysConfigData.avsbus_vdd; + if (AVSBUS_VDN == i_type) + { + l_trace_type = 'n'; + l_data = G_sysConfigData.avsbus_vdn; + } + +#ifdef AVSDEBUG + static uint32_t L_trace_count[ERRORCOUNT_MAXTYPES][ERRORCOUNT_MAXCMDS] = {{0}}; + uint32_t * l_trace_count = &L_trace_count[i_type][l_cmd_index]; + uint32_t DEBUG_TRACE_MAX = 2; + if (*l_trace_count < DEBUG_TRACE_MAX) + { + TRAC_INFO("avsbus_read: Vd%c %c - bus[%d] rail[%d]", + l_trace_type, l_trace_cmd, l_data.bus, l_data.rail); + } +#endif + + // Determine register based on the bus number + uint32_t o2sst_reg = OCB_O2SST0B; + uint32_t o2srd_reg = OCB_O2SRD0B; + if (1 == l_data.bus) + { + o2sst_reg = OCB_O2SST1B; + o2srd_reg = OCB_O2SRD1B; + } + + // HW: Wait for bus op to complete + // HW: arbitration between two bridges + // HW: o2s_ongoning: 0 -> 1 + // HW: execution completes + // HW: o2s_ongoing 1 -> 0 + + // Since read was started in previous tick, it should have already completed + // (no need to poll/wait on o2s_ongoing) enum occReasonCode rc = OCC_SUCCESS_REASON_CODE; uint64_t l_status = in64(o2sst_reg); // OCC O2S Status Register @@ -297,46 +358,16 @@ uint16_t avsbus_read(const avsbus_type_e i_type, // 7 FSM error // 8:63 reserved // GrrrrBrF rrrrrrrr rrrrrrrr rrrrrrrr - uint32_t l_max_attempts = O2S_ONGOING_CHECK_ATTEMPTS; - - while ((1 == (l_status >> 63)) && - (0 == (l_status & 0x0500000000000000))) - { - if (l_max_attempts-- == 0) - { - l_failure = TRUE; - (*l_error_count)++; - if ((*l_error_count == 1) || (*l_error_count == MAX_READ_ATTEMPTS)) - { - TRAC_ERR("avsbus_read: Vd%c %c timeout waiting for o2s_ongoing change O2SST[0x%08X] = [0x%08X] / Command[0x%08X]", - l_trace_type, l_trace_cmd, o2sst_reg, WORD_HIGH(l_status), WORD_HIGH(value)); - /* - * @errortype - * @moduleid PSS_MID_AVSBUS_READ - * @reasoncode AVSBUS_TIMEOUT - * @userdata1 AVS Bus type/bus/rail - * @userdata2 status - * @devdesc task_apss_complete_pwr_meas schedule failed - * @devdesc Timeout when reading AVS Bus - */ - rc = AVSBUS_TIMEOUT; - } - break; - } - // TODO: RTC 163992 - //ssx_sleep(SSX_NANOSECONDS(O2S_ONGOING_CHECK_DELAY_NS)); - l_status = in64(o2sst_reg); - } if (0 != (l_status & 0x0500000000000000)) { + // error bit was set l_failure = TRUE; (*l_error_count)++; if ((*l_error_count == 1) || (*l_error_count == MAX_READ_ATTEMPTS)) { - // error bit was set - TRAC_ERR("avsbus_read: Error found in Vd%c %c O2SST[0x%08X] = [0x%08X] / Command[0x%08X]", - l_trace_type, l_trace_cmd, o2sst_reg, WORD_HIGH(l_status), WORD_HIGH(value)); + TRAC_ERR("avsbus_read: Error found in Vd%c %c O2SST[0x%08X] = [0x%08X]", + l_trace_type, l_trace_cmd, o2sst_reg, WORD_HIGH(l_status)); /* * @errortype * @moduleid PSS_MID_AVSBUS_READ @@ -348,13 +379,31 @@ uint16_t avsbus_read(const avsbus_type_e i_type, rc = AVSBUS_ERROR; } } + else if (1 == (l_status >> 63)) // o2s_ongoing + { + // o2s_ongoing bit was still set (operation did not complete) + l_failure = TRUE; + (*l_error_count)++; + if ((*l_error_count == 1) || (*l_error_count == MAX_READ_ATTEMPTS)) + { + TRAC_ERR("avsbus_read: Vd%c %c timeout waiting for o2s_ongoing change O2SST[0x%08X] = [0x%08X]", + l_trace_type, l_trace_cmd, o2sst_reg, WORD_HIGH(l_status)); + /* + * @errortype + * @moduleid PSS_MID_AVSBUS_READ + * @reasoncode AVSBUS_TIMEOUT + * @userdata1 AVS Bus type/bus/rail + * @userdata2 status + * @devdesc Timeout when reading AVS Bus + */ + rc = AVSBUS_TIMEOUT; + } + } if (FALSE == l_failure) { // Read the response data - value = in64(o2srd_reg); - - // Check for valid command operation and extract read data + uint64_t value = in64(o2srd_reg); // AVS Bus response (read voltage or current): // 0:1 SlaveAck (0b00 from slave indicates good CRC and action was taken) // 2 0 @@ -363,11 +412,34 @@ uint16_t avsbus_read(const avsbus_type_e i_type, // 24:28 Reserved (must be all 1s) // 29:31 CRC // AA0SSSSS VVVVVVVV VVVVVVVV 11111CCC - if (0 == (value & 0xC000000000000000)) + + // Validate CRC + const uint64_t crc = avs_crc_calculate(value); + if (crc != (value & AVS_CRC_MASK)) + { + l_failure = TRUE; + (*l_error_count)++; + if ((*l_error_count == 1) || (*l_error_count == MAX_READ_ATTEMPTS)) + { + TRAC_ERR("avsbus_read: CRC mismatch in Vd%c %c rsp O2SRD[0x%08X] = [0x%08X] (calculated CRC 0x%08X)", + l_trace_type, l_trace_cmd, o2srd_reg, WORD_HIGH(value), WORD_HIGH(crc)); + /* + * @errortype + * @moduleid PSS_MID_AVSBUS_READ + * @reasoncode AVSBUS_CRC_ERROR + * @userdata1 AVS Bus type/bus/rail + * @userdata2 status + * @devdesc CRC error reading AVS Bus + */ + rc = AVSBUS_CRC_ERROR; + } + } + // Check for valid command operation and extract read data + else if (0 == (value & 0xC000000000000000)) { o_reading = (value >> 40) & 0x0000FFFF; #ifdef AVSDEBUG - if (!*l_traced) + if (*l_trace_count < DEBUG_TRACE_MAX) { if (i_cmdtype == AVSBUS_VOLTAGE) { @@ -403,31 +475,39 @@ uint16_t avsbus_read(const avsbus_type_e i_type, if (l_failure) { - if (*l_error_count == MAX_READ_ATTEMPTS) + enum occExtReasonCode exrc = ERC_AVSBUS_VDD_VOLTAGE_FAILURE; + if (AVSBUS_VDD == i_type) { - TRAC_ERR("avsbus_read: Reached %d consecutive Vd%c %c errors, requesting reset", - *l_error_count, l_trace_type, l_trace_cmd); - G_avsbus_vdd_monitoring = FALSE; - G_avsbus_vdn_monitoring = FALSE; - enum occExtReasonCode exrc = ERC_AVSBUS_VDD_VOLTAGE_FAILURE; - if (AVSBUS_VDD == i_type) + if (i_cmdtype == AVSBUS_CURRENT) { - if (i_cmdtype == AVSBUS_CURRENT) - { - exrc = ERC_AVSBUS_VDD_CURRENT_FAILURE; - } + exrc = ERC_AVSBUS_VDD_CURRENT_FAILURE; + INCREMENT_ERR_HISTORY(ERR_AVSBUS_VDD_CURRENT); } else { - if (i_cmdtype == AVSBUS_CURRENT) - { - exrc = ERC_AVSBUS_VDN_CURRENT_FAILURE; - } - else - { - exrc = ERC_AVSBUS_VDN_VOLTAGE_FAILURE; - } + INCREMENT_ERR_HISTORY(ERR_AVSBUS_VDD_VOLTAGE); + } + } + else + { + if (i_cmdtype == AVSBUS_CURRENT) + { + exrc = ERC_AVSBUS_VDN_CURRENT_FAILURE; + INCREMENT_ERR_HISTORY(ERR_AVSBUS_VDN_CURRENT); } + else + { + exrc = ERC_AVSBUS_VDN_VOLTAGE_FAILURE; + INCREMENT_ERR_HISTORY(ERR_AVSBUS_VDN_VOLTAGE); + } + } + + if (*l_error_count == MAX_READ_ATTEMPTS) + { + TRAC_ERR("avsbus_read: Reached %d consecutive Vd%c %c errors, requesting reset", + *l_error_count, l_trace_type, l_trace_cmd); + G_avsbus_vdd_monitoring = FALSE; + G_avsbus_vdn_monitoring = FALSE; errlHndl_t l_err = createErrl(PSS_MID_AVSBUS_READ, rc, exrc, @@ -444,8 +524,9 @@ uint16_t avsbus_read(const avsbus_type_e i_type, REQUEST_RESET(l_err); } } + #ifdef AVSDEBUG - *l_traced = TRUE; // DEBUG + ++*l_trace_count; // DEBUG #endif return o_reading; @@ -453,5 +534,22 @@ uint16_t avsbus_read(const avsbus_type_e i_type, } // end avsbus_read() +// Start the AVS Bus read for both buses (if enabled) +void initiate_avsbus_reads(avsbus_cmdtype_e i_cmdType) +{ + if (G_avsbus_vdd_monitoring) + { + // AVS Bus Vdd config data was received: + // Initiate AVS Bus read for Vdd (voltage or current) + avsbus_read_start(AVSBUS_VDD, i_cmdType); + } + + if (G_avsbus_vdn_monitoring) + { + // AVS Bus Vdn config data was received: + // Initiate AVS Bus read for Vdn (voltage or current) + avsbus_read_start(AVSBUS_VDN, i_cmdType); + } +} // end initiate_avsbus_reads() diff --git a/src/occ_405/pss/avsbus.h b/src/occ_405/pss/avsbus.h index f2dfb2e..80b91cf 100755 --- a/src/occ_405/pss/avsbus.h +++ b/src/occ_405/pss/avsbus.h @@ -48,9 +48,16 @@ typedef enum // Setup the AVS Bus for reading void avsbus_init(); -// Read and return the voltage or current for specified rail -// (voltage units are mV, current units are in 10mA) +// Initiate AVS Bus read for specified cmdtype (Voltage / Current) +// (results can then be read on the next tick) +void initiate_avsbus_reads(avsbus_cmdtype_e i_cmdType); + +// Process AVS Bus read results (or errors) for specified bus/cmdtype. +// Returns the data requested (voltage units are mV, current units are in 10mA) +// Predictive error will be logged after MAX_READ_ATTEMPTS failures on the specific +// bus/cmdtype and an OCC reset will be requested uint16_t avsbus_read(const avsbus_type_e i_type, const avsbus_cmdtype_e i_cmdtype); + #endif //_AVSBUS_H diff --git a/src/occ_405/sensor/sensor_enum.h b/src/occ_405/sensor/sensor_enum.h index 0c793d0..37c411c 100755 --- a/src/occ_405/sensor/sensor_enum.h +++ b/src/occ_405/sensor/sensor_enum.h @@ -69,6 +69,9 @@ enum e_gsid PROBE250US6, // Internal Sensor for debug via AMESTER PROBE250US7, // Internal Sensor for debug via AMESTER + VOLTVDDSENSE, // chip voltage (remote sense adjusted for loadline) + VOLTVDNSENSE, // chip voltage (remote sense adjusted for loadline) + GPEtickdur0, // Duration on the GPE0 Engine GPEtickdur1, // Duration on the GPE1 Engine RTLtickdur, // Duration on the RTL tick interrupt diff --git a/src/occ_405/sensor/sensor_info.c b/src/occ_405/sensor/sensor_info.c index cc9e253..dc7e77f 100755 --- a/src/occ_405/sensor/sensor_info.c +++ b/src/occ_405/sensor/sensor_info.c @@ -223,6 +223,8 @@ const sensor_info_t G_sensor_info[] = SENSOR_INFO_T_ENTRY( PROBE250US5, "n/a\0", AMEC_SENSOR_TYPE_GENERIC, AMEC_SENSOR_LOC_OCC, AMEC_SENSOR_NONUM, AMEEFP_250US_IN_HZ, AMEFP( 1, 0) ), SENSOR_INFO_T_ENTRY( PROBE250US6, "n/a\0", AMEC_SENSOR_TYPE_GENERIC, AMEC_SENSOR_LOC_OCC, AMEC_SENSOR_NONUM, AMEEFP_250US_IN_HZ, AMEFP( 1, 0) ), SENSOR_INFO_T_ENTRY( PROBE250US7, "n/a\0", AMEC_SENSOR_TYPE_GENERIC, AMEC_SENSOR_LOC_OCC, AMEC_SENSOR_NONUM, AMEEFP_250US_IN_HZ, AMEFP( 1, 0) ), + SENSOR_INFO_T_ENTRY( VOLTVDDSENSE, "mV\0", AMEC_SENSOR_TYPE_VOLTAGE, AMEC_SENSOR_LOC_OCC, AMEC_SENSOR_NONUM, AMEEFP_250US_IN_HZ, AMEFP( 1, -1) ), + SENSOR_INFO_T_ENTRY( VOLTVDNSENSE, "mV\0", AMEC_SENSOR_TYPE_VOLTAGE, AMEC_SENSOR_LOC_OCC, AMEC_SENSOR_NONUM, AMEEFP_250US_IN_HZ, AMEFP( 1, -1) ), SENSOR_INFO_T_ENTRY( GPEtickdur0, "us\0", AMEC_SENSOR_TYPE_TIME, AMEC_SENSOR_LOC_OCC, AMEC_SENSOR_NONUM, AMEEFP_250US_IN_HZ, AMEFP( 1, 0) ), SENSOR_INFO_T_ENTRY( GPEtickdur1, "us\0", AMEC_SENSOR_TYPE_TIME, AMEC_SENSOR_LOC_OCC, AMEC_SENSOR_NONUM, AMEEFP_250US_IN_HZ, AMEFP( 1, 0) ), SENSOR_INFO_T_ENTRY( RTLtickdur, "us\0", AMEC_SENSOR_TYPE_TIME, AMEC_SENSOR_LOC_OCC, AMEC_SENSOR_NONUM, AMEEFP_250US_IN_HZ, AMEFP( 1, 0) ), diff --git a/src/occ_405/sensor/sensor_table.c b/src/occ_405/sensor/sensor_table.c index 33c34d7..faa7d68 100755 --- a/src/occ_405/sensor/sensor_table.c +++ b/src/occ_405/sensor/sensor_table.c @@ -287,7 +287,8 @@ const sensor_ptr_t G_amec_sensor_list[] = SENSOR_PTR( PROBE250US5, &g_amec_sys.fw.probe250us[5]), SENSOR_PTR( PROBE250US6, &g_amec_sys.fw.probe250us[6]), SENSOR_PTR( PROBE250US7, &g_amec_sys.fw.probe250us[7]), - + SENSOR_PTR( VOLTVDDSENSE, &g_amec_sys.fw.voltvddsense), + SENSOR_PTR( VOLTVDNSENSE, &g_amec_sys.fw.voltvdnsense), SENSOR_PTR( GPEtickdur0, &g_amec_sys.fw.gpetickdur[0]), SENSOR_PTR( GPEtickdur1, &g_amec_sys.fw.gpetickdur[1]), SENSOR_PTR( RTLtickdur, &g_amec_sys.fw.prcdupdatedur), @@ -467,6 +468,8 @@ const minisensor_ptr_t G_amec_mini_sensor_list[] INIT_SECTION = MINI_SENSOR_PTR( PROBE250US5, NULL), MINI_SENSOR_PTR( PROBE250US6, NULL), MINI_SENSOR_PTR( PROBE250US7, NULL), + MINI_SENSOR_PTR( VOLTVDDSENSE, NULL), + MINI_SENSOR_PTR( VOLTVDNSENSE, NULL), MINI_SENSOR_PTR( GPEtickdur0, NULL), MINI_SENSOR_PTR( GPEtickdur1, NULL), MINI_SENSOR_PTR( RTLtickdur, NULL), -- cgit v1.2.1