summaryrefslogtreecommitdiffstats
path: root/device
diff options
context:
space:
mode:
Diffstat (limited to 'device')
-rw-r--r--device/processor.c4
-rw-r--r--device/serial.c77
2 files changed, 81 insertions, 0 deletions
diff --git a/device/processor.c b/device/processor.c
new file mode 100644
index 0000000..5c4b500
--- /dev/null
+++ b/device/processor.c
@@ -0,0 +1,4 @@
+#include "arch/processor.h"
+
+page_directory_t *pd_current(void) { return processor_current()->pd; }
+tcb_t *tcb_current(void) { return processor_current()->tcb; }
diff --git a/device/serial.c b/device/serial.c
new file mode 100644
index 0000000..5000e0e
--- /dev/null
+++ b/device/serial.c
@@ -0,0 +1,77 @@
+#include "device/serial.h"
+#include "device/uart.h"
+#include "jove.h"
+
+serial_dev_t COM1;
+
+serial_dev_t
+serial_new(uint16_t com)
+{
+ serial_dev_t dev = { .com = com };
+ serial_set_int(&dev, false);
+ serial_set_baud(&dev, 3);
+ serial_set_lcr(&dev, 1 | 2);
+ serial_set_fcr(&dev, 1 | 2 | 4 | 0xC0);
+ serial_set_fcr(&dev, 1 | 2 | 8);
+ serial_set_mcr(&dev, 1 | 2 | 4 | 8);
+ return dev;
+}
+
+void
+serial_set_int(serial_dev_t *dev, bool enable)
+{
+ poutb(SERIAL_UART_COM_IER(dev->com), enable);
+}
+
+void
+serial_set_baud(serial_dev_t *dev, uint16_t baud)
+{
+ /* Enable DLAB. */
+ poutb(SERIAL_UART_COM_LCR(dev->com), SERIAL_UART_COM_LCR(dev->com) | 0x80);
+ /* Write low & high bits. */
+ poutb(SERIAL_UART_COM_DLAB_DLL(dev->com), baud & 0xFF);
+ poutb(SERIAL_UART_COM_DLAB_DLH(dev->com), (baud >> 8) & 0xFF);
+ /* Disable DLAB. */
+ poutb(SERIAL_UART_COM_LCR(dev->com), SERIAL_UART_COM_LCR(dev->com) & 0x7F);
+}
+
+void
+serial_set_fcr(serial_dev_t *dev, uint16_t flg)
+{
+ poutb(SERIAL_UART_COM_FCR(dev->com), flg);
+}
+
+void
+serial_set_lcr(serial_dev_t *dev, uint16_t flg)
+{
+ poutb(SERIAL_UART_COM_LCR(dev->com), flg);
+}
+
+void
+serial_set_mcr(serial_dev_t *dev, uint16_t flg)
+{
+ poutb(SERIAL_UART_COM_MCR(dev->com), flg);
+}
+
+uint8_t
+serial_line_status(serial_dev_t *dev)
+{
+ return pinb(SERIAL_UART_COM_LSR(dev->com));
+}
+
+void
+serial_write(serial_dev_t *dev, const char *s, size_t len)
+{
+ for(; len > 0; len--) {
+ char c = *(s++);
+ while((serial_line_status(dev) & 0x20) == 0) {}
+ if(c == '\n') poutb(dev->com, '\r');
+ poutb(dev->com, c);
+ }
+}
+
+void
+serial_setup(void)
+{
+ COM1 = serial_new(SERIAL_UART_COM1);
+}