MBVGADevice.cpp 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. #include <Kernel/Devices/MBVGADevice.h>
  2. #include <Kernel/Process.h>
  3. #include <Kernel/VM/AnonymousVMObject.h>
  4. #include <Kernel/VM/MemoryManager.h>
  5. #include <LibC/errno_numbers.h>
  6. #include <LibC/sys/ioctl_numbers.h>
  7. static MBVGADevice* s_the;
  8. MBVGADevice& MBVGADevice::the()
  9. {
  10. return *s_the;
  11. }
  12. MBVGADevice::MBVGADevice(PhysicalAddress addr, int pitch, int width, int height)
  13. : BlockDevice(29, 0)
  14. , m_framebuffer_address(addr)
  15. , m_framebuffer_pitch(pitch)
  16. , m_framebuffer_width(width)
  17. , m_framebuffer_height(height)
  18. {
  19. dbg() << "MBVGADevice address=" << addr << ", pitch=" << pitch << ", width=" << width << ", height=" << height;
  20. s_the = this;
  21. }
  22. KResultOr<Region*> MBVGADevice::mmap(Process& process, FileDescription&, VirtualAddress preferred_vaddr, size_t offset, size_t size, int prot)
  23. {
  24. ASSERT(offset == 0);
  25. ASSERT(size == framebuffer_size_in_bytes());
  26. auto vmobject = AnonymousVMObject::create_for_physical_range(m_framebuffer_address, framebuffer_size_in_bytes());
  27. auto* region = process.allocate_region_with_vmobject(
  28. preferred_vaddr,
  29. framebuffer_size_in_bytes(),
  30. move(vmobject),
  31. 0,
  32. "MBVGA Framebuffer",
  33. prot);
  34. kprintf("MBVGA: %s(%u) created Region{%p} with size %u for framebuffer P%x with vaddr V%p\n",
  35. process.name().characters(), process.pid(),
  36. region, region->size(), m_framebuffer_address.as_ptr(), region->vaddr().get());
  37. ASSERT(region);
  38. return region;
  39. }
  40. int MBVGADevice::ioctl(FileDescription&, unsigned request, unsigned arg)
  41. {
  42. switch (request) {
  43. case FB_IOCTL_GET_SIZE_IN_BYTES: {
  44. auto* out = (size_t*)arg;
  45. if (!current->process().validate_write_typed(out))
  46. return -EFAULT;
  47. *out = framebuffer_size_in_bytes();
  48. return 0;
  49. }
  50. case FB_IOCTL_GET_BUFFER: {
  51. auto* index = (int*)arg;
  52. if (!current->process().validate_write_typed(index))
  53. return -EFAULT;
  54. *index = 0;
  55. return 0;
  56. }
  57. case FB_IOCTL_GET_RESOLUTION: {
  58. auto* resolution = (FBResolution*)arg;
  59. if (!current->process().validate_write_typed(resolution))
  60. return -EFAULT;
  61. resolution->pitch = m_framebuffer_pitch;
  62. resolution->width = m_framebuffer_width;
  63. resolution->height = m_framebuffer_height;
  64. return 0;
  65. }
  66. case FB_IOCTL_SET_RESOLUTION: {
  67. auto* resolution = (FBResolution*)arg;
  68. if (!current->process().validate_read_typed(resolution) || !current->process().validate_write_typed(resolution))
  69. return -EFAULT;
  70. resolution->pitch = m_framebuffer_pitch;
  71. resolution->width = m_framebuffer_width;
  72. resolution->height = m_framebuffer_height;
  73. return 0;
  74. }
  75. default:
  76. return -EINVAL;
  77. };
  78. }