
Hi Simon,
-----"Simon Glass" sjg@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@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