[haiku-commits] Change in haiku[master]: sparc: add kernel debug output

  • From: Gerrit <review@xxxxxxxxxxxxxxxxxxx>
  • To: waddlesplash <waddlesplash@xxxxxxxxx>, haiku-commits@xxxxxxxxxxxxx
  • Date: Thu, 31 Dec 2020 23:47:37 +0000

From Adrien Destugues <pulkomandy@xxxxxxxxx>:

Adrien Destugues has uploaded this change for review. ( 
https://review.haiku-os.org/c/haiku/+/3579 ;)


Change subject: sparc: add kernel debug output
......................................................................

sparc: add kernel debug output

Mostly the same as PowerPC, using OpenFirmware.
---
M headers/private/kernel/arch/sparc/arch_platform.h
M src/system/kernel/arch/sparc/arch_debug_console.cpp
M src/system/kernel/arch/sparc/arch_platform.cpp
3 files changed, 243 insertions(+), 10 deletions(-)



  git pull ssh://git.haiku-os.org:22/haiku refs/changes/79/3579/1

diff --git a/headers/private/kernel/arch/sparc/arch_platform.h 
b/headers/private/kernel/arch/sparc/arch_platform.h
index 24e774e..edee385 100644
--- a/headers/private/kernel/arch/sparc/arch_platform.h
+++ b/headers/private/kernel/arch/sparc/arch_platform.h
@@ -10,7 +10,7 @@
 struct real_time_data;

 enum sparc_platform_type {
-       PPC_PLATFORM_OPEN_FIRMWARE = 0,
+       SPARC_PLATFORM_OPEN_FIRMWARE = 0,
 };

 namespace BPrivate {
diff --git a/src/system/kernel/arch/sparc/arch_debug_console.cpp 
b/src/system/kernel/arch/sparc/arch_debug_console.cpp
index 32eaa29..1b5f336 100644
--- a/src/system/kernel/arch/sparc/arch_debug_console.cpp
+++ b/src/system/kernel/arch/sparc/arch_debug_console.cpp
@@ -7,6 +7,7 @@
  */


+#include <arch_platform.h>
 #include <arch/debug_console.h>
 #include <boot/kernel_args.h>
 #include <kernel.h>
@@ -30,7 +31,8 @@
 int
 arch_debug_blue_screen_try_getchar(void)
 {
-       return 0;
+       // TODO: Implement correctly!
+       return arch_debug_blue_screen_getchar();
 }


@@ -52,13 +54,14 @@
 char
 arch_debug_serial_getchar(void)
 {
-       return 0;
+       return SparcPlatform::Default()->SerialDebugGetChar();
 }


 void
 arch_debug_serial_putchar(const char c)
 {
+       return SparcPlatform::Default()->SerialDebugPutChar(c);
 }


@@ -82,7 +85,7 @@
 status_t
 arch_debug_console_init(kernel_args *args)
 {
-       return B_OK;
+       return SparcPlatform::Default()->InitSerialDebug(args);
 }


@@ -92,4 +95,3 @@
        return B_OK;
 }

-
diff --git a/src/system/kernel/arch/sparc/arch_platform.cpp 
b/src/system/kernel/arch/sparc/arch_platform.cpp
index 30a2394..c638d8c 100644
--- a/src/system/kernel/arch/sparc/arch_platform.cpp
+++ b/src/system/kernel/arch/sparc/arch_platform.cpp
@@ -1,22 +1,253 @@
-/* Copyright 2019, Adrien Destugues, pulkomandy@xxxxxxxxxxxxx.
- * Distributed under the terms of the MIT License.
+/*
+ * Copyright 2006, Ingo Weinhold <bonefish@xxxxxxxxxxxxxxx>.
+ * Copyright 2019-2020, Adrien Destugues, pulkomandy@xxxxxxxxxxxxx.
+ * All rights reserved. Distributed under the terms of the MIT License.
  */

+#include <arch_platform.h>

-#include <arch/platform.h>
+#include <new>

+#include <KernelExport.h>
+
+#include <arch/generic/debug_uart.h>
+#include <boot/kernel_args.h>
+#include <platform/openfirmware/openfirmware.h>
+#include <real_time_clock.h>
+#include <util/kernel_cpp.h>
+
+
+static SparcPlatform *sSparcPlatform;
+
+
+// constructor
+SparcPlatform::SparcPlatform(sparc_platform_type platformType)
+       : fPlatformType(platformType)
+{
+}
+
+// destructor
+SparcPlatform::~SparcPlatform()
+{
+}
+
+// Default
+SparcPlatform *
+SparcPlatform::Default()
+{
+       return sSparcPlatform;
+}
+
+
+// #pragma mark - Open Firmware
+
+
+namespace BPrivate {
+
+class SparcOpenFirmware : public SparcPlatform {
+public:
+       SparcOpenFirmware();
+       virtual ~SparcOpenFirmware();
+
+       virtual status_t Init(struct kernel_args *kernelArgs);
+       virtual status_t InitSerialDebug(struct kernel_args *kernelArgs);
+       virtual status_t InitPostVM(struct kernel_args *kernelArgs);
+       virtual status_t InitRTC(struct kernel_args *kernelArgs,
+               struct real_time_data *data);
+
+       virtual char SerialDebugGetChar();
+       virtual void SerialDebugPutChar(char c);
+
+       virtual void SetHardwareRTC(uint32 seconds);
+       virtual uint32 GetHardwareRTC();
+
+       virtual void ShutDown(bool reboot);
+
+private:
+       int     fInput;
+       int     fOutput;
+       int     fRTC;
+};
+
+}      // namespace BPrivate
+
+using BPrivate::SparcOpenFirmware;
+
+
+// OF debugger commands
+
+// debug_command_of_exit
+static int
+debug_command_of_exit(int argc, char **argv)
+{
+       of_exit();
+       kprintf("of_exit() failed!\n");
+       return 0;
+}
+
+// debug_command_of_enter
+static int
+debug_command_of_enter(int argc, char **argv)
+{
+       of_call_client_function("enter", 0, 0);
+       return 0;
+}
+
+
+// constructor
+SparcOpenFirmware::SparcOpenFirmware()
+       : SparcPlatform(SPARC_PLATFORM_OPEN_FIRMWARE),
+         fInput(-1),
+         fOutput(-1),
+         fRTC(-1)
+{
+}
+
+// destructor
+SparcOpenFirmware::~SparcOpenFirmware()
+{
+}
+
+// Init
+status_t
+SparcOpenFirmware::Init(struct kernel_args *kernelArgs)
+{
+       return of_init(
+               
(intptr_t(*)(void*))kernelArgs->platform_args.openfirmware_entry);
+}
+
+// InitSerialDebug
+status_t
+SparcOpenFirmware::InitSerialDebug(struct kernel_args *kernelArgs)
+{
+       if (of_getprop(gChosen, "stdin", &fInput, sizeof(int)) == OF_FAILED)
+               return B_ERROR;
+       if (!kernelArgs->frame_buffer.enabled) {
+               if (of_getprop(gChosen, "stdout", &fOutput, sizeof(int)) == 
OF_FAILED)
+                       return B_ERROR;
+       }
+
+       return B_OK;
+}
+
+// InitPostVM
+status_t
+SparcOpenFirmware::InitPostVM(struct kernel_args *kernelArgs)
+{
+       add_debugger_command("of_exit", &debug_command_of_exit,
+               "Exit to the Open Firmware prompt. No way to get back into the 
OS!");
+       add_debugger_command("of_enter", &debug_command_of_enter,
+               "Enter a subordinate Open Firmware interpreter. Quitting it 
returns "
+               "to KDL.");
+
+       return B_OK;
+}
+
+// InitRTC
+status_t
+SparcOpenFirmware::InitRTC(struct kernel_args *kernelArgs,
+       struct real_time_data *data)
+{
+       // open RTC
+       fRTC = of_open(kernelArgs->platform_args.rtc_path);
+       if (fRTC == OF_FAILED) {
+               dprintf("SparcOpenFirmware::InitRTC(): Failed open RTC 
device!\n");
+               return B_ERROR;
+       }
+
+       return B_OK;
+}
+
+// DebugSerialGetChar
+char
+SparcOpenFirmware::SerialDebugGetChar()
+{
+       int key;
+       if (of_interpret("key", 0, 1, &key) == OF_FAILED)
+               return 0;
+       return (char)key;
+}
+
+// DebugSerialPutChar
+void
+SparcOpenFirmware::SerialDebugPutChar(char c)
+{
+       if (fOutput == -1)
+               return;
+
+       if (c == '\n')
+               of_write(fOutput, "\r\n", 2);
+       else
+               of_write(fOutput, &c, 1);
+}
+
+// SetHardwareRTC
+void
+SparcOpenFirmware::SetHardwareRTC(uint32 seconds)
+{
+       struct tm t;
+       rtc_secs_to_tm(seconds, &t);
+
+       t.tm_year += RTC_EPOCH_BASE_YEAR;
+       t.tm_mon++;
+
+       if (of_call_method(fRTC, "set-time", 6, 0, t.tm_year, t.tm_mon, 
t.tm_mday,
+                       t.tm_hour, t.tm_min, t.tm_sec) == OF_FAILED) {
+               dprintf("SparcOpenFirmware::SetHardwareRTC(): Failed to set 
RTC!\n");
+       }
+}
+
+// GetHardwareRTC
+uint32
+SparcOpenFirmware::GetHardwareRTC()
+{
+       struct tm t;
+       if (of_call_method(fRTC, "get-time", 0, 6, &t.tm_year, &t.tm_mon,
+                       &t.tm_mday, &t.tm_hour, &t.tm_min, &t.tm_sec) == 
OF_FAILED) {
+               dprintf("SparcOpenFirmware::GetHardwareRTC(): Failed to get 
RTC!\n");
+               return 0;
+       }
+
+       t.tm_year -= RTC_EPOCH_BASE_YEAR;
+       t.tm_mon--;
+
+       return rtc_tm_to_secs(&t);
+}
+
+// ShutDown
+void
+SparcOpenFirmware::ShutDown(bool reboot)
+{
+       if (reboot) {
+               of_interpret("reset-all", 0, 0);
+       } else {
+               // not standardized, so it might fail
+               of_interpret("shut-down", 0, 0);
+       }
+}
+
+
+// # pragma mark -
+
+
+#define PLATFORM_BUFFER_SIZE sizeof(SparcOpenFirmware)
+// static buffer for constructing the actual SparcPlatform
+static char *sSparcPlatformBuffer[PLATFORM_BUFFER_SIZE];

 status_t
 arch_platform_init(struct kernel_args *kernelArgs)
 {
-       return B_OK;
+       // only OpenFirmware supported for now
+       sSparcPlatform = new(sSparcPlatformBuffer) SparcOpenFirmware;
+
+       return sSparcPlatform->Init(kernelArgs);
 }


 status_t
 arch_platform_init_post_vm(struct kernel_args *kernelArgs)
 {
-       return B_OK;
+       return sSparcPlatform->InitPostVM(kernelArgs);
 }



--
To view, visit https://review.haiku-os.org/c/haiku/+/3579
To unsubscribe, or for help writing mail filters, visit 
https://review.haiku-os.org/settings

Gerrit-Project: haiku
Gerrit-Branch: master
Gerrit-Change-Id: I197cc181e92da92c272ee9cfa20c8ad2d2c63d41
Gerrit-Change-Number: 3579
Gerrit-PatchSet: 1
Gerrit-Owner: Adrien Destugues <pulkomandy@xxxxxxxxx>
Gerrit-MessageType: newchange

Other related posts:

  • » [haiku-commits] Change in haiku[master]: sparc: add kernel debug output - Gerrit