Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
3263 Serge 1
 
2
#include 
3
4
 
5
 
6
                unsigned int *ecx, unsigned int *edx)
7
{
8
    /* ecx is often an input as well as an output. */
9
    asm volatile("cpuid"
10
        : "=a" (*eax),
11
          "=b" (*ebx),
12
          "=c" (*ecx),
13
          "=d" (*edx)
14
        : "0" (*eax), "2" (*ecx)
15
        : "memory");
16
}
17
18
 
19
static inline void cpuid_count(unsigned int op, int count,
20
                               unsigned int *eax, unsigned int *ebx,
21
                               unsigned int *ecx, unsigned int *edx)
22
{
23
    *eax = op;
24
    *ecx = count;
25
    native_cpuid(eax, ebx, ecx, edx);
26
}
27
28
 
29
 
30
        CACHE_TYPE_NULL = 0,
31
        CACHE_TYPE_DATA = 1,
32
        CACHE_TYPE_INST = 2,
33
        CACHE_TYPE_UNIFIED = 3
34
};
35
36
 
37
 
38
        struct {
39
                enum _cache_type        type:5;
40
                unsigned int            level:3;
41
                unsigned int            is_self_initializing:1;
42
                unsigned int            is_fully_associative:1;
43
                unsigned int            reserved:4;
44
                unsigned int            num_threads_sharing:12;
45
                unsigned int            num_cores_on_die:6;
46
        } split;
47
        uint32_t full;
48
};
49
50
 
51
        struct {
52
                unsigned int            coherency_line_size:12;
53
                unsigned int            physical_line_partition:10;
54
                unsigned int            ways_of_associativity:10;
55
        } split;
56
        uint32_t full;
57
};
58
59
 
60
        struct {
61
                unsigned int            number_of_sets:32;
62
        } split;
63
        uint32_t full;
64
};
65
66
 
67
        union _cpuid4_leaf_eax eax;
68
        union _cpuid4_leaf_ebx ebx;
69
        union _cpuid4_leaf_ecx ecx;
70
        unsigned long size;
71
};
72
73
 
74
cpuid4_cache_lookup_regs(int index,
75
                   struct _cpuid4_info_regs *this_leaf)
76
{
77
    union _cpuid4_leaf_eax  eax;
78
    union _cpuid4_leaf_ebx  ebx;
79
    union _cpuid4_leaf_ecx  ecx;
80
    unsigned                edx;
81
82
 
83
84
 
85
        return -1; /* better error ? */
86
87
 
88
    this_leaf->ebx = ebx;
89
    this_leaf->ecx = ecx;
90
    this_leaf->size = (ecx.split.number_of_sets  + 1) *
91
              (ebx.split.coherency_line_size     + 1) *
92
              (ebx.split.physical_line_partition + 1) *
93
              (ebx.split.ways_of_associativity   + 1);
94
    return 0;
95
}
96
97
 
98
{
99
    unsigned int        eax, ebx, ecx, edx, op;
100
    union _cpuid4_leaf_eax  cache_eax;
101
    int             i = -1;
102
103
 
104
        ++i;
105
        /* Do cpuid(op) loop to find out num_cache_leaves */
106
        cpuid_count(4, i, &eax, &ebx, &ecx, &edx);
107
        cache_eax.full = eax;
108
    } while (cache_eax.split.type != CACHE_TYPE_NULL);
109
    return i;
110
};
111
112
 
113
{
114
    unsigned int new_l1d = 0, new_l1i = 0; /* Cache sizes from cpuid(4)  */
115
    unsigned int new_l2 = 0, new_l3 = 0, i; /* Cache sizes from cpuid(4) */
116
    unsigned int num_cache_leaves;
117
118
 
119
120
 
121
    {
122
        struct _cpuid4_info_regs this_leaf;
123
        int retval;
124
125
 
126
        if (retval >= 0) {
127
            switch (this_leaf.eax.split.level)
128
            {
129
                case 1:
130
                    if (this_leaf.eax.split.type == CACHE_TYPE_DATA)
131
                        new_l1d = this_leaf.size;
132
                    else if (this_leaf.eax.split.type == CACHE_TYPE_INST)
133
                        new_l1i = this_leaf.size;
134
                    break;
135
                case 2:
136
                    new_l2 = this_leaf.size;
137
                    break;
138
                case 3:
139
                    new_l3 = this_leaf.size;
140
                    break;
141
                default:
142
                    break;
143
            }
144
        }
145
    }
146
    printf("l2 cache %d l3 cache %d\n", new_l2, new_l3);
147
148
 
149
};
150