summaryrefslogtreecommitdiff
path: root/kernel/serial.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/serial.c')
-rw-r--r--kernel/serial.c52
1 files changed, 52 insertions, 0 deletions
diff --git a/kernel/serial.c b/kernel/serial.c
new file mode 100644
index 0000000..7f23298
--- /dev/null
+++ b/kernel/serial.c
@@ -0,0 +1,52 @@
+#include <asm/io.h>
+#include <kernel/con.h>
+
+/* 115200 baud */
+#define DIVISOR 1
+
+#define RSBASE 0x3F8
+
+#define RSDATA RSBASE
+#define RSINTEN (RSBASE + 1)
+#define RSFIFOC (RSBASE + 2)
+#define RSLINEC (RSBASE + 3)
+#define RSMODEMC (RSBASE + 4)
+#define RSLINES (RSBASE + 5)
+#define RSMODEMS (RSBASE + 6)
+#define RSSCRATCH (RSBASE + 7)
+
+static int rsputs(char *s) {
+ while(*s) {
+ while((inb(RSLINES) & 0x20) == 0);
+ outb(RSDATA, *s++);
+ }
+
+ return 0;
+}
+
+void serial_init(void) {
+ outb(RSSCRATCH, 0x00);
+ outb(RSSCRATCH, 0xAA);
+ if(inb(RSSCRATCH) != 0xAA) {
+ printk("[rs] COM0 not detected!\n");
+ return;
+ }
+
+ /* enable access to the divisor */
+ outb(RSLINEC, inb(RSLINEC) | 0x80);
+ /* write the divisor */
+ outb(RSBASE, DIVISOR);
+ outb(RSBASE + 1, DIVISOR >> 8);
+ /* restore access to the divisor */
+ outb(RSLINEC, inb(RSLINEC) & 0x7F);
+ /* configure port parameters */
+ outb(RSLINEC, 0x03);
+ outb(RSINTEN, 0x00);
+
+ rsputs("[kernel] Serial monitor initialized!\n\r");
+ printk("[rs] Serial port COM0 initialized!\n");
+}
+
+int sys_rsputs(char *s) {
+ return rsputs(s);
+}