1 #pragma once
2
3 /*
4 * Author: Andreas Herrmann <andreas.herrmann3@amd.com>
5 *
6 * Copyright (C) 2008 Advanced Micro Devices, Inc.
7 *
8 * Licensed under the terms of the GNU GENERAL PUBLIC LICENSE version 2.
9 * See file COPYING for details.
10 */
11
12 #define _RANGE(name, args...) \
13 unsigned char name##_range[] = { args }
14
15 #define _NAMES(name, args...) \
16 const char *name##_spec[] = { args }
17
18 #define _SPEC(addr, name, desc, prefix) \
19 {addr, #name, desc, prefix##name##_range, prefix##name##_spec}
20
21 #define MSR_MAX_LEN 32
22 struct reg_spec {
23 unsigned int address;
24 const char *name;
25 const char *desc;
26 unsigned char *bits;
27 const char **spec;
28 };
29
get_reg_spec(uint32_t msr,struct reg_spec * table)30 static struct reg_spec *get_reg_spec(uint32_t msr, struct reg_spec *table)
31 {
32 int i;
33 for (i = 0; table[i].name; i++)
34 if (msr == table[i].address)
35 return &(table[i]);
36 return NULL;
37 }
38
get_reg_addr(const char * name,struct reg_spec * table)39 static uint32_t get_reg_addr(const char *name, struct reg_spec *table)
40 {
41 int i;
42
43 for (i = 0; table[i].name; i++)
44 if (strcmp(name, table[i].name) == 0)
45 return table[i].address;
46
47 return -1;
48 }
49
get_reg_name(uint32_t reg,struct reg_spec * table)50 static const char *get_reg_name(uint32_t reg, struct reg_spec *table)
51 {
52 struct reg_spec *d;
53 const char *s = NULL;
54
55 d = get_reg_spec(reg, table);
56 if (d)
57 s = d->name;
58
59 return s;
60 }
61
print_reg_bits(struct reg_spec * reg,uint64_t val,uint8_t list,uint8_t verb)62 static void print_reg_bits(struct reg_spec *reg, uint64_t val, uint8_t list,
63 uint8_t verb)
64 {
65 unsigned char *r;
66 const char **d;
67 int i, j, k;
68 int first, any;
69 uint64_t t;
70 const char *s;
71
72 if (!reg || !reg->bits || !reg->spec)
73 return;
74
75 any = 0;
76 first = 1;
77 r = reg->bits;
78 d = reg->spec;
79 for (i = 0, j = 0; r[i]; i++, j = k + 1){
80 k = j + r[i] - 1;
81 if (d[i] == 0) {
82 if (verb == 2 || verb == 4)
83 s = "res";
84 else /* hide reserved fields */
85 continue;
86 } else
87 s = d[i];
88
89 if (verb > 2)
90 fprintf(stdout, "\n ");
91 else
92 fprintf(stdout, "%s", first ? " (" : ", ");
93
94 if (list)
95 printf("%d-%d:%s", j, k, s);
96 else {
97 if (r[i] == 64)
98 t = val;
99 else
100 t = (val >> j) & ((1ULL<<r[i]) - 1);
101
102 fprintf(stdout, "%s=%#llx", s, (unsigned long long) t);
103 }
104 first = 0;
105 any = 1;
106 }
107 if (any && verb <= 2)
108 fprintf(stdout, ")");
109 }
110
print_reg(struct reg_spec * reg,uint64_t val,uint8_t list,uint8_t all,uint8_t verb)111 static void print_reg(struct reg_spec *reg, uint64_t val, uint8_t list,
112 uint8_t all, uint8_t verb)
113 {
114 if (list) {
115 if ((verb == 0 || verb == 3 || verb ==4) && reg->desc)
116 fprintf(stdout, "%-*s: 0x%8.8x; %s", all ? 20 : 0,
117 reg->name, reg->address, reg->desc);
118 else
119 fprintf(stdout, "%-*s: 0x%8.8x", all ? 20 : 0,
120 reg->name, reg->address);
121
122 } else
123 fprintf(stdout, "%-*s = 0x%16.16llx", all ? 20 : 0,
124 reg->name, (unsigned long long) val);
125
126 if (verb)
127 print_reg_bits(reg, val, list, verb);
128
129 fprintf(stdout, "\n");
130 }
131