diff src/impl/vm_impl_private.cbc @ 217:f940ff602312

copyuvm_loop
author tobaru
date Fri, 24 Jan 2020 16:17:25 +0900
parents 0f1700bd5cff
children 1c923ae14607
line wrap: on
line diff
--- a/src/impl/vm_impl_private.cbc	Fri Jan 24 15:22:44 2020 +0900
+++ b/src/impl/vm_impl_private.cbc	Fri Jan 24 16:17:25 2020 +0900
@@ -213,3 +213,59 @@
 
     goto next(ret, ...);
 }
+
+__code copyuvm_check_nullvm_impl(struct vm_impl* vm_impl, pde_t* pgdir, uint sz, __code next(int ret, ...)) {
+    pde_t *d;
+    pte_t *pte;
+    uint pa, i, ap;
+    char *mem;
+
+    // allocate a new first level page directory
+    d = kpt_alloc();
+    if (d == NULL ) {
+        ret = NULL;
+        goto next(ret, ...);
+    }
+    i = 0;
+
+    goto copyuvm_loopvm_impl(vm_impl, pgdir, sz, *d, *pte, pa, i, ap, *mem, next(ret, ...));
+}
+
+__code copyuvm_loopvm_impl(struct vm_impl* vm_impl, pde_t* pgdir, uint sz, pde_t* d, pte_t* pte, uint pa, uint i, uint ap, char* mem, __code next(int ret, ...)) {
+
+    if (i < sz) { 
+        if ((pte = walkpgdir(pgdir, (void *) i, 0)) == 0) {
+            panic("copyuvm: pte should exist");
+        }
+
+        if (!(*pte & PE_TYPES)) {
+            panic("copyuvm: page not present");
+        }
+
+        pa = PTE_ADDR (*pte);
+        ap = PTE_AP (*pte);
+
+        if ((mem = alloc_page()) == 0) {
+            goto copyuvm_loop_bad(vm_impl, d, next(...));
+        }
+
+        memmove(mem, (char*) p2v(pa), PTE_SZ);
+
+        if (mappages(d, (void*) i, PTE_SZ, v2p(mem), ap) < 0) {
+            goto copyuvm_loop_bad(vm_impl, d, next(...));
+        }
+        goto copyuvm_loopvm_impl(vm_impl, pgdir, sz, d, pte, pa, i + PTE_SZ, ap, mem, next(ret, ...));
+    }
+    ret = d;
+    goto next(ret, ...);
+}
+
+__code copyuvm_loop_check_walkpgdir() {
+
+}
+
+__code copyuvm_loop_bad(struct vm_impl* vm_impl, pde_t* d, __code next(int ret, ...)) {
+    freevm(d);
+    ret = 0;
+    goto next(ret, ...);
+}