vmap: Use {map,unmap}_segment() helpers
[akaros.git] / kern / arch / x86 / msr.c
1 /* Copyright (c) 2015 Google Inc
2  * Davide Libenzi <dlibenzi@google.com>
3  * See LICENSE for details.
4  */
5
6 #include <ros/common.h>
7 #include <compiler.h>
8 #include <kmalloc.h>
9 #include <kthread.h>
10 #include <string.h>
11 #include <stdio.h>
12 #include <assert.h>
13 #include <error.h>
14 #include <pmap.h>
15 #include <umem.h>
16 #include <smp.h>
17 #include <core_set.h>
18 #include <completion.h>
19 #include <arch/uaccess.h>
20 #include <arch/msr.h>
21
22 struct smp_read_values {
23         const struct msr_address *msra;
24         struct msr_value *msrv;
25         int err;
26 };
27
28 struct smp_write_values {
29         const struct msr_address *msra;
30         const struct msr_value *msrv;
31         int err;
32 };
33
34 static void msr_smp_read(void *opaque)
35 {
36         struct smp_read_values *srv = (struct smp_read_values *) opaque;
37         int err, coreno = core_id();
38         uint32_t addr;
39         uint64_t value;
40
41         err = msr_get_core_address(coreno, srv->msra, &addr);
42         if (err)
43                 goto errout;
44         err = read_msr_safe(addr, &value);
45         if (err)
46                 goto errout;
47         err = msr_set_core_value(coreno, value, srv->msrv);
48         if (err)
49                 goto errout;
50
51         return;
52
53 errout:
54         srv->err = err;
55 }
56
57 int msr_cores_read(const struct core_set *cset, const struct msr_address *msra,
58                    struct msr_value *msrv)
59 {
60         int err;
61         struct smp_read_values srv;
62
63         ZERO_DATA(srv);
64         srv.msra = msra;
65         srv.msrv = msrv;
66         srv.err = 0;
67         smp_do_in_cores(cset, msr_smp_read, &srv);
68
69         return srv.err;
70 }
71
72 int msr_core_read(unsigned int coreno, uint32_t addr, uint64_t *value)
73 {
74         int err;
75         struct core_set cset;
76         struct msr_address msra;
77         struct msr_value msrv;
78
79         core_set_init(&cset);
80         core_set_setcpu(&cset, coreno);
81         msr_set_address(&msra, addr);
82         msr_set_values(&msrv, NULL, 0);
83         err = msr_cores_read(&cset, &msra, &msrv);
84         *value = msrv.value;
85
86         return err;
87 }
88
89 static void msr_smp_write(void *opaque)
90 {
91         struct smp_write_values *swv = (struct smp_write_values *) opaque;
92         int err, coreno = core_id();
93         uint32_t addr;
94         uint64_t value;
95
96         err = msr_get_core_address(coreno, swv->msra, &addr);
97         if (err)
98                 goto errout;
99         err = msr_get_core_value(coreno, swv->msrv, &value);
100         if (err)
101                 goto errout;
102         err = write_msr_safe(addr, value);
103         if (err)
104                 goto errout;
105
106         return;
107
108 errout:
109         swv->err = err;
110 }
111
112 int msr_cores_write(const struct core_set *cset, const struct msr_address *msra,
113                     const struct msr_value *msrv)
114 {
115         struct smp_write_values swv;
116
117         ZERO_DATA(swv);
118         swv.msra = msra;
119         swv.msrv = msrv;
120         swv.err = 0;
121         smp_do_in_cores(cset, msr_smp_write, &swv);
122
123         return swv.err;
124 }
125
126 int msr_core_write(unsigned int coreno, uint32_t addr, uint64_t value)
127 {
128         struct core_set cset;
129         struct msr_address msra;
130         struct msr_value msrv;
131
132         core_set_init(&cset);
133         core_set_setcpu(&cset, coreno);
134         msr_set_address(&msra, addr);
135         msr_set_value(&msrv, value);
136
137         return msr_cores_write(&cset, &msra, &msrv);
138 }