PKUOS - Pintos
Pintos source browser for PKU Operating System course
Macros | Enumerations | Functions | Variables
serial.c File Reference
#include "devices/serial.h"
#include <debug.h>
#include "devices/input.h"
#include "devices/intq.h"
#include "devices/timer.h"
#include "threads/io.h"
#include "threads/interrupt.h"
#include "threads/synch.h"
#include "threads/thread.h"
Include dependency graph for serial.c:

Go to the source code of this file.

Macros

#define IO_BASE   0x3f8
 Register definitions for the 16550A UART used in PCs. More...
 
#define RBR_REG   (IO_BASE + 0)
 DLAB=0 registers. More...
 
#define THR_REG   (IO_BASE + 0)
 Transmitter Holding Reg. More...
 
#define IER_REG   (IO_BASE + 1)
 Interrupt Enable Reg. More...
 
#define LS_REG   (IO_BASE + 0)
 DLAB=1 registers. More...
 
#define MS_REG   (IO_BASE + 1)
 Divisor Latch (MSB). More...
 
#define IIR_REG   (IO_BASE + 2)
 DLAB-insensitive registers. More...
 
#define FCR_REG   (IO_BASE + 2)
 FIFO Control Reg. More...
 
#define LCR_REG   (IO_BASE + 3)
 Line Control Register. More...
 
#define MCR_REG   (IO_BASE + 4)
 MODEM Control Register. More...
 
#define LSR_REG   (IO_BASE + 5)
 Line Status Register (read-only). More...
 
#define IER_RECV   0x01
 Interrupt Enable Register bits. More...
 
#define IER_XMIT   0x02
 Interrupt when transmit finishes. More...
 
#define LCR_N81   0x03
 Line Control Register bits. More...
 
#define LCR_DLAB   0x80
 Divisor Latch Access Bit (DLAB). More...
 
#define MCR_OUT2   0x08
 MODEM Control Register. More...
 
#define LSR_DR   0x01
 Line Status Register. More...
 
#define LSR_THRE   0x20
 THR Empty. More...
 

Enumerations

enum  { UNINIT , POLL , QUEUE }
 Transmission mode. More...
 

Functions

static void set_serial (int bps)
 Configures the serial port for BPS bits per second. More...
 
static void putc_poll (uint8_t byte)
 Polls the serial port until it's ready, and then transmits BYTE. More...
 
static void write_ier (void)
 Update interrupt enable register. More...
 
static void init_poll (void)
 Initializes the serial port device for polling mode. More...
 
void serial_init_queue (void)
 Initializes the serial port device for queued interrupt-driven I/O. More...
 
void serial_putc (uint8_t byte)
 Sends BYTE to the serial port. More...
 
void serial_flush (void)
 Flushes anything in the serial buffer out the port in polling mode. More...
 
void serial_notify (void)
 The fullness of the input buffer may have changed. More...
 
static void serial_interrupt (struct intr_frame *f UNUSED)
 Serial interrupt handler. More...
 

Variables

static enum { ... }  mode
 Transmission mode. More...
 
static struct intq txq
 Data to be transmitted. More...
 
static intr_handler_func serial_interrupt
 

Macro Definition Documentation

◆ FCR_REG

#define FCR_REG   (IO_BASE + 2)

FIFO Control Reg.

(write-only).

Definition at line 31 of file serial.c.

◆ IER_RECV

#define IER_RECV   0x01

Interrupt Enable Register bits.

Interrupt when data received.

Definition at line 37 of file serial.c.

◆ IER_REG

#define IER_REG   (IO_BASE + 1)

Interrupt Enable Reg.

Definition at line 23 of file serial.c.

◆ IER_XMIT

#define IER_XMIT   0x02

Interrupt when transmit finishes.

Definition at line 38 of file serial.c.

◆ IIR_REG

#define IIR_REG   (IO_BASE + 2)

DLAB-insensitive registers.

Interrupt Identification Reg. (read-only)

Definition at line 30 of file serial.c.

◆ IO_BASE

#define IO_BASE   0x3f8

Register definitions for the 16550A UART used in PCs.

The 16550A has a lot more going on than shown here, but this is all we need.

Refer to [PC16650D] for hardware information. I/O port base address for the first serial port.

Definition at line 18 of file serial.c.

◆ LCR_DLAB

#define LCR_DLAB   0x80

Divisor Latch Access Bit (DLAB).

Definition at line 42 of file serial.c.

◆ LCR_N81

#define LCR_N81   0x03

Line Control Register bits.

No parity, 8 data bits, 1 stop bit.

Definition at line 41 of file serial.c.

◆ LCR_REG

#define LCR_REG   (IO_BASE + 3)

Line Control Register.

Definition at line 32 of file serial.c.

◆ LS_REG

#define LS_REG   (IO_BASE + 0)

DLAB=1 registers.

Divisor Latch (LSB).

Definition at line 26 of file serial.c.

◆ LSR_DR

#define LSR_DR   0x01

Line Status Register.

Data Ready: received data byte is in RBR.

Definition at line 48 of file serial.c.

◆ LSR_REG

#define LSR_REG   (IO_BASE + 5)

Line Status Register (read-only).

Definition at line 34 of file serial.c.

◆ LSR_THRE

