aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/debug.c5
-rw-r--r--src/uapi/dispatch.c1
-rw-r--r--src/uapi/mem.c28
-rw-r--r--src/vmem.c28
4 files changed, 61 insertions, 1 deletions
diff --git a/src/debug.c b/src/debug.c
index 9573bbc..567911b 100644
--- a/src/debug.c
+++ b/src/debug.c
@@ -753,7 +753,10 @@ void dbg(const char *fmt, ...)
if (is_set(flags, PRECS_FLAG))
i = precision;
- chars_written += __puts(s);
+ for (; *s && i--;) {
+ __putchar(*s++);
+ chars_written++;
+ }
fmt++;
break;
diff --git a/src/uapi/dispatch.c b/src/uapi/dispatch.c
index 16a17d2..4135171 100644
--- a/src/uapi/dispatch.c
+++ b/src/uapi/dispatch.c
@@ -50,6 +50,7 @@ void handle_syscall(sys_arg_t syscall, sys_arg_t a, sys_arg_t b,
case SYS_PUTCH: sys_putch(t, a, b, c, d, e); break;
case SYS_REQ_MEM: sys_req_mem(t, a, b, c, d, e); break;
case SYS_REQ_PMEM: sys_req_pmem(t, a, b, c, d, e); break;
+ case SYS_REQ_PAGE: sys_req_page(t, a, b, c, d, e); break;
case SYS_REQ_FIXMEM: sys_req_fixmem(t, a, b, c, d, e); break;
case SYS_REQ_SHAREDMEM: sys_req_sharedmem(t, a, b, c, d, e); break;
case SYS_REF_SHAREDMEM: sys_ref_sharedmem(t, a, b, c, d, e); break;
diff --git a/src/uapi/mem.c b/src/uapi/mem.c
index 17823a1..49370fc 100644
--- a/src/uapi/mem.c
+++ b/src/uapi/mem.c
@@ -106,6 +106,34 @@ SYSCALL_DEFINE3(req_pmem)(struct tcb *t, sys_arg_t paddr, sys_arg_t size,
}
/**
+ * Allocate some contiguous region in memory.
+ * Due to page allocation constraints, this is generally just one page that's
+ * larger than the \p size parameter. Should work fine for 4K - 2M allocations,
+ * which I assume is generally what is used, but we'll see if I have to
+ * implement an actually good page allocator at some point.
+ *
+ * @param t Current tcb.
+ * @param size Minimum size of mapping.
+ * @param flags Flags of mapping. Unsure why you'd want anything besides VM_W |
+ * VM_R, but eh.
+ *
+ * @return \see sys_req_page().
+ */
+SYSCALL_DEFINE2(req_page)(struct tcb *t, sys_arg_t size, sys_arg_t flags)
+{
+ struct tcb *r = get_cproc(t);
+
+ pm_t addr = 0;
+ vm_t start = 0;
+ size_t asize = 0;
+ flags = sanitize_uvflags(flags);
+ if (!(start = alloc_uvpage(r, size, flags, &addr, &asize)))
+ return_args1(t, ERR_OOMEM);
+
+ return_args4(t, OK, start, addr, asize);
+}
+
+/**
* Request shared memory syscall handler.
*
* @param t Current tcb.
diff --git a/src/vmem.c b/src/vmem.c
index 27e1b2f..261ef42 100644
--- a/src/vmem.c
+++ b/src/vmem.c
@@ -279,6 +279,34 @@ vm_t map_fixed_uvmem(struct tcb *t, pm_t start, size_t size, vmflags_t flags)
return v + (start % BASE_PAGE_SIZE);
}
+vm_t alloc_uvpage(struct tcb *t, size_t size, vmflags_t flags, pm_t *startp,
+ size_t *sizep)
+{
+ enum mm_order order = nearest_order(size);
+ size = order_size(order);
+
+ const vm_t v = alloc_region(&t->uvmem.region, size, &size, flags);
+ if (!v)
+ return 0;
+
+ pm_t start = alloc_page(order);
+ if (!start) {
+ free_region(&t->uvmem.region, size);
+ return 0;
+ }
+
+ if (map_fixed_region(t->proc.vmem, v, start, size, flags)) {
+ unmap_region(t->proc.vmem, v, size);
+ free_region(&t->uvmem.region, v);
+ return NULL;
+ }
+
+ *startp = (pm_t)__pa(start);
+ *sizep = size;
+ return v;
+}
+
+
/* free_shared_uvmem shouldn't be needed, likely to work with free_uvmem */
vm_t alloc_shared_uvmem(struct tcb *s, size_t size, vmflags_t flags)
{