summaryrefslogtreecommitdiff
path: root/Kernel/Prekernel
diff options
context:
space:
mode:
authorMarcin Undak <mcinek@gmail.com>2021-10-20 00:29:41 -0400
committerAndreas Kling <kling@serenityos.org>2021-10-31 12:35:53 +0100
commite7141c423057af6b2d24ceac0626904392f307c7 (patch)
treed144c7277c8461234387aaa844589e50dbffd64e /Kernel/Prekernel
parentdbb61620bed5bb9db130f98fe8688d733e3cb6e1 (diff)
downloadserenity-e7141c423057af6b2d24ceac0626904392f307c7.zip
Kernel: Add very simple PPM parser for Aarch64
This is much simpler and more embeddable version than libGFX one. Solely purpose is to draw initial boot logo on screen before kernel is even booted.
Diffstat (limited to 'Kernel/Prekernel')
-rw-r--r--Kernel/Prekernel/Arch/aarch64/BootPPMParser.cpp111
-rw-r--r--Kernel/Prekernel/Arch/aarch64/BootPPMParser.h38
-rw-r--r--Kernel/Prekernel/CMakeLists.txt1
3 files changed, 150 insertions, 0 deletions
diff --git a/Kernel/Prekernel/Arch/aarch64/BootPPMParser.cpp b/Kernel/Prekernel/Arch/aarch64/BootPPMParser.cpp
new file mode 100644
index 0000000000..6061e1c427
--- /dev/null
+++ b/Kernel/Prekernel/Arch/aarch64/BootPPMParser.cpp
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2021, Marcin Undak <mcinek@gmail.com>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#include "BootPPMParser.h"
+
+namespace Prekernel {
+
+BootPPMParser::BootPPMParser(u8 const* buffer, u32 buffer_size)
+{
+ m_cursor = reinterpret_cast<char const*>(buffer);
+ m_buffer_end = m_cursor + buffer_size;
+}
+
+bool BootPPMParser::parse()
+{
+ if (!check_position()) {
+ return false;
+ }
+ if (!parse_magic()) {
+ return false;
+ }
+ if (!parse_new_line()) {
+ return false;
+ }
+ if (!parse_comment()) {
+ return false;
+ }
+ if (!parse_integer(image.width)) {
+ return false;
+ }
+ if (!parse_integer(image.height)) {
+ return false;
+ }
+ u32 max_color_value;
+ if (!parse_integer(max_color_value) || max_color_value != 255) {
+ return false;
+ }
+
+ image.pixel_data = reinterpret_cast<u8 const*>(m_cursor);
+
+ return true;
+}
+
+bool BootPPMParser::check_position() const
+{
+ if (m_cursor >= m_buffer_end) {
+ return false;
+ }
+ return true;
+}
+
+bool BootPPMParser::parse_magic()
+{
+ if (m_cursor[0] != 'P' || m_cursor[1] != '6') {
+ return false;
+ }
+ m_cursor += 2;
+
+ return check_position();
+}
+
+bool BootPPMParser::parse_new_line()
+{
+ if (*m_cursor != '\n') {
+ return false;
+ }
+ ++m_cursor;
+
+ return check_position();
+}
+
+bool BootPPMParser::parse_comment()
+{
+ if (*m_cursor == '#') {
+ // Skip to the next new line character
+ while (check_position() && *m_cursor != '\n') {
+ ++m_cursor;
+ }
+ ++m_cursor;
+ }
+
+ return check_position();
+}
+
+bool BootPPMParser::parse_integer(u32& value)
+{
+ auto begin = m_cursor;
+ while (check_position() && *m_cursor != ' ' && *m_cursor != '\n') {
+ ++m_cursor;
+ }
+ auto end = m_cursor;
+ ++m_cursor;
+
+ if (!check_position()) {
+ return false;
+ }
+
+ value = 0;
+ u32 multiplier = 1;
+ while (--end >= begin) {
+ value += multiplier * (*end - '0');
+ multiplier *= 10;
+ }
+
+ return true;
+}
+
+}
diff --git a/Kernel/Prekernel/Arch/aarch64/BootPPMParser.h b/Kernel/Prekernel/Arch/aarch64/BootPPMParser.h
new file mode 100644
index 0000000000..a311a50a7a
--- /dev/null
+++ b/Kernel/Prekernel/Arch/aarch64/BootPPMParser.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2021, Marcin Undak <mcinek@gmail.com>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#pragma once
+
+#include <AK/Types.h>
+
+namespace Prekernel {
+
+// Quick parser for .ppm image format (raw PortablePixMap)
+// This is much simpler version than userland implementation in PPMLoader.cpp
+class BootPPMParser {
+public:
+ struct {
+ u32 width = 0;
+ u32 height = 0;
+ u8 const* pixel_data = nullptr;
+ } image;
+
+ BootPPMParser(u8 const* buffer, u32 buffer_size);
+
+ bool parse();
+
+private:
+ char const* m_cursor;
+ char const* m_buffer_end;
+
+ bool check_position() const;
+ bool parse_magic();
+ bool parse_new_line();
+ bool parse_comment();
+ bool parse_integer(u32& value);
+};
+
+}
diff --git a/Kernel/Prekernel/CMakeLists.txt b/Kernel/Prekernel/CMakeLists.txt
index bdedd59c9a..9fde4dcb59 100644
--- a/Kernel/Prekernel/CMakeLists.txt
+++ b/Kernel/Prekernel/CMakeLists.txt
@@ -6,6 +6,7 @@ if ("${SERENITY_ARCH}" STREQUAL "aarch64")
set(SOURCES
${SOURCES}
Arch/aarch64/Aarch64_asm_utils.S
+ Arch/aarch64/BootPPMParser.cpp
Arch/aarch64/GPIO.cpp
Arch/aarch64/Framebuffer.cpp
Arch/aarch64/Mailbox.cpp