#define LSR_THRE   0x20

THR Empty.

Definition at line 49 of file serial.c.

◆ MCR_OUT2

#define MCR_OUT2   0x08

MODEM Control Register.

Output line 2.

Definition at line 45 of file serial.c.

◆ MCR_REG

#define MCR_REG   (IO_BASE + 4)

MODEM Control Register.

Definition at line 33 of file serial.c.

◆ MS_REG

#define MS_REG   (IO_BASE + 1)

Divisor Latch (MSB).

Definition at line 27 of file serial.c.

◆ RBR_REG

#define RBR_REG   (IO_BASE + 0)

DLAB=0 registers.

Receiver Buffer Reg. (read-only).

Definition at line 21 of file serial.c.

◆ THR_REG

#define THR_REG   (IO_BASE + 0)

Transmitter Holding Reg.

(write-only).

Definition at line 22 of file serial.c.

Enumeration Type Documentation

◆ anonymous enum

anonymous enum

Transmission mode.

Enumerator
UNINIT 
POLL 
QUEUE 

Definition at line 52 of file serial.c.

Function Documentation

◆ init_poll()

static void init_poll ( void  )
static

Initializes the serial port device for polling mode.

Polling mode busy-waits for the serial port to become free before writing to it. It's slow, but until interrupts have been initialized it's all we can do.

< Turn off all interrupts.

< Disable FIFO.

< 9.6 kbps, N-8-1.

< Required to enable interrupts.

Definition at line 67 of file serial.c.

References ASSERT, FCR_REG, IER_REG, intq_init(), MCR_OUT2, MCR_REG, mode, outb(), POLL, set_serial(), txq, and UNINIT.

Referenced by serial_init_queue(), and serial_putc().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ putc_poll()

static void putc_poll ( uint8_t  byte)
static

Polls the serial port until it's ready, and then transmits BYTE.

Definition at line 199 of file serial.c.

References ASSERT, inb(), intr_get_level(), INTR_OFF, LSR_REG, LSR_THRE, outb(), and THR_REG.

Referenced by serial_flush(), and serial_putc().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ serial_flush()

void serial_flush ( void  )

Flushes anything in the serial buffer out the port in polling mode.

Definition at line 135 of file serial.c.

References intq_empty(), intq_getc(), intr_disable(), intr_set_level(), putc_poll(), and txq.

Referenced by debug_panic(), and shutdown_power_off().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ serial_init_queue()

void serial_init_queue ( void  )

Initializes the serial port device for queued interrupt-driven I/O.

With interrupt-driven I/O we don't waste CPU time waiting for the serial device to become ready.

Definition at line 82 of file serial.c.

References ASSERT, init_poll(), intr_disable(), intr_register_ext(), intr_set_level(), mode, POLL, QUEUE, serial_interrupt, UNINIT, and write_ier().

Referenced by pintos_init().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ serial_interrupt()

static void serial_interrupt ( struct intr_frame *f  UNUSED)
static

Serial interrupt handler.

Definition at line 210 of file serial.c.

References IIR_REG, inb(), input_full(), input_putc(), intq_empty(), intq_getc(), LSR_DR, LSR_REG, LSR_THRE, outb(), RBR_REG, THR_REG, txq, and write_ier().

Here is the call graph for this function:

◆ serial_notify()

void serial_notify ( void  )

The fullness of the input buffer may have changed.

devices/serial.h

Reassess whether we should block receive interrupts. Called by the input buffer routines when characters are added to or removed from the buffer.

Definition at line 148 of file serial.c.

References ASSERT, intr_get_level(), INTR_OFF, mode, QUEUE, and write_ier().

Referenced by input_getc(), and input_putc().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ serial_putc()

void serial_putc ( uint8_t  byte)

Sends BYTE to the serial port.

Definition at line 99 of file serial.c.

References init_poll(), intq_full(), intq_getc(), intq_putc(), intr_disable(), INTR_OFF, intr_set_level(), mode, putc_poll(), QUEUE, txq, UNINIT, and write_ier().

Referenced by putchar_have_lock().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ set_serial()

static void set_serial ( int  bps)
static

Configures the serial port for BPS bits per second.

< Base rate of 16550A, in Hz.

< Clock rate divisor.

Definition at line 157 of file serial.c.

References ASSERT, LCR_DLAB, LCR_N81, LCR_REG, LS_REG, MS_REG, and outb().

Referenced by init_poll().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ write_ier()

static void write_ier ( void  )
static

Update interrupt enable register.

Definition at line 177 of file serial.c.

References ASSERT, IER_RECV, IER_REG, IER_XMIT, input_full(), intq_empty(), intr_get_level(), INTR_OFF, outb(), and txq.

Referenced by serial_init_queue(), serial_interrupt(), serial_notify(), and serial_putc().

Here is the call graph for this function:
Here is the caller graph for this function:

Variable Documentation

◆ 

enum { ... } mode

◆ serial_interrupt

intr_handler_func serial_interrupt
static

Definition at line 60 of file serial.c.

Referenced by serial_init_queue().

◆ txq

struct intq txq
static

Data to be transmitted.

Definition at line 55 of file serial.c.

Referenced by init_poll(), serial_flush(), serial_interrupt(), serial_putc(), and write_ier().