sparc: add kernel debug output
Mostly the same as PowerPC, using OpenFirmware. Change-Id: I197cc181e92da92c272ee9cfa20c8ad2d2c63d41 Reviewed-on: https://review.haiku-os.org/c/haiku/+/3579 Reviewed-by: waddlesplash <waddlesplash@gmail.com>
This commit is contained in:
parent
7c2dc33027
commit
b992c828cf
@ -10,7 +10,7 @@
|
|||||||
struct real_time_data;
|
struct real_time_data;
|
||||||
|
|
||||||
enum sparc_platform_type {
|
enum sparc_platform_type {
|
||||||
PPC_PLATFORM_OPEN_FIRMWARE = 0,
|
SPARC_PLATFORM_OPEN_FIRMWARE = 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace BPrivate {
|
namespace BPrivate {
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <arch_platform.h>
|
||||||
#include <arch/debug_console.h>
|
#include <arch/debug_console.h>
|
||||||
#include <boot/kernel_args.h>
|
#include <boot/kernel_args.h>
|
||||||
#include <kernel.h>
|
#include <kernel.h>
|
||||||
@ -30,7 +31,8 @@ arch_debug_install_interrupt_handlers(void)
|
|||||||
int
|
int
|
||||||
arch_debug_blue_screen_try_getchar(void)
|
arch_debug_blue_screen_try_getchar(void)
|
||||||
{
|
{
|
||||||
return 0;
|
// TODO: Implement correctly!
|
||||||
|
return arch_debug_blue_screen_getchar();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -52,13 +54,14 @@ arch_debug_serial_try_getchar(void)
|
|||||||
char
|
char
|
||||||
arch_debug_serial_getchar(void)
|
arch_debug_serial_getchar(void)
|
||||||
{
|
{
|
||||||
return 0;
|
return SparcPlatform::Default()->SerialDebugGetChar();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
arch_debug_serial_putchar(const char c)
|
arch_debug_serial_putchar(const char c)
|
||||||
{
|
{
|
||||||
|
return SparcPlatform::Default()->SerialDebugPutChar(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -82,7 +85,7 @@ arch_debug_serial_early_boot_message(const char *string)
|
|||||||
status_t
|
status_t
|
||||||
arch_debug_console_init(kernel_args *args)
|
arch_debug_console_init(kernel_args *args)
|
||||||
{
|
{
|
||||||
return B_OK;
|
return SparcPlatform::Default()->InitSerialDebug(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -92,4 +95,3 @@ arch_debug_console_init_settings(kernel_args *args)
|
|||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,22 +1,253 @@
|
|||||||
/* Copyright 2019, Adrien Destugues, pulkomandy@pulkomandy.tk.
|
/*
|
||||||
* Distributed under the terms of the MIT License.
|
* Copyright 2006, Ingo Weinhold <bonefish@cs.tu-berlin.de>.
|
||||||
|
* Copyright 2019-2020, Adrien Destugues, pulkomandy@pulkomandy.tk.
|
||||||
|
* 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((uint32_t)fOutput, "\r\n", 2);
|
||||||
|
else
|
||||||
|
of_write((uint32_t)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((uint32_t)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((uint32_t)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
|
status_t
|
||||||
arch_platform_init(struct kernel_args *kernelArgs)
|
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
|
status_t
|
||||||
arch_platform_init_post_vm(struct kernel_args *kernelArgs)
|
arch_platform_init_post_vm(struct kernel_args *kernelArgs)
|
||||||
{
|
{
|
||||||
return B_OK;
|
return sSparcPlatform->InitPostVM(kernelArgs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user