serial.c 1.6 KB
Newer Older
Z
Zihao Yu 已提交
1
#include "common.h"
2
#include "device/map.h"
Z
Zihao Yu 已提交
3 4

/* http://en.wikibooks.org/wiki/Serial_Programming/8250_UART_Programming */
5
// NOTE: this is compatible to 16550
Z
Zihao Yu 已提交
6 7

#define SERIAL_PORT 0x3F8
8
#define SERIAL_MMIO 0xa10003F8
9

Z
Zihao Yu 已提交
10
#define CH_OFFSET 0
11 12 13
#define LSR_OFFSET 5
#define LSR_TX_READY 0x20
#define LSR_RX_READY 0x01
Z
Zihao Yu 已提交
14

Z
Zihao Yu 已提交
15 16 17 18
#define QUEUE_SIZE 1024
static char queue[QUEUE_SIZE] = {};
static int f = 0, r = 0;

19
static uint8_t *serial_base = NULL;
Z
Zihao Yu 已提交
20

Z
Zihao Yu 已提交
21 22 23 24 25 26 27 28 29
static void serial_enqueue(char ch) {
  int next = (r + 1) % QUEUE_SIZE;
  if (next != f) {
    // not full
    queue[r] = ch;
    r = next;
  }
}

30 31 32 33 34 35 36 37
static char serial_dequeue() {
  char ch = 0xff;
  if (f != r) {
    ch = queue[f];
    f = (f + 1) % QUEUE_SIZE;
  }
  return ch;
}
38

Z
Zihao Yu 已提交
39 40 41 42
static inline uint8_t serial_rx_ready_flag(void) {
  return (f == r ? 0 : LSR_RX_READY);
}

43 44 45
static void serial_io_handler(uint32_t offset, int len, bool is_write) {
  assert(len == 1);
  switch (offset) {
Z
Zihao Yu 已提交
46
    /* We bind the serial port with the host stdout in NEMU. */
47 48 49 50 51
    case CH_OFFSET:
      if (is_write) putc(serial_base[0], stderr);
      else serial_base[0] = serial_dequeue();
      break;
    case LSR_OFFSET:
Z
Zihao Yu 已提交
52
      if (!is_write) serial_base[5] = LSR_TX_READY | serial_rx_ready_flag();
53
      break;
Z
Zihao Yu 已提交
54 55 56 57 58 59 60 61 62
  }
}

static void preset_input() {
  char buf[128] = "memtrace\n";
  int i;
  for (i = 0; i < strlen(buf); i ++) {
    serial_enqueue(buf[i]);
  }
Z
Zihao Yu 已提交
63 64 65
}

void init_serial() {
66 67 68
  serial_base = new_space(8);
  add_pio_map("serial", SERIAL_PORT, serial_base, 8, serial_io_handler);
  add_mmio_map("serial", SERIAL_MMIO, serial_base, 8, serial_io_handler);
Z
Zihao Yu 已提交
69 70

  preset_input();
Z
Zihao Yu 已提交
71
}