summaryrefslogtreecommitdiff
path: root/src/kernel/klog.c
diff options
context:
space:
mode:
authorBrett Weiland <brett_weiland@bpcspace.com>2021-08-29 02:52:48 -0500
committerBrett Weiland <brett_weiland@bpcspace.com>2021-08-29 02:52:48 -0500
commit1f71b9576db536af84155363e14fc49e92de2eef (patch)
tree23f65a31cc89785befb70517b203625e2296326f /src/kernel/klog.c
parentdc0e84d5779db68e081c667faadc19a20de861ea (diff)
backup 8.29.21
Diffstat (limited to 'src/kernel/klog.c')
-rw-r--r--src/kernel/klog.c180
1 files changed, 136 insertions, 44 deletions
diff --git a/src/kernel/klog.c b/src/kernel/klog.c
index 52444b1..c62c4d3 100644
--- a/src/kernel/klog.c
+++ b/src/kernel/klog.c
@@ -1,57 +1,104 @@
#include <stdint.h>
-#include <serial.h>
#include <io.h>
#include <printf.h>
-#include <kernel.h>
+#include <addr.h>
#include <stdbool.h>
#include <libc.h>
+#include <klog.h>
-//README
-//this file has some temporary workarounds until I get further into development
-//this isn't going to be the serial driver I end up keeping
+//right now, this program is simply for debuging.
+//Later in development, we will hook it up to a TTY, impliment FCS, etc
#define VIDEO_BUFFER PHYS_TO_VIRT(0xb8000)
#define MAX_LOOPBACK_ATTEMPTS 20
-//later we'll set it up for interrupting instead of polling
-bool init_serial(uint16_t port) {
- outb_wait(port + 1, 0x00);
- outb_wait(port + 2, 0x00);
- outb_wait(port + 3, 0x80);
- outb_wait(port + 0, 0x01); //here
- outb_wait(port + 1, 0x00);
- outb_wait(port + 3, 0x03);
- outb_wait(port + 2, 0xc7);
- outb_wait(port + 4, 0x0b);
- outb_wait(port + 4, 0x1e);
-
-
- //we shouldn't accept this as a loopback success.
- //I'm making an exception because my dell desktop has a faulty serial port
- //that requires some extra effort.
-
- uint8_t loopback_byte;
- for(int attempts = 0; attempts < MAX_LOOPBACK_ATTEMPTS; attempts++) {
- outb_wait(port + 0, 0xae); // test char
- loopback_byte = inb(port);
- if(loopback_byte == 0xae) break;
- }
+#define KLOG_COM1 0
+#define KLOG_COM2 1
+#define KLOG_COM3 2
+#define KLOG_COM4 3
+#define KLOG_SCREEN 4
+
+static int debug_output = KLOG_SCREEN;
+
+#define SERIAL_THR 0 //transmitter holding buffer
+#define SERIAL_RBR 1 //receiving holding buffer
+#define SERIAL_DLL 0 //divisor latch low byte
+#define SERIAL_DLH 1 //divisor latch high byte
+#define SERIAL_FCR 2
+#define SERIAL_IIR 2
+#define SERIAL_LCR 3
+#define SERIAL_MCR 4
+#define SERIAL_LSR 5
+#define SERIAL_MSR 6
+#define SERIAL_SR 7
+
+#define COM1 0x3f8
+#define COM2 0x2f8
+#define COM3 0x3e8
+#define COM4 0x2e8
+
+uint16_t serial_ports[4] = {COM1, COM2, COM3, COM4};
+
+/**
+enum com_ports {
+ COM1 = 0x3f8,
+ COM2 = 0x2f8,
+ COM3 = 0x3e8,
+ COM4 = 0x2e8
+};
+**/
+
+
+static bool detect_serial(uint16_t port) {
+ outb(port + SERIAL_FCR, 0xe7);
+ outb(port + SERIAL_SR, 0xba);
+ if((inb(port + SERIAL_IIR) & (1 << 6)) && (inb(port + SERIAL_SR) == 0xba)) {
+ outb_wait(port + 1, 0x00);
+ outb_wait(port + 2, 0x00);
+ outb_wait(port + 3, 0x80);
+ outb_wait(port + 0, 0x01);
+ outb_wait(port + 1, 0x00);
+ outb_wait(port + 3, 0x03);
+ outb_wait(port + 2, 0xc7);
+ outb_wait(port + 4, 0x0b);
+ outb_wait(port + 4, 0x1e);
- if(loopback_byte != 0xae) {
- //I'm sorry if these next few lines give you a stroke. They gave me one.
+
+ uint8_t loopback_byte;
+ for(int attempts = 0; attempts < MAX_LOOPBACK_ATTEMPTS; attempts++) {
+ outb_wait(port + 0, 0xae);
+ loopback_byte = inb(port);
+ if(loopback_byte == 0xae) break;
+ }
+
+ if(loopback_byte != 0xae) {
+ //you better delete this once you get tty drivers working...
+ int a = 0 / 0;
+ }
- //My old Dell test desktop has disfunctional serial hardware that only works after a reboot.
- //Seeing we don't have ACPI set up yet, we can't reboot without crashing.
- //IM GOING TO REMOVE THIS ONCE I DEVELOP THE "REAL" SERIAL DRIVER!!!!
- asm("mov rax, 0\n"
- "div rax\n");
- return false;
+ outb_wait(port + 4, 0x0f);
+ return true;
}
-
- outb_wait(port + 4, 0x0f);
- return true;
+ return false;
}
+
+//this function is going to be teleted after ttys work.
+//but, for now, if a serial port is detected, it'll set debug_output to 0-3 (com port #).
+//debug_output == 4 is for screen output.
+void init_klog() {
+ for(unsigned int p = 0; p < (sizeof(serial_ports) / sizeof(uint16_t)); p++) {
+ if(detect_serial(serial_ports[p])) {
+ debug_output = p;
+ return;
+ }
+ }
+ debug_output = KLOG_SCREEN;
+ _putchar('\n');
+}
+
+
+
void _putchar_serial(uint16_t port, char msg) {
while(!(inb(port + 5) & 0x20)); //wait for transmit to be done
outb_wait(port, msg);
@@ -80,13 +127,10 @@ void next_line() {
}
void move_cursor(unsigned int x, unsigned int y) {
- //yeah yeah yeah, it doens't test for overflows... I'm gonna delete this once i get serial working
- //on my second desktop
on_char = x;
on_line = y;
}
-//until we get serial working on hp
void _putchar_screen(char msg) {
if(on_char >= 80) {
next_line();
@@ -94,7 +138,55 @@ void _putchar_screen(char msg) {
next_line();
return;
}
- char *screen_buffer = (void *)((uint64_t)VIDEO_BUFFER + ((on_line * 160) + (on_char * 2)));
- *screen_buffer = msg;
+ *(char *)((uint64_t)VIDEO_BUFFER + ((on_line * 160) + (on_char * 2))) = msg;
on_char++;
}
+
+
+
+void _putchar(char character) {
+ if(debug_output < (sizeof(serial_ports) / sizeof(uint16_t))) {
+ _putchar_serial(serial_ports[debug_output], character);
+ }
+ else {
+ _putchar_screen(character);
+ }
+}
+
+
+
+
+/**
+ * Set the value "0xE7" to the FCR to test the status of the FIFO flags.
+Read the value of the IIR to test for what flags actually got set.
+If Bit 6 is set Then
+ If Bit 7 is set Then
+ If Bit 5 is set Then
+ UART is 16750 (64 bit fifo)
+ Else
+ UART is 16550A (idk why this matters, 16 bit fifo)
+ End If
+ Else
+ UART is 16550 (16 bit fifo)
+ End If
+Else you know the chip doesn't use FIFO, so we need to check the scratch register
+ Set some arbitrary value like 0x2A to the Scratch Register.
+ If the arbitrary value comes back identical
+ UART is 16450 (idk why this matters, 1 byte at a time)
+ Else
+ UART is 8250 (one byte at a time)
+ End If
+End If
+
+#define UART_16750 0
+#define UART_16550A 1
+#define UART_16550 2
+#define UART_16450 3
+#define UART_8250 4
+
+#define KLOG_COM1 0
+#define KLOG_COM2 1
+#define KLOG_COM3 2
+#define KLOG_COM4 3
+#define KLOG_SCREEN 4 * 5 // 5 leaves enough space for com ports
+**/