[Skiboot] [PATCH v10 10/11] skiboot: Add core IMC related counter configuration

Madhavan Srinivasan maddy at linux.vnet.ibm.com
Fri May 5 16:31:00 AEST 2017



On Thursday 04 May 2017 10:12 AM, Madhavan Srinivasan wrote:
> From: Anju T Sudhakar <anju at linux.vnet.ibm.com>
>
> Add support to start, stop and initialize the core IMC counters.
> To initialize the core IMC counters, it takes a physical address per
> core as an input and writes that address to PDBAR[14:50] bits.
> It also initializes the event_mask with time interval to posted the
> core imc counter data to the given memory location. Finally, htc_mode
> scom bits controls core imc engine (start/stop).
>
> Signed-off-by: Hemant Kumar <hemant at linux.vnet.ibm.com>
> Signed-off-by: Madhavan Srinivasan <maddy at linux.vnet.ibm.com>
> Signed-off-by: Anju T Sudhakar <anju at linux.vnet.ibm.com>
> ---
>   hw/imc.c           | 144 +++++++++++++++++++++++++++++++++++++++++++++++++----
>   include/imc.h      |  10 ++++
>   include/opal-api.h |   1 +
>   3 files changed, 144 insertions(+), 11 deletions(-)
>
> diff --git a/hw/imc.c b/hw/imc.c
> index 67f199c04949..183d0eab8923 100644
> --- a/hw/imc.c
> +++ b/hw/imc.c
> @@ -83,6 +83,26 @@ size_t imc_catalog_size;
>   const char **imc_prop_to_fix(struct dt_node *node);
>   const char *prop_to_fix[] = {"events", NULL};
>
> +
> +/*
> + * A Quad contains 4 cores in Power 9, and there are 4 addresses for
> + * the CHTM attached to each core.
> + * So, for core index 0 to core index 3, we have a sequential range of
> + * SCOM port addresses in the arrays below, each for PDBAR and HTM mode.
> + */
> +unsigned int pdbar_scom_index[] = {
> +	0x1001220B,
> +	0x1001230B,
> +	0x1001260B,
> +	0x1001270B
> +};
> +unsigned int htm_scom_index[] = {
> +	0x10012200,
> +	0x10012300,
> +	0x10012600,
> +	0x10012700
> +};
> +
>   static struct imc_chip_cb *get_imc_cb(void)
>   {
>   	uint64_t cb_loc;
> @@ -158,7 +178,9 @@ err:
>    */
>   const char **imc_prop_to_fix(struct dt_node *node)
>   {
> -	if (dt_node_is_compatible(node, "ibm,imc-counters-nest"))
> +	if (dt_node_is_compatible(node, "ibm,imc-counters-nest") ||
> +		dt_node_is_compatible(node, "ibm,imc-counters-core") ||
> +		dt_node_is_compatible(node, "ibm,imc-counters-thread"))
>   		return prop_to_fix;
>
>   	return NULL;
> @@ -282,26 +304,84 @@ err:
>   }
>
>   /*
> - * opal_imc_counters_init : This call initialize the IMC engine.
> - *
> + * opal_imc_counters_init : This call initializes core IMC Engine for the
> + *			    current core, by initializing the pdbars, htm_mode,
> + *			    and the event_mask.
>    * This call is not being used in case of NEST IMC.
> - * Additional arguments will be added to this call in the following patch.
>    */
> -static int64_t opal_imc_counters_init(uint32_t type)
> +static int64_t opal_imc_counters_init(uint32_t type, uint64_t addr)
>   {
> -	if (type == OPAL_IMC_COUNTERS_NEST)
> +	struct proc_chip *chip;
> +	int core_id, phys_core_id, ret = OPAL_PARAMETER;
> +
> +	switch (type) {
> +	case OPAL_IMC_COUNTERS_NEST:
>   		prerror("IMC: unknown operation for nest imc\n");
> +		break;

My bad. Missed to address mpe's suggestion incase of _INIT call.
Will wait for some more comments on the patchset, if any and will respin.

Maddy

> +	case OPAL_IMC_COUNTERS_CORE:
> +		chip = get_chip(this_cpu()->chip_id);
> +		phys_core_id = cpu_get_core_index(this_cpu());
> +		core_id = phys_core_id % 4;
> +
> +		/*
> +		 * Core IMC hardware mandate initing of three scoms
> +		 * to enbale or disable of the Core IMC engine.
> +		 *
> +		 * PDBAR: Scom contains the real address to store per-core
> +		 *        counter data in memory along with other bits.
> +		 *
> +		 * EventMask: Scom contain bits to denote event to multiplex
> +		 *            at different MSR[HV PR] values, along with bits for
> +		 *            sampling duration.
> +		 *
> +		 * HTM Scom: scom to enable counter data movement to memory.
> +		 */
> +		ret = xscom_write(chip->id,
> +				XSCOM_ADDR_P9_EP(phys_core_id,
> +						pdbar_scom_index[core_id]),
> +				(u64)(CORE_IMC_PDBAR_MASK & addr));
> +		if (ret < 0) {
> +			prerror("IMC: error in xscom_write for pdbar\n");
> +			goto hw_err;
> +		}
>
> -	return OPAL_SUCCESS;
> +		ret = xscom_write(chip->id,
> +				XSCOM_ADDR_P9_EC(phys_core_id,
> +					 CORE_IMC_EVENT_MASK_ADDR),
> +				(u64)CORE_IMC_EVENT_MASK);
> +		if (ret < 0) {
> +			prerror("IMC: error in xscom_write for event mask\n");
> +			goto hw_err;
> +		}
> +
> +		ret = xscom_write(chip->id,
> +				XSCOM_ADDR_P9_EP(phys_core_id,
> +						htm_scom_index[core_id]),
> +				(u64)CORE_IMC_HTM_MODE_DISABLE);
> +		if (ret < 0) {
> +			prerror("IMC: error in xscom_write for htm mode\n");
> +			goto hw_err;
> +		}
> +
> +		ret = OPAL_SUCCESS;
> +		break;
> +	default:
> +		return ret;
> +	}
> +
> +	return ret;
> +hw_err:
> +	return OPAL_HARDWARE;
>   }
> -opal_call(OPAL_IMC_COUNTERS_INIT, opal_imc_counters_init, 1);
> +opal_call(OPAL_IMC_COUNTERS_INIT, opal_imc_counters_init, 2);
>
> -/* opal_imc_counters_control_start: This call starts the nest imc engine. */
> +/* opal_imc_counters_control_start: This call starts the nest/core imc engine. */
>   static int64_t opal_imc_counters_start(uint32_t type)
>   {
>   	u64 op, status;
>   	struct imc_chip_cb *cb;
> -	int ret = OPAL_SUCCESS;
> +	struct proc_chip *chip;
> +	int core_id, phys_core_id, ret = OPAL_SUCCESS;
>
>   	switch (type) {
>   	case OPAL_IMC_COUNTERS_NEST:
> @@ -320,6 +400,28 @@ static int64_t opal_imc_counters_start(uint32_t type)
>   		cb->imc_chip_command = op;
>
>   		break;
> +	case OPAL_IMC_COUNTERS_CORE:
> +		/*
> +		* Enables the core imc engine by appropriately setting
> +		* bits 4-9 of the HTM_MODE scom port. No initialization
> +		* is done in this call. This just enables the the counters
> +		* to count with the previous initialization.
> +		*/
> +		chip = get_chip(this_cpu()->chip_id);
> +		phys_core_id = cpu_get_core_index(this_cpu());
> +		core_id = phys_core_id % 4;
> +
> +		ret = xscom_write(chip->id,
> +				XSCOM_ADDR_P9_EP(phys_core_id,
> +						htm_scom_index[core_id]),
> +				(u64) CORE_IMC_HTM_MODE_ENABLE);
> +
> +		if (ret < 0) {
> +			prerror("IMC: error in xscom_write for htm_mode\n");
> +			return OPAL_HARDWARE;
> +		}
> +
> +		break;
>   	default:
>   		prerror("IMC: Unknown Domain \n");
>   		return OPAL_PARAMETER;
> @@ -334,7 +436,8 @@ static int64_t opal_imc_counters_stop(uint32_t type)
>   {
>   	u64 op, status;
>   	struct imc_chip_cb *cb;
> -	int ret = OPAL_SUCCESS;
> +	struct proc_chip *chip;
> +	int core_id, phys_core_id, ret = OPAL_SUCCESS;
>
>   	switch (type) {
>   	case OPAL_IMC_COUNTERS_NEST:
> @@ -353,6 +456,25 @@ static int64_t opal_imc_counters_stop(uint32_t type)
>   		cb->imc_chip_command = op;
>
>   		break;
> +	case OPAL_IMC_COUNTERS_CORE:
> +		/*
> +		* Disables the core imc engine by clearing
> +		* bits 4-9 of the HTM_MODE scom port.
> +		*/
> +		chip = get_chip(this_cpu()->chip_id);
> +		phys_core_id = cpu_get_core_index(this_cpu());
> +		core_id = phys_core_id % 4;
> +
> +		ret = xscom_write(chip->id,
> +				XSCOM_ADDR_P9_EP(phys_core_id,
> +						htm_scom_index[core_id]),
> +				(u64) CORE_IMC_HTM_MODE_DISABLE);
> +		if (ret < 0) {
> +			prerror("IMC: error in xscom_write for htm_mode\n");
> +			return OPAL_HARDWARE;
> +		}
> +
> +		break;
>   	default:
>   		prerror("IMC: Unknown Domain \n");
>   		return OPAL_PARAMETER;
> diff --git a/include/imc.h b/include/imc.h
> index c7ad5fa933b7..5a3d53c22ca1 100644
> --- a/include/imc.h
> +++ b/include/imc.h
> @@ -116,6 +116,16 @@ struct imc_chip_cb
>
>   #define MAX_NEST_UNITS			48
>
> +/*
> + * Core IMC SCOMs
> + */
> +#define CORE_IMC_EVENT_MASK_ADDR	0x20010AA8ull
> +#define CORE_IMC_EVENT_MASK		0x0001020000000000ull
> +#define CORE_IMC_PDBAR_MASK		0x0003ffffffffe000ull
> +#define CORE_IMC_NCU_MODE		0x0800000000000000ull
> +#define CORE_IMC_HTM_MODE_ENABLE	0xE800000000000000ull
> +#define CORE_IMC_HTM_MODE_DISABLE	0xE000000000000000ull
> +
>   void imc_init(void);
>   void imc_catalog_preload(void);
>   #endif /* __IMC_H */
> diff --git a/include/opal-api.h b/include/opal-api.h
> index e22358a1bbab..6497c94cd46a 100644
> --- a/include/opal-api.h
> +++ b/include/opal-api.h
> @@ -1221,6 +1221,7 @@ enum {
>   /* Operation argument to IMC Microcode */
>   enum {
>   	OPAL_IMC_COUNTERS_NEST = 1,
> +	OPAL_IMC_COUNTERS_CORE = 2,
>   };
>
>



More information about the Skiboot mailing list