[PATCH 18/22] x86: mtrr: Add support for writing to MTRRs on any CPU

Wolfgang Wallner wolfgang.wallner at br-automation.com
Wed Jun 10 15:28:22 CEST 2020


Hi Simon,

-----"Simon Glass" <sjg at chromium.org> schrieb: -----
> Betreff: [PATCH 18/22] x86: mtrr: Add support for writing to MTRRs on any CPU
> 
> To enable support for the 'mtrr' command, add a way to perform MTRR
> operations on selected CPUs.
> 
> This works by setting up a little 'operation' structure and sending it
> around the CPUs for action.
> 
> Signed-off-by: Simon Glass <sjg at chromium.org>
> ---
> 
>  arch/x86/cpu/mtrr.c         | 81 +++++++++++++++++++++++++++++++++++++
>  arch/x86/include/asm/mtrr.h | 21 ++++++++++
>  2 files changed, 102 insertions(+)
> 
> diff --git a/arch/x86/cpu/mtrr.c b/arch/x86/cpu/mtrr.c
> index a48c9d8232e..25f317d4298 100644
> --- a/arch/x86/cpu/mtrr.c
> +++ b/arch/x86/cpu/mtrr.c
> @@ -221,3 +221,84 @@ int mtrr_set_next_var(uint type, uint64_t start, uint64_t size)
>  
>  	return 0;
>  }
> +
> +/** enum mtrr_opcode - supported operations for mtrr_do_oper() */
> +enum mtrr_opcode {
> +	MTRR_OP_SET,
> +	MTRR_OP_SET_VALID,
> +};
> +
> +/**
> + * struct mtrr_oper - An MTRR operation to perform on a CPU
> + *
> + * @opcode: Indicates operation to perform
> + * @reg: MTRR reg number to select (0-7, -1 = all)
> + * @valid: Valid value to write for MTRR_OP_SET_VALID
> + * @base: Base value to write for MTRR_OP_SET
> + * @mask: Mask value to write for MTRR_OP_SET
> + */
> +struct mtrr_oper {
> +	enum mtrr_opcode opcode;
> +	int reg;
> +	bool valid;
> +	u64 base;
> +	u64 mask;
> +};
> +
> +static void mtrr_do_oper(void *arg)
> +{
> +	struct mtrr_oper *oper = arg;
> +	u64 mask;
> +
> +	switch (oper->opcode) {
> +	case MTRR_OP_SET_VALID:
> +		mask = native_read_msr(MTRR_PHYS_MASK_MSR(oper->reg));
> +		if (oper->valid)
> +			mask |= MTRR_PHYS_MASK_VALID;
> +		else
> +			mask &= ~MTRR_PHYS_MASK_VALID;
> +		wrmsrl(MTRR_PHYS_MASK_MSR(oper->reg), mask);
> +		break;
> +	case MTRR_OP_SET:
> +		wrmsrl(MTRR_PHYS_BASE_MSR(oper->reg), oper->base);
> +		wrmsrl(MTRR_PHYS_MASK_MSR(oper->reg), oper->mask);
> +		break;
> +	}
> +}
> +
> +static int mtrr_start_op(int cpu_select, struct mtrr_oper *oper)
> +{
> +	struct mtrr_state state;
> +	int ret;
> +
> +	mtrr_open(&state, true);
> +	ret = mp_run_on_cpus(cpu_select, mtrr_do_oper, oper);
> +	mtrr_close(&state, true);
> +	if (ret)
> +		return log_msg_ret("run", ret);
> +
> +	return 0;
> +}
> +
> +int mtrr_set_valid(int cpu_select, int reg, bool valid)

With the introduction of this function in this patch there are now two
conflicting implementations of mtrr_set_valid(), and this commit does not
compile.

The conflicting function is removed in the following patch. Could these
two patches be merged so we don't break bisectability?

> +{
> +	struct mtrr_oper oper;
> +
> +	oper.opcode = MTRR_OP_SET_VALID;
> +	oper.reg = reg;
> +	oper.valid = valid;
> +
> +	return mtrr_start_op(cpu_select, &oper);
> +}
> +
> +int mtrr_set(int cpu_select, int reg, u64 base, u64 mask)
> +{
> +	struct mtrr_oper oper;
> +
> +	oper.opcode = MTRR_OP_SET;
> +	oper.reg = reg;
> +	oper.base = base;
> +	oper.mask = mask;
> +
> +	return mtrr_start_op(cpu_select, &oper);
> +}
> diff --git a/arch/x86/include/asm/mtrr.h b/arch/x86/include/asm/mtrr.h
> index 476d6f8a9cf..6c50a67e1fe 100644
> --- a/arch/x86/include/asm/mtrr.h
> +++ b/arch/x86/include/asm/mtrr.h
> @@ -159,6 +159,27 @@ int mtrr_set_next_var(uint type, uint64_t base, uint64_t size);
>   */
>  void mtrr_save_all(struct mtrr_info *info);
>  
> +/**
> + * mtrr_set_valid() - Set the valid flag for a selected MTRR and CPU(s)
> + *
> + * @cpu_select: Selected CPUs (either a CPU number or MP_SELECT_...)
> + * @reg: MTRR register to write (0-7)
> + * @valid: Valid flag to write
> + * @return 0 on success, -ve on error
> + */
> +int mtrr_set_valid(int cpu_select, int reg, bool valid);
> +
> +/**
> + * mtrr_set() - Set the valid flag for a selected MTRR and CPU(s)
> + *
> + * @cpu_select: Selected CPUs (either a CPU number or MP_SELECT_...)
> + * @reg: MTRR register to write (0-7)
> + * @base: Base address and MTRR_BASE_TYPE_MASK
> + * @mask: Mask and MTRR_PHYS_MASK_VALID
> + * @return 0 on success, -ve on error
> + */
> +int mtrr_set(int cpu_select, int reg, u64 base, u64 mask);
> +
>  #endif
>  
>  #if ((CONFIG_XIP_ROM_SIZE & (CONFIG_XIP_ROM_SIZE - 1)) != 0)
> -- 
> 2.27.0.rc0.183.gde8f92d652-goog

regards, Wolfgang



More information about the U-Boot mailing list