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
|
#include "message.h"
#include "api/error.h"
#include "jove.h"
#include "hal/memory.h"
#include "hal/obj.h"
#include "lib/printf.h"
static inline uintptr_t
s_message_addr(jove_owned_obj_t *message_obj)
{
return (obj_getvalue(message_obj) >> 1) << 12;
}
int message_new(jove_owned_obj_t *untyped_obj)
{
uintmax_t untyped_value = obj_getvalue(untyped_obj);
jove_untyped_t *untyped = obj_deref(untyped_obj);
if(untyped->limit != 0x1000) {
klogf("Passed untyped has bad size : %x vs %x\n", untyped->limit, MESSAGE_SIZE);
return -EBADSIZE;
}
if(untyped_value & (MESSAGE_ALIGN - 1)) {
klogf("Passed untyped has bad alignment : %x\n", untyped_value & (MESSAGE_ALIGN - 1));
return -EALIGN;
}
obj_settype(untyped_obj, JOVE_OBJ_MESSAGE);
obj_setvalue(untyped_obj, obj_getvalue(untyped_obj) >> 11);
return 0;
}
inline int
message_hasmap(jove_owned_obj_t *message_obj)
{
return obj_getvalue(message_obj) & 1;
}
virtaddr_t
message_unmap(jove_owned_obj_t *message_obj, jove_owned_obj_t *pagedir_obj)
{
errno = 0;
if(message_hasmap(message_obj) == 0) {
klogf("Message %p doesn't have a map\n", obj_getvalue(message_obj));
errno = -ENOMAP;
return 0;
}
virtaddr_t message_vaddr = s_message_addr(message_obj);
virtaddr_t *mapping = pagedir_get_mapping(pagedir_obj, message_vaddr);
physaddr_t message_pfn = pagedir_mapping_get_pfn(mapping);
pagedir_mapping_set_present(mapping, false);
obj_setvalue(message_obj, message_pfn << 1);
pagedir_invlpg(message_vaddr);
message_klogf("Unmapped message %p from %p\n", message_pfn << 12, message_vaddr);
return message_vaddr;
}
int
message_map(jove_owned_obj_t *message, jove_owned_obj_t *pagedir, virtaddr_t vaddr)
{
if(message_hasmap(message)) {
return -EHASMAP;
}
virtaddr_t message_paddr = s_message_addr(message);
virtaddr_t *mapping = pagedir_get_mapping(pagedir, vaddr);
if(pagedir_mapping_is_present(mapping)) {
klogf("Mapping %p is occupied\n",
mapping, message);
return -EHASMAP;
}
pagedir_mapping_set_pfn(mapping, message_paddr >> 12);
pagedir_mapping_set_present(mapping, true);
pagedir_mapping_set_writeable(mapping, true);
pagedir_mapping_set_user(mapping, true);
pagedir_mapping_set_type(mapping, JOVE_MAPPING_TYPE_MESSAGE);
pagedir_invlpg(vaddr);
message_klogf("Mapped message %p to %p\n", message_paddr, vaddr);
obj_setvalue(message, (vaddr >> 11) | 1);
return 0;
}
virtaddr_t message_getdata(jove_owned_obj_t *message)
{
uintptr_t message_addr = s_message_addr(message);
if(message_hasmap(message)) return message_addr;
return (virtaddr_t)phys_tovirt(message_addr);
}
|