Mercurial > hg > Members > menikon > CbC_xv6
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, ...); +}