Serenity Operating System
at portability 115 lines 4.2 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) 55{ 56 REQUIRE_PROMISE(video); 57 ASSERT(offset == 0); 58 ASSERT(size == framebuffer_size_in_bytes()); 59 auto vmobject = AnonymousVMObject::create_for_physical_range(m_framebuffer_address, framebuffer_size_in_bytes()); 60 if (!vmobject) 61 return KResult(-ENOMEM); 62 auto* region = process.allocate_region_with_vmobject( 63 preferred_vaddr, 64 framebuffer_size_in_bytes(), 65 vmobject.release_nonnull(), 66 0, 67 "MBVGA Framebuffer", 68 prot); 69 dbg() << "MBVGADevice: mmap with size " << region->size() << " at " << region->vaddr(); 70 ASSERT(region); 71 return region; 72} 73 74int MBVGADevice::ioctl(FileDescription&, unsigned request, unsigned arg) 75{ 76 REQUIRE_PROMISE(video); 77 switch (request) { 78 case FB_IOCTL_GET_SIZE_IN_BYTES: { 79 auto* out = (size_t*)arg; 80 if (!Process::current->validate_write_typed(out)) 81 return -EFAULT; 82 *out = framebuffer_size_in_bytes(); 83 return 0; 84 } 85 case FB_IOCTL_GET_BUFFER: { 86 auto* index = (int*)arg; 87 if (!Process::current->validate_write_typed(index)) 88 return -EFAULT; 89 *index = 0; 90 return 0; 91 } 92 case FB_IOCTL_GET_RESOLUTION: { 93 auto* resolution = (FBResolution*)arg; 94 if (!Process::current->validate_write_typed(resolution)) 95 return -EFAULT; 96 resolution->pitch = m_framebuffer_pitch; 97 resolution->width = m_framebuffer_width; 98 resolution->height = m_framebuffer_height; 99 return 0; 100 } 101 case FB_IOCTL_SET_RESOLUTION: { 102 auto* resolution = (FBResolution*)arg; 103 if (!Process::current->validate_read_typed(resolution) || !Process::current->validate_write_typed(resolution)) 104 return -EFAULT; 105 resolution->pitch = m_framebuffer_pitch; 106 resolution->width = m_framebuffer_width; 107 resolution->height = m_framebuffer_height; 108 return 0; 109 } 110 default: 111 return -EINVAL; 112 }; 113} 114 115}