Kernel: Add Framebuffer class for Raspberry Pi
It initializes framebuffer and exposes access to its properties.
This commit is contained in:
parent
3cc5752a69
commit
dbb61620be
Notes:
sideshowbarker
2024-07-18 01:42:24 +09:00
Author: https://github.com/mundak Commit: https://github.com/SerenityOS/serenity/commit/dbb61620bed Pull-request: https://github.com/SerenityOS/serenity/pull/10482 Reviewed-by: https://github.com/ADKaster Reviewed-by: https://github.com/Hendiadyoin1 Reviewed-by: https://github.com/cqundefine Reviewed-by: https://github.com/nico
4 changed files with 167 additions and 1 deletions
114
Kernel/Prekernel/Arch/aarch64/Framebuffer.cpp
Normal file
114
Kernel/Prekernel/Arch/aarch64/Framebuffer.cpp
Normal file
|
@ -0,0 +1,114 @@
|
|||
/*
|
||||
* Copyright (c) 2021, Marcin Undak <mcinek@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <Kernel/Prekernel/Arch/aarch64/Framebuffer.h>
|
||||
#include <Kernel/Prekernel/Arch/aarch64/FramebufferMailboxMessages.h>
|
||||
#include <Kernel/Prekernel/Arch/aarch64/Utils.h>
|
||||
|
||||
namespace Prekernel {
|
||||
|
||||
Framebuffer::Framebuffer()
|
||||
{
|
||||
// FIXME: query HDMI for best mode
|
||||
// https://github.com/raspberrypi/userland/blob/master/host_applications/linux/apps/tvservice/tvservice.c
|
||||
m_width = 1280;
|
||||
m_height = 720;
|
||||
m_depth = 32;
|
||||
m_initialized = false;
|
||||
|
||||
struct __attribute__((aligned(16))) {
|
||||
Mailbox::MessageHeader header;
|
||||
FramebufferSetPhysicalSizeMboxMessage set_physical_size;
|
||||
FramebufferSetVirtualSizeMboxMessage set_virtual_size;
|
||||
FramebufferSetVirtualOffsetMboxMessage set_virtual_offset;
|
||||
FramebufferSetDepthMboxMessage set_depth;
|
||||
FramebufferSetPixelOrderMboxMessage set_pixel_order;
|
||||
FramebufferAllocateBufferMboxMessage allocate_buffer;
|
||||
FramebufferGetPithMboxMessage get_pitch;
|
||||
Mailbox::MessageTail tail;
|
||||
} message_queue;
|
||||
|
||||
message_queue.header.set_queue_size(sizeof(message_queue));
|
||||
message_queue.set_physical_size.width = m_width;
|
||||
message_queue.set_physical_size.height = m_height;
|
||||
message_queue.set_virtual_size.width = m_width;
|
||||
message_queue.set_virtual_size.height = m_height;
|
||||
|
||||
// FIXME! those next 2 lines crash...
|
||||
// message_queue.set_virtual_offset.x = 0;
|
||||
// message_queue.set_virtual_offset.y = 0;
|
||||
|
||||
message_queue.set_depth.depth_bits = 32;
|
||||
message_queue.set_pixel_order.pixel_order = FramebufferSetPixelOrderMboxMessage::PixelOrder::RGB;
|
||||
message_queue.allocate_buffer.alignment = 4096;
|
||||
|
||||
if (!Mailbox::the().send_queue(&message_queue, sizeof(message_queue))) {
|
||||
warnln("Framebuffer(): Mailbox send failed.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Now message queue contains responses. Process them.
|
||||
|
||||
if (message_queue.set_physical_size.width != m_width || message_queue.set_physical_size.height != m_height) {
|
||||
warnln("Framebuffer(): Setting physical dimension failed.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (message_queue.set_virtual_size.width != m_width || message_queue.set_virtual_size.height != m_height) {
|
||||
warnln("Framebuffer(): Setting virtual dimension failed.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (message_queue.set_virtual_offset.x != 0 || message_queue.set_virtual_offset.y != 0) {
|
||||
warnln("Framebuffer(): Setting virtual offset failed.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (message_queue.set_depth.depth_bits != m_depth) {
|
||||
warnln("Framebuffer(): Setting depth failed.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (message_queue.allocate_buffer.size == 0 || message_queue.allocate_buffer.address == 0) {
|
||||
warnln("Framebuffer(): Allocating buffer failed.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (message_queue.get_pitch.pitch == 0) {
|
||||
warnln("Framebuffer(): Retrieving pitch failed.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Convert GPU address space to RAM
|
||||
// GPU maps memory from 0x80000000 instead of 0x00000000
|
||||
m_gpu_buffer = reinterpret_cast<u8*>(message_queue.allocate_buffer.address & 0x3FFFFFFF);
|
||||
|
||||
m_buffer_size = message_queue.allocate_buffer.size;
|
||||
m_pitch = message_queue.get_pitch.pitch;
|
||||
|
||||
switch (message_queue.set_pixel_order.pixel_order) {
|
||||
case FramebufferSetPixelOrderMboxMessage::PixelOrder::RGB:
|
||||
m_pixel_order = PixelOrder::RGB;
|
||||
break;
|
||||
case FramebufferSetPixelOrderMboxMessage::PixelOrder::BGR:
|
||||
m_pixel_order = PixelOrder::BGR;
|
||||
break;
|
||||
default:
|
||||
warnln("Framebuffer(): Unsupported pixel order reported by GPU.");
|
||||
m_pixel_order = PixelOrder::RGB;
|
||||
break;
|
||||
}
|
||||
|
||||
dbgln("Initialized framebuffer: 1280 x 720 @ 32 bits");
|
||||
m_initialized = true;
|
||||
}
|
||||
|
||||
Framebuffer& Framebuffer::the()
|
||||
{
|
||||
static Framebuffer instance;
|
||||
return instance;
|
||||
}
|
||||
}
|
43
Kernel/Prekernel/Arch/aarch64/Framebuffer.h
Normal file
43
Kernel/Prekernel/Arch/aarch64/Framebuffer.h
Normal file
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* Copyright (c) 2021, Marcin Undak <mcinek@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AK/Types.h>
|
||||
|
||||
namespace Prekernel {
|
||||
|
||||
class Framebuffer {
|
||||
public:
|
||||
enum class PixelOrder {
|
||||
RGB,
|
||||
BGR,
|
||||
};
|
||||
|
||||
static Framebuffer& the();
|
||||
|
||||
bool initialized() const { return m_initialized; }
|
||||
u16 width() const { return m_width; }
|
||||
u16 height() const { return m_height; }
|
||||
u8 depth() const { return m_depth; }
|
||||
u8* gpu_buffer() const { return m_gpu_buffer; }
|
||||
u32 buffer_size() const { return m_buffer_size; }
|
||||
u32 pitch() const { return m_pitch; }
|
||||
PixelOrder pixel_order() { return m_pixel_order; }
|
||||
|
||||
private:
|
||||
u16 m_width;
|
||||
u16 m_height;
|
||||
u8 m_depth;
|
||||
u8* m_gpu_buffer;
|
||||
u32 m_buffer_size;
|
||||
u32 m_pitch;
|
||||
bool m_initialized;
|
||||
PixelOrder m_pixel_order;
|
||||
|
||||
Framebuffer();
|
||||
};
|
||||
}
|
|
@ -22,6 +22,7 @@ public:
|
|||
height = 0;
|
||||
}
|
||||
};
|
||||
static_assert(sizeof(FramebufferSetPhysicalSizeMboxMessage) == 20);
|
||||
|
||||
class FramebufferSetVirtualSizeMboxMessage : public Mailbox::Message {
|
||||
public:
|
||||
|
@ -35,6 +36,7 @@ public:
|
|||
height = 0;
|
||||
}
|
||||
};
|
||||
static_assert(sizeof(FramebufferSetVirtualSizeMboxMessage) == 20);
|
||||
|
||||
class FramebufferSetVirtualOffsetMboxMessage : public Mailbox::Message {
|
||||
public:
|
||||
|
@ -48,6 +50,7 @@ public:
|
|||
y = 0;
|
||||
}
|
||||
};
|
||||
static_assert(sizeof(FramebufferSetVirtualOffsetMboxMessage) == 20);
|
||||
|
||||
class FramebufferSetDepthMboxMessage : public Mailbox::Message {
|
||||
public:
|
||||
|
@ -59,6 +62,7 @@ public:
|
|||
depth_bits = 0;
|
||||
}
|
||||
};
|
||||
static_assert(sizeof(FramebufferSetDepthMboxMessage) == 16);
|
||||
|
||||
class FramebufferSetPixelOrderMboxMessage : public Mailbox::Message {
|
||||
public:
|
||||
|
@ -75,6 +79,7 @@ public:
|
|||
pixel_order = PixelOrder::BGR;
|
||||
}
|
||||
};
|
||||
static_assert(sizeof(FramebufferSetPixelOrderMboxMessage) == 16);
|
||||
|
||||
class FramebufferAllocateBufferMboxMessage : public Mailbox::Message {
|
||||
public:
|
||||
|
@ -91,6 +96,7 @@ public:
|
|||
size = 0;
|
||||
}
|
||||
};
|
||||
static_assert(sizeof(FramebufferAllocateBufferMboxMessage) == 20);
|
||||
|
||||
class FramebufferGetPithMboxMessage : public Mailbox::Message {
|
||||
public:
|
||||
|
@ -102,4 +108,6 @@ public:
|
|||
pitch = 0;
|
||||
}
|
||||
};
|
||||
static_assert(sizeof(FramebufferGetPithMboxMessage) == 16);
|
||||
|
||||
}
|
||||
|
|
|
@ -5,14 +5,15 @@ set(SOURCES
|
|||
if ("${SERENITY_ARCH}" STREQUAL "aarch64")
|
||||
set(SOURCES
|
||||
${SOURCES}
|
||||
Arch/aarch64/Aarch64_asm_utils.S
|
||||
Arch/aarch64/GPIO.cpp
|
||||
Arch/aarch64/Framebuffer.cpp
|
||||
Arch/aarch64/Mailbox.cpp
|
||||
Arch/aarch64/MainIdRegister.cpp
|
||||
Arch/aarch64/MMIO.cpp
|
||||
Arch/aarch64/Timer.cpp
|
||||
Arch/aarch64/UART.cpp
|
||||
Arch/aarch64/Utils.cpp
|
||||
Arch/aarch64/Aarch64_asm_utils.S
|
||||
Arch/aarch64/boot.S
|
||||
Arch/aarch64/init.cpp
|
||||
)
|
||||
|
|
Loading…
Add table
Reference in a new issue