#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); }