AquilaOS documentation
How it works, and its code
Loading...
Searching...
No Matches
8250.c
Go to the documentation of this file.
1
11
12#include <core/system.h>
13#include <core/module.h>
14
15#include <dev/tty.h>
16#include <dev/uart.h>
17#include <dev/irq.h>
18#include <dev/platform.h>
19#include <cpu/io.h>
20#include <mm/mm.h>
21
22MALLOC_DEFINE(M_UART_8250, "uart-8250", "8250 UART");
23
24#define UART_IER 1 /* interrupt enable */
25#define UART_FCR 2 /* FIFO control */
26#define UART_LCR 3 /* line control */
27#define UART_MCR 4 /* modem control */
28#define UART_LSR 5 /* line status */
29#define UART_SCR 7 /* scratch */
30#define UART_DLL 0 /* divisor latch, low byte (when DLAB is set) */
31#define UART_DLH 1 /* divisor latch, high byte (when DLAB is set) */
32#define UART_LCR_DLAB 0x80
33
34#define UART_8250_MAX 4
35
38struct uart_8250 {
39 struct uart uart;
40 struct ioaddr io;
41};
42
43/* the registers of the UART `u` (a struct uart *) */
44#define IO(u) (&((struct uart_8250 *) (u))->io)
45
47static int serial_empty(struct ioaddr *io)
48{
49 return io_in8(io, UART_LSR) & 0x20;
50}
51
53static int serial_received(struct ioaddr *io)
54{
55 return io_in8(io, UART_LSR) & 0x01;
56}
57
59static char uart_8250_receive(struct uart *u)
60{
61 return io_in8(IO(u), 0);
62}
63
65static ssize_t uart_8250_transmit(struct uart *u, char c)
66{
67 /* wait, a bounded time, for the transmit holding register to empty */
68 for (size_t i = 0; i < 100000 && !serial_empty(IO(u)); ++i)
69 ;
70
71 io_out8(IO(u), 0, c);
72 return 1;
73}
74
77static void uart_8250_irq(void *arg)
78{
79 struct uart *u = arg;
80
81 /* take every byte the FIFO has: one interrupt may come for several
82 * bytes, and no other may come for those left (v86's 16550 doesn't
83 * raise another) */
84 while (serial_received(IO(u))) {
85 if (u->tty) /* if it is open */
87 else
89 }
90
91 if (serial_empty(IO(u))) {
92 if (u->tty) /* if it is open */
94 }
95}
96
99static void uart_8250_comm_init(struct uart *u)
100{
101 struct ioaddr *io = IO(u);
102
103 /* let the output still in the UART go first; the wait is bounded, as
104 * in uart_8250_transmit(), for a UART that never empties */
105 for (size_t i = 0; i < 100000 && !serial_empty(io); ++i)
106 ;
107
108 io_out8(io, UART_IER, 0x00); /* no interrupts meanwhile */
109
110 io_out8(io, UART_LCR, 0x03); /* 8 bits, no parity, one stop bit */
111 io_out8(io, UART_FCR, 0xC7); /* the FIFOs on and cleared, 14-byte threshold */
112 io_out8(io, UART_MCR, 0x0B); /* DTR, RTS, and OUT2 (interrupts) */
113
114 /* the speed: the divisor of 115200, written with DLAB set */
115 int lcr = io_in8(io, UART_LCR);
116 io_out8(io, UART_LCR, lcr | UART_LCR_DLAB);
117 io_out8(io, UART_DLL, 0x03); /* 115200 / 3: 38400 baud */
118 io_out8(io, UART_DLH, 0x00);
119 io_out8(io, UART_LCR, lcr & ~UART_LCR_DLAB);
120
121 io_out8(io, UART_IER, 0x01); /* the "data received" interrupt only */
122}
123
126static int uart_8250_present(struct ioaddr *io)
127{
128 io_out8(io, UART_SCR, 0x5A);
129
130 if (io_in8(io, UART_SCR) != 0x5A)
131 return 0;
132
133 io_out8(io, UART_SCR, 0xA5);
134 return io_in8(io, UART_SCR) == 0xA5;
135}
136
139static int uart_8250_attach(const struct platform_device *pd, int id)
140{
141 struct uart_8250 *u = kmalloc(sizeof(*u), &M_UART_8250, M_ZERO);
142
143 if (!u)
144 return -ENOMEM;
145
146 int err = platform_device_io(pd, &u->io);
147
148 if (!err && (!uart_8250_present(&u->io) || !pd->nirq))
149 err = -ENODEV;
150
151 if (err) {
152 kfree(u);
153 return err;
154 }
155
156 u->uart.name = "8250";
160
161 if ((err = irq_install(pd->irq[0], uart_8250_irq, u))) {
162 kfree(u);
163 return err;
164 }
165
166 printk("8250: ttyS%d at %p (%s), irq %d\n", id, (void *) pd->io.addr,
167 ioaddr_type_str(&u->io), pd->irq[0]);
168
169 uart_register(id, &u->uart);
170 return 0;
171}
172
175static int uart_8250_init(void)
176{
177 const struct platform_device *pd;
178 int id = 0;
179
180 for (int i = 0; id < UART_8250_MAX && (pd = platform_device_get("8250", i)); ++i)
181 if (!uart_8250_attach(pd, id))
182 ++id;
183
184 return 0;
185}
186
#define UART_SCR
Definition 8250.c:29
#define UART_LSR
Definition 8250.c:28
static int uart_8250_init(void)
Attaches to the platform's 8250s that are there, as /dev/ttyS0 and up, in the platform's order.
Definition 8250.c:175
static int uart_8250_present(struct ioaddr *io)
Returns whether a UART is really there: its scratch register keeps what is written to it,...
Definition 8250.c:126
static int serial_empty(struct ioaddr *io)
Returns whether the transmitter can take a character.
Definition 8250.c:47
static int serial_received(struct ioaddr *io)
Returns whether a received character is waiting.
Definition 8250.c:53
static char uart_8250_receive(struct uart *u)
Takes one received character.
Definition 8250.c:59
static ssize_t uart_8250_transmit(struct uart *u, char c)
Sends one character, once the transmitter can take it.
Definition 8250.c:65
static void uart_8250_comm_init(struct uart *u)
Sets a UART up when it is first opened: 38400 baud, 8 bits, no parity, one stop bit,...
Definition 8250.c:99
#define UART_8250_MAX
Definition 8250.c:34
static int uart_8250_attach(const struct platform_device *pd, int id)
Attaches to one of the platform's 8250s, if it is there, as /dev/ttyS<id>.
Definition 8250.c:139
static void uart_8250_irq(void *arg)
Handles a UART's interrupt: every received character goes to the terminal, or is dropped if no one ha...
Definition 8250.c:77
#define IO(u)
Definition 8250.c:44
int irq_install(unsigned irq, irq_handler_t fn, void *arg)
Installs a handler for an IRQ.
Definition irq.c:32
static uint8_t io_in8(struct ioaddr *io, uintptr_t off)
Reads an 8-, 16- or 32-bit register.
Definition io.h:28
static void io_out8(struct ioaddr *io, uintptr_t off, uint8_t val)
Writes an 8-, 16- or 32-bit register.
Definition io.h:44
#define UART_FCR
Definition uart.c:18
#define UART_LCR
Definition uart.c:19
#define UART_DLL
Definition uart.c:21
#define UART_MCR
Definition uart.c:20
#define UART_IER
Definition uart.c:17
#define UART_LCR_DLAB
Definition uart.c:23
#define UART_DLH
Definition uart.c:22
static char * ioaddr_type_str(struct ioaddr *io)
Definition io.h:101
void uart_transmit_handler(struct uart *u, size_t size)
Sends characters that the terminal output to its UART.
Definition uart.c:59
int uart_register(int id, struct uart *u)
Registers a UART, as /dev/ttyS<id>.
Definition uart.c:278
void uart_receive_handler(struct uart *u, size_t size)
Takes characters a UART received, and gives them to its terminal.
Definition uart.c:35
#define MALLOC_DEFINE(type, _name, _desc)
Definition kvmem.h:30
void * kmalloc(size_t size, struct malloc_type *type, int flags)
Allocates memory for one of the kernel's structures.
Definition kvmem.c:123
#define M_ZERO
Definition kvmem.h:26
void kfree(void *)
Frees an object that kmalloc() gave.
Definition kvmem.c:146
#define MODULE_INIT(name, i, f)
Definition module.h:10
int platform_device_io(const struct platform_device *pd, struct ioaddr *io)
Gets a device's registers, ready for io_in8() and the others.
Definition platform.c:38
const struct platform_device * platform_device_get(const char *name, int index)
Finds one of the platform's devices by its driver's name.
Definition platform.c:21
int printk(const char *fmt,...)
Writes a kernel message, to the message buffer and the consoles.
Definition printk.c:249
#define NULL
Definition stddef.h:27
Where a device's registers are.
Definition io.h:95
uintptr_t addr
Definition io.h:97
A device of the platform's table.
Definition platform.h:20
unsigned irq[PLATFORM_IRQS]
Definition platform.h:25
struct ioaddr io
Definition platform.h:22
One UART: the terminal layer's struct uart (first, so that a pointer to one is a pointer to the other...
Definition 8250.c:38
struct uart uart
Definition 8250.c:39
struct ioaddr io
Definition 8250.c:40
A serial port.
Definition uart.h:17
char * name
Definition uart.h:18
ssize_t(*) transmit(struct uart *u, char c)
Definition uart.h:32
void(*) init(struct uart *u)
Definition uart.h:31
char(*) receive(struct uart *u)
Definition uart.h:33
struct tty * tty
Definition uart.h:23
long int ssize_t
Definition types.h:12