Determining Opteron processor revisions on Solaris



For a while now I've been doing quite a bit of work on the Opteron processor. For some of this work it's important to know which revision of processor you currently have in the machine you've cobbled together. This should be a doddle, right? Well, not quite.
So, how do you know if you have a rev B or a rev E processor then? The processor revision is determined by a bunch of values returned by the CPUID instruction - these include the family, model and step of the processor. These values can then be used in a lookup table which is given in the Opteron revision guide which can be found here. On a Solaris system the family, model and step can be found using psrinfo(1M):
# psrinfo -pv
The physical processor has 2 virtual processors (0 1)
  x86 (AuthenticAMD family 15 model 33 step 2 clock 2190 MHz)
        Dual Core AMD Opteron(tm) Processor 275
The physical processor has 2 virtual processors (2 3)
  x86 (AuthenticAMD family 15 model 33 step 2 clock 2190 MHz)
        Dual Core AMD Opteron(tm) Processor 275
So, armed with these numbers I can go and look up the processor revision. However, if you take a look at the revision guide, you'll see it's not quite as straight forward as you may hope (to say the least).
However, you can cheat a bit. In the amd memory controller driver in Solaris the saliant information contained in the previously mentioned table is represented in the mc_rev_map[] array:
static const mc_rev_map_t mc_rev_map[] = {
        { 0xf, 0x00, 0x0f, MC_REV_PRE_D, "B/C/CG" },
        { 0xf, 0x10, 0x1f, MC_REV_D_E, "D" },
        { 0xf, 0x20, 0x3f, MC_REV_D_E, "E" },
        { 0xf, 0x40, 0x5f, MC_REV_F, "F" },
        { 0, 0, 0, MC_REV_UNKNOWN, NULL }
};
Where a mc_rev_map_t looks like:
typedef struct mc_rev_map {
        uint_t rm_family;
        uint_t rm_modello;
        uint_t rm_modelhi;
        uint_t rm_rev;
        const char \*rm_name;
} mc_rev_map_t;
Using the contents of this array you can see which revision you have by simply seeing which range (using the rm_modello and rm_modelhi members) your processors model falls within. We can see from the psrinfo output given earlier, that this machine has Rev E processors.
However, instead of doing this we can use mdb to do our work for us. Every memory controller on the system is represented in a struct mc and these, conveniently, contain a member, mc_revname, which identifies the processor revision of it's associated processor. We can look at all the memory controllers on the system using the mc_list global variable which is a pointer to the front of the list of memory controller structure:
 > \*mc_list::list mc_t mc_next | ::print mc_t mc_revname
mc_revname = 0xfffffffff01eb550 "E"
mc_revname = 0xfffffffff01eb550 "E"
It's always more fun with mdb!!
Comments:

So how hard would it be to add an option to psrinfo that just tells you what you want to know?

Posted by Chris Quenelle on June 26, 2006 at 06:33 PM GMT+00:00 #

For me it would be really hard as it's now written in Perl:-) . It naturally sits there yes. I'll drop Sasha Kolbasov and see what he thinks.

Posted by Jon Haslam on June 27, 2006 at 01:02 PM GMT+00:00 #

The above comment is obviously meant to say, "... drop Sasha Kolbasov a line...". Sigh...

Posted by Jon Haslam on June 27, 2006 at 01:04 PM GMT+00:00 #

Post a Comment:
Comments are closed for this entry.
About

jonh

Search

Categories
Archives
« April 2014
MonTueWedThuFriSatSun
 
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
    
       
Today