48
48
#include "hw/i386/apic_internal.h"
49
49
#endif
50
50
51
+
52
+ /* Cache topology CPUID constants: */
53
+
54
+ /* CPUID Leaf 2 Descriptors */
55
+
56
+ #define CPUID_2_L1D_32KB_8WAY_64B 0x2c
57
+ #define CPUID_2_L1I_32KB_8WAY_64B 0x30
58
+ #define CPUID_2_L2_2MB_8WAY_64B 0x7d
59
+
60
+
61
+ /* CPUID Leaf 4 constants: */
62
+
63
+ /* EAX: */
64
+ #define CPUID_4_TYPE_DCACHE 1
65
+ #define CPUID_4_TYPE_ICACHE 2
66
+ #define CPUID_4_TYPE_UNIFIED 3
67
+
68
+ #define CPUID_4_LEVEL (l ) ((l) << 5)
69
+
70
+ #define CPUID_4_SELF_INIT_LEVEL (1 << 8)
71
+ #define CPUID_4_FULLY_ASSOC (1 << 9)
72
+
73
+ /* EDX: */
74
+ #define CPUID_4_NO_INVD_SHARING (1 << 0)
75
+ #define CPUID_4_INCLUSIVE (1 << 1)
76
+ #define CPUID_4_COMPLEX_IDX (1 << 2)
77
+
78
+ #define ASSOC_FULL 0xFF
79
+
80
+ /* AMD associativity encoding used on CPUID Leaf 0x80000006: */
81
+ #define AMD_ENC_ASSOC (a ) (a <= 1 ? a : \
82
+ a == 2 ? 0x2 : \
83
+ a == 4 ? 0x4 : \
84
+ a == 8 ? 0x6 : \
85
+ a == 16 ? 0x8 : \
86
+ a == 32 ? 0xA : \
87
+ a == 48 ? 0xB : \
88
+ a == 64 ? 0xC : \
89
+ a == 96 ? 0xD : \
90
+ a == 128 ? 0xE : \
91
+ a == ASSOC_FULL ? 0xF : \
92
+ 0 /* invalid value */ )
93
+
94
+
95
+ /* Definitions of the hardcoded cache entries we expose: */
96
+
97
+ /* L1 data cache: */
98
+ #define L1D_LINE_SIZE 64
99
+ #define L1D_ASSOCIATIVITY 8
100
+ #define L1D_SETS 64
101
+ #define L1D_PARTITIONS 1
102
+ /* Size = LINE_SIZE*ASSOCIATIVITY*SETS*PARTITIONS = 32KiB */
103
+ #define L1D_DESCRIPTOR CPUID_2_L1D_32KB_8WAY_64B
104
+ /*FIXME: CPUID leaf 0x80000005 is inconsistent with leaves 2 & 4 */
105
+ #define L1D_LINES_PER_TAG 1
106
+ #define L1D_SIZE_KB_AMD 64
107
+ #define L1D_ASSOCIATIVITY_AMD 2
108
+
109
+ /* L1 instruction cache: */
110
+ #define L1I_LINE_SIZE 64
111
+ #define L1I_ASSOCIATIVITY 8
112
+ #define L1I_SETS 64
113
+ #define L1I_PARTITIONS 1
114
+ /* Size = LINE_SIZE*ASSOCIATIVITY*SETS*PARTITIONS = 32KiB */
115
+ #define L1I_DESCRIPTOR CPUID_2_L1I_32KB_8WAY_64B
116
+ /*FIXME: CPUID leaf 0x80000005 is inconsistent with leaves 2 & 4 */
117
+ #define L1I_LINES_PER_TAG 1
118
+ #define L1I_SIZE_KB_AMD 64
119
+ #define L1I_ASSOCIATIVITY_AMD 2
120
+
121
+ /* Level 2 unified cache: */
122
+ #define L2_LINE_SIZE 64
123
+ #define L2_ASSOCIATIVITY 16
124
+ #define L2_SETS 4096
125
+ #define L2_PARTITIONS 1
126
+ /* Size = LINE_SIZE*ASSOCIATIVITY*SETS*PARTITIONS = 4MiB */
127
+ /*FIXME: CPUID leaf 2 descriptor is inconsistent with CPUID leaf 4 */
128
+ #define L2_DESCRIPTOR CPUID_2_L2_2MB_8WAY_64B
129
+ /*FIXME: CPUID leaf 0x80000006 is inconsistent with leaves 2 & 4 */
130
+ #define L2_LINES_PER_TAG 1
131
+ #define L2_SIZE_KB_AMD 512
132
+
133
+ /* No L3 cache: */
134
+ #define L3_SIZE_KB 0 /* disabled */
135
+ #define L3_ASSOCIATIVITY 0 /* disabled */
136
+ #define L3_LINES_PER_TAG 0 /* disabled */
137
+ #define L3_LINE_SIZE 0 /* disabled */
138
+
139
+ /* TLB definitions: */
140
+
141
+ #define L1_DTLB_2M_ASSOC 1
142
+ #define L1_DTLB_2M_ENTRIES 255
143
+ #define L1_DTLB_4K_ASSOC 1
144
+ #define L1_DTLB_4K_ENTRIES 255
145
+
146
+ #define L1_ITLB_2M_ASSOC 1
147
+ #define L1_ITLB_2M_ENTRIES 255
148
+ #define L1_ITLB_4K_ASSOC 1
149
+ #define L1_ITLB_4K_ENTRIES 255
150
+
151
+ #define L2_DTLB_2M_ASSOC 0 /* disabled */
152
+ #define L2_DTLB_2M_ENTRIES 0 /* disabled */
153
+ #define L2_DTLB_4K_ASSOC 4
154
+ #define L2_DTLB_4K_ENTRIES 512
155
+
156
+ #define L2_ITLB_2M_ASSOC 0 /* disabled */
157
+ #define L2_ITLB_2M_ENTRIES 0 /* disabled */
158
+ #define L2_ITLB_4K_ASSOC 4
159
+ #define L2_ITLB_4K_ENTRIES 512
160
+
161
+
162
+
51
163
static void x86_cpu_vendor_words2str (char * dst , uint32_t vendor1 ,
52
164
uint32_t vendor2 , uint32_t vendor3 )
53
165
{
@@ -1950,10 +2062,12 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
1950
2062
break ;
1951
2063
case 2 :
1952
2064
/* cache info: needed for Pentium Pro compatibility */
1953
- * eax = 1 ;
2065
+ * eax = 1 ; /* Number of CPUID[EAX=2] calls required */
1954
2066
* ebx = 0 ;
1955
2067
* ecx = 0 ;
1956
- * edx = 0x2c307d ;
2068
+ * edx = (L1D_DESCRIPTOR << 16 ) | \
2069
+ (L1I_DESCRIPTOR << 8 ) | \
2070
+ (L2_DESCRIPTOR );
1957
2071
break ;
1958
2072
case 4 :
1959
2073
/* cache info: needed for Core compatibility */
@@ -1964,25 +2078,37 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
1964
2078
}
1965
2079
switch (count ) {
1966
2080
case 0 : /* L1 dcache info */
1967
- * eax |= 0x0000121 ;
1968
- * ebx = 0x1c0003f ;
1969
- * ecx = 0x000003f ;
1970
- * edx = 0x0000001 ;
2081
+ * eax |= CPUID_4_TYPE_DCACHE | \
2082
+ CPUID_4_LEVEL (1 ) | \
2083
+ CPUID_4_SELF_INIT_LEVEL ;
2084
+ * ebx = (L1D_LINE_SIZE - 1 ) | \
2085
+ ((L1D_PARTITIONS - 1 ) << 12 ) | \
2086
+ ((L1D_ASSOCIATIVITY - 1 ) << 22 );
2087
+ * ecx = L1D_SETS - 1 ;
2088
+ * edx = CPUID_4_NO_INVD_SHARING ;
1971
2089
break ;
1972
2090
case 1 : /* L1 icache info */
1973
- * eax |= 0x0000122 ;
1974
- * ebx = 0x1c0003f ;
1975
- * ecx = 0x000003f ;
1976
- * edx = 0x0000001 ;
2091
+ * eax |= CPUID_4_TYPE_ICACHE | \
2092
+ CPUID_4_LEVEL (1 ) | \
2093
+ CPUID_4_SELF_INIT_LEVEL ;
2094
+ * ebx = (L1I_LINE_SIZE - 1 ) | \
2095
+ ((L1I_PARTITIONS - 1 ) << 12 ) | \
2096
+ ((L1I_ASSOCIATIVITY - 1 ) << 22 );
2097
+ * ecx = L1I_SETS - 1 ;
2098
+ * edx = CPUID_4_NO_INVD_SHARING ;
1977
2099
break ;
1978
2100
case 2 : /* L2 cache info */
1979
- * eax |= 0x0000143 ;
2101
+ * eax |= CPUID_4_TYPE_UNIFIED | \
2102
+ CPUID_4_LEVEL (2 ) | \
2103
+ CPUID_4_SELF_INIT_LEVEL ;
1980
2104
if (cs -> nr_threads > 1 ) {
1981
2105
* eax |= (cs -> nr_threads - 1 ) << 14 ;
1982
2106
}
1983
- * ebx = 0x3c0003f ;
1984
- * ecx = 0x0000fff ;
1985
- * edx = 0x0000001 ;
2107
+ * ebx = (L2_LINE_SIZE - 1 ) | \
2108
+ ((L2_PARTITIONS - 1 ) << 12 ) | \
2109
+ ((L2_ASSOCIATIVITY - 1 ) << 22 );
2110
+ * ecx = L2_SETS - 1 ;
2111
+ * edx = CPUID_4_NO_INVD_SHARING ;
1986
2112
break ;
1987
2113
default : /* end of info */
1988
2114
* eax = 0 ;
@@ -2102,17 +2228,31 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
2102
2228
break ;
2103
2229
case 0x80000005 :
2104
2230
/* cache info (L1 cache) */
2105
- * eax = 0x01ff01ff ;
2106
- * ebx = 0x01ff01ff ;
2107
- * ecx = 0x40020140 ;
2108
- * edx = 0x40020140 ;
2231
+ * eax = (L1_DTLB_2M_ASSOC << 24 ) | (L1_DTLB_2M_ENTRIES << 16 ) | \
2232
+ (L1_ITLB_2M_ASSOC << 8 ) | (L1_ITLB_2M_ENTRIES );
2233
+ * ebx = (L1_DTLB_4K_ASSOC << 24 ) | (L1_DTLB_4K_ENTRIES << 16 ) | \
2234
+ (L1_ITLB_4K_ASSOC << 8 ) | (L1_ITLB_4K_ENTRIES );
2235
+ * ecx = (L1D_SIZE_KB_AMD << 24 ) | (L1D_ASSOCIATIVITY_AMD << 16 ) | \
2236
+ (L1D_LINES_PER_TAG << 8 ) | (L1D_LINE_SIZE );
2237
+ * edx = (L1I_SIZE_KB_AMD << 24 ) | (L1I_ASSOCIATIVITY_AMD << 16 ) | \
2238
+ (L1I_LINES_PER_TAG << 8 ) | (L1I_LINE_SIZE );
2109
2239
break ;
2110
2240
case 0x80000006 :
2111
2241
/* cache info (L2 cache) */
2112
- * eax = 0 ;
2113
- * ebx = 0x42004200 ;
2114
- * ecx = 0x02008140 ;
2115
- * edx = 0 ;
2242
+ * eax = (AMD_ENC_ASSOC (L2_DTLB_2M_ASSOC ) << 28 ) | \
2243
+ (L2_DTLB_2M_ENTRIES << 16 ) | \
2244
+ (AMD_ENC_ASSOC (L2_ITLB_2M_ASSOC ) << 12 ) | \
2245
+ (L2_ITLB_2M_ENTRIES );
2246
+ * ebx = (AMD_ENC_ASSOC (L2_DTLB_4K_ASSOC ) << 28 ) | \
2247
+ (L2_DTLB_4K_ENTRIES << 16 ) | \
2248
+ (AMD_ENC_ASSOC (L2_ITLB_4K_ASSOC ) << 12 ) | \
2249
+ (L2_ITLB_4K_ENTRIES );
2250
+ * ecx = (L2_SIZE_KB_AMD << 16 ) | \
2251
+ (AMD_ENC_ASSOC (L2_ASSOCIATIVITY ) << 12 ) | \
2252
+ (L2_LINES_PER_TAG << 8 ) | (L2_LINE_SIZE );
2253
+ * edx = ((L3_SIZE_KB /512 ) << 18 ) | \
2254
+ (AMD_ENC_ASSOC (L3_ASSOCIATIVITY ) << 12 ) | \
2255
+ (L3_LINES_PER_TAG << 8 ) | (L3_LINE_SIZE );
2116
2256
break ;
2117
2257
case 0x80000008 :
2118
2258
/* virtual & phys address size in low 2 bytes. */
0 commit comments