diff options
| author | Michael Floyd <mfloyd@us.ibm.com> | 2018-02-05 10:30:38 -0600 |
|---|---|---|
| committer | hostboot <hostboot@us.ibm.com> | 2018-03-22 14:08:27 -0500 |
| commit | 45251a638379a482376b4df39a078e991abedc0d (patch) | |
| tree | 87480ae5acb681f9789106a10e4d73ac9c974a42 /import | |
| parent | 9740ca18348d3c66673931ecaa1d2d96ca64365c (diff) | |
| download | talos-hcode-45251a638379a482376b4df39a078e991abedc0d.tar.gz talos-hcode-45251a638379a482376b4df39a078e991abedc0d.zip | |
CME Code Size Reduction ATTEMPT#3
-- some IOTA kernel cleanup
-- also add checking for IOTA execution stack overflow
-- re-coded to eliminate some math library macro usage
-- added native 16-bit multiply
-- re-coded to remove redundancy from external interrupt handler
-- removed dec handler (optional define) and other minor cleanup
-- fixed Interrupt initialization code in std_init (all PPE images)
-- always inline pstate_db0_clip_bcast & update_vdm_jump_values_in_dpll
-- optimized pls calculation code
-- optimized pstate init, db1 handler, core good handling
-- optimized pmcr requests and pmsr updates (always write for both cores)
Key_Cronus_Test=PM_REGRESS
Change-Id: I6965a5a581562f0bb1cd735642f592cb4954970b
Original-Change-Id: If48fec5832bd5e46cb89f0d6a97d90a488e8ff7b
CQ: SW415503
RTC: 178789
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/53381
Tested-by: PPE CI <ppe-ci+hostboot@us.ibm.com>
Tested-by: Hostboot CI <hostboot-ci+hostboot@us.ibm.com>
Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com>
Tested-by: Cronus HW CI <cronushw-ci+hostboot@us.ibm.com>
Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com>
Reviewed-by: YUE DU <daviddu@us.ibm.com>
Reviewed-by: RANGANATHPRASAD G. BRAHMASAMUDRA <prasadbgr@in.ibm.com>
Reviewed-by: Gregory S. Still <stillgs@us.ibm.com>
Diffstat (limited to 'import')
24 files changed, 161 insertions, 1590 deletions
diff --git a/import/chips/p9/common/pmlib/include/cmehw_common.h b/import/chips/p9/common/pmlib/include/cmehw_common.h index 76517870..52689d00 100644 --- a/import/chips/p9/common/pmlib/include/cmehw_common.h +++ b/import/chips/p9/common/pmlib/include/cmehw_common.h @@ -35,9 +35,9 @@ enum CME_CORE_MASKS { - CME_MASK_C0 = 2, - CME_MASK_C1 = 1, - CME_MASK_BC = 3 + CME_MASK_C0 = 2, // Just Core0 = 0b10 + CME_MASK_C1 = 1, // Just Core1 = 0b01 + CME_MASK_BC = 3 // Both Cores = 0b11 }; /// CME SCOM @@ -57,12 +57,6 @@ enum CME_BCEBAR_INDEXES CME_BCEBAR_1 = 1 }; -enum CME_ERR_INJ_BIT_POS -{ - CME_PSTATE_HCODE_ERR_INJ_BIT = 0x00000002, - CME_STOP_HCODE_ERR_INJ_BIT = 0x00000001, -}; - #define CME_SCOM_ADDR(addr, core, op) (addr | (core << 22) | (op << 20)) // cme getscom default with 'eq' op diff --git a/import/chips/p9/common/pmlib/include/ppehw_common.h b/import/chips/p9/common/pmlib/include/ppehw_common.h index 3b3efafb..cc01e185 100644 --- a/import/chips/p9/common/pmlib/include/ppehw_common.h +++ b/import/chips/p9/common/pmlib/include/ppehw_common.h @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HCODE Project */ /* */ -/* COPYRIGHT 2015,2017 */ +/* COPYRIGHT 2015,2018 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -25,6 +25,8 @@ #ifndef __PPEHW_COMMON_H__ #define __PPEHW_COMMON_H__ +#include "ppe42math.h" + /// 64bits data typedef union { diff --git a/import/chips/p9/procedures/hwp/lib/p9_pstate_parameter_block.h b/import/chips/p9/procedures/hwp/lib/p9_pstate_parameter_block.h deleted file mode 100644 index 120c48db..00000000 --- a/import/chips/p9/procedures/hwp/lib/p9_pstate_parameter_block.h +++ /dev/null @@ -1,452 +0,0 @@ -/* IBM_PROLOG_BEGIN_TAG */ -/* This is an automatically generated prolog. */ -/* */ -/* $Source: import/chips/p9/procedures/hwp/lib/p9_pstate_parameter_block.h $ */ -/* */ -/* OpenPOWER HCODE Project */ -/* */ -/* COPYRIGHT 2015,2017 */ -/* [+] International Business Machines Corp. */ -/* */ -/* */ -/* Licensed under the Apache License, Version 2.0 (the "License"); */ -/* you may not use this file except in compliance with the License. */ -/* You may obtain a copy of the License at */ -/* */ -/* http://www.apache.org/licenses/LICENSE-2.0 */ -/* */ -/* Unless required by applicable law or agreed to in writing, software */ -/* distributed under the License is distributed on an "AS IS" BASIS, */ -/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ -/* implied. See the License for the specific language governing */ -/* permissions and limitations under the License. */ -/* */ -/* IBM_PROLOG_END_TAG */ -/// @file p9_pstate_parameter_block.h -/// @brief Definitons of paramater information used to process pstates -/// -// *HWP HW Owner : Greg Still <stillgs@us.ibm.com> -// *HWP HW Owner : Michael Floyd <mfloyd@us.ibm.com> -// *HWP FW Owner : Martha Broyles <mbroyles@us.ibm.com> -// *HWP Team : PM -// *HWP Level : 1 -// *HWP Consumed by : PGPE, OCC - -#ifndef __P9_PSTATE_PARAMETER_BLOCK_H__ -#define __P9_PSTATE_PARAMETER_BLOCK_H__ - -#include <p9_pstates.h> - -// ssrivath- See if this is required -#ifdef __cplusplus -extern "C" { -#endif - -//ssrivath, Also defined in p9_pstates.h -// can remove from here if below structure is moved to p9_pstates.h -#define MAX_ACTIVE_CORES 24 - -/// An internal operating point -/// -/// Internal operating points include characterization (both the original, -/// unbiased values and biased by external attributes) and load-line corrected -/// voltages for the external VRM. For the internal VRM, effective e-voltages -/// and maxreg voltages are stored. All voltages are stored as -/// uV. Characterization currents are in mA. Frequencies are in KHz. The -/// Pstate of the operating point (as a potentially out-of-bounds value) is -/// also stored. - -typedef struct -{ - - uint32_t vdd_uv; - uint32_t vcs_uv; - uint32_t vdd_corrected_uv; - uint32_t vcs_corrected_uv; - uint32_t vdd_corrected_wof_uv[MAX_ACTIVE_CORES]; - uint32_t vcs_corrected_wof_uv[MAX_ACTIVE_CORES]; - uint32_t vdd_ivrm_effective_uv; - uint32_t vcs_ivrm_effective_uv; - uint32_t vdd_maxreg_uv; - uint32_t vcs_maxreg_uv; - uint32_t idd_ma; - uint32_t ics_ma; - uint32_t frequency_khz; - int32_t pstate; - -} OperatingPoint; - - -/// Constants required to compute and interpolate operating points -/// -/// The nominal frequency and frequency step-size is given in Hz. Load-line -/// and on-chip distribution resistances are given in micro-Ohms. -/// -/// \todo Confirm that the "eVID V[dd,cs] Eff" correction is modeled as a simple -/// resistance similar to the load line. - -typedef struct -{ - - uint32_t reference_frequency_khz; - uint32_t frequency_step_khz; // This is the reference frequency / DPPL_DIVIDER - uint32_t vdd_load_line_uohm; - uint32_t vcs_load_line_uohm; - uint32_t vdn_load_line_uohm; - uint32_t vdd_distribution_uohm; - uint32_t vcs_distribution_uohm; - uint32_t vdn_distribution_uohm; - uint32_t vdd_voffset_uv; - uint32_t vcs_voffset_uv; - uint32_t vdn_voffset_uv; -} OperatingPointParameters; - - -/// A chip characterization - -typedef struct -{ - - VpdOperatingPoint* vpd; - VpdOperatingPoint* vpd_unbiased; - OperatingPoint* ops; - OperatingPointParameters* parameters; - uint32_t points; - uint32_t max_cores; // Needed for WOF - -} ChipCharacterization; - - -/// @todo IVRM structures based no an HCode design are not complete -/// The following is the P8 structure for reference. -typedef struct IVRM_PARM_DATA -{ - uint32_t vin_min; // Minimum input voltage - uint32_t vin_max; // Maximum input voltage - uint32_t vin_table_step_size; // Granularity of Vin table entries - uint32_t vin_table_setsperrow; // Vin sets per Vds row - uint32_t vin_table_pfetstrperset; // PFET Strength values per Vin set - uint32_t vout_min; // Minimum regulated output voltage - uint32_t vout_max; // Maximum regulated output voltage - uint32_t vin_entries_per_vds; // Vin array entries per vds region - uint32_t vds_min_range_upper_bound; // Starting point for vds regions - uint32_t vds_step_percent; // vds region step muliplier - uint32_t vds_region_entries; // vds region array entries (in hardware) - uint32_t pfetstr_default; // Default PFET Strength with no calibration - uint32_t positive_guardband; // Plus side guardband (%) - uint32_t negative_guardband; // Negative side guardband (%) - uint32_t number_of_coefficients; // Number of coefficents in cal data - uint32_t force_pfetstr_values; // 0 - calculated; 1 = forced - uint32_t forced_pfetstr_value; // If force_pfetstr_values = 1, use this value - // 5b value used as it to fill in all entries -} ivrm_parm_data_t; - -//Section added back by ssrivath -// START OF PARMS REQUIRED VPD parsing procedures -//#define S132A_POINTS 4 - Replaced by NUM_OP_POINTS -#define PSTATE_STEPSIZE 1 -#define EVRM_DELAY_NS 100 -#define DEAD_ZONE_5MV 20 // 100mV -#define PDV_BUFFER_SIZE 51 -#define PDV_BUFFER_ALLOC 512 - -//#define PDM_BUFFER_SIZE 105 -#define PDM_BUFFER_SIZE 257 // Value is for version 3 @ 256 + 1 for version number -#define PDM_BUFFER_ALLOC 513 // Value is for version 2 @ 512 + 1 for version number -//#define BIAS_PCT_UNIT 0.005 -#define BIAS_PCT_UNIT 0.5 -#define BOOST_PCT_UNIT 0.001 -#define POUNDM_POINTS 13 -#define POUNDM_MEASUREMENTS_PER_POINT 4 - -// #V 2 dimensional array values (5x5) - 5 operating point and 5 values per operating point -#define PV_D 5 -#define PV_W 5 - -// Replaced by VPD_PV_ORDER_STR -//// order of operating points from slow to fast in #V -//// 1=pwrsave 0=nominal 2=turbo. 3=ultraturbo -//#define PV_OP_ORDER {1, 0, 2, 3} -//#define PV_OP_ORDER_STR {"Nominal", "PowerSave", "Turbo", "UltraTurbo"} -//#define PV_OP_ORDER_MIN_VALID {1, 1, 1, 0} - -// IQ Keyword Sizes -#define IQ_BUFFER_SIZE 9 -#define IQ_BUFFER_ALLOC 64 -// END OF PARMS REQUIRED VPD parsing procedures - - -// Structure contatining all attributes required by Pstate Parameter block -typedef struct -{ - uint32_t attr_freq_core_ceiling_mhz; - -// Loadline, Distribution loss and Distribution offset attributes -// uint32_t attr_proc_r_loadline_vdd; -// uint32_t attr_proc_r_loadline_vcs; -// uint32_t attr_proc_r_distloss_vdd; -// uint32_t attr_proc_r_distloss_vcs; -// uint32_t attr_proc_vrm_voffset_vdd; -// uint32_t attr_proc_vrm_voffset_vcs; - - uint32_t attr_proc_r_loadline_vdd_uohm; - uint32_t attr_proc_r_distloss_vdd_uohm; - uint32_t attr_proc_vrm_voffset_vdd_uohm; - uint32_t attr_proc_r_loadline_vdn_uohm; - uint32_t attr_proc_r_distloss_vdn_uohm; - uint32_t attr_proc_vrm_voffset_vdn_uohm; - uint32_t attr_proc_r_loadline_vcs_uohm; - uint32_t attr_proc_r_distloss_vcs_uohm; - uint32_t attr_proc_vrm_voffset_vcs_uohm; - -// Voltage Bias attributes -// uint32_t attr_voltage_ext_vdd_bias_up; -// uint32_t attr_voltage_ext_vcs_bias_up; -// uint32_t attr_voltage_ext_vdd_bias_down; -// uint32_t attr_voltage_ext_vcs_bias_down; -// uint32_t attr_voltage_int_vdd_bias_up; -// uint32_t attr_voltage_int_vcs_bias_up; -// uint32_t attr_voltage_int_vdd_bias_down; -// uint32_t attr_voltage_int_vcs_bias_down ; - -// uint32_t attr_freq_proc_refclock; - uint32_t attr_freq_proc_refclock_khz; - uint32_t attr_proc_dpll_divider; - uint32_t attr_cpm_turbo_boost_percent; - uint32_t attr_cpm_inflection_points[16]; - -// Frequency Bias attributes -// uint32_t attr_freq_ext_bias_up; -// uint32_t attr_freq_ext_bias_down; - - int32_t attr_freq_ext_bias_ultraturbo; - int32_t attr_freq_ext_bias_turbo; - int32_t attr_freq_ext_bias_nominal; - int32_t attr_freq_ext_bias_powersave; - -// Voltage Bias attributes -// uint32_t attr_voltage_ext_bias_up; -// uint32_t attr_voltage_ext_bias_down; -// uint32_t attr_voltage_int_bias_up; -// uint32_t attr_voltage_int_bias_down; - - int32_t attr_voltage_vdd_bias_ultraturbo; - int32_t attr_voltage_vdd_bias_turbo; - int32_t attr_voltage_vdd_bias_nominal; - int32_t attr_voltage_vdd_bias_powersave; - int32_t attr_voltage_vcs_bias; - int32_t attr_voltage_vdn_bias; - int32_t attr_voltage_int_vdd_bias; - - uint32_t attr_dpll_bias; - uint32_t attr_undervolting; - uint32_t attr_pm_safe_frequency_mhz; - -// uint32_t attr_freq_core_floor; - uint32_t attr_freq_core_floor_mhz; - uint32_t attr_boot_freq_mhz; - -// Resonant clock frequency attrmbutes -// uint32_t attr_pm_resonant_clock_full_clock_sector_buffer_frequency; -// uint32_t attr_pm_resonant_clock_low_band_lower_frequency; -// uint32_t attr_pm_resonant_clock_low_band_upper_frequency; -// uint32_t attr_pm_resonant_clock_high_band_lower_frequency; -// uint32_t attr_pm_resonant_clock_high_band_upper_frequency; - - uint32_t attr_pm_resonant_clock_full_clock_sector_buffer_frequency_khz; - uint32_t attr_pm_resonant_clock_low_band_lower_frequency_khz; - uint32_t attr_pm_resonant_clock_low_band_upper_frequency_khz; - uint32_t attr_pm_resonant_clock_high_band_lower_frequency_khz; - uint32_t attr_pm_resonant_clock_high_band_upper_frequency_khz; - - uint8_t attr_system_wof_enabled; - uint8_t attr_system_ivrms_enabled; - uint32_t attr_tdp_rdp_current_factor; - -// P8 attributes not needed in P9 -// uint8_t attr_chip_ec_feature_resonant_clk_valid; -// uint8_t attr_proc_ec_core_hang_pulse_bug; -// uint8_t attr_chip_ec_feature_ivrm_winkle_bug; -// uint8_t attr_pm_system_ivrm_vpd_min_level; - -} AttributeList; - -//ssrivath, Start of function declarations - -// ---------------------------------------------------------------------- -// Function prototypes -// ---------------------------------------------------------------------- - -/// ---------------------------------------------------------------- -/// @brief Get #V data and put into array -/// @param[i] i_target Chip Target -/// @param[i] attr_mvpd_data 6x5 array to hold the #V data -/// @return FAPI2::SUCCESS -/// ---------------------------------------------------------------- -fapi2::ReturnCode -proc_get_mvpd_data ( const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target, - AttributeList* attr, - uint32_t attr_mvpd_data[PV_D][PV_W], - uint32_t* valid_pdv_points, - uint8_t* present_chiplets ); - -/// ------------------------------------------------------------------- -/// @brief Perform data validity check on #V data -/// @param[i] poundv_data pointer to array of #V data -/// @return FAPI2::SUCCESS -/// ------------------------------------------------------------------- - -fapi2::ReturnCode -proc_chk_valid_poundv ( const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target, - AttributeList* attr, - const uint32_t chiplet_mvpd_data[PV_D][PV_W], - uint32_t* valid_pdv_points, - uint8_t chiplet_num, - uint8_t bucket_id); - - -/// ---------------------------------------------------------------- -/// @brief Get IQ (IDDQ) data and put into array -/// @param[in] i_target => Chip Target -/// @param[inout] attr_mvpd_iddq => 24 x 16 array to hold the IQ data -/// @return FAPI2::SUCCESS -/// ---------------------------------------------------------------- - -fapi2::ReturnCode -proc_get_mvpd_iddq ( const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target, - PstateSuperStructure* pss); - -/// ----------------------------------------------------------------------- -/// @brief Get needed attributes -/// @param[in] i_target => Chip Target -/// @param[inout] attr => pointer to attribute list structure -/// @return FAPI2::SUCCESS -/// ----------------------------------------------------------------------- - -fapi2::ReturnCode -proc_get_attributes ( const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target, - AttributeList* i_attr); - -/// --------------------------------------------------------------------------- -/// @brief Check and process #V bias attributes for external and internal -/// @param[in] attr_mvpd_data => 5x5 array to hold the #V data -/// @param[in] *attr => pointer to attribute list structure -/// @param[inout] * volt_int_vdd_bias => pointer to internal vdd bias -/// @param[inout] * volt_int_vcs_bias => pointer to internal vcs bias -/// @return FAPI2::SUCCESS -/// --------------------------------------------------------------------------- - -fapi2::ReturnCode -proc_get_extint_bias ( uint32_t attr_mvpd_data[PV_D][PV_W], - const AttributeList* attr, - double* volt_int_vdd_bias, - double* volt_int_vcs_bias); - -/// ------------------------------------------------------------------- -/// @brief Boost max frequency in pstate table based on boost attribute -/// @param[inout] *pss => pointer to pstate superstructure -/// @param[in] *attr => pointer to attribute list structure -/// @return FAPI2::SUCCESS -/// ------------------------------------------------------------------- - -fapi2::ReturnCode -proc_boost_gpst ( PstateSuperStructure* pss, - uint32_t attr_boost_percent); - -/// ------------------------------------------------------------ -/// @brief Update Psafe_pstate -/// @param[inout] *pss => pointer to pstate superstructure -/// @param[in] *attr => pointer to attribute list structure -/// @return FAPI2::SUCCESS -/// ------------------------------------------------------------ - -fapi2::ReturnCode -proc_upd_psafe_ps ( PstateSuperStructure* pss, - const AttributeList* attr); - -/// ------------------------------------------------------------ -/// @brief Update Floor_pstate -/// @param[inout] *pss => pointer to pstate superstructure -/// @param[in] *attr => pointer to attribute list structure -/// @return FAPI2::SUCCESS -/// ------------------------------------------------------------ - -fapi2::ReturnCode -proc_upd_floor_ps ( PstateSuperStructure* pss, - const AttributeList* attr); - -/// ------------------------------------------------------------------- -/// @brief Convert Resonant Clocking attributes to pstate values and update superstructure with those values -/// @param[inout] *pss => pointer to pstate superstructure -/// @param[in] *attr => pointer to attribute list structure -/// @return FAPI2::SUCCESS -/// ------------------------------------------------------------------- - -fapi2::ReturnCode -proc_res_clock ( PstateSuperStructure* pss, - AttributeList* attr_list); - -/// ------------------------------------------------------------ -/// @brief Populate a subset of the WOFElements structure from Attributes -/// @param[inout] *pss => pointer to pstate superstructure -/// @param[in] *attr => pointer to attribute list structure -/// @return FAPI2::SUCCESS -/// ------------------------------------------------------------ - -fapi2::ReturnCode -load_wof_attributes ( PstateSuperStructure* pss, - const AttributeList* attr); - -/// ------------------------------------------------------------ -/// @brief Copy VPD operating point into destination in assending order -/// @param[in] &src[NUM_OP_POINTS] => reference to source VPD structure (array) -/// @param[out] *dest[NUM_OP_POINTS] => pointer to destination VpdOperatingPoint structure -/// @return FAPI2::SUCCESS -/// ------------------------------------------------------------ - -fapi2::ReturnCode -load_mvpd_operating_point ( const uint32_t src[PV_D][PV_W], - VpdOperatingPoint* dest); - -/// ------------------------------------------------------------ -/// @brief Update CPM Range table -/// @param[inout] *pss => pointer to pstate superstructure -/// @param[in] *attr => pointer to attribute list structure -/// @return FAPI2::SUCCESS -/// ------------------------------------------------------------ - -//fapi2::ReturnCode -//proc_upd_cpmrange ( PstateSuperStructure *pss, -// const AttributeList *attr); - - -/// @typedef p9_pstate_parameter_block_FP_t -/// function pointer typedef definition for HWP call support -typedef fapi2::ReturnCode (*p9_pstate_parameter_block_FP_t) ( - const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>&); - -extern "C" -{ - -/// ------------------------------------------------------------------- -/// @brief Populate Pstate super structure from VPD data -/// @param[in] i_target => Chip Target -/// @param[inout] *pss => pointer to pstate superstructure -/// @return FAPI2::SUCCESS -/// ------------------------------------------------------------------- - fapi2::ReturnCode - p9_pstate_parameter_block( const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target, - PstateSuperStructure* io_pss); - -} // extern C - - -//ssrivath, End of function declarations - -// ssrivath- See if this is required - -#ifdef __cplusplus -} // end extern C -#endif - -#endif // __P9_PSTATE_PARAMETER_BLOCK_H__ diff --git a/import/chips/p9/procedures/hwp/lib/p9_pstates.h b/import/chips/p9/procedures/hwp/lib/p9_pstates.h deleted file mode 100644 index 5a7e8ae4..00000000 --- a/import/chips/p9/procedures/hwp/lib/p9_pstates.h +++ /dev/null @@ -1,977 +0,0 @@ -/* IBM_PROLOG_BEGIN_TAG */ -/* This is an automatically generated prolog. */ -/* */ -/* $Source: import/chips/p9/procedures/hwp/lib/p9_pstates.h $ */ -/* */ -/* OpenPOWER HCODE Project */ -/* */ -/* COPYRIGHT 2015,2017 */ -/* [+] International Business Machines Corp. */ -/* */ -/* */ -/* Licensed under the Apache License, Version 2.0 (the "License"); */ -/* you may not use this file except in compliance with the License. */ -/* You may obtain a copy of the License at */ -/* */ -/* http://www.apache.org/licenses/LICENSE-2.0 */ -/* */ -/* Unless required by applicable law or agreed to in writing, software */ -/* distributed under the License is distributed on an "AS IS" BASIS, */ -/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ -/* implied. See the License for the specific language governing */ -/* permissions and limitations under the License. */ -/* */ -/* IBM_PROLOG_END_TAG */ -/// @file p9_pstates.h -/// @brief Pstate structures and support routines for OCC product firmware -/// -// *HWP HW Owner : Greg Still <stillgs@us.ibm.com> -// *HWP HW Owner : Michael Floyd <mfloyd@us.ibm.com> -// *HWP FW Owner : Martha Broyles <bilpatil@in.ibm.com> -// *HWP Team : PM -// *HWP Level : 1 -// *HWP Consumed by : PGPE, OCC - - -// @todo RTC 162565 - Temporary definition, -// Pick up p9_pm_utils code for revlev when code is merged -#ifdef _BIG_ENDIAN - - #define revle16(x) x - #define revle32(x) x - #define revle64(x) x - -#else - - uint16_t revle16(uint16_t i_x); - uint32_t revle32(uint32_t i_x); - uint64_t revle64(uint64_t i_x); - -#endif - -#ifndef __P9_PSTATES_H__ -#define __P9_PSTATES_H__ - -/// A Pstate type -/// -/// Pstates are unsigned but, to avoid bugs, Pstate register fields should -/// always be extracted to a variable of type Pstate. If the size of Pstate -/// variables ever changes we will have to revisit this convention. -typedef uint8_t Pstate; - -/// A DPLL frequency code -/// -/// DPLL frequency codes (Fmax and Fmult) are 15 bits -typedef uint16_t DpllCode; - -/// An AVS VID code -typedef uint16_t VidAVS; - -/// The minimum Pstate (knowing the increasing Pstates numbers represent -/// decreasing frequency) -#define PSTATE_MIN 255 - -/// The maximum Pstate (knowing the increasing Pstates numbers represent -/// decreasing frequency) -#define PSTATE_MAX 0 - -/// The minimum \e legal DPLL frequency code -/// -/// This is ~1GHz with a 16.6MHz tick frequency. -/// @todo Check this and the maximum -#define DPLL_MIN 0x03c - -/// The maximum DPLL frequency code -#define DPLL_MAX 0x1ff - -/// The minimum \a legal (non-power-off) AVS VID code -/// @todo Need to check with J. Kuesmann if there is a limit. May want this -/// to be an attribute. -#define AVS_MIN 0x0000 - -/// The maximum \a legal (non-power-off) AVS VID code -/// @todo Need to check with J. Kuesmann if there is a limit. May want this -/// to be an attribute. -#define AVS_MAX 0xFFFF - -//////////////////////////////////////////////////////////////////////////// -// Global and Local Pstate Tables -//////////////////////////////////////////////////////////////////////////// - -/// The Local Pstate table has 32 x 64-bit entries -#define LOCAL_PSTATE_ARRAY_ENTRIES 32 - -/// The Local Pstate Table alignment in memory. The alignment is -/// specified in the traditional log2 form. -/// The generated table applies to allow Quads in P9. -/// @todo see if there is really any alignment requirement from the OCC team -#define LOCAL_PSTATE_TABLE_ALIGNMENT 10 // 1KB - -/// The VDS/VIN table has 32 x 64-bit entries -/// @todo We need to discuss if VDS is precomputed (like in P8) to avoid -/// division during runtime. Leaving this from P8 for now. -#define VDSVIN_ARRAY_ENTRIES 64 - -/// The AVS VID base voltage in micro-Volts -#define AVS_BASE_UV 1612500 - -/// The AVS VID step as an unsigned number (micro-Volts) -#define AVS_STEP_UV 1000 - -//ssrivath, Is this the same as IVID_BASE_UV and IVID_STEP_UV below -/// The VRM-11 VID base voltage in micro-Volts -#define VRM11_BASE_UV 1612500 - -/// The VRM-11 VID step as an unsigned number (micro-Volts) -#define VRM11_STEP_UV 6250 - -// ssrivath, iVID values based on Section 2.8.7 of spec -/// The iVID base voltage in micro-Volts -#define IVID_BASE_UV 512000 - -/// The iVID step as an unsigned number (micro-Volts) -#define IVID_STEP_UV 4000 - -/// Maximum number of Quads (4 cores plus associated caches) -#define MAX_QUADS 6 - -// Constants associated with VRM stepping -// @todo Determine what is needed here (eg Attribute mapping) and if any constants -// are warrented - -/// VPD #V Operating Points -#define VPD_PV_POINTS 4 -#define VPD_PV_ORDER_STR {"PowerSave", "Nominal ", "Turbo ", "UltraTurbo"} -#define POWERSAVE 1 -#define NOMINAL 0 -#define TURBO 2 -#define ULTRA 3 -#define POWERBUS 4 -#define VPD_PV_ORDER {POWERSAVE, NOMINAL, TURBO, ULTRA} - -/// IDDQ readings, -#define IDDQ_MEASUREMENTS 6 -#define MEASUREMENT_ELEMENTS 6 // Number of Quads for P9 -#define IDDQ_READINGS_PER_IQ 2 -#define IDDQ_ARRAY_VOLTAGES {0.60, 0.70, 0.80, 0.90, 1.00, 1.10} - -/// WOF Items -#define NUM_ACTIVE_CORES 24 -#define MAX_UT_PSTATES 64 // Oversized - -//ssrivath, Temporary definition -#define PGP_NCORES 24 - -/// Error/Panic codes for support routines -/// @todo Review the necessary error codes. This are really PGPE functions now -/// and many below elsewhere. However, the error code plumbing from PGPE to -/// OCC for error logging purposes is an action. - -#define VRM11_INVALID_VOLTAGE 0x00876101 - -#define PSTATE_OVERFLOW 0x00778a01 -#define PSTATE_UNDERFLOW 0x00778a02 - -#define PSTATE_LT_PSTATE_MIN 0x00778a03 -#define PSTATE_GT_PSTATE_MAX 0x00778a04 - -#define DPLL_OVERFLOW 0x00d75501 -#define DPLL_UNDERFLOW 0x00d75502 - -#define AVSVID_OVERFLOW 0x00843101 -#define AVSVID_UNDERFLOW 0x00843102 - -#define GPST_INVALID_OBJECT 0x00477801 -#define GPST_INVALID_ARGUMENT 0x00477802 -#define GPST_INVALID_ENTRY 0x00477803 -#define GPST_PSTATE_CLIPPED_LOW 0x00477804 -#define GPST_PSTATE_CLIPPED_HIGH 0x00477805 -#define GPST_BUG 0x00477806 -#define GPST_PSTATE_GT_GPST_PMAX 0x00477807 - -#define LPST_INVALID_OBJECT 0x00477901 -#define LPST_GPST_WARNING 0x00477902 -#define LPST_INCR_CLIP_ERROR 0x00477903 - -/// PstateParmsBlock Magic Number -/// -/// This magic number identifies a particular version of the -/// PstateParmsBlock and its substructures. The version number should be -/// kept up to date as changes are made to the layout or contents of the -/// structure. - -#define PSTATE_PARMSBLOCK_MAGIC 0x5053544154453030ull /* PSTATE00 */ - - -/// \defgroup pstate_options Pstate Options -/// -/// These are flag bits for the \a options field of the PstateOptions -/// structure. -/// -/// @{ - - -/// pgpe_pstate() - Disable Pstate Hcode -#define PSTATE_DISABLE 0x01 - -/// pgpe_pstate() - Disable IVRM use. -#define PSTATE_IVRMS_DISABLE 0x02 - -/// pgpe_pstate() - Disable Resonant Clock use. -#define PSTATE_RESCLK_DISABLE 0x04 - -/// pgpe_pstate() - Disable VDM use. -#define PSTATE_VDM_DISABLE 0x08 - -/// pgpe_pstate() - Force the system to the minimum Pstate at initialization -/// -/// This mode is added as a workaround for the case that the AVSBus interface -/// is not working correctly during initial bringup. This forces Pstate mode -/// to come up at a low frequency. -#define PSTATE_FORCE_INITIAL_PMIN 0x10 - -/// @} - - -/// \defgroup pstate_options Pstate Options -/// -/// These are flag bits for the \a options field of the PstateOptions -/// structure. -/// -/// @{ - -/// pgpe_gpst_output() - Bypass producing the Global Pstate table into HOMER -#define PSTATE_NO_GPST 0x01 - -/// cme_lps_install() - Bylass Local Pstate installation and setup -#define PSTATE_NO_INSTALL_LPSA 0x02 - -/// cme_resclk_install - Bypass resonant clocking Pstate limit setup -#define PSTATE_NO_INSTALL_RESCLK 0x04 - -/// pgpe_enable_pstates() - Force the system to the minimum Pstate at -/// initialization -/// -/// This mode is added as a workaround for the case that the AVSBus interface -/// is not working correctly during initial bringup. This forces Pstate mode -/// to come up at a low frequency. -#define PSTATE_FORCE_INITIAL_PMIN 0x10 - -/// @} - -#ifdef __cplusplus -extern "C" { -#endif - -#include <stdint.h> - - -/// Standard options controlling Pstate setup and installation procedures - -typedef struct -{ - - /// Option flags; See \ref pstate_options - uint32_t options; - - /// Pad structure to 8 bytes. Could also be used for other options later. - uint32_t pad; - -} PGPEPstateOptions; - - -/// Standard options controlling Pstate setup and installation procedures - -typedef struct -{ - - /// Option flags; See \ref pstate_options - uint32_t options; - - /// Pad structure to 8 bytes. Could also be used for other options later. - uint32_t pad; - -} QMPstateOptions; - -// ssrivath, Moving from pstate param header to this file @TODO - Consolidate with PGPE/QM PState options -typedef struct -{ - - /// Option flags; See \ref pstate_options - uint32_t options; - - /// Pad structure to 8 bytes. Could also be used for other options later. - uint32_t pad; - -} PstateOptions; - - -/// Resonant Clock Stepping Entry -/// -typedef union -{ - uint16_t value; - struct - { -#ifdef _BIG_ENDIAN - uint16_t sector_buffer : 4; - uint16_t spare1 : 1; - uint16_t pulse_enable : 1; - uint16_t pulse_mode : 2; - uint16_t resonant_switch : 4; - uint16_t spare4 : 4; -#else - uint16_t spare4 : 4; - uint16_t resonant_switch : 4; - uint16_t pulse_mode : 2; - uint16_t pulse_enable : 1; - uint16_t spare1 : 1; - uint16_t sector_buffer : 4; -#endif // _BIG_ENDIAN - } fields; - -} ResonantClockingStepEntry; - -static const uint32_t RESCLK_FREQ_REGIONS = 8; -static const uint32_t RESCLK_STEPS = 64; -static const uint32_t RESCLK_L3_STEPS = 4; - -typedef struct ResonantClockControl -{ - uint8_t resclk_freq[RESCLK_FREQ_REGIONS]; // Lower frequency of Resclk Regions - - uint8_t resclk_index[RESCLK_FREQ_REGIONS]; // Index into value array for the - // respective Resclk Region - - /// Array containing the transition steps - ResonantClockingStepEntry steparray[RESCLK_STEPS]; - - /// Delay between steps (in nanoseconds) - /// Maximum delay: 65.536us - uint16_t step_delay_ns; - - /// L3 Clock Stepping Array - uint8_t l3_steparray[RESCLK_L3_STEPS]; - - /// Resonant Clock Voltage Threshold (in millivolts) - /// This value is used to choose the appropriate L3 clock region setting. - uint16_t l3_threshold_mv; - -} ResonantClockingSetup; - -// ssrivath, Modified units for vdd/vcs/idd/ics as per P9 VPD spec -/// A VPD operating point -/// -/// VPD operating points are stored without load-line correction. Frequencies -/// are in MHz, voltages are specified in units of 1mV, and characterization -/// currents are specified in units of 100mA. -/// -//ssrivath, Is maxreg points part of P9 VPD ? -/// \bug The assumption is that the 'maxreg' points for the iVRM will also be -/// supplied in the VPD in units of 5mv. If they are supplied in some other -/// form then chip_characterization_create() will need to be modified. - -typedef struct -{ - - uint32_t vdd_mv; - uint32_t vcs_mv; - //uint32_t vdd_maxreg_5mv; - //uint32_t vcs_maxreg_5mv; - uint32_t idd_100ma; - uint32_t ics_100ma; - uint32_t frequency_mhz; - -} VpdOperatingPoint; - -/// VPD Biases. -/// -/// Percent bias applied to VPD operating points prior to interolation -/// -/// All values on in .5 percent (half percent -> hp) -typedef struct -{ - - int8_t vdd_ext_hp; - int8_t vdd_int_hp; - int8_t vdn_ext_hp; - int8_t vcs_ext_hp; - int8_t frequency_hp; - -} VpdBias; - -/// System Power Distribution Paramenters -/// -/// Parameters set by system design that influence the power distribution -/// for a rail to the processor module. This values are typically set in the -/// system machine readable workbook and are used in the generation of the -/// Global Pstate Table. This values are carried in the Pstate SuperStructure -/// for use and/or reference by OCC firmware (eg the WOF algorithm) - -typedef struct -{ - - /// Loadline - /// Impedance (binary microOhms) of the load line from a processor VDD VRM - /// to the Processor Module pins. - uint32_t loadline_uohm; - - /// Distribution Loss - /// Impedance (binary in microOhms) of the VDD distribution loss sense point - /// to the circuit. - uint32_t distloss_uohm; - - /// Distribution Offset - /// Offset voltage (binary in microvolts) to apply to the rail VRM - /// distribution to the processor module. - uint32_t distoffset_uv; - -} SysPowerDistParms; - - - -/// IDDQ Reading Type -/// Each entry is 2 bytes. The values are in 6.25mA units; this allow for a -/// maximum value of 409.6A to be represented. -/// -typedef uint16_t iddq_entry_t; - -/// AvgTemp Reading Type -/// Each entry is 1 byte. The values are in 0.5degC units; this allow for a -/// maximum value of 127degC to be represented. -/// -typedef uint16_t avgtemp_entry_t; - -/// Iddq Table -/// -/// A set of arrays of leakage values (Iddq) collected at various voltage -/// conditions during manufacturing test that will feed into the Workload -/// Optimized Frequency algorithms on the OCC. These values are not installed -/// in any hardware facilities. -/// -typedef struct -{ - - /// IDDQ version - uint8_t iddq_version; - - /// Good Quads per Sort - uint8_t good_quads_per_sort; - - /// Good Normal Cores per Sort - uint8_t good_normal_cores_per_sort; - - /// Good Caches per Sort - uint8_t good_caches_per_sort; - - /// Good Normal Cores - uint8_t good_normal_cores[MAX_QUADS]; - - /// Good Caches - uint8_t good_caches[MAX_QUADS]; - - /// RDP to TDP Scaling Factor in 0.01% units - uint16_t rdp_to_tdp_scale_factor; - - /// WOF Iddq Margin (aging factor) in 0.01% units - uint16_t wof_iddq_margin_factor; - - /// Temperature Scale Factor per 10C in 0.01% units - uint16_t temperature_scale_factor; - - /// Spare - uint8_t spare[10]; - - /// IVDD ALL Good Cores ON; 6.25mA units - iddq_entry_t ivdd_all_good_cores_on[IDDQ_MEASUREMENTS]; - - /// IVDD ALL Cores OFF; 6.25mA units - iddq_entry_t ivdd_all_cores_off[IDDQ_MEASUREMENTS]; - - /// IVDD ALL Good Cores OFF; 6.25mA units - iddq_entry_t ivdd_all_good_cores_off[IDDQ_MEASUREMENTS]; - - /// IVDD Quad 0 Good Cores ON, Caches ON; 6.25mA units - iddq_entry_t ivdd_quad_good_cores_on[MAX_QUADS][IDDQ_MEASUREMENTS]; - - /// IVDDN ; 6.25mA units - iddq_entry_t ivdn; - - - /// IVDD ALL Good Cores ON, Caches ON; 6.25mA units - avgtemp_entry_t avgtemp_all_good_cores_on[IDDQ_MEASUREMENTS]; - - /// avgtemp ALL Cores OFF, Caches OFF; 6.25mA units - avgtemp_entry_t avgtemp_all_cores_off_caches_off[IDDQ_MEASUREMENTS]; - - /// avgtemp ALL Good Cores OFF, Caches ON; 6.25mA units - avgtemp_entry_t avgtemp_all_good_cores_off[IDDQ_MEASUREMENTS]; - - /// avgtemp Quad 0 Good Cores ON, Caches ON; 6.25mA units - avgtemp_entry_t avgtemp_quad_good_cores_on[MAX_QUADS][IDDQ_MEASUREMENTS]; - - /// avgtempN ; 6.25mA units - avgtemp_entry_t avgtemp_vdn; - -} IddqTable; - -// -/// UltraTurbo Segment VIDs by Core Count -typedef struct -{ - - /// Number of Segment Pstates - uint8_t ut_segment_pstates; - - /// Maximum number of core possibly active - uint8_t ut_max_cores; - - /// VDD VID modification - /// 1 core active = offset 0 - /// 2 cores active = offset 1 - /// ... - /// 12 cores active = offset 11 - uint8_t ut_segment_vdd_vid[MAX_UT_PSTATES][NUM_ACTIVE_CORES]; - - /// VCS VID modification - /// 1 core active = offset 0 - /// 2 cores active = offset 1 - /// ... - /// 12 cores active = offset 11 - uint8_t ut_segment_vcs_vid[MAX_UT_PSTATES][NUM_ACTIVE_CORES]; - -} VIDModificationTable; - -/// Workload Optimized Frequency (WOF) Elements -/// -/// Structure defining various control elements needed by the WOF algorithm -/// firmware running on the OCC. -/// -typedef struct -{ - - /// WOF Enablement - uint8_t wof_enabled; - - /// TDP<>RDP Current Factor - /// Value read from ??? VPD - /// Defines the scaling factor that converts current (amperage) value from - /// the Thermal Design Point to the Regulator Design Point (RDP) as input - /// to the Workload Optimization Frequency (WOF) OCC algorithm. - /// - /// This is a ratio value and has a granularity of 0.01 decimal. Data - /// is held in hexidecimal (eg 1.22 is represented as 122 and then converted - /// to hex 0x7A). - uint32_t tdp_rdp_factor; - - /// UltraTurbo Segment VIDs by Core Count - VIDModificationTable ut_vid_mod; - - uint8_t pad[4]; - -} WOFElements; - -/// VDM/Droop Parameter Block -/// -typedef struct -{ - uint8_t vid_compare_override_mv_enable; - uint8_t vid_compare_override_mv[VPD_PV_POINTS]; - uint8_t vdm_response; - - // For the following *_enable fields, bits are defined to indicate - // which of the respective *override* array entries are valid. - // bit 0: UltraTurbo; bit 1: Turbo; bit 2: Nominal; bit 3: PowSave - uint8_t droop_small_override_enable; - uint8_t droop_large_override_enable; - uint8_t droop_extreme_override_enable; - uint8_t overvolt_override_enable; - uint16_t fmin_override_khz_enable; - uint16_t fmax_override_khz_enable; - - // The respecitve *_enable above indicate which index values are valid - uint8_t droop_small_override[VPD_PV_POINTS]; - uint8_t droop_large_override[VPD_PV_POINTS]; - uint8_t droop_extreme_override[VPD_PV_POINTS]; - uint8_t overvolt_override[VPD_PV_POINTS]; - uint16_t fmin_override_khz[VPD_PV_POINTS]; - uint16_t fmax_override_khz[VPD_PV_POINTS]; - - /// Pad structure to 8-byte alignment - /// @todo pad once fully structure is complete. - // uint8_t pad[1]; - -} VDMParmBlock; - - -/// The layout of the data created by the Pstate table creation firmware for -/// comsumption by the Pstate GPE. This data will reside in the Quad -/// Power Management Region (QPMR). -/// - -/// Standard options controlling Pstate setup procedures - -/// System Power Distribution Paramenters -/// -/// Parameters set by system design that influence the power distribution -/// for a rail to the processor module. This values are typically set in the -/// system machine readable workbook and are used in the generation of the -/// Global Pstate Table. This values are carried in the Pstate SuperStructure -/// for use and/or reference by OCC firmware (eg the WOF algorithm) - - -/// Quad Manager Flags -/// - -typedef union -{ - uint16_t value; - struct - { -#ifdef _BIG_ENDIAN - uint16_t resclk_enable : 1; - uint16_t ivrm_enable : 1; - uint16_t wof_enable : 1; - uint16_t dpll_dynamic_fmax_enable : 1; - uint16_t dpll_dynamic_fmin_enable : 1; - uint16_t dpll_droop_protect_enable : 1; - uint16_t reserved : 10; -#else - uint16_t reserved : 10; - uint16_t dpll_droop_protect_enable : 1; - uint16_t dpll_dynamic_fmin_enable : 1; - uint16_t dpll_dynamic_fmax_enable : 1; - uint16_t wof_enable : 1; - uint16_t ivrm_enable : 1; - uint16_t resclk_enable : 1; -#endif // _BIG_ENDIAN - } fields; - -} QuadManagerFlags; - -/// IVRM Parameter Block -/// -/// @todo Major work item. Largely will seed the CME Quad Manager to perform -/// iVRM voltage calculations - -static const uint32_t IVRM_ARRAY_SIZE = 64; -typedef struct iVRMInfo -{ - - /// Pwidth from 0.03125 to 1.96875 in 1/32 increments at Vin=Vin_Max - uint8_t strength_lookup[IVRM_ARRAY_SIZE]; // Each entry is a six bit value, right justified - - /// Scaling factor for the Vin_Adder calculation. - uint8_t vin_multiplier[IVRM_ARRAY_SIZE]; // Each entry is from 0 to 255. - - /// Vin_Max used in Vin_Adder calculation (in millivolts) - uint16_t vin_max_mv; - - /// Delay between steps (in nanoseconds) - /// Maximum delay: 65.536us - uint16_t step_delay_ns; - - /// Stabilization delay once target voltage has been reached (in nanoseconds) - /// Maximum delay: 65.536us - uint16_t stablization_delay_ns; - - /// Deadzone (in millivolts) - /// Maximum: 255mV. If this value is 0, 50mV is assumed. - uint8_t deadzone_mv; - - /// Pad to 8B - uint8_t pad; - -} IvrmParmBlock; - - -/// The layout of the data created by the Pstate table creation firmware for -/// comsumption by the CME Quad Manager. This data will reside in the Core -/// Power Management Region (CPMR). -/// -typedef struct -{ - - /// Magic Number - uint64_t magic; // the last byte of this number the structure's version. - - // QM Flags - QuadManagerFlags qmflags; - - /// Operating points - /// - /// VPD operating points are stored without load-line correction. Frequencies - /// are in MHz, voltages are specified in units of 5mV, and currents are - /// in units of 500mA. - VpdOperatingPoint operating_points[VPD_PV_POINTS]; - - /// Loadlines and Distribution values for the VDD rail - SysPowerDistParms vdd_sysparm; - - /// External Biases - /// - /// Biases applied to the VPD operating points prior to load-line correction - /// in setting the external voltages. This is used to recompute the Vin voltage - /// based on the Global Actual Pstate . - /// Values in 0.5% - VpdBias ext_biases[VPD_PV_POINTS]; - - /// Internal Biases - /// - /// Biases applied to the VPD operating points that are used for interpolation - /// in setting the internal voltages (eg Vout to the iVRMs) as part of the - /// Local Actual Pstate. - /// Values in 0.5% - VpdBias int_biases[VPD_PV_POINTS]; - - /// IVRM Data - IvrmParmBlock ivrm; - - /// Resonant Clock Grid Management Setup - ResonantClockingSetup resclk; - - /// VDM Data - VDMParmBlock vdm; - -} LocalPstateParmBlock; - -/// Global Pstate Parameter Block -/// -/// The GlobalPstateParameterBlock is an abstraction of a set of voltage/frequency -/// operating points along with hardware limits. Besides the hardware global -/// Pstate table, the abstract table contains enough extra information to make -/// it the self-contained source for setting up and managing voltage and -/// frequency in either Hardware or Firmware Pstate mode. -/// -/// When installed in PMC, Global Pstate table indices are adjusted such that -/// the defined Pstates begin with table entry 0. The table need not be full - -/// the \a pmin and \a entries fields define the minimum and maximum Pstates -/// represented in the table. However at least 1 entry must be defined to -/// create a legal table. -/// -/// Note that Global Pstate table structures to be mapped into PMC hardware -/// must be 1KB-aligned. This requirement is fullfilled by ensuring that -/// instances of this structure are 1KB-aligned. -typedef struct -{ - - - /// Magic Number - uint64_t magic; // the last byte of this number the structure's version. - - /// Pstate options - /// - /// The options are included as part of the GlobalPstateTable so that they - /// are available to all procedures after gpsm_initialize(). - PstateOptions options; - - /// The frequency associated with Pstate[0] in KHz - uint32_t reference_frequency_khz; - - /// The frequency step in KHz - uint32_t frequency_step_khz; - - /// Operating points - /// - /// VPD operating points are stored without load-line correction. Frequencies - /// are in MHz, voltages are specified in units of 5mV, and currents are - /// in units of 500mA. - VpdOperatingPoint operating_points[VPD_PV_POINTS]; - - /// Biases - /// - /// Biases applied to the VPD operating points prior to load-line correction - /// in setting the external voltages. - /// Values in 0.5% - VpdBias ext_biases[VPD_PV_POINTS]; - - /// Loadlines and Distribution values for the VDD rail - SysPowerDistParms vdd_sysparm; - - /// Loadlines and Distribution values for the VCS rail - SysPowerDistParms vcs_sysparm; - - /// Loadlines and Distribution values for the VDN rail - SysPowerDistParms vdn_sysparm; - - /// The "Safe" Voltage - /// - /// A voltage to be used when safe-mode is activated - /// @todo Need to detail this out yet. - uint32_t safe_voltage_mv; - - /// The "Safe" Frequency - /// - /// A voltage to be used when safe-mode is activated - /// @todo Need to detail this out yet. - uint32_t safe_frequency_khz; - - /// The exponent of the exponential encoding of Pstate stepping delay - uint8_t vrm_stepdelay_range; - - /// The significand of the exponential encoding of Pstate stepping delay - uint8_t vrm_stepdelay_value; - - /// VDM Data - VDMParmBlock vdm; - - /// The following are needed to generated the Pstate Table to HOMER. - - /// Internal Biases - /// - /// Biases applied to the VPD operating points that are used for interpolation - /// in setting the internal voltages (eg Vout to the iVRMs) as part of the - /// Local Actual Pstate. - /// Values in 0.5% - VpdBias int_biases[VPD_PV_POINTS]; - - /// IVRM Data - IvrmParmBlock ivrm; - - /// Resonant Clock Grid Management Setup - ResonantClockingSetup resclk; - - // @todo DPLL Droop Settings. These need communication to SGPE for STOP - -} GlobalPstateParmBlock; - - - - -/// The layout of the data created by the Pstate table creation firmware for -/// comsumption by the OCC firmware. This data will reside in the Quad -/// Power Management Region (QPMR). -/// -typedef struct -{ - - /// Magic Number - uint64_t magic; // the last byte of this number the structure's version. - - /// Operating points - /// - /// VPD operating points are stored without load-line correction. Frequencies - /// are in MHz, voltages are specified in units of 5mV, and currents are - /// in units of 500mA. - VpdOperatingPoint operating_points[VPD_PV_POINTS]; - - /// Loadlines and Distribution values for the VDD rail - SysPowerDistParms vdd_sysparm; - - /// Loadlines and Distribution values for the VCS rail - SysPowerDistParms vcs_sysparm; - - /// Iddq Table - IddqTable iddq; - - /// WOF Controls - WOFElements wof; - - // Frequency Limits - uint32_t frequency_min_khz; // Comes from PowerSave #V point after biases - uint32_t frequency_max_khz; // Comes from UltraTurbo #V point after biases - uint32_t frequency_step_khz; // Comes from refclk/dpll_divider attributes. - - // Todo: Martha asked for min_psate and max_pstate - uint32_t pstate_min; // Comes from PowerSave #V point after biases - uint32_t pstate_max; // Comes from UltraTurbo #V point after biases - -} OCCPstateParmBlock; - - -/// The layout of the various Pstate Parameter Blocks (PPBs) passed a single -/// structure for data movement. -/// -/// This structure is only used for passing Pstate data from the FSP/HostService -/// for placement into HOMER for consumption by into OCC, the Pstate PGPE and -/// CME. Therefore there is no alignment requirement. - -typedef struct -{ - - /// Magic Number - uint64_t magic; - - // PGPE content - GlobalPstateParmBlock globalppb; - - // CME content - LocalPstateParmBlock localppb; - - // OCC content - OCCPstateParmBlock occppb; - -} PstateSuperStructure; - -/// Pstate Table -/// -/// This structure defines the Pstate Table content -/// -- 16B structure - -typedef struct -{ - /// Pstate number - Pstate pstate; - - /// Assocated Frequency (in MHz) - uint16_t frequency_mhz; - - /// External VRM setpoint (in mV). this directly translates to AVSBus value - uint16_t external_vdd_mv; - - /// Effective VDD voltage at the module pins. This accounts for the system - /// parameter effects. - uint16_t effective_vdd_mv; - - /// Maximum iVRM regulation voltage. This is effective_vdd_mv - dead_zone_mv. - uint16_t max_regulation_vdd_mv; - - /// Internal VDD voltage at the output of the PFET header - uint16_t internal_vdd_mv; - - /// Pad to 16 bytes - uint32_t spare; - -} PstateTable; - -/// Generated Pstate Table -/// -/// This structure defines the Pstate Tables generated by PGPE Hcode upon -/// initialization. This content depicts the values that will be computed on the -/// fly during Pstate protocol execution based on the PstateSuperStructure -/// parameter content. - -static const uint32_t MAX_PSTATE_TABLE_ENTRIES = 128; - -typedef struct -{ - - /// Magic Number - uint64_t magic; // ASCII: "PSTATABL" - - // PGPE content - GlobalPstateParmBlock globalppb; - - /// The fastest frequency - after biases have been applied - uint32_t pstate0_frequency_khz; - - /// Highest Pstate Number => slowest Pstate generated - uint32_t highest_pstate; - - /// Generated table with system paramters included but without biases - PstateTable raw_pstates[MAX_PSTATE_TABLE_ENTRIES]; - - /// Generated table with system paramters and biases - /// Note: if all bias attributes are 0, this content will be the same - /// as the raw_pstates content. - PstateTable biased_pstates[MAX_PSTATE_TABLE_ENTRIES]; - -} GeneratedPstateInfo; - - - -#ifdef __cplusplus -} // end extern C -#endif - -#endif /* __P9_PSTATES_H__ */ diff --git a/import/chips/p9/procedures/ppe/iota/iota.c b/import/chips/p9/procedures/ppe/iota/iota.c index 0e36b6d2..109ded0e 100644 --- a/import/chips/p9/procedures/ppe/iota/iota.c +++ b/import/chips/p9/procedures/ppe/iota/iota.c @@ -43,15 +43,16 @@ iotaMachineState g_iota_machine_state_stack[(IOTA_MAX_NESTED_INTERRUPTS)] __attr { [ 0 ... (IOTA_MAX_NESTED_INTERRUPTS - 1) ] = IOTA_MACHINE_STATE_INIT }; -uint64_t g_iota_execution_stack[(IOTA_EXECUTION_STACK_SIZE / 8)] __attribute__((aligned(8))) = +uint64_t g_iota_execution_stack[((IOTA_EXECUTION_STACK_SIZE / 8) + 1)] __attribute__((aligned(8))) = { - [ 0 ... ((IOTA_EXECUTION_STACK_SIZE / 8) - 1) ] = IOTA_STACK_PATTERN + [ 0 ... (IOTA_EXECUTION_STACK_SIZE / 8) ] = IOTA_STACK_PATTERN }; iotaMachineState* g_iota_curr_machine_state_ptr = g_iota_machine_state_stack; iotaTimerFuncPtr g_iota_dec_handler = IOTA_TIMER_HANDLER(__iota_halt); iotaTimerFuncPtr g_iota_fit_handler = IOTA_TIMER_HANDLER(__iota_halt); +#if IOTA_IDLE_TASKS_ENABLE void _iota_evaluate_idle_tasks() { // Iterate over all idle tasks @@ -81,6 +82,7 @@ void _iota_evaluate_idle_tasks() } } } +#endif // IOTA_IDLE_TASKS_ENABLE extern void main(void); @@ -102,14 +104,17 @@ void iota_run() while(1) { +#if IOTA_IDLE_TASKS_ENABLE // Run any enabled idle tasks _iota_evaluate_idle_tasks(); +#endif // Put PPE engine into wait mode (idle). ppe_idle(); } } +#if IOTA_IDLE_TASKS_ENABLE void iota_set_idle_task_state(uint32_t state, uint32_t idle_task_idx) { if(idle_task_idx < g_iota_idle_task_list_size) @@ -127,6 +132,7 @@ void iota_set_idle_task_state(uint32_t state, uint32_t idle_task_idx) } } } +#endif void _iota_schedule(uint32_t schedule_reason) { @@ -152,9 +158,8 @@ void _iota_schedule(uint32_t schedule_reason) if(g_iota_task_list[task_idx] != IOTA_NO_TASK) { - uint32_t irq = cntlz64(g_ext_irq_vector); mtmsr(IOTA_DEFAULT_MSR); - g_iota_task_list[task_idx](task_idx, irq); + g_iota_task_list[task_idx](); // Interrupts are disabled once the task returns wrteei(0); iota_uih_restore(); @@ -166,15 +171,24 @@ void _iota_schedule(uint32_t schedule_reason) break; +#if ENABLE_CME_DEC_TIMER + case _IOTA_SCHEDULE_REASON_DEC: g_iota_dec_handler(); break; +#endif + +#if !DISABLE_CME_FIT_TIMER case _IOTA_SCHEDULE_REASON_FIT: g_iota_fit_handler(); break; +#endif + } +#if IOTA_IDLE_TASKS_ENABLE + // Check for idle tasks here // Rationale: if the g_iota_curr_machine_state_ptr == // g_iota_machine_state_stack, @@ -189,6 +203,14 @@ void _iota_schedule(uint32_t schedule_reason) mtmsr(ctx); } +#endif + + // Check execution stack integrity + if(g_iota_execution_stack[0] != IOTA_STACK_PATTERN) + { + iota_dead(IOTA_EXECUTION_STACK_OVERFLOW); + } + // Decrement machine state pointer if(g_iota_curr_machine_state_ptr > g_iota_machine_state_stack) { diff --git a/import/chips/p9/procedures/ppe/iota/iota.h b/import/chips/p9/procedures/ppe/iota/iota.h index f9a237b9..1e4c79ad 100644 --- a/import/chips/p9/procedures/ppe/iota/iota.h +++ b/import/chips/p9/procedures/ppe/iota/iota.h @@ -33,6 +33,11 @@ #include "iota_ppe42.h" #include "cme_register_addresses.h" +// Default for IOTA_IDLE_TASKS_ENABLE is no idle task support +#if !defined(IOTA_IDLE_TASKS_ENABLE) + #define IOTA_IDLE_TASKS_ENABLE 0 +#endif + /** * Run the main IOTA kernel loop * @note does not return @@ -42,13 +47,14 @@ void iota_run() __attribute__((noreturn)); #define iota_halt() __iota_halt() #define iota_dead(code) PK_PANIC((code)) -/** - * Set the state of an idle task - * @param[in] The state - * @param[in[ The task index in the idle task table - */ -void iota_set_idle_task_state(uint32_t state, uint32_t idle_task_idx); - +#if IOTA_IDLE_TASKS_ENABLE + /** + * Set the state of an idle task + * @param[in] The state + * @param[in[ The task index in the idle task table + */ + void iota_set_idle_task_state(uint32_t state, uint32_t idle_task_idx); +#endif /// IOTA --- CONSTANTS #if !defined(IOTA_STACK_PATTERN) @@ -106,6 +112,8 @@ void iota_set_idle_task_state(uint32_t state, uint32_t idle_task_idx); #define IOTA_FIT_HANDLER(function) g_iota_fit_handler \ = IOTA_TIMER_HANDLER(function); +#if IOTA_IDLE_TASKS_ENABLE + #define IOTA_BEGIN_IDLE_TASK_TABLE \ iotaIdleTask g_iota_idle_task_list[] \ SECTION(".sdata.g_iota_idle_task_list") = { @@ -113,6 +121,7 @@ void iota_set_idle_task_state(uint32_t state, uint32_t idle_task_idx); }; \ uint32_t const g_iota_idle_task_list_size \ = (uint32_t)(sizeof(g_iota_idle_task_list)/sizeof(iotaIdleTask)); +#endif #define IOTA_BEGIN_TASK_TABLE \ iotaTaskFuncPtr g_iota_task_list[] SECTION(".sdata.g_iota_task_list") = { @@ -171,7 +180,7 @@ typedef struct uint32_t padding; // needs to be 8B aligned } iotaMachineState; -typedef void (*iotaTaskFuncPtr )(uint32_t arg, uint32_t irq); +typedef void (*iotaTaskFuncPtr )( ); typedef void (*iotaTimerFuncPtr)(void ); typedef struct @@ -183,11 +192,14 @@ typedef struct extern iotaMachineState g_iota_machine_state_stack[]; extern iotaMachineState* g_iota_curr_machine_state_ptr; extern iotaTaskFuncPtr g_iota_task_list[]; -extern iotaIdleTask g_iota_idle_task_list[]; -extern uint32_t const g_iota_idle_task_list_size; extern uint32_t const g_iota_task_list_size; extern uint64_t g_iota_execution_stack[]; +#if IOTA_IDLE_TASKS_ENABLE + extern iotaIdleTask g_iota_idle_task_list[]; + extern uint32_t const g_iota_idle_task_list_size; +#endif + void _iota_boot(); void _iota_schedule(uint32_t schedule_reason); void _iota_evaluate_idle_tasks(); diff --git a/import/chips/p9/procedures/ppe/iota/iota_panic_codes.h b/import/chips/p9/procedures/ppe/iota/iota_panic_codes.h index d79f757d..688e145a 100644 --- a/import/chips/p9/procedures/ppe/iota/iota_panic_codes.h +++ b/import/chips/p9/procedures/ppe/iota/iota_panic_codes.h @@ -51,8 +51,8 @@ typedef enum IOTA_ILLEGAL_INSTRUCTION = 0x0008, IOTA_SOFTWARE_HALT = 0x0009, IOTA_DEC_NOT_SUPPORTED = 0x000a, - IOTA_UNUSED_000d = 0x000d, - IOTA_UNUSED_001c = 0x001c, + IOTA_WATCHDOG_NOT_SUPPORTED = 0x000d, + IOTA_EXECUTION_STACK_OVERFLOW = 0x001c, IOTA_UNUSED_001d = 0x001d, IOTA_UNUSED_001e = 0x001e, IOTA_UNUSED_001f = 0x001f, @@ -266,6 +266,7 @@ typedef enum #define IOTA_ILLEGAL_INSTRUCTION 0x0008 #define IOTA_SOFTWARE_HALT 0x0009 #define IOTA_DEC_NOT_SUPPORTED 0x000a +#define IOTA_WATCHDOG_NOT_SUPPORTED 0x000d #endif // __ASSEMBLER__ #endif diff --git a/import/chips/p9/procedures/ppe/iota/iota_ppe42.S b/import/chips/p9/procedures/ppe/iota/iota_ppe42.S index 58ee0491..017ddd5f 100644 --- a/import/chips/p9/procedures/ppe/iota/iota_ppe42.S +++ b/import/chips/p9/procedures/ppe/iota/iota_ppe42.S @@ -102,9 +102,7 @@ __iota_save_interrupt_state_and_schedule: # Task completed, need to restore machine state now # Get pointer to machine state - lis %r3, g_iota_curr_machine_state_ptr@h - ori %r3, %r3, g_iota_curr_machine_state_ptr@l - lwz %r3, 0(%r3) + lwz %r3, g_iota_curr_machine_state_ptr@sda21(0) # Restore d0 first (need sp in r1) lvd %d0, _IOTA_SAVE_D0_OFFSET(%r3) # Save the restore value of r3 to _IOTA_TEMPORARY_R3_STACK_OFFSET(sp) diff --git a/import/chips/p9/procedures/ppe/iota/iota_ppe42.h b/import/chips/p9/procedures/ppe/iota/iota_ppe42.h index aa9a26a7..7065d0bb 100644 --- a/import/chips/p9/procedures/ppe/iota/iota_ppe42.h +++ b/import/chips/p9/procedures/ppe/iota/iota_ppe42.h @@ -79,9 +79,7 @@ # temporarily place r3 on the stack, without incrementing sp stw %r3, _IOTA_TEMPORARY_R3_STACK_OFFSET(%r1) # load the pointer to the location of where to save machine state -lis %r3, g_iota_curr_machine_state_ptr@h -ori %r3, %r3, g_iota_curr_machine_state_ptr@l -lwz %r3, 0(%r3) +lwz %r3, g_iota_curr_machine_state_ptr@sda21(0) # save d8 stvd %d8, _IOTA_SAVE_D8_OFFSET(%r3) mr %r9, %r3 diff --git a/import/chips/p9/procedures/ppe/iota/iota_ppe42_vectors.S b/import/chips/p9/procedures/ppe/iota/iota_ppe42_vectors.S index 3c316112..720fb492 100644 --- a/import/chips/p9/procedures/ppe/iota/iota_ppe42_vectors.S +++ b/import/chips/p9/procedures/ppe/iota/iota_ppe42_vectors.S @@ -85,4 +85,5 @@ __fit_interrupt: .global __watchdog_interrupt .org __vectors + 0x0140 __watchdog_interrupt: - b __watchdog_interrupt + /* b __watchdog_interrupt */ + _pk_panic IOTA_WATCHDOG_NOT_SUPPORTED diff --git a/import/chips/p9/procedures/ppe/iota/pk.h b/import/chips/p9/procedures/ppe/iota/pk.h index 98f05c0d..e0e3ccdf 100644 --- a/import/chips/p9/procedures/ppe/iota/pk.h +++ b/import/chips/p9/procedures/ppe/iota/pk.h @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HCODE Project */ /* */ -/* COPYRIGHT 2017 */ +/* COPYRIGHT 2017,2018 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -49,6 +49,9 @@ extern uint64_t pk_timebase_get(); #define pk_halt() iota_halt() #define pk_irq_vec_restore(...) +#define compile_assert(name,e) \ + enum { compile_assert__##name = 1/(e) }; + // This sets the SPRG0 in pk. static inline void ppe42_app_ctx_set(uint16_t app_ctx) diff --git a/import/chips/p9/procedures/ppe/pk/kernel/pk.h b/import/chips/p9/procedures/ppe/pk/kernel/pk.h index e431e005..c0b2166e 100644 --- a/import/chips/p9/procedures/ppe/pk/kernel/pk.h +++ b/import/chips/p9/procedures/ppe/pk/kernel/pk.h @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HCODE Project */ /* */ -/* COPYRIGHT 2015,2017 */ +/* COPYRIGHT 2015,2018 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -59,6 +59,9 @@ #include "pk_kernel.h" //#include "pk_io.h" +#define compile_assert(name,e) \ + enum { compile_assert__##name = 1/(e) }; + #ifndef __ASSEMBLER__ #define MIN(X, Y) \ diff --git a/import/chips/p9/procedures/ppe/pk/ppe42/ppe42_spr.h b/import/chips/p9/procedures/ppe/pk/ppe42/ppe42_spr.h index 96215c7b..2995dab5 100644 --- a/import/chips/p9/procedures/ppe/pk/ppe42/ppe42_spr.h +++ b/import/chips/p9/procedures/ppe/pk/ppe42/ppe42_spr.h @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HCODE Project */ /* */ -/* COPYRIGHT 2015,2017 */ +/* COPYRIGHT 2015,2018 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -138,6 +138,10 @@ typedef union asm volatile ("mfspr %0, %1" : "=r" (__value) : "i" (sprn) : "memory"); \ __value;}) +#define mfpir() \ + ({uint32_t __value; \ + asm volatile ("mfspr %0, 1023" : "=r" (__value) : : "memory"); \ + __value;}) /// Move to SPR /// diff --git a/import/chips/p9/procedures/ppe/pk/ppe42/ppe42math.h b/import/chips/p9/procedures/ppe/pk/ppe42/ppe42math.h index 8d7676fb..0fbbc25a 100644 --- a/import/chips/p9/procedures/ppe/pk/ppe42/ppe42math.h +++ b/import/chips/p9/procedures/ppe/pk/ppe42/ppe42math.h @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HCODE Project */ /* */ -/* COPYRIGHT 2016,2017 */ +/* COPYRIGHT 2016,2018 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -25,6 +25,26 @@ #ifndef _MATH_H #define _MATH_H +// Provide a way to use the native 16-bit multiply instruction +// Unfortunately the compiler does not know to use it +/// Signed 16 bit multiply, 32 bit product +#define muls16(x,y) \ + ({\ + int32_t __x = (x); \ + int32_t __y = (y); \ + int32_t __z; \ + asm volatile ("mullhw %0,%1,%2" : "=r" (__z) : "r" (__x), "r" (__y) : "cc"); \ + __z;}) + +/// Unsigned 16 bit multiply, 32 bit product +#define mulu16(x,y) \ + ({\ + uint32_t __x = (x); \ + uint32_t __y = (y); \ + uint32_t __z; \ + asm volatile("mullhwu %0,%1,%2" : "=r" (__z) : "r" (__x), "r" (__y) : "cc"); \ + __z;}) + #ifdef __cplusplus extern "C" { diff --git a/import/chips/p9/procedures/ppe/pk/std/std_init.c b/import/chips/p9/procedures/ppe/pk/std/std_init.c index 8ccc1e20..eab5808d 100644 --- a/import/chips/p9/procedures/ppe/pk/std/std_init.c +++ b/import/chips/p9/procedures/ppe/pk/std/std_init.c @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HCODE Project */ /* */ -/* COPYRIGHT 2015,2017 */ +/* COPYRIGHT 2015,2018 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -40,30 +40,22 @@ void __hwmacro_setup(void) { - //mask all interrupts - out64(STD_LCL_EIMR_OR, 0xffffffffffffffffull); - - //Set all interrupts to active low, level sensitive by default - out64(STD_LCL_EIPR_CLR, 0xffffffffffffffffull); - out64(STD_LCL_EITR_CLR, 0xffffffffffffffffull); - - //set up the configured type - out64(STD_LCL_EITR_OR, g_ext_irqs_type); + //mask all interrupts to prevent spurious pulse to PPE + out64(STD_LCL_EIMR, 0xffffffffffffffffull); //set up the configured polarity - out64(STD_LCL_EIPR_OR, g_ext_irqs_polarity); + out64(STD_LCL_EIPR, g_ext_irqs_polarity); - //clear the status of all active-high interrupts (has no affect on - //level sensitive interrupts) - out64(STD_LCL_EISR_CLR, g_ext_irqs_polarity); + //set up the configured type + out64(STD_LCL_EITR, g_ext_irqs_type); - //clear the status of all active-low interrupts (has no affect on - //level sensitive interrupts) - out64(STD_LCL_EISR_OR, ~g_ext_irqs_polarity); + //clear the status of all edge interrupts + out64(STD_LCL_EISR_CLR, g_ext_irqs_type); //unmask the interrupts that are to be enabled by default out64(STD_LCL_EIMR_CLR, g_ext_irqs_enable); //wait for the last operation to complete sync(); + } diff --git a/import/chips/p9/procedures/ppe_closed/cme/iota_app_cfg.h b/import/chips/p9/procedures/ppe_closed/cme/iota_app_cfg.h index b6c5c070..c565ec75 100644 --- a/import/chips/p9/procedures/ppe_closed/cme/iota_app_cfg.h +++ b/import/chips/p9/procedures/ppe_closed/cme/iota_app_cfg.h @@ -51,6 +51,9 @@ //An "idle" task is one that only runs when the ppe42 engine would otherwise //be idle and thus has the lowest priority and can be interrupted by anything. +//To enable IDLE task support in the kernel set this to 1. (OPT) +#define IOTA_IDLE_TASKS_ENABLE 0 + //To automatically disable an "IDLE" task after executing, set this to 1. (OPT) #define IOTA_AUTO_DISABLE_IDLE_TASKS 0 diff --git a/import/chips/p9/procedures/ppe_closed/cme/p9_cme.h b/import/chips/p9/procedures/ppe_closed/cme/p9_cme.h index 8bdee2ba..54f93b28 100644 --- a/import/chips/p9/procedures/ppe_closed/cme/p9_cme.h +++ b/import/chips/p9/procedures/ppe_closed/cme/p9_cme.h @@ -50,12 +50,6 @@ typedef struct uint32_t core_enabled; uint32_t spurr_freq_ref_upper; -#if !DISABLE_PERIODIC_CORE_QUIESCE && (NIMBUS_DD_LEVEL == 20 || NIMBUS_DD_LEVEL == 21 || CUMULUS_DD_LEVEL == 10) - - CmeFitRecord fit_record; - -#endif - } CmeRecord; diff --git a/import/chips/p9/procedures/ppe_closed/cme/p9_cme_irq.h b/import/chips/p9/procedures/ppe_closed/cme/p9_cme_irq.h index 67e95b2f..3fe0e411 100644 --- a/import/chips/p9/procedures/ppe_closed/cme/p9_cme_irq.h +++ b/import/chips/p9/procedures/ppe_closed/cme/p9_cme_irq.h @@ -47,9 +47,6 @@ // definitions in cme_irq_common.c #include <stdint.h> -#if !defined(__IOTA__) - #include "pk.h" -#endif // Priority Levels #define IDX_PRTY_LVL_HIPRTY 0 @@ -139,52 +136,3 @@ IRQ_VEC_PRTY10_CME ^ \ IRQ_VEC_PRTY11_CME ^ \ IRQ_VEC_PRTY12_CME ) - - -#define compile_assert(name,e) \ - enum { compile_assert__##name = 1/(e) }; - - -#if !defined(__IOTA__) -extern const uint64_t ext_irq_vectors_cme[NUM_EXT_IRQ_PRTY_LEVELS][2]; -extern uint32_t g_current_prty_level; - -extern uint8_t -g_eimr_stack[NUM_EXT_IRQ_PRTY_LEVELS] __attribute__((section(".sbss"))); - -extern int g_eimr_stack_ctr; - -extern uint64_t -g_eimr_override_stack[NUM_EXT_IRQ_PRTY_LEVELS] __attribute__((section(".sbss"))); - -extern uint64_t g_eimr_override; - -/// Restore a vector of interrupts by overwriting EIMR. -UNLESS__PPE42_IRQ_CORE_C__(extern) -inline void -pk_irq_vec_restore(PkMachineContext* context) -{ - pk_critical_section_enter(context); - - if (g_eimr_stack_ctr >= 0) - { - out64(STD_LCL_EIMR, - ext_irq_vectors_cme[g_eimr_stack[g_eimr_stack_ctr]][IDX_MASK_VEC]); - out64(STD_LCL_EIMR_CLR, - g_eimr_override_stack[g_eimr_stack_ctr]); - out64(STD_LCL_EIMR_OR, - g_eimr_override); - // Restore the prty level tracker to the task that was interrupted, if any. - g_current_prty_level = g_eimr_stack[g_eimr_stack_ctr]; - g_eimr_stack_ctr--; - } - else - { - PK_TRACE_ERR("ERROR: Messed up EIMR book keeping: g_eimr_stack_ctr=%d. HALT CME!", - g_eimr_stack_ctr); - PK_PANIC(CME_UIH_EIMR_STACK_UNDERFLOW); - } - - //pk_critical_section_exit(context); -} -#endif diff --git a/import/chips/p9/procedures/ppe_closed/cme/p9_cme_irq_priority_table.c b/import/chips/p9/procedures/ppe_closed/cme/p9_cme_irq_priority_table.c index 7388698b..bf5a39b2 100644 --- a/import/chips/p9/procedures/ppe_closed/cme/p9_cme_irq_priority_table.c +++ b/import/chips/p9/procedures/ppe_closed/cme/p9_cme_irq_priority_table.c @@ -29,13 +29,10 @@ // as the index into the ext_irq_vectors_cme[][] table. #include "p9_cme_irq.h" +#include "p9_cme_pstate.h" +#include "iota_app_cfg.h" -#if defined(__IOTA__) - #include "iota_app_cfg.h" - const uint64_t ext_irq_vectors_cme[IOTA_NUM_EXT_IRQ_PRIORITIES][2] = -#else - const uint64_t ext_irq_vectors_cme[NUM_EXT_IRQ_PRTY_LEVELS][2] = -#endif +const uint64_t ext_irq_vectors_cme[IOTA_NUM_EXT_IRQ_PRIORITIES][2] = { /* 0: IDX_PRTY_VEC 1: IDX_MASK_VEC */ { diff --git a/import/chips/p9/procedures/ppe_closed/cme/pstate_cme/p9_cme_pstate.h b/import/chips/p9/procedures/ppe_closed/cme/pstate_cme/p9_cme_pstate.h index 748e589e..74f162bf 100644 --- a/import/chips/p9/procedures/ppe_closed/cme/pstate_cme/p9_cme_pstate.h +++ b/import/chips/p9/procedures/ppe_closed/cme/pstate_cme/p9_cme_pstate.h @@ -67,9 +67,9 @@ typedef struct { uint32_t core0_resclk_idx; //4 uint32_t core1_resclk_idx; //8 - uint32_t l2_ex0_resclk_idx; //12 - uint32_t l2_ex1_resclk_idx; //16 - uint32_t common_resclk_idx; //20 + uint32_t common_resclk_idx; //12 + uint32_t l2_ex0_resclk_idx; //16 + uint32_t l2_ex1_resclk_idx; //20 } cme_resclk_data_t; typedef struct @@ -169,24 +169,18 @@ enum DB0_TRIGGER typedef struct { -#if !defined(__IOTA__) - PkSemaphore sem[2]; -#endif - uint32_t qmFlag; //4 - uint32_t siblingCMEFlag; //8 - uint32_t quadPstate; //12 - uint32_t cmeMaskGoodCore; //16 - uint32_t globalPstate; //20 -#ifdef USE_CME_RESCLK_FEATURE + uint32_t qmFlag; //4 + uint32_t siblingCMEFlag; //8 + uint32_t quadPstate; //12 + uint32_t firstGoodCoreMask; //16 + uint32_t globalPstate; //20 cme_resclk_data_t resclkData; //40 -#endif//USE_CME_RESCLK_FEATURE -#ifdef USE_CME_VDM_FEATURE - cme_vdm_data_t vdmData; //56 -#endif//USE_CME_VDM_FEATURE - uint32_t pmin; //60 - uint32_t safeMode; //64 - uint32_t pmax; //68 - uint32_t pstatesSuspended; //72(0x48) + cme_vdm_data_t vdmData; //56 + uint32_t pmin; //60 + uint32_t safeMode; //64 + uint32_t pmax; //68 + uint32_t pstatesSuspended; //72 + uint32_t nextPstate; //76 } CmePstateRecord; typedef struct @@ -194,15 +188,16 @@ typedef struct uint32_t seqNum; } cme_pstate_pmcr_data_t; -void p9_cme_pstate_pmcr_thread(void*); -void p9_cme_pstate_db0_thread(void*); -void p9_cme_pstate_pmcr_handler(void*, PkIrqId); -void p9_cme_pstate_db0_handler(void*, PkIrqId); -void p9_cme_pstate_db3_handler(void*, PkIrqId); +void p9_cme_pstate_init(); +void p9_cme_init_done(); + +void p9_cme_pstate_pmcr_handler(); +void p9_cme_pstate_db0_handler(); +void p9_cme_pstate_db3_handler(); void p9_cme_pstate_db3_handler_replay_db0(); void p9_cme_pstate_db3_handler_high_priority_pstate(); -void p9_cme_pstate_intercme_in0_irq_handler(void*, PkIrqId); -void p9_cme_pstate_intercme_msg_handler(void* arg, PkIrqId irq); +void p9_cme_pstate_intercme_in0_irq_handler(void); +void p9_cme_pstate_intercme_msg_handler(void); void p9_cme_pstate_db0_safe_mode(); int send_pig_packet(uint64_t data, uint32_t coreMask); uint32_t poll_dpll_stat(); @@ -212,8 +207,8 @@ void intercme_msg_send(uint32_t msg, INTERCME_MSG_TYPE type); void intercme_msg_recv(uint32_t* msg, INTERCME_MSG_TYPE type); void intercme_direct(INTERCME_DIRECT_INTF intf, INTERCME_DIRECT_TYPE type, uint32_t retry_enable); void p9_cme_core_stop_analog_control(uint32_t core_mask, ANALOG_CONTROL enable); -void p9_cme_pstate_pmsr_updt(uint32_t coreMask); -void p9_cme_pstate_pmsr_updt_in_progress(uint32_t coreMask); +void p9_cme_pstate_pmsr_updt(); +void p9_cme_pstate_pmsr_updt_in_progress(); void p9_cme_pstate_sibling_lock_and_intercme_protocol(uint32_t process_intercme_in0); void p9_cme_pstate_process_db0_sibling(); @@ -223,7 +218,6 @@ void p9_cme_pstate_process_db0_sibling(); #endif//USE_CME_RESCLK_FEATURE #ifdef USE_CME_VDM_FEATURE uint32_t calc_vdm_jump_values(uint32_t pstate, uint32_t region); -uint32_t update_vdm_jump_values_in_dpll(uint32_t pstate, uint32_t region); uint32_t p9_cme_vdm_update(uint32_t pstate); uint32_t pstate_to_vid_compare(uint32_t pstate, uint32_t region); uint32_t pstate_to_vpd_region(uint32_t pstate); diff --git a/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_cme_copy_scan_ring.c b/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_cme_copy_scan_ring.c index 1a6ba744..86168718 100644 --- a/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_cme_copy_scan_ring.c +++ b/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_cme_copy_scan_ring.c @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HCODE Project */ /* */ -/* COPYRIGHT 2015,2017 */ +/* COPYRIGHT 2015,2018 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -224,7 +224,7 @@ void bce_irr_run() } } -void bce_irr_thread(void* args) +void bce_irr_thread() { while(1) { @@ -251,7 +251,8 @@ void start_cme_block_copy(uint32_t barIndex, uint32_t bcMembase, uint32_t bcSram l_cmePir = (((l_cmePir << 1) & CME_INST_ID_MASK) | l_exId); // get CME instance number //let us find out HOMER address where core specific scan rings reside. - bcMembase = bcMembase + (( l_cmePir * bcLength ) << 5 ); + // use native 16-bit PPE multiply instruction + bcMembase = bcMembase + (mulu16( l_cmePir , bcLength ) << 5 ); bcMembase = bcMembase >> 5; PK_TRACE( "Start cme block copy MBASE 0x%08x SBSE 0x%08x Len 0x%08x CME Ist %d", diff --git a/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_cme_copy_scan_ring.h b/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_cme_copy_scan_ring.h index 560919e2..63148b64 100644 --- a/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_cme_copy_scan_ring.h +++ b/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_cme_copy_scan_ring.h @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HCODE Project */ /* */ -/* COPYRIGHT 2015,2017 */ +/* COPYRIGHT 2015,2018 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -41,7 +41,7 @@ BceReturnCode_t check_cme_block_copy(); #if TEST_ONLY_BCE_IRR void bce_irr_setup(); void bce_irr_run(); - void bce_irr_thread(void*); + void bce_irr_thread(); #endif #endif diff --git a/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_hcd_core_scomcust.c b/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_hcd_core_scomcust.c index a13adeff..45db2bec 100644 --- a/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_hcd_core_scomcust.c +++ b/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_hcd_core_scomcust.c @@ -34,18 +34,19 @@ p9_hcd_core_scomcust(uint32_t core) cmeHeader_t* pCmeImgHdr = (cmeHeader_t*)(CME_SRAM_HEADER_ADDR); ScomEntry_t* pCmeScomRes = 0; - int i, core_mask; + uint32_t i, core_mask, core_offset = 0; - for (core_mask = 2; core_mask != 0; core_mask--) + + for (core_mask = 2; core_mask != 0; core_mask--, core_offset += pCmeImgHdr->g_cme_scom_length >> 1) { if (core & core_mask) { pCmeScomRes = (ScomEntry_t*)(CME_SRAM_BASE_ADDR + - (pCmeImgHdr->g_cme_scom_offset << 5) + ((pCmeImgHdr->g_cme_scom_length >> 1) * (core_mask & 1))); + (pCmeImgHdr->g_cme_scom_offset << 5) + core_offset); PK_TRACE("p9_hcd_core_scomcust core[%d] scom_offset [%08X] size = %d", core, (CME_SRAM_BASE_ADDR + - (pCmeImgHdr->g_cme_scom_offset << 5) + ((pCmeImgHdr->g_cme_scom_length >> 1) * (core_mask & 1))), sizeof(ScomEntry_t)); + (pCmeImgHdr->g_cme_scom_offset << 5) + core_offset), sizeof(ScomEntry_t)); for(i = 0; pCmeScomRes->scomEntryAddress; i++, pCmeScomRes++) { diff --git a/import/chips/p9/procedures/ppe_closed/cme/utils/p9_putringutils.c b/import/chips/p9/procedures/ppe_closed/cme/utils/p9_putringutils.c index 3654776d..04390b37 100644 --- a/import/chips/p9/procedures/ppe_closed/cme/utils/p9_putringutils.c +++ b/import/chips/p9/procedures/ppe_closed/cme/utils/p9_putringutils.c @@ -258,7 +258,7 @@ int rs4DecompressionSvc( uint32_t i, x; uint32_t l_data; uint32_t l_spyData; - uint32_t l_maxRotate = 4095; + const uint32_t l_maxRotate = 4095; uint8_t* l_rs4Str = 0; CompressedScanData* l_rs4Header = NULL; @@ -341,13 +341,25 @@ int rs4DecompressionSvc( // Do the ROTATE operation if (l_bitRotates > l_maxRotate) { - for (; l_bitRotates > l_maxRotate; ) + +// Prevent PPE compiler from using a software divide +// (l_bitRotates/l_maxRotate) to pre-calculate number of loop iterations +// this saves 128 Bytes and takes less time than a software divide +// (hide behind the getscoms) + uint32_t primenum = 32749; //largest 15-bit prime + uint32_t fakenumber = primenum; + +// fakenumber can never be zero + for (; (l_bitRotates > l_maxRotate) || (fakenumber == 0); ) { l_bitRotates -= l_maxRotate; CME_GETSCOM_OP(0x00038000 | l_maxRotate, i_core, i_scom_op, l_scomData); - } - l_bitRotates = l_bitRotates % l_maxRotate; + if ((fakenumber -= 7) < 15) + { + fakenumber = primenum; // ensure always >0 + } + } } CME_GETSCOM_OP(0x00038000 | l_bitRotates, i_core, i_scom_op, l_scomData); |

