Do not call functions inside assert()
[akaros.git] / kern / arch / riscv / env.c
1 #include <arch/arch.h>
2 #include <assert.h>
3 #include <env.h>
4 #include <pmap.h>
5 #include <trap.h>
6
7 void save_fp_state(ancillary_state_t *silly)
8 {
9         uintptr_t sr = enable_fp();
10         uint32_t fsr = read_fsr();
11
12         asm("fsd f0,%0" : "=m"(silly->fpr[0]));
13         asm("fsd f1,%0" : "=m"(silly->fpr[1]));
14         asm("fsd f2,%0" : "=m"(silly->fpr[2]));
15         asm("fsd f3,%0" : "=m"(silly->fpr[3]));
16         asm("fsd f4,%0" : "=m"(silly->fpr[4]));
17         asm("fsd f5,%0" : "=m"(silly->fpr[5]));
18         asm("fsd f6,%0" : "=m"(silly->fpr[6]));
19         asm("fsd f7,%0" : "=m"(silly->fpr[7]));
20         asm("fsd f8,%0" : "=m"(silly->fpr[8]));
21         asm("fsd f9,%0" : "=m"(silly->fpr[9]));
22         asm("fsd f10,%0" : "=m"(silly->fpr[10]));
23         asm("fsd f11,%0" : "=m"(silly->fpr[11]));
24         asm("fsd f12,%0" : "=m"(silly->fpr[12]));
25         asm("fsd f13,%0" : "=m"(silly->fpr[13]));
26         asm("fsd f14,%0" : "=m"(silly->fpr[14]));
27         asm("fsd f15,%0" : "=m"(silly->fpr[15]));
28         asm("fsd f16,%0" : "=m"(silly->fpr[16]));
29         asm("fsd f17,%0" : "=m"(silly->fpr[17]));
30         asm("fsd f18,%0" : "=m"(silly->fpr[18]));
31         asm("fsd f19,%0" : "=m"(silly->fpr[19]));
32         asm("fsd f20,%0" : "=m"(silly->fpr[20]));
33         asm("fsd f21,%0" : "=m"(silly->fpr[21]));
34         asm("fsd f22,%0" : "=m"(silly->fpr[22]));
35         asm("fsd f23,%0" : "=m"(silly->fpr[23]));
36         asm("fsd f24,%0" : "=m"(silly->fpr[24]));
37         asm("fsd f25,%0" : "=m"(silly->fpr[25]));
38         asm("fsd f26,%0" : "=m"(silly->fpr[26]));
39         asm("fsd f27,%0" : "=m"(silly->fpr[27]));
40         asm("fsd f28,%0" : "=m"(silly->fpr[28]));
41         asm("fsd f29,%0" : "=m"(silly->fpr[29]));
42         asm("fsd f30,%0" : "=m"(silly->fpr[30]));
43         asm("fsd f31,%0" : "=m"(silly->fpr[31]));
44
45         silly->fsr = fsr;
46         mtpcr(PCR_SR, sr);
47 }
48
49 void restore_fp_state(ancillary_state_t *silly)
50 {
51         uintptr_t sr = enable_fp();
52         uint32_t fsr = silly->fsr;
53
54         asm("fld f0,%0" : : "m"(silly->fpr[0]));
55         asm("fld f1,%0" : : "m"(silly->fpr[1]));
56         asm("fld f2,%0" : : "m"(silly->fpr[2]));
57         asm("fld f3,%0" : : "m"(silly->fpr[3]));
58         asm("fld f4,%0" : : "m"(silly->fpr[4]));
59         asm("fld f5,%0" : : "m"(silly->fpr[5]));
60         asm("fld f6,%0" : : "m"(silly->fpr[6]));
61         asm("fld f7,%0" : : "m"(silly->fpr[7]));
62         asm("fld f8,%0" : : "m"(silly->fpr[8]));
63         asm("fld f9,%0" : : "m"(silly->fpr[9]));
64         asm("fld f10,%0" : : "m"(silly->fpr[10]));
65         asm("fld f11,%0" : : "m"(silly->fpr[11]));
66         asm("fld f12,%0" : : "m"(silly->fpr[12]));
67         asm("fld f13,%0" : : "m"(silly->fpr[13]));
68         asm("fld f14,%0" : : "m"(silly->fpr[14]));
69         asm("fld f15,%0" : : "m"(silly->fpr[15]));
70         asm("fld f16,%0" : : "m"(silly->fpr[16]));
71         asm("fld f17,%0" : : "m"(silly->fpr[17]));
72         asm("fld f18,%0" : : "m"(silly->fpr[18]));
73         asm("fld f19,%0" : : "m"(silly->fpr[19]));
74         asm("fld f20,%0" : : "m"(silly->fpr[20]));
75         asm("fld f21,%0" : : "m"(silly->fpr[21]));
76         asm("fld f22,%0" : : "m"(silly->fpr[22]));
77         asm("fld f23,%0" : : "m"(silly->fpr[23]));
78         asm("fld f24,%0" : : "m"(silly->fpr[24]));
79         asm("fld f25,%0" : : "m"(silly->fpr[25]));
80         asm("fld f26,%0" : : "m"(silly->fpr[26]));
81         asm("fld f27,%0" : : "m"(silly->fpr[27]));
82         asm("fld f28,%0" : : "m"(silly->fpr[28]));
83         asm("fld f29,%0" : : "m"(silly->fpr[29]));
84         asm("fld f30,%0" : : "m"(silly->fpr[30]));
85         asm("fld f31,%0" : : "m"(silly->fpr[31]));
86
87         write_fsr(fsr);
88         mtpcr(PCR_SR, sr);
89 }
90
91 void init_fp_state(void)
92 {
93         uintptr_t sr = enable_fp();
94
95         asm("fcvt.d.w f0, x0; fcvt.d.w f1 ,x0; fcvt.d.w f2, x0; fcvt.d.w f3, "
96             "x0;");
97         asm("fcvt.d.w f4, x0; fcvt.d.w f5, x0; fcvt.d.w f6, x0; fcvt.d.w f7, "
98             "x0;");
99         asm("fcvt.d.w f8, x0; fcvt.d.w f9, x0; fcvt.d.w f10,x0; fcvt.d.w "
100             "f11,x0;");
101         asm("fcvt.d.w f12,x0; fcvt.d.w f13,x0; fcvt.d.w f14,x0; fcvt.d.w "
102             "f15,x0;");
103         asm("fcvt.d.w f16,x0; fcvt.d.w f17,x0; fcvt.d.w f18,x0; fcvt.d.w "
104             "f19,x0;");
105         asm("fcvt.d.w f20,x0; fcvt.d.w f21,x0; fcvt.d.w f22,x0; fcvt.d.w "
106             "f23,x0;");
107         asm("fcvt.d.w f24,x0; fcvt.d.w f25,x0; fcvt.d.w f26,x0; fcvt.d.w "
108             "f27,x0;");
109         asm("fcvt.d.w f28,x0; fcvt.d.w f29,x0; fcvt.d.w f30,x0; fcvt.d.w "
110             "f31,x0;");
111         asm("mtfsr x0");
112
113         mtpcr(PCR_SR, sr);
114 }
115
116 static int user_mem_walk_recursive(env_t *e, uintptr_t start, size_t len,
117                                    mem_walk_callback_t callback, void *arg,
118                                    mem_walk_callback_t pt_callback,
119                                    void *pt_arg, pte_t *pt, int level)
120 {
121         int ret = 0;
122         int pgshift = L1PGSHIFT - level * (L1PGSHIFT - L2PGSHIFT);
123         uintptr_t pgsize = 1UL << pgshift;
124
125         uintptr_t start_idx = (start >> pgshift) & (NPTENTRIES - 1);
126         uintptr_t end_idx = ((start + len - 1) >> pgshift) & (NPTENTRIES - 1);
127
128         for (uintptr_t idx = start_idx; idx <= end_idx; idx++) {
129                 uintptr_t pgaddr =
130                     ROUNDDOWN(start, pgsize) + (idx - start_idx) * pgsize;
131                 pte_t *pte = &pt[idx];
132
133                 if (*pte & PTE_T) {
134                         assert(level < NPTLEVELS - 1);
135                         uintptr_t st = MAX(pgaddr, start);
136                         size_t ln = MIN(start + len, pgaddr + pgsize) - st;
137                         if ((ret = user_mem_walk_recursive(
138                                  e, st, ln, callback, arg, pt_callback, pt_arg,
139                                  KADDR(PTD_ADDR(*pte)), level + 1)))
140                                 goto out;
141                         if (pt_callback != NULL &&
142                             (ret = pt_callback(e, pte, (void *)pgaddr, arg)))
143                                 goto out;
144                 } else if (callback != NULL)
145                         if ((ret = callback(e, pte, (void *)pgaddr, arg)))
146                                 goto out;
147         }
148 out:
149         return ret;
150 }
151
152 int env_user_mem_walk(env_t *e, void *start, size_t len,
153                       mem_walk_callback_t callback, void *arg)
154 {
155         assert(PGOFF(start) == 0 && PGOFF(len) == 0);
156         return user_mem_walk_recursive(e, (uintptr_t)start, len, callback, arg,
157                                        NULL, NULL, e->env_pgdir, 0);
158 }
159
160 void env_pagetable_free(env_t *e)
161 {
162         int ret;
163
164         int pt_free(env_t * e, pte_t * pte, void *va, void *arg)
165         {
166                 if (!PAGE_PRESENT(pte))
167                         return 0;
168                 page_decref(pa2page(PTD_ADDR(*pte)));
169                 return 0;
170         }
171
172         ret = user_mem_walk_recursive(e, 0, KERNBASE, NULL, NULL, pt_free, NULL,
173                                       e->env_pgdir, 0)
174         assert(ret == 0);
175 }