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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
|
/*
* (C) 2002 Dave Jones.
*
* Licensed under the terms of the GNU GPL License version 2.
*
* MTRR register dumping.
* TODO : decode the registers too.
*/
#include <stdio.h>
#include <asm/mtrr.h>
#include "x86info.h"
#define IA32_MTRRCAP_SMRR 0x800
#define IA32_MTRRCAP_WC 0x400
#define IA32_MTRRCAP_FIX 0x100
#define IA32_MTRRCAP_VCNT 0xFF
#define IA32_MTRR_DEFTYPE_E 0x800
#define IA32_MTRR_DEFTYPE_FE 0x400
#define IA32_MTRR_DEFTYPE_TYPE 0xFF
#define IA32_PHYBASE_TYPE 0XFF
#define IA32_PHYMASK_VALID 0X800
static unsigned int max_phy_addr = 0;
static char * mtrr_types[MTRR_NUM_TYPES] =
{
"uncacheable",
"write-combining",
"?",
"?",
"write-through",
"write-protect",
"write-back",
};
static void decode_address(unsigned long long val)
{
switch (max_phy_addr) {
case 40:
printf("0x%07x ", (unsigned int) ((val >> 12) & 0xFFFFFFF));
break;
case 36:
default:
printf("0x%06x ", (unsigned int) ((val >> 12) & 0xFFFFFF));
break;
}
}
static void set_max_phy_addr(struct cpudata *cpu)
{
unsigned int value;
if (!max_phy_addr) {
cpuid(cpu->number, 0x80000008,&value, NULL, NULL, NULL);
max_phy_addr = (value & 0xFF);
}
}
static int mtrr_value(int cpu, int msr, unsigned long long * val)
{
if (read_msr(cpu, msr, val) == 1)
return 1;
else
return 0;
}
static void dump_mtrr(int cpu, int msr)
{
unsigned long long val=0;
if (read_msr(cpu, msr, &val) == 1)
printf("0x%016llx\n", val);
}
static void decode_mtrrcap(int cpu, int msr)
{
unsigned long long val;
int ret;
ret = mtrr_value(cpu,msr,&val);
if (ret) {
printf("0x%016llx ", val);
printf("(smrr flag: 0x%01x, ",(unsigned int) (val & IA32_MTRRCAP_SMRR) >> 11 );
printf("wc flag: 0x%01x, ",(unsigned int) (val&IA32_MTRRCAP_WC) >> 10);
printf("fix flag: 0x%01x, ",(unsigned int) (val&IA32_MTRRCAP_FIX) >> 8);
printf("vcnt field: 0x%02x (%d))\n",(unsigned int) (val&IA32_MTRRCAP_VCNT) , (int) (val&IA32_MTRRCAP_VCNT));
}
}
static void decode_mtrr_deftype(int cpu, int msr)
{
unsigned long long val;
int ret;
ret = mtrr_value(cpu,msr,&val);
if (ret) {
printf("0x%016llx ", val);
printf("(fixed-range flag: 0x%01x, ",(unsigned int) (val&IA32_MTRR_DEFTYPE_FE) >> 10);
printf("mtrr flag: 0x%01x, ",(unsigned int) (val&IA32_MTRR_DEFTYPE_E) >> 11);
printf("type field: 0x%02x (%s))\n", (unsigned int) (val&IA32_MTRR_DEFTYPE_TYPE) >> 8,
mtrr_types[((val&IA32_MTRR_DEFTYPE_TYPE) >> 8)]);
}
}
static void decode_mtrr_physbase(int cpu, int msr)
{
unsigned long long val;
int ret;
ret = mtrr_value(cpu,msr,&val);
if (ret) {
printf("0x%016llx ", val);
printf("(physbase field:");
decode_address(val);
printf("type field: 0x%02x (%s))\n",(unsigned int) (val&IA32_PHYBASE_TYPE),
mtrr_types[((val&IA32_PHYBASE_TYPE))]);
}
}
static void decode_mtrr_physmask(int cpu, int msr)
{
unsigned long long val;
int ret;
ret = mtrr_value(cpu,msr,&val);
if (ret) {
printf("0x%016llx ", val);
printf("(physmask field:");
decode_address(val);
printf("valid flag: %d)\n",(int) (val&IA32_PHYMASK_VALID)>>11);
}
}
void dump_mtrrs(struct cpudata *cpu)
{
unsigned long long val = 0;
unsigned int i;
if (!(cpu->flags_edx & (X86_FEATURE_MTRR)))
return;
/*
* If MTRR registers are not accessible like in some
* virtualization systems then return
*/
if (!read_msr(cpu->number, 0xfe, &val))
return;
printf("MTRR registers:\n");
printf("MTRRcap (0xfe): ");
decode_mtrrcap(cpu->number, 0xfe);
set_max_phy_addr(cpu);
for (i = 0; i < 16; i+=2) {
printf("MTRRphysBase%u (0x%x): ", i/2, (unsigned int) 0x200+i);
decode_mtrr_physbase(cpu->number, 0x200+i);
printf("MTRRphysMask%u (0x%x): ", i/2, (unsigned int) 0x201+i);
decode_mtrr_physmask(cpu->number, 0x201+i);
}
printf("MTRRfix64K_00000 (0x250): ");
dump_mtrr (cpu->number, 0x250);
printf("MTRRfix16K_80000 (0x258): ");
dump_mtrr (cpu->number, 0x258);
printf("MTRRfix16K_A0000 (0x259): ");
dump_mtrr (cpu->number, 0x259);
printf("MTRRfix4K_C8000 (0x269): ");
dump_mtrr (cpu->number, 0x269);
printf("MTRRfix4K_D0000 0x26a: ");
dump_mtrr (cpu->number, 0x26a);
printf("MTRRfix4K_D8000 0x26b: ");
dump_mtrr (cpu->number, 0x26b);
printf("MTRRfix4K_E0000 0x26c: ");
dump_mtrr (cpu->number, 0x26c);
printf("MTRRfix4K_E8000 0x26d: ");
dump_mtrr (cpu->number, 0x26d);
printf("MTRRfix4K_F0000 0x26e: ");
dump_mtrr (cpu->number, 0x26e);
printf("MTRRfix4K_F8000 0x26f: ");
dump_mtrr (cpu->number, 0x26f);
printf("MTRRdefType (0x2ff): ");
decode_mtrr_deftype(cpu->number, 0x2ff);
printf("\n");
}
|