summaryrefslogtreecommitdiff
path: root/src/kernel/mem.c
diff options
context:
space:
mode:
authordzwdz2021-08-22 11:35:00 +0200
committerdzwdz2021-08-22 11:35:00 +0200
commit5aaf1d48ec052d1582eae2c7642adc8829a6711b (patch)
tree40745bc8d62035b812c6f36f0629c13221ae42e3 /src/kernel/mem.c
parentc0a5b44bc8261dec6d4ffaadb244ecbff962719b (diff)
await() 2: pass the exit message
Diffstat (limited to 'src/kernel/mem.c')
-rw-r--r--src/kernel/mem.c32
1 files changed, 32 insertions, 0 deletions
diff --git a/src/kernel/mem.c b/src/kernel/mem.c
index 9ba0231..63f5379 100644
--- a/src/kernel/mem.c
+++ b/src/kernel/mem.c
@@ -1,5 +1,6 @@
#include <kernel/arch/generic.h>
#include <kernel/mem.h>
+#include <kernel/util.h>
#include <stdint.h>
static void *highest_page;
@@ -78,3 +79,34 @@ bool virt_iter_next(struct virt_iter *iter) {
iter->_virt += partial;
return true;
}
+
+bool virt_user_cpy(
+ struct pagedir *dest_pages, void *dest,
+ struct pagedir *src_pages, const void *src, size_t length)
+{
+ struct virt_iter dest_iter, src_iter;
+ size_t min;
+
+ virt_iter_new(&dest_iter, dest, length, dest_pages, true, true);
+ virt_iter_new( &src_iter, src, length, src_pages, true, false);
+ dest_iter.frag_len = 0;
+ src_iter.frag_len = 0;
+
+ for (;;) {
+ if (dest_iter.frag_len <= 0)
+ if (!virt_iter_next(&dest_iter)) break;
+ if ( src_iter.frag_len <= 0)
+ if (!virt_iter_next( &src_iter)) break;
+
+ min = src_iter.frag_len < dest_iter.frag_len
+ ? src_iter.frag_len : dest_iter.frag_len;
+ memcpy(dest_iter.frag, src_iter.frag, min);
+
+ dest_iter.frag_len -= min;
+ dest_iter.frag += min;
+ src_iter.frag_len -= min;
+ src_iter.frag += min;
+ }
+
+ return !(dest_iter.error || src_iter.error);
+}