akaros/kern/arch/riscv/env.c
<<
>>
Prefs
   1#include <arch/arch.h>
   2#include <assert.h>
   3#include <env.h>
   4#include <pmap.h>
   5#include <trap.h>
   6
   7void 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
  49void 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
  91void 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
 116static 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        }
 148out:
 149        return ret;
 150}
 151
 152int 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
 160void 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}
 176