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