1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
|
/* SPDX-License-Identifier: GPL-3.0-or-later */
/* Copyright 2021 - 2022, Kim Kuparinen < kimi.h.kuparinen@gmail.com > */
/**
* @file mem.c
* Memory handling syscall implementations.
* \todo Should we return more error information?
*/
#include <apos/uapi.h>
#include <apos/utils.h>
#include <apos/vmem.h>
#include <apos/dmem.h>
/**
* Memory request syscall handler.
*
* @param size Minimum size of allocation.
* @param flags Flags of allocation.
* @return \ref OK and start of allocation when succesful,
* \ref ERR_OOMEM and \c NULL otherwise.
*/
SYSCALL_DEFINE2(req_mem)(struct tcb *t, sys_arg_t size, sys_arg_t flags)
{
struct tcb *r = get_cproc(t);
vm_t start = 0;
if ((start = alloc_uvmem(r, size, flags)))
return SYS_RET1(ERR_OOMEM);
return SYS_RET2(OK, start);
}
/**
* Fixed memory request syscall handler.
*
* @param fixed Address which should be included in allocation.
* @param size Minimum size of allocation after \c start.
* @param flags Flags of allocation.
* @return \ref OK and start of allocation when succesful,
* \ref ERR_OOMEM and \c NULL otherwise.
*/
SYSCALL_DEFINE3(req_fixmem)(struct tcb *t, sys_arg_t fixed, sys_arg_t size, sys_arg_t flags)
{
struct tcb *r = get_cproc(t);
vm_t start = 0;
if ((start = alloc_fixed_uvmem(r, fixed, size, flags)))
return SYS_RET1(ERR_OOMEM);
return SYS_RET2(OK, start);
}
/**
* Free memory syscall handler.
*
* @param start Start of allocation to free.
* @return \ref OK and \c 0 when succesful, \ref ERR_NF and \c 0 otherwise.
*/
SYSCALL_DEFINE1(free_mem)(struct tcb *t, sys_arg_t start)
{
struct tcb *r = get_cproc(t);
vm_t vm_start = (vm_t)start;
stat_t status = OK;
if (vm_start > __pre_top && vm_start < __post_base)
status = free_uvmem(r, vm_start);
else
status = free_devmem(r, vm_start);
if (status)
return SYS_RET1(ERR_NF);
return SYS_RET1(OK);
}
/**
* Request physical memory syscall handler.
*
* @param paddr Physical address to map.
* @param size Minimum size of allocation.
* @param flags Flags of allocation.
* @return \ref OK and start of allocation when succesful,
* \ref ERR_OOMEM and \c NULL otherwise.
*/
SYSCALL_DEFINE3(req_pmem)(struct tcb *t, sys_arg_t paddr, sys_arg_t size, sys_arg_t flags)
{
/* this will require some pondering, but essentially this syscall should
* only be used for device access, so any addresses requested should be
* outside the RAM area, and I'll probably have to implement some method
* that keeps track of used regions outside of RAM. We'll see.
*/
struct tcb *r = get_cproc(t);
vm_t start = 0;
if ((start = alloc_devmem(r, paddr, size, flags)))
return SYS_RET1(ERR_OOMEM);
return SYS_RET2(OK, start);
}
/**
* Request shared memory syscall handler.
*
* @param size Minimum size of allocation.
* @param flags Flags of allocation.
* @return \ref OK and start of allocation when succesful,
* \ref ERR_OOMEM and \c NULL otherwise.
*/
SYSCALL_DEFINE2(req_sharedmem)(struct tcb *t, sys_arg_t size, sys_arg_t flags)
{
/** \todo check that requester is server */
struct tcb *r = get_cproc(t);
vm_t start = 0;
if ((start = alloc_shared_uvmem(r, size, flags)))
return SYS_RET1(ERR_OOMEM);
return SYS_RET2(OK, start);
}
/**
* Reference shared memory syscall handler.
*
* @param tid Thread ID of shared memory owner.
* @param va Start of shared memory in \c tid.
* @param flags Flags of reference.
* @return \ref OK and start of reference when succesful,
* \ref ERR_OOMEM and \c NULL otherwise.
*/
SYSCALL_DEFINE3(ref_sharedmem)(struct tcb *t, sys_arg_t tid, sys_arg_t va, sys_arg_t flags)
{
struct tcb *t2 = get_tcb(tid);
vm_t start = 0;
if ((start = ref_shared_uvmem(t, t2, va, flags)))
return SYS_RET1(ERR_OOMEM);
return SYS_RET2(OK, start);
}
/** \todo add some way to specify who gets to access the shared memory? */
|