Serenity Operating System
at master 91 lines 2.8 kB view raw
1/* 2 * Copyright (c) 2022, the SerenityOS developers. 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7#include <Kernel/Graphics/Console/BootFramebufferConsole.h> 8#include <Kernel/Locking/Spinlock.h> 9#include <Kernel/Memory/MemoryManager.h> 10 11namespace Kernel::Graphics { 12 13BootFramebufferConsole::BootFramebufferConsole(PhysicalAddress framebuffer_addr, size_t width, size_t height, size_t pitch) 14 : GenericFramebufferConsoleImpl(width, height, pitch) 15{ 16 // NOTE: We're very early in the boot process, memory allocations shouldn't really fail 17 auto framebuffer_end = Memory::page_round_up(framebuffer_addr.offset(height * pitch * sizeof(u32)).get()).release_value(); 18 m_framebuffer = MM.allocate_kernel_region(framebuffer_addr.page_base(), framebuffer_end - framebuffer_addr.page_base().get(), "Boot Framebuffer"sv, Memory::Region::Access::ReadWrite).release_value(); 19 20 [[maybe_unused]] auto result = m_framebuffer->set_write_combine(true); 21 m_framebuffer_data = m_framebuffer->vaddr().offset(framebuffer_addr.offset_in_page()).as_ptr(); 22 memset(m_framebuffer_data, 0, height * pitch * sizeof(u32)); 23} 24 25void BootFramebufferConsole::clear(size_t x, size_t y, size_t length) 26{ 27 SpinlockLocker lock(m_lock); 28 if (m_framebuffer_data) 29 GenericFramebufferConsoleImpl::clear(x, y, length); 30} 31 32void BootFramebufferConsole::clear_glyph(size_t x, size_t y) 33{ 34 35 VERIFY(m_lock.is_locked()); 36 GenericFramebufferConsoleImpl::clear_glyph(x, y); 37} 38 39void BootFramebufferConsole::enable() 40{ 41 // Once disabled, ignore requests to re-enable 42} 43 44void BootFramebufferConsole::disable() 45{ 46 SpinlockLocker lock(m_lock); 47 GenericFramebufferConsoleImpl::disable(); 48 m_framebuffer = nullptr; 49 m_framebuffer_data = nullptr; 50} 51 52void BootFramebufferConsole::write(size_t x, size_t y, char ch, Color background, Color foreground, bool critical) 53{ 54 SpinlockLocker lock(m_lock); 55 if (m_framebuffer_data) 56 GenericFramebufferConsoleImpl::write(x, y, ch, background, foreground, critical); 57} 58 59void BootFramebufferConsole::set_cursor(size_t x, size_t y) 60{ 61 // Note: To ensure we don't trigger a deadlock, let's assert in 62 // case we already locked the spinlock, so we know there's a bug 63 // in the call path. 64 VERIFY(!m_lock.is_locked()); 65 SpinlockLocker lock(m_lock); 66 hide_cursor(); 67 m_x = x; 68 m_y = y; 69 show_cursor(); 70} 71 72void BootFramebufferConsole::hide_cursor() 73{ 74 VERIFY(m_lock.is_locked()); 75 GenericFramebufferConsoleImpl::hide_cursor(); 76} 77 78void BootFramebufferConsole::show_cursor() 79{ 80 VERIFY(m_lock.is_locked()); 81 GenericFramebufferConsoleImpl::show_cursor(); 82} 83 84u8* BootFramebufferConsole::framebuffer_data() 85{ 86 VERIFY(m_lock.is_locked()); 87 VERIFY(m_framebuffer_data); 88 return m_framebuffer_data; 89} 90 91}