Voxia OS v0.0.1
Hobby Project Operating System Targeting x86-64
Loading...
Searching...
No Matches
mmap.c
Go to the documentation of this file.
1#include "hal/cpu/core.h"
2#include "hal/cpu/paging.h"
3#include "libk/serial.h"
6#include "memory/vm_manager.h"
7#include "sys/err_no.h"
8#include <str.h>
9#include <sys/syscall.h>
10
11#define MAP_FAILED ((void*)-1)
12
13#define MAP_SHARED 0x01
14#define MAP_PRIVATE 0x02
15#define MAP_SHARED_VALIDATE 0x03
16#define MAP_TYPE 0x0f
17#define MAP_FIXED 0x10
18#define MAP_ANON 0x20
19#define MAP_ANONYMOUS MAP_ANON
20#define MAP_NORESERVE 0x4000
21#define MAP_GROWSDOWN 0x0100
22#define MAP_DENYWRITE 0x0800
23#define MAP_EXECUTABLE 0x1000
24#define MAP_LOCKED 0x2000
25#define MAP_POPULATE 0x8000
26#define MAP_NONBLOCK 0x10000
27#define MAP_STACK 0x20000
28#define MAP_HUGETLB 0x40000
29#define MAP_SYNC 0x80000
30#define MAP_FIXED_NOREPLACE 0x100000
31#define MAP_FILE 0
32
33#define MAP_HUGE_SHIFT 26
34#define MAP_HUGE_MASK 0x3f
35#define MAP_HUGE_16KB (14 << 26)
36#define MAP_HUGE_64KB (16 << 26)
37#define MAP_HUGE_512KB (19 << 26)
38#define MAP_HUGE_1MB (20 << 26)
39#define MAP_HUGE_2MB (21 << 26)
40#define MAP_HUGE_8MB (23 << 26)
41#define MAP_HUGE_16MB (24 << 26)
42#define MAP_HUGE_32MB (25 << 26)
43#define MAP_HUGE_256MB (28 << 26)
44#define MAP_HUGE_512MB (29 << 26)
45#define MAP_HUGE_1GB (30 << 26)
46#define MAP_HUGE_2GB (31 << 26)
47#define MAP_HUGE_16GB (34U << 26)
48
49static uint64_t mmap_prot_to_flags(int prot) {
50 if (prot == PROT_NONE)
51 return 0;
52
53 uint64_t flags = 0;
54 if (prot & (PROT_READ | PROT_WRITE | PROT_EXEC))
56 if (prot & PROT_WRITE)
58 if (!(prot & PROT_EXEC))
60
61 return flags;
62}
63
66 size_t len_4kb) {
67 if (flags & MAP_FIXED) {
68 if (!addr)
69 return 0; /* MAP_FIXED + NULL → EINVAL */
70 return (uintptr_t)addr;
71 }
72
74}
75
76static void* mmap_handle_anonymous(thread_t* thr, process_t* procc, void* addr,
77 int flags, size_t len_4kb,
78 uint64_t mmap_flags) {
79 serial2_printf("anonymous mmap: flags=0x%x\n", flags);
80
81 uintptr_t virt_addr =
82 mmap_resolve_virt_addr(addr, flags, procc->vm_page, len_4kb);
83
84 if (!virt_addr)
85 return (flags & MAP_FIXED) ? (void*)-EINVAL : (void*)-ENOMEM;
86
87 uintptr_t phys = (uintptr_t)phys_base_alloc(len_4kb);
88 if (!phys)
89 return (void*)-ENOMEM;
90
91 vxMultipleMmap(thr->page, virt_addr, phys, len_4kb, mmap_flags);
92 serial2_printf("mmaped virt=0x%x phys=0x%x flags=%b\n", virt_addr, phys,
93 mmap_flags);
94
95 vma_register(procc->vm_page, phys, virt_addr, len_4kb * BLOCK_SIZE);
96
97 return (void*)virt_addr;
98}
99
100void* syscall_mmap(void* addr, size_t len, int prot, int flags, int fd,
101 long off) {
102 auto thr = get_current_core_data()->active_thread;
103 auto procc = thr ? thr->process : nullptr;
104
105 if (!thr || !procc)
106 return (void*)-ENOENT;
107
108 serial_trace("mmap_request: addr=0x%x len=0x%x prot=%d "
109 "flags=0x%x fd=0x%x off=0x%x\n",
110 addr, len, prot, flags, fd, off);
111
112 if (len == 0)
113 return (void*)-EINVAL;
114
115 size_t len_4kb = ALIGN_UP(len, 0x1000) / 0x1000;
116 uint64_t mmap_flags = mmap_prot_to_flags(prot);
117
118 if (flags & MAP_ANONYMOUS)
119 return mmap_handle_anonymous(thr, procc, addr, flags, len_4kb,
120 mmap_flags);
121
122 if (flags & MAP_PRIVATE)
123 serial2_printf("mmap: MAP_PRIVATE not yet implemented\n");
124
125 serial2_printf("mmap: unsupported flags=0x%x\n", flags);
126 return (void*)-ENOSPC;
127}
each_core_data * get_current_core_data(void)
Definition core.c:54
volatile uint64_t addr
Definition e1000.hpp:0
#define ENOENT
Definition err_no.h:5
#define ENOSPC
Definition err_no.h:27
#define ENOMEM
Definition err_no.h:15
struct thread thread_t
Definition thread.h:29
uint16_t flags
Definition thread.h:5
void serial2_printf(const char *fmt,...)
#define EINVAL
#define ALIGN_UP(x, align)
Definition memory_utils.h:6
void * syscall_mmap(void *addr, size_t len, int prot, int flags, int fd, long off)
Definition mmap.c:100
static uintptr_t mmap_resolve_virt_addr(void *addr, int flags, struct virtual_memory_page *vm_page, size_t len_4kb)
Definition mmap.c:64
#define MAP_FIXED
Definition mmap.c:17
#define MAP_PRIVATE
Definition mmap.c:14
static uint64_t mmap_prot_to_flags(int prot)
Definition mmap.c:49
static void * mmap_handle_anonymous(thread_t *thr, process_t *procc, void *addr, int flags, size_t len_4kb, uint64_t mmap_flags)
Definition mmap.c:76
#define MAP_ANONYMOUS
Definition mmap.c:19
size_t len
Definition oct2bin.h:7
void vxMultipleMmap(page_t page_dir, uint64_t virt, uint64_t phys, uint64_t size, uint64_t flags)
Definition paging.c:340
#define PAGE_PRESENT
Definition paging.h:34
#define PAGE_NO_EXECUTE
Definition paging.h:43
#define PAGE_WRITABLE
Definition paging.h:35
void * phys_base_alloc(uint64_t block)
#define BLOCK_SIZE
struct virtual_memory_page * vm_page
Definition process.h:15
#define serial_trace(...)
Definition serial.h:19
volatile uintptr_t * page
Definition thread.h:29
#define PROT_READ
Definition syscall.h:26
#define PROT_WRITE
Definition syscall.h:27
#define PROT_NONE
Definition syscall.h:25
#define PROT_EXEC
Definition syscall.h:28
unsigned long uintptr_t
Definition type.h:73
unsigned long uint64_t
Definition type.h:25
uintptr_t vma_lookup_free_vaddr(struct virtual_memory_page *page, mem_vma_region region, size_t size)
Definition vm_manager.c:156
void vma_register(struct virtual_memory_page *page, uintptr_t phys_address, uintptr_t virt_addr, size_t size)
Definition vm_manager.c:101
@ VMA_REGION_PROCESS
Definition vm_manager.h:25