74 lines
2.1 KiB
C++
74 lines
2.1 KiB
C++
#include "fs/devices/Framebuffer.h"
|
|
#include "std/stdio.h"
|
|
#include "std/stdlib.h"
|
|
#include "std/string.h"
|
|
#include "memory/MemoryManager.h"
|
|
#include "utils/Addresses.h"
|
|
#include "misc/utils.h"
|
|
#include "std/errno.h"
|
|
#include "bootboot.h"
|
|
|
|
extern BOOTBOOT bootboot;
|
|
extern char fb[1];
|
|
|
|
#define MAP_FAIL(errno) 0xffffffffffffff00 | (unsigned char)(errno)
|
|
|
|
extern uint64_t clock_now();
|
|
|
|
VFS::Node* FramebufferDevice::create_new(const char* devname)
|
|
{
|
|
VFS::Node* dev = new VFS::Node;
|
|
dev->write_func = FramebufferDevice::write;
|
|
dev->mmap_func = FramebufferDevice::mmap;
|
|
dev->ioctl_func = FramebufferDevice::ioctl;
|
|
dev->inode = 0;
|
|
dev->length = 0;
|
|
dev->type = VFS_DEVICE;
|
|
dev->flags = 0;
|
|
dev->uid = dev->gid = 0;
|
|
dev->mode = 0222;
|
|
dev->atime = dev->ctime = dev->mtime = clock_now();
|
|
strncpy(dev->name, devname, sizeof(dev->name));
|
|
return dev;
|
|
}
|
|
|
|
uintptr_t FramebufferDevice::mmap(VFS::Node* node, uintptr_t addr, size_t size, int prot, off_t offset)
|
|
{
|
|
if (!node) return -1;
|
|
int real_prot = prot & ~(MAP_AS_OWNED_BY_TASK);
|
|
if(round_down_to_nearest_page(offset) != (uintptr_t)offset)
|
|
{
|
|
return MAP_FAIL(EINVAL);
|
|
}
|
|
if((size + offset) > bootboot.fb_size)
|
|
{
|
|
return MAP_FAIL(ERANGE); // FIXME: Should probably be EOVERFLOW.
|
|
}
|
|
MemoryManager::map_several_pages(bootboot.fb_ptr + offset, addr, Utilities::get_blocks_from_size(PAGE_SIZE, size), real_prot);
|
|
return addr;
|
|
}
|
|
|
|
ssize_t FramebufferDevice::write(VFS::Node* node, size_t offset, size_t size, const char* buffer)
|
|
{
|
|
if (!node) return -1;
|
|
if((size + offset) > (uint64_t)bootboot.fb_size)
|
|
{
|
|
size = (uint64_t)bootboot.fb_size - offset;
|
|
}
|
|
memcpy(fb + offset, buffer, size);
|
|
return (ssize_t)size;
|
|
}
|
|
|
|
#define FB_GET_WIDTH 0
|
|
#define FB_GET_HEIGHT 1
|
|
|
|
long FramebufferDevice::ioctl(VFS::Node* node, int cmd, uintptr_t)
|
|
{
|
|
if (!node) return -1;
|
|
switch(cmd)
|
|
{
|
|
case FB_GET_WIDTH: return (long)bootboot.fb_width;
|
|
case FB_GET_HEIGHT: return (long)bootboot.fb_height;
|
|
default: return -EINVAL;
|
|
}
|
|
} |