Serenity Operating System
at hosted 117 lines 4.3 kB view raw
1/* 2 * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, this 9 * list of conditions and the following disclaimer. 10 * 11 * 2. Redistributions in binary form must reproduce the above copyright notice, 12 * this list of conditions and the following disclaimer in the documentation 13 * and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 21 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 22 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 23 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 */ 26 27#include <Kernel/Devices/MBVGADevice.h> 28#include <Kernel/Process.h> 29#include <Kernel/VM/AnonymousVMObject.h> 30#include <Kernel/VM/MemoryManager.h> 31#include <LibC/errno_numbers.h> 32#include <LibC/sys/ioctl_numbers.h> 33 34namespace Kernel { 35 36static MBVGADevice* s_the; 37 38MBVGADevice& MBVGADevice::the() 39{ 40 return *s_the; 41} 42 43MBVGADevice::MBVGADevice(PhysicalAddress addr, int pitch, int width, int height) 44 : BlockDevice(29, 0) 45 , m_framebuffer_address(addr) 46 , m_framebuffer_pitch(pitch) 47 , m_framebuffer_width(width) 48 , m_framebuffer_height(height) 49{ 50 dbg() << "MBVGADevice address=" << addr << ", pitch=" << pitch << ", width=" << width << ", height=" << height; 51 s_the = this; 52} 53 54KResultOr<Region*> MBVGADevice::mmap(Process& process, FileDescription&, VirtualAddress preferred_vaddr, size_t offset, size_t size, int prot, bool shared) 55{ 56 REQUIRE_PROMISE(video); 57 if (!shared) 58 return KResult(-ENODEV); 59 ASSERT(offset == 0); 60 ASSERT(size == framebuffer_size_in_bytes()); 61 auto vmobject = AnonymousVMObject::create_for_physical_range(m_framebuffer_address, framebuffer_size_in_bytes()); 62 if (!vmobject) 63 return KResult(-ENOMEM); 64 auto* region = process.allocate_region_with_vmobject( 65 preferred_vaddr, 66 framebuffer_size_in_bytes(), 67 vmobject.release_nonnull(), 68 0, 69 "MBVGA Framebuffer", 70 prot); 71 dbg() << "MBVGADevice: mmap with size " << region->size() << " at " << region->vaddr(); 72 ASSERT(region); 73 return region; 74} 75 76int MBVGADevice::ioctl(FileDescription&, unsigned request, unsigned arg) 77{ 78 REQUIRE_PROMISE(video); 79 switch (request) { 80 case FB_IOCTL_GET_SIZE_IN_BYTES: { 81 auto* out = (size_t*)arg; 82 if (!Process::current->validate_write_typed(out)) 83 return -EFAULT; 84 *out = framebuffer_size_in_bytes(); 85 return 0; 86 } 87 case FB_IOCTL_GET_BUFFER: { 88 auto* index = (int*)arg; 89 if (!Process::current->validate_write_typed(index)) 90 return -EFAULT; 91 *index = 0; 92 return 0; 93 } 94 case FB_IOCTL_GET_RESOLUTION: { 95 auto* resolution = (FBResolution*)arg; 96 if (!Process::current->validate_write_typed(resolution)) 97 return -EFAULT; 98 resolution->pitch = m_framebuffer_pitch; 99 resolution->width = m_framebuffer_width; 100 resolution->height = m_framebuffer_height; 101 return 0; 102 } 103 case FB_IOCTL_SET_RESOLUTION: { 104 auto* resolution = (FBResolution*)arg; 105 if (!Process::current->validate_read_typed(resolution) || !Process::current->validate_write_typed(resolution)) 106 return -EFAULT; 107 resolution->pitch = m_framebuffer_pitch; 108 resolution->width = m_framebuffer_width; 109 resolution->height = m_framebuffer_height; 110 return 0; 111 } 112 default: 113 return -EINVAL; 114 }; 115} 116 117}