parlib: Improve panic() and assert()
[akaros.git] / kern / arch / x86 / msr.h
1 /* Copyright (c) 2015 Google Inc
2  * Davide Libenzi <dlibenzi@google.com>
3  * See LICENSE for details.
4  */
5
6 #pragma once
7
8 #include <sys/types.h>
9 #include <ros/errno.h>
10 #include <stdio.h>
11 #include <string.h>
12 #include <core_set.h>
13
14 /* The msr_address and msr_value structures allow to specify either a single
15  * address/value for all cores, or dedicated ones for every core.
16  * This allow a single logical call to msr_cores_read()/msr_cores_write() APIs,
17  * to read/write MSRs at different addresses and using different values.
18  */
19 struct msr_address {
20         uint32_t addr;
21         const uint32_t *addresses;
22         size_t num_addresses;
23 };
24
25 struct msr_value {
26         uint64_t value;
27         uint64_t *values;
28         size_t num_values;
29 };
30
31 int msr_cores_read(const struct core_set *cset, const struct msr_address *msra,
32                                    struct msr_value *msrv);
33 int msr_core_read(unsigned int core, uint32_t addr, uint64_t *value);
34 int msr_cores_write(const struct core_set *cset, const struct msr_address *msra,
35                                         const struct msr_value *msrv);
36 int msr_core_write(unsigned int core, uint32_t addr, uint64_t value);
37
38 static inline void msr_set_address(struct msr_address *msra, uint32_t addr)
39 {
40         ZERO_DATA(*msra);
41         msra->addr = addr;
42 }
43
44 static inline void msr_set_addresses(struct msr_address *msra,
45                                                                          const uint32_t *addresses,
46                                                                          size_t num_addresses)
47 {
48         ZERO_DATA(*msra);
49         msra->addresses = addresses;
50         msra->num_addresses = num_addresses;
51 }
52
53 static inline int msr_get_core_address(unsigned int coreno,
54                                                                            const struct msr_address *msra,
55                                                                            uint32_t *paddr)
56 {
57         if (msra->addresses != NULL) {
58                 if (coreno >= (unsigned int) msra->num_addresses)
59                         return -ERANGE;
60
61                 *paddr = msra->addresses[coreno];
62         } else {
63                 *paddr = msra->addr;
64         }
65
66         return 0;
67 }
68
69 static inline void msr_set_value(struct msr_value *msrv, uint64_t value)
70 {
71         ZERO_DATA(*msrv);
72         msrv->value = value;
73 }
74
75 static inline void msr_set_values(struct msr_value *msrv,
76                                                                   const uint64_t *values, size_t num_values)
77 {
78         ZERO_DATA(*msrv);
79
80         /* Avoid supporting two APIs, one for setting const values, and one for
81          * setting the non const ones.
82          */
83         msrv->values = (uint64_t *) values;
84         msrv->num_values = num_values;
85 }
86
87 static inline int msr_set_core_value(unsigned int coreno, uint64_t value,
88                                                                          struct msr_value *msrv)
89 {
90         if (msrv->values != NULL) {
91                 if (coreno >= (unsigned int) msrv->num_values)
92                         return -ERANGE;
93
94                 msrv->values[coreno] = value;
95         } else {
96                 msrv->value = value;
97         }
98
99         return 0;
100 }
101
102 static inline int msr_get_core_value(unsigned int coreno,
103                                                                          const struct msr_value *msrv,
104                                                                          uint64_t *pvalue)
105 {
106         if (msrv->values != NULL) {
107                 if (coreno >= (unsigned int) msrv->num_values)
108                         return -ERANGE;
109
110                 *pvalue = msrv->values[coreno];
111         } else {
112                 *pvalue = msrv->value;
113         }
114
115         return 0;
116 }