1/*
2 * Copyright 2019 Haiku, Inc. All Rights Reserved.
3 * Distributed under the terms of the MIT License.
4 */
5#include <arch/debug_console.h>
6#include <arch/generic/debug_uart.h>
7#include <arch/generic/debug_uart_8250.h>
8// #include <arch/arm/arch_uart_8250_omap.h>
9#include <arch/arm/arch_uart_pl011.h>
10#include <arch/arm64/arch_uart_linflex.h>
11#include <boot/kernel_args.h>
12#include <kernel.h>
13#include <vm/vm.h>
14#include <string.h>
15
16
17static DebugUART *sArchDebugUART = NULL;
18
19
20void
21arch_debug_remove_interrupt_handler(uint32 line)
22{
23}
24
25
26void
27arch_debug_install_interrupt_handlers(void)
28{
29}
30
31
32int
33arch_debug_blue_screen_try_getchar(void)
34{
35	// TODO: Implement correctly!
36	return arch_debug_blue_screen_getchar();
37}
38
39
40char
41arch_debug_blue_screen_getchar(void)
42{
43	return arch_debug_serial_getchar();
44}
45
46
47int
48arch_debug_serial_try_getchar(void)
49{
50	// TODO: Implement correctly!
51	return arch_debug_serial_getchar();
52}
53
54
55char
56arch_debug_serial_getchar(void)
57{
58	if (sArchDebugUART == NULL)
59		return '\0';
60
61	return sArchDebugUART->GetChar(false);
62}
63
64
65void
66arch_debug_serial_putchar(const char c)
67{
68	if (sArchDebugUART == NULL)
69		return;
70
71	sArchDebugUART->PutChar(c);
72}
73
74
75void
76arch_debug_serial_puts(const char *s)
77{
78	while (*s != '\0') {
79		char ch = *s;
80		if (ch == '\n') {
81			arch_debug_serial_putchar('\r');
82			arch_debug_serial_putchar('\n');
83		} else if (ch != '\r')
84			arch_debug_serial_putchar(ch);
85		s++;
86	}
87}
88
89
90void
91arch_debug_serial_early_boot_message(const char *string)
92{
93	// this function will only be called in fatal situations
94	arch_debug_serial_puts(string);
95}
96
97
98status_t
99arch_debug_console_init(kernel_args *args)
100{
101	if (strncmp(args->arch_args.uart.kind, UART_KIND_PL011,
102		sizeof(args->arch_args.uart.kind)) == 0) {
103		sArchDebugUART = arch_get_uart_pl011(args->arch_args.uart.regs.start,
104			args->arch_args.uart.clock);
105	} else if (strncmp(args->arch_args.uart.kind, UART_KIND_LINFLEX,
106		sizeof(args->arch_args.uart.kind)) == 0) {
107		sArchDebugUART = arch_get_uart_linflex(args->arch_args.uart.regs.start,
108			args->arch_args.uart.clock);
109	}/* else if (strncmp(args->arch_args.uart.kind, UART_KIND_8250_OMAP,
110		sizeof(args->arch_args.uart.kind)) == 0) {
111		sArchDebugUART = arch_get_uart_8250_omap(args->arch_args.uart.regs.start,
112			args->arch_args.uart.clock);
113	}*/ else if (strncmp(args->arch_args.uart.kind, UART_KIND_8250,
114		sizeof(args->arch_args.uart.kind)) == 0) {
115		sArchDebugUART = arch_get_uart_8250(args->arch_args.uart.regs.start,
116			args->arch_args.uart.clock);
117	}
118
119	// Oh well.
120	if (sArchDebugUART == NULL)
121		return B_ERROR;
122
123	sArchDebugUART->InitEarly();
124
125	return B_OK;
126}
127
128
129status_t
130arch_debug_console_init_settings(kernel_args *args)
131{
132	return B_OK;
133}
134