summaryrefslogtreecommitdiff
path: root/src/kernel/klog.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/kernel/klog.c')
-rw-r--r--src/kernel/klog.c100
1 files changed, 100 insertions, 0 deletions
diff --git a/src/kernel/klog.c b/src/kernel/klog.c
new file mode 100644
index 0000000..52444b1
--- /dev/null
+++ b/src/kernel/klog.c
@@ -0,0 +1,100 @@
+#include <stdint.h>
+#include <serial.h>
+#include <io.h>
+#include <printf.h>
+#include <kernel.h>
+#include <stdbool.h>
+#include <libc.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
+
+#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;
+ }
+
+ if(loopback_byte != 0xae) {
+ //I'm sorry if these next few lines give you a stroke. They gave me one.
+
+ //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;
+}
+
+void _putchar_serial(uint16_t port, char msg) {
+ while(!(inb(port + 5) & 0x20)); //wait for transmit to be done
+ outb_wait(port, msg);
+}
+
+static unsigned int on_char = 0;
+static unsigned int on_line = 0;
+
+
+void clear_screen() {
+ char *screen_buffer = (void *)VIDEO_BUFFER;
+ for(unsigned int i = 0; i <= (80 * 25); i++) screen_buffer[i * 2] = ' ';
+ on_char = 0;
+ on_line = 0;
+}
+
+void next_line() {
+ if(on_line >= 25) {
+ on_line = 0;
+ clear_screen();
+ }
+ else {
+ on_line++;
+ }
+ on_char = 0;
+}
+
+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();
+ } else if(msg == '\n') {
+ next_line();
+ return;
+ }
+ char *screen_buffer = (void *)((uint64_t)VIDEO_BUFFER + ((on_line * 160) + (on_char * 2)));
+ *screen_buffer = msg;
+ on_char++;
+}