[PATCH v5 22/46] x86: Add functions to convert between mtrr size and mask
Simon Glass
sjg at chromium.org
Sat Mar 15 15:25:42 CET 2025
Rather than repeating the same code in several places, add some
functions which can do the conversion.
Use the cpu_phys_address_size() function to obtain the physical-address
size, since it is more reliable with kvm, where the host CPU may have a
different value from the emulation CPU.
Signed-off-by: Simon Glass <sjg at chromium.org>
---
(no changes since v3)
Changes in v3:
- Add new patch with functions to convert between mtrr size and mask
arch/x86/cpu/mtrr.c | 33 +++++++++++++++++++++++++--------
arch/x86/include/asm/mtrr.h | 16 ++++++++++++++++
cmd/x86/mtrr.c | 5 ++---
3 files changed, 43 insertions(+), 11 deletions(-)
diff --git a/arch/x86/cpu/mtrr.c b/arch/x86/cpu/mtrr.c
index 07ea89162de..fca7b28f815 100644
--- a/arch/x86/cpu/mtrr.c
+++ b/arch/x86/cpu/mtrr.c
@@ -16,6 +16,7 @@
* since the MTRR registers are sometimes in flux.
*/
+#include <cpu.h>
#include <cpu_func.h>
#include <log.h>
#include <sort.h>
@@ -39,6 +40,27 @@ static const char *const mtrr_type_name[MTRR_TYPE_COUNT] = {
"Back",
};
+u64 mtrr_to_size(u64 mask)
+{
+ u64 size;
+
+ size = ~mask & ((1ULL << cpu_phys_address_size()) - 1);
+ size |= (1 << 12) - 1;
+ size += 1;
+
+ return size;
+}
+
+u64 mtrr_to_mask(u64 size)
+{
+ u64 mask;
+
+ mask = ~(size - 1);
+ mask &= (1ull << cpu_phys_address_size()) - 1;
+
+ return mask;
+}
+
/* Prepare to adjust MTRRs */
void mtrr_open(struct mtrr_state *state, bool do_caches)
{
@@ -68,11 +90,9 @@ void mtrr_close(struct mtrr_state *state, bool do_caches)
static void set_var_mtrr(uint reg, uint type, uint64_t start, uint64_t size)
{
- u64 mask;
+ u64 mask = mtrr_to_mask(size);
wrmsrl(MTRR_PHYS_BASE_MSR(reg), start | type);
- mask = ~(size - 1);
- mask &= (1ULL << CONFIG_CPU_ADDR_BITS) - 1;
wrmsrl(MTRR_PHYS_MASK_MSR(reg), mask | MTRR_PHYS_MASK_VALID);
}
@@ -204,8 +224,7 @@ int mtrr_add_request(int type, uint64_t start, uint64_t size)
req->size = size;
debug("%d: type=%d, %08llx %08llx\n", gd->arch.mtrr_req_count - 1,
req->type, req->start, req->size);
- mask = ~(req->size - 1);
- mask &= (1ULL << CONFIG_CPU_ADDR_BITS) - 1;
+ mask = mtrr_to_mask(req->size);
mask |= MTRR_PHYS_MASK_VALID;
debug(" %016llx %016llx\n", req->start | req->type, mask);
@@ -360,9 +379,7 @@ int mtrr_list(int reg_count, int cpu_select)
base = info.mtrr[i].base;
mask = info.mtrr[i].mask;
- size = ~mask & ((1ULL << CONFIG_CPU_ADDR_BITS) - 1);
- size |= (1 << 12) - 1;
- size += 1;
+ size = mtrr_to_size(mask);
valid = mask & MTRR_PHYS_MASK_VALID;
type = mtrr_type_name[base & MTRR_BASE_TYPE_MASK];
printf("%d %-5s %-12s %016llx %016llx %016llx\n", i,
diff --git a/arch/x86/include/asm/mtrr.h b/arch/x86/include/asm/mtrr.h
index 2e995f54061..67e897daa25 100644
--- a/arch/x86/include/asm/mtrr.h
+++ b/arch/x86/include/asm/mtrr.h
@@ -90,6 +90,22 @@ struct mtrr_info {
struct mtrr mtrr[MTRR_MAX_COUNT];
};
+/**
+ * mtrr_to_size() - Convert a mask to a size value
+ *
+ * @mask: Value of the mask register
+ * Return: associated size
+ */
+u64 mtrr_to_size(u64 mask);
+
+/**
+ * mtrr_to_mask() - Convert a size to a mask value
+ *
+ * @size: Value of the size register
+ * Return: associated mask, without MTRR_PHYS_MASK_VALID
+ */
+u64 mtrr_to_mask(u64 size);
+
/**
* mtrr_open() - Prepare to adjust MTRRs
*
diff --git a/cmd/x86/mtrr.c b/cmd/x86/mtrr.c
index b2afb598c73..93be84f74b8 100644
--- a/cmd/x86/mtrr.c
+++ b/cmd/x86/mtrr.c
@@ -14,7 +14,7 @@ static int do_mtrr_set(int cpu_select, uint reg, int argc, char *const argv[])
{
const char *typename = argv[0];
uint32_t start, size;
- uint64_t base, mask;
+ u64 base, mask;
int type = -1;
bool valid;
int ret;
@@ -31,8 +31,7 @@ static int do_mtrr_set(int cpu_select, uint reg, int argc, char *const argv[])
base = start | type;
valid = native_read_msr(MTRR_PHYS_MASK_MSR(reg)) & MTRR_PHYS_MASK_VALID;
- mask = ~((uint64_t)size - 1);
- mask &= (1ULL << CONFIG_CPU_ADDR_BITS) - 1;
+ mask = mtrr_to_mask(size);
if (valid)
mask |= MTRR_PHYS_MASK_VALID;
--
2.43.0
More information about the U-Boot
mailing list