blob: e72ce335d7a3c354e821420871348bcc8bf1e434 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
|
/* SPDX-License-Identifier: GPL-2.0-only */
#include <cpu/x86/msr.h>
#include <cpu/x86/mtrr.h>
#include <soc/pci_devs.h>
#include <soc/reg_access.h>
asmlinkage void *soc_set_mtrrs(void *top_of_stack)
{
union {
uint32_t u32[2];
uint64_t u64;
msr_t msr;
} data;
uint32_t mtrr_count;
uint32_t *mtrr_data;
uint32_t mtrr_reg;
/*
* The stack contents are initialized in src/soc/intel/common/stack.c
* to be the following:
*
* *
* *
* *
* +36: MTRR mask 1 63:32
* +32: MTRR mask 1 31:0
* +28: MTRR base 1 63:32
* +24: MTRR base 1 31:0
* +20: MTRR mask 0 63:32
* +16: MTRR mask 0 31:0
* +12: MTRR base 0 63:32
* +8: MTRR base 0 31:0
* +4: Number of MTRRs to setup (described above)
* top_of_stack --> +0: Number of variable MTRRs to clear
*
* This routine:
* * Clears all of the variable MTRRs
* * Initializes the variable MTRRs with the data passed in
* * Returns the new top of stack after removing all of the
* data passed in.
*/
/* Clear all of the variable MTRRs (base and mask). */
mtrr_reg = MTRR_PHYS_BASE(0);
mtrr_data = top_of_stack;
mtrr_count = (*mtrr_data++) * 2;
data.u64 = 0;
while (mtrr_count-- > 0)
soc_msr_write(mtrr_reg++, data.msr);
/* Setup the specified variable MTRRs */
mtrr_reg = MTRR_PHYS_BASE(0);
mtrr_count = *mtrr_data++;
while (mtrr_count-- > 0) {
data.u32[0] = *mtrr_data++;
data.u32[1] = *mtrr_data++;
soc_msr_write(mtrr_reg++, data.msr); /* Base */
data.u32[0] = *mtrr_data++;
data.u32[1] = *mtrr_data++;
soc_msr_write(mtrr_reg++, data.msr); /* Mask */
}
/* Remove setup_stack_and_mtrrs data and return the new top_of_stack */
top_of_stack = mtrr_data;
return top_of_stack;
}
asmlinkage void soc_enable_mtrrs(void)
{
union {
uint32_t u32[2];
uint64_t u64;
msr_t msr;
} data;
/* Enable MTRR. */
data.msr = soc_msr_read(MTRR_DEF_TYPE_MSR);
data.u32[0] |= MTRR_DEF_TYPE_EN;
soc_msr_write(MTRR_DEF_TYPE_MSR, data.msr);
}
|