77 lines
1.7 KiB
C
77 lines
1.7 KiB
C
#include <sys/acpi.h>
|
|
#include <arch/amd64/hal/ioapic.h>
|
|
|
|
#include <io.h>
|
|
#include <kprint.h>
|
|
|
|
#define COM1 0x3F8
|
|
|
|
#define LINE_CTRL_REG 0x3
|
|
#define LINE_STAT_REG 0x5
|
|
#define INT_ENABLE_REG 0x1
|
|
#define MDM_CTRL_REG 0x4
|
|
|
|
#define DIVISOR 0x12 // We want a baud rate of 9600, so the divisor here is 12
|
|
|
|
bool serial_enabled = false;
|
|
|
|
void serial_init(){
|
|
|
|
/* Disable interrupts */
|
|
outb(COM1 + INT_ENABLE_REG, 0);
|
|
|
|
/* Set the DLAB bit */
|
|
outb(COM1 + LINE_CTRL_REG, (1 << 7));
|
|
|
|
/* Send least significant byte of divisor */
|
|
outb(COM1 + 1, 0);
|
|
|
|
/* Send most significant byte of divisor */
|
|
outb(COM1, 12);
|
|
|
|
/* Clear the DLAB bit */
|
|
outb(COM1 + LINE_CTRL_REG, (0 << 7));
|
|
|
|
/* Set the character length to 8 bits, parity to none and stop bit to 1 */
|
|
outb(COM1 + LINE_CTRL_REG, 0b00000011);
|
|
|
|
/* Set DTR, RTS and enables IRQ */
|
|
outb(COM1 + MDM_CTRL_REG, 0b00001101);
|
|
|
|
/* Set loopback testing mode to see if UART werks */
|
|
outb(COM1 + MDM_CTRL_REG, 0b00011110);
|
|
|
|
outb(COM1, 0xAE);
|
|
|
|
if(inb(COM1) != 0xAE){
|
|
klog(__func__, "Serial controller failed test, serial output will not work");
|
|
return;
|
|
}
|
|
|
|
/* Disable loopback and set DTR bit */
|
|
outb(COM1 + MDM_CTRL_REG, 0b00001111);
|
|
|
|
serial_enabled = true;
|
|
|
|
}
|
|
|
|
uint8_t serial_read(){
|
|
while((inb(COM1 + LINE_STAT_REG) & 0x1) == 0){ asm("nop"); }
|
|
|
|
return inb(COM1);
|
|
}
|
|
|
|
void serial_write(uint8_t data){
|
|
while((inb(COM1 + LINE_STAT_REG) & (1 << 5)) == 0){ asm("nop"); }
|
|
|
|
outb(COM1, data);
|
|
}
|
|
|
|
void serial_print(char *str){
|
|
uint64_t i = 0;
|
|
while (str[i] != '\0') {
|
|
serial_write(str[i]);
|
|
i++;
|
|
}
|
|
}
|
|
|