Skip to content
Snippets Groups Projects
uart.c 1.26 KiB
Newer Older
rsc's avatar
rsc committed
// Intel 8250 serial port (UART).

#include "types.h"
#include "defs.h"
#include "param.h"
#include "traps.h"
#include "spinlock.h"
#include "fs.h"
#include "file.h"
rsc's avatar
rsc committed
#include "mmu.h"
#include "proc.h"
#include "x86.h"

rsc's avatar
rsc committed
#define COM1    0x3f8
rsc's avatar
rsc committed

rsc's avatar
rsc committed
static int uart;    // is there a uart?
rsc's avatar
rsc committed

void
uartinit(void)
{
rsc's avatar
rsc committed
  char *p;
rsc's avatar
rsc committed

rsc's avatar
rsc committed
  // Turn off the FIFO
  outb(COM1+2, 0);
  
  // 9600 baud, 8 data bits, 1 stop bit, parity off.
  outb(COM1+3, 0x80);    // Unlock divisor
  outb(COM1+0, 115200/9600);
  outb(COM1+1, 0);
  outb(COM1+3, 0x03);    // Lock divisor, 8 data bits.
  outb(COM1+4, 0);
  outb(COM1+1, 0x01);    // Enable receive interrupts.
rsc's avatar
rsc committed

rsc's avatar
rsc committed
  // If status is 0xFF, no serial port.
  if(inb(COM1+5) == 0xFF)
    return;
  uart = 1;
rsc's avatar
rsc committed

rsc's avatar
rsc committed
  // Acknowledge pre-existing interrupt conditions;
  // enable interrupts.
  inb(COM1+2);
  inb(COM1+0);
  picenable(IRQ_COM1);
  ioapicenable(IRQ_COM1, 0);
  
  // Announce that we're here.
  for(p="xv6...\n"; *p; p++)
    uartputc(*p);
rsc's avatar
rsc committed
}

void
uartputc(int c)
{
rsc's avatar
rsc committed
  int i;
rsc's avatar
rsc committed

rsc's avatar
rsc committed
  if(!uart)
    return;
  for(i = 0; i < 128 && !(inb(COM1+5) & 0x20); i++)
    microdelay(10);
  outb(COM1+0, c);
rsc's avatar
rsc committed
}

static int
uartgetc(void)
{
rsc's avatar
rsc committed
  if(!uart)
    return -1;
  if(!(inb(COM1+5) & 0x01))
    return -1;
  return inb(COM1+0);
rsc's avatar
rsc committed
}

void
uartintr(void)
{
rsc's avatar
rsc committed
  consoleintr(uartgetc);
rsc's avatar
rsc committed
}