root/memdump/serial.c

Revision 3dededd20d70d571268417dc41edc95f0fe6602e, 1.6 KB (checked in by H. Peter Anvin <hpa@…>, 2 years ago)

memdump: allow outputting S-records

Allow outputting S-records, for users who only have the capability of
passively monitoring a serial port as opposed to being able to capture
the contents directly.

Signed-off-by: H. Peter Anvin <hpa@…>

  • Property mode set to 100644
Line 
1#include <stdbool.h>
2#include <stdio.h>
3
4#include "mystuff.h"
5#include "file.h"
6#include "io.h"
7
8enum {
9    THR = 0,
10    RBR = 0,
11    DLL = 0,
12    DLM = 1,
13    IER = 1,
14    IIR = 2,
15    FCR = 2,
16    LCR = 3,
17    MCR = 4,
18    LSR = 5,
19    MSR = 6,
20    SCR = 7,
21};
22
23int serial_init(struct serial_if *sif)
24{
25    uint16_t port = sif->port;
26    uint8_t dll, dlm, lcr;
27
28    /* Set 115200n81 */
29    outb(0x83, port + LCR);
30    outb(0x01, port + DLL);
31    outb(0x00, port + DLM);
32    (void)inb(port + IER);      /* Synchronize */
33    dll = inb(port + DLL);
34    dlm = inb(port + DLM);
35    lcr = inb(port + LCR);
36    outb(0x03, port + LCR);
37    (void)inb(port + IER);      /* Synchronize */
38
39    if (dll != 0x01 || dlm != 0x00 || lcr != 0x83)
40        return -1;              /* This doesn't look like a serial port */
41
42    /* Disable interrupts */
43    outb(port + IER, 0);
44
45    /* Enable 16550A FIFOs if available */
46    outb(port + FCR, 0x01);     /* Enable FIFO */
47    (void)inb(port + IER);      /* Synchronize */
48    if (inb(port + IIR) < 0xc0)
49        outb(port + FCR, 0x00); /* Disable FIFOs if non-functional */
50    (void)inb(port + IER);      /* Synchronize */
51
52    return 0;
53}
54
55void serial_write(struct serial_if *sif, const void *data, size_t n)
56{
57    uint16_t port = sif->port;
58    const char *p = data;
59    uint8_t lsr;
60
61    while (n--) {
62        do {
63            lsr = inb(port + LSR);
64        } while (!(lsr & 0x20));
65
66        outb(*p++, port + THR);
67    }
68}
69
70void serial_read(struct serial_if *sif, void *data, size_t n)
71{
72    uint16_t port = sif->port;
73    char *p = data;
74    uint8_t lsr;
75
76    while (n--) {
77        do {
78            lsr = inb(port + LSR);
79        } while (!(lsr & 0x01));
80
81        *p++ = inb(port + RBR);
82    }
83}
Note: See TracBrowser for help on using the browser.