kernel: Let devices use shared memory

This commit is contained in:
apio 2023-08-03 09:25:23 +02:00
parent c5e24e478f
commit d8f6af99b8
Signed by: apio
GPG Key ID: B8A7D06E42258954
5 changed files with 45 additions and 1 deletions

View File

@ -10,6 +10,11 @@ class Device : public Shareable
virtual Result<usize> write(const u8* buf, usize offset, usize length) = 0;
virtual Result<u64> query_shared_memory(off_t, usize)
{
return err(EACCES);
}
virtual Result<u64> ioctl(int, void*)
{
return err(ENOTTY);
@ -44,4 +49,7 @@ class Device : public Shareable
virtual bool will_block_if_read() const = 0;
virtual ~Device() = default;
protected:
Option<u64> m_shmid;
};

View File

@ -1,4 +1,6 @@
#include "fs/devices/FramebufferDevice.h"
#include "arch/MMU.h"
#include "memory/SharedMemory.h"
#include "video/Framebuffer.h"
#include <bits/ioctl-defs.h>
#include <luna/CString.h>
@ -23,6 +25,32 @@ Result<usize> FramebufferDevice::write(const u8* buf, usize offset, usize length
return length;
}
Result<u64> FramebufferDevice::query_shared_memory(off_t offset, usize count)
{
if (offset + (count * ARCH_PAGE_SIZE) > Framebuffer::size()) return err(EINVAL);
if (!m_shmid.has_value())
{
u64 shmid = TRY(SharedMemory::create(Framebuffer::ptr() + offset, offset, count));
m_shmid = shmid;
auto* shm = g_shared_memory_map.try_get_ref(shmid);
shm->device = SharedPtr<Device> { this };
return shmid;
}
auto* shm = g_shared_memory_map.try_get_ref(*m_shmid);
if (shm->offset > offset)
{
TRY(shm->grow_backward(Framebuffer::ptr() + offset, (shm->offset - offset) / ARCH_PAGE_SIZE));
}
if (shm->frames.size() < count)
{
TRY(shm->grow_forward(Framebuffer::ptr() + offset + (shm->frames.size() * ARCH_PAGE_SIZE),
count - shm->frames.size()));
}
return *m_shmid;
}
usize FramebufferDevice::size() const
{
return Framebuffer::size();

View File

@ -11,6 +11,8 @@ class FramebufferDevice : public Device
Result<usize> write(const u8*, usize, usize) override;
Result<u64> query_shared_memory(off_t offset, usize count) override;
bool will_block_if_read() const override;
bool is_block_device() const override

View File

@ -304,6 +304,10 @@ void VMRegion::sync_shared()
if (used && (flags & MAP_SHARED) && (prot & PROT_WRITE))
{
SharedMemory* shmem = g_shared_memory_map.try_get_ref(shmid);
if (shmem) { shmem->inode->write((const u8*)start, offset, count * ARCH_PAGE_SIZE); }
if (shmem)
{
if (shmem->inode) shmem->inode->write((const u8*)start, offset, count * ARCH_PAGE_SIZE);
if (shmem->device) shmem->device->write((const u8*)start, offset, count * ARCH_PAGE_SIZE);
}
}
}

View File

@ -1,5 +1,6 @@
#pragma once
#include "fs/VFS.h"
#include "fs/devices/Device.h"
#include <luna/HashMap.h>
#include <luna/Vector.h>
#include <sys/types.h>
@ -10,6 +11,7 @@ struct SharedMemory
off_t offset;
int prot;
SharedPtr<VFS::Inode> inode {};
SharedPtr<Device> device {};
int refs { 0 };
static Result<u64> create(u8* mem, off_t offset, usize count);