mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 09:47:35 +00:00
Kernel: Implement generic framebuffer ioctls in BXVGA
This also hides some functions that were previously public, since that same functionality is now exposed via ioctl functions.
This commit is contained in:
parent
5e46122a82
commit
3932dfbb04
2 changed files with 47 additions and 27 deletions
|
@ -5,6 +5,7 @@
|
||||||
#include <Kernel/VM/AnonymousVMObject.h>
|
#include <Kernel/VM/AnonymousVMObject.h>
|
||||||
#include <Kernel/VM/MemoryManager.h>
|
#include <Kernel/VM/MemoryManager.h>
|
||||||
#include <LibC/errno_numbers.h>
|
#include <LibC/errno_numbers.h>
|
||||||
|
#include <LibC/sys/ioctl_numbers.h>
|
||||||
|
|
||||||
#define VBE_DISPI_IOPORT_INDEX 0x01CE
|
#define VBE_DISPI_IOPORT_INDEX 0x01CE
|
||||||
#define VBE_DISPI_IOPORT_DATA 0x01CF
|
#define VBE_DISPI_IOPORT_DATA 0x01CF
|
||||||
|
@ -23,13 +24,6 @@
|
||||||
#define VBE_DISPI_ENABLED 0x01
|
#define VBE_DISPI_ENABLED 0x01
|
||||||
#define VBE_DISPI_LFB_ENABLED 0x40
|
#define VBE_DISPI_LFB_ENABLED 0x40
|
||||||
|
|
||||||
#define BXVGA_DEV_IOCTL_SET_Y_OFFSET 1982
|
|
||||||
#define BXVGA_DEV_IOCTL_SET_RESOLUTION 1985
|
|
||||||
struct BXVGAResolution {
|
|
||||||
int width;
|
|
||||||
int height;
|
|
||||||
};
|
|
||||||
|
|
||||||
static BXVGADevice* s_the;
|
static BXVGADevice* s_the;
|
||||||
|
|
||||||
BXVGADevice& BXVGADevice::the()
|
BXVGADevice& BXVGADevice::the()
|
||||||
|
@ -52,6 +46,7 @@ void BXVGADevice::set_register(u16 index, u16 data)
|
||||||
|
|
||||||
void BXVGADevice::set_resolution(int width, int height)
|
void BXVGADevice::set_resolution(int width, int height)
|
||||||
{
|
{
|
||||||
|
m_framebuffer_pitch = width * sizeof(u32);
|
||||||
m_framebuffer_width = width;
|
m_framebuffer_width = width;
|
||||||
m_framebuffer_height = height;
|
m_framebuffer_height = height;
|
||||||
|
|
||||||
|
@ -65,10 +60,11 @@ void BXVGADevice::set_resolution(int width, int height)
|
||||||
set_register(VBE_DISPI_INDEX_BANK, 0);
|
set_register(VBE_DISPI_INDEX_BANK, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BXVGADevice::set_y_offset(int offset)
|
void BXVGADevice::set_y_offset(int y_offset)
|
||||||
{
|
{
|
||||||
ASSERT(offset <= m_framebuffer_height);
|
ASSERT(y_offset == 0 || y_offset == m_framebuffer_height);
|
||||||
set_register(VBE_DISPI_INDEX_Y_OFFSET, (u16)offset);
|
m_y_offset = y_offset;
|
||||||
|
set_register(VBE_DISPI_INDEX_Y_OFFSET, (u16)y_offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 BXVGADevice::find_framebuffer_address()
|
u32 BXVGADevice::find_framebuffer_address()
|
||||||
|
@ -90,7 +86,7 @@ KResultOr<Region*> BXVGADevice::mmap(Process& process, FileDescription&, Virtual
|
||||||
{
|
{
|
||||||
ASSERT(offset == 0);
|
ASSERT(offset == 0);
|
||||||
ASSERT(size == framebuffer_size_in_bytes());
|
ASSERT(size == framebuffer_size_in_bytes());
|
||||||
auto vmo = AnonymousVMObject::create_for_physical_range(framebuffer_address(), framebuffer_size_in_bytes());
|
auto vmo = AnonymousVMObject::create_for_physical_range(m_framebuffer_address, framebuffer_size_in_bytes());
|
||||||
auto* region = process.allocate_region_with_vmo(
|
auto* region = process.allocate_region_with_vmo(
|
||||||
preferred_vaddr,
|
preferred_vaddr,
|
||||||
framebuffer_size_in_bytes(),
|
framebuffer_size_in_bytes(),
|
||||||
|
@ -100,7 +96,7 @@ KResultOr<Region*> BXVGADevice::mmap(Process& process, FileDescription&, Virtual
|
||||||
prot);
|
prot);
|
||||||
kprintf("BXVGA: %s(%u) created Region{%p} with size %u for framebuffer P%x with vaddr L%x\n",
|
kprintf("BXVGA: %s(%u) created Region{%p} with size %u for framebuffer P%x with vaddr L%x\n",
|
||||||
process.name().characters(), process.pid(),
|
process.name().characters(), process.pid(),
|
||||||
region, region->size(), framebuffer_address().as_ptr(), region->vaddr().get());
|
region, region->size(), m_framebuffer_address.as_ptr(), region->vaddr().get());
|
||||||
ASSERT(region);
|
ASSERT(region);
|
||||||
return region;
|
return region;
|
||||||
}
|
}
|
||||||
|
@ -108,16 +104,43 @@ KResultOr<Region*> BXVGADevice::mmap(Process& process, FileDescription&, Virtual
|
||||||
int BXVGADevice::ioctl(FileDescription&, unsigned request, unsigned arg)
|
int BXVGADevice::ioctl(FileDescription&, unsigned request, unsigned arg)
|
||||||
{
|
{
|
||||||
switch (request) {
|
switch (request) {
|
||||||
case BXVGA_DEV_IOCTL_SET_Y_OFFSET:
|
case FB_IOCTL_GET_SIZE_IN_BYTES: {
|
||||||
if (arg > (unsigned)m_framebuffer_height * 2)
|
auto* out = (size_t*)arg;
|
||||||
return -EINVAL;
|
if (!current->process().validate_write_typed(out))
|
||||||
set_y_offset((int)arg);
|
return -EFAULT;
|
||||||
|
*out = framebuffer_size_in_bytes();
|
||||||
return 0;
|
return 0;
|
||||||
case BXVGA_DEV_IOCTL_SET_RESOLUTION: {
|
}
|
||||||
auto* resolution = (const BXVGAResolution*)arg;
|
case FB_IOCTL_GET_BUFFER: {
|
||||||
if (!current->process().validate_read_typed(resolution))
|
auto* index = (int*)arg;
|
||||||
|
if (!current->process().validate_write_typed(index))
|
||||||
|
return -EFAULT;
|
||||||
|
*index = m_y_offset == 0 ? 0 : 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
case FB_IOCTL_SET_BUFFER: {
|
||||||
|
if (arg != 0 && arg != 1)
|
||||||
|
return -EINVAL;
|
||||||
|
set_y_offset(arg == 0 ? 0 : m_framebuffer_height);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
case FB_IOCTL_GET_RESOLUTION: {
|
||||||
|
auto* resolution = (FBResolution*)arg;
|
||||||
|
if (!current->process().validate_write_typed(resolution))
|
||||||
|
return -EFAULT;
|
||||||
|
resolution->pitch = m_framebuffer_pitch;
|
||||||
|
resolution->width = m_framebuffer_width;
|
||||||
|
resolution->height = m_framebuffer_height;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
case FB_IOCTL_SET_RESOLUTION: {
|
||||||
|
auto* resolution = (FBResolution*)arg;
|
||||||
|
if (!current->process().validate_read_typed(resolution) || !current->process().validate_write_typed(resolution))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
set_resolution(resolution->width, resolution->height);
|
set_resolution(resolution->width, resolution->height);
|
||||||
|
resolution->pitch = m_framebuffer_pitch;
|
||||||
|
resolution->width = m_framebuffer_width;
|
||||||
|
resolution->height = m_framebuffer_height;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -12,17 +12,9 @@ public:
|
||||||
|
|
||||||
BXVGADevice();
|
BXVGADevice();
|
||||||
|
|
||||||
PhysicalAddress framebuffer_address() const { return m_framebuffer_address; }
|
|
||||||
void set_resolution(int width, int height);
|
|
||||||
void set_y_offset(int);
|
|
||||||
|
|
||||||
virtual int ioctl(FileDescription&, unsigned request, unsigned arg) override;
|
virtual int ioctl(FileDescription&, unsigned request, unsigned arg) override;
|
||||||
virtual KResultOr<Region*> mmap(Process&, FileDescription&, VirtualAddress preferred_vaddr, size_t offset, size_t, int prot) override;
|
virtual KResultOr<Region*> mmap(Process&, FileDescription&, VirtualAddress preferred_vaddr, size_t offset, size_t, int prot) override;
|
||||||
|
|
||||||
size_t framebuffer_size_in_bytes() const { return m_framebuffer_width * m_framebuffer_height * sizeof(u32) * 2; }
|
|
||||||
int framebuffer_width() const { return m_framebuffer_width; }
|
|
||||||
int framebuffer_height() const { return m_framebuffer_height; }
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
virtual const char* class_name() const override { return "BXVGA"; }
|
virtual const char* class_name() const override { return "BXVGA"; }
|
||||||
virtual bool can_read(FileDescription&) const override;
|
virtual bool can_read(FileDescription&) const override;
|
||||||
|
@ -32,8 +24,13 @@ private:
|
||||||
|
|
||||||
void set_register(u16 index, u16 value);
|
void set_register(u16 index, u16 value);
|
||||||
u32 find_framebuffer_address();
|
u32 find_framebuffer_address();
|
||||||
|
size_t framebuffer_size_in_bytes() const { return m_framebuffer_pitch * m_framebuffer_height * 2; }
|
||||||
|
void set_resolution(int width, int height);
|
||||||
|
void set_y_offset(int);
|
||||||
|
|
||||||
PhysicalAddress m_framebuffer_address;
|
PhysicalAddress m_framebuffer_address;
|
||||||
|
int m_framebuffer_pitch { 0 };
|
||||||
int m_framebuffer_width { 0 };
|
int m_framebuffer_width { 0 };
|
||||||
int m_framebuffer_height { 0 };
|
int m_framebuffer_height { 0 };
|
||||||
|
int m_y_offset { 0 };
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue