/* This file is part of Fennix Kernel. Fennix Kernel is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Fennix Kernel is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Fennix Kernel. If not, see . */ #include #include #include #include #include #include "../../syscalls.h" #include "../../kernel.h" #include "../../ipc.h" using InterProcessCommunication::IPC; using InterProcessCommunication::IPCID; using Tasking::PCB; using Tasking::TCB; using Tasking::TaskState::Ready; using Tasking::TaskState::Terminated; using namespace Memory; #define SysFrm SyscallsFrame #if defined(a64) typedef long arch_t; #elif defined(a32) typedef int arch_t; #endif /* https://pubs.opengroup.org/onlinepubs/009604499/functions/mmap.html */ void *sys_mmap(SysFrm *, void *addr, size_t len, int prot, int flags, int fildes, off_t off) { if (len == 0) return (void *)-EINVAL; if (fildes != -1) return (void *)-ENOSYS; bool p_None = prot & sc_PROT_NONE; bool p_Read = prot & sc_PROT_READ; bool p_Write = prot & sc_PROT_WRITE; bool p_Exec = prot & sc_PROT_EXEC; bool m_Shared = flags & sc_MAP_SHARED; bool m_Private = flags & sc_MAP_PRIVATE; bool m_Fixed = flags & sc_MAP_FIXED; bool m_Anon = flags & sc_MAP_ANONYMOUS; UNUSED(p_None); UNUSED(m_Anon); debug("N:%d R:%d W:%d E:%d", p_None, p_Read, p_Write, p_Exec); debug("S:%d P:%d F:%d A:%d", m_Shared, m_Private, m_Fixed, m_Anon); int UnknownFlags = flags & ~(sc_MAP_SHARED | sc_MAP_PRIVATE | sc_MAP_FIXED | sc_MAP_ANONYMOUS); if (UnknownFlags) { debug("Unknown flags: %x", UnknownFlags); return (void *)-EINVAL; } if (len > PAGE_SIZE_2M) fixme("large page 2 MiB (requested %d)", TO_MiB(len)); else if (len > PAGE_SIZE_1G) fixme("huge page 1 GiB (requested %d)", TO_GiB(len)); if (off % PAGE_SIZE) return (void *)-EINVAL; if (uintptr_t(addr) % PAGE_SIZE && m_Fixed) return (void *)-EINVAL; if ((m_Shared && m_Private) || (!m_Shared && !m_Private)) return (void *)-EINVAL; Tasking::PCB *pcb = thisProcess; Memory::VirtualMemoryArea *vma = pcb->vma; intptr_t ret = (intptr_t)vma->CreateCoWRegion(addr, len, p_Read, p_Write, p_Exec, m_Fixed, m_Shared); return (void *)ret; }