reorganize source
[com32] / src / serial.c
diff --git a/src/serial.c b/src/serial.c
deleted file mode 100644 (file)
index 6954508..0000000
+++ /dev/null
@@ -1,361 +0,0 @@
-/*
-pcboot - bootable PC demo/game kernel
-Copyright (C) 2018  John Tsiombikas <nuclear@member.fsf.org>
-
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY, without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program.  If not, see <https://www.gnu.org/licenses/>.
-*/
-#include <stdio.h>
-#include <string.h>
-#include <assert.h>
-#include "config.h"
-#include "serial.h"
-#include "asmops.h"
-#include "intr.h"
-#include "panic.h"
-
-#define UART1_BASE     0x3f8
-#define UART2_BASE     0x2f8
-#define UART1_IRQ      4
-#define UART2_IRQ      3
-
-#define UART_DATA      0
-#define UART_INTR      1
-#define UART_DIVLO     0
-#define UART_DIVHI     1
-#define UART_FIFO      2
-#define UART_IID       2
-#define UART_LCTL      3
-#define UART_MCTL      4
-#define UART_LSTAT     5
-#define UART_MSTAT     6
-
-/* interrupt enable register bits */
-#define INTR_RECV      1
-#define INTR_SEND      2
-#define INTR_LSTAT     4
-#define INTR_DELTA     8
-
-/* fifo control register bits */
-#define FIFO_ENABLE            0x01
-#define FIFO_RECV_CLEAR        0x02
-#define FIFO_SEND_CLEAR        0x04
-#define FIFO_DMA               0x08
-#define FIFO_TRIG_4            0x40
-#define FIFO_TRIG_8            0x80
-#define FIFO_TRIG_14   0xc0
-
-/* interrupt id register bits */
-#define IID_PENDING            0x01
-#define IID_ID0                        0x02
-#define IID_ID1                        0x04
-#define IID_ID2                        0x08
-#define IID_FIFO_EN            0xc0
-
-#define IID_SOURCE             0xe
-
-#define IID_DELTA              0
-#define IID_SEND               0x2
-#define IID_RECV               0x4
-#define IID_FIFO               0xc
-#define IID_STATUS             0x6
-
-/* line control register bits */
-#define LCTL_BITS_8    0x03
-#define LCTL_STOP_2    0x04
-#define LCTL_DLAB      0x80
-#define LCTL_8N1       LCTL_BITS_8
-#define LCTL_8N2       (LCTL_BITS_8 | LCTL_STOP_2)
-
-/* modem control register bits */
-#define MCTL_DTR       0x01
-#define MCTL_RTS       0x02
-#define MCTL_OUT1      0x04
-#define MCTL_OUT2      0x08
-#define MCTL_LOOP      0x10
-
-/* line status register bits */
-#define LST_DRDY               0x01
-#define LST_ERR_OVER   0x02
-#define LST_ERR_PARITY 0x04
-#define LST_ERR_FRAME  0x08
-#define LST_ERR_BRK            0x10
-#define LST_TREG_EMPTY 0x20
-#define LST_TIDLE              0x40
-#define LST_ERROR              0x80
-
-/* modem status register bits */
-#define MST_DELTA_CTS  0x01
-#define MST_DELTA_DSR  0x02
-#define MST_TERI               0x04
-#define MST_DELTA_DCD  0x08
-#define MST_CTS                        0x10
-#define MST_DSR                        0x20
-#define MST_RING               0x40
-#define MST_DCD                        0x80
-
-/* interrupt controller stuff */
-#define PIC1_CMD_PORT  0x20
-#define PIC1_DATA_PORT 0x21
-#define PIC2_CMD_PORT  0xa0
-#define PIC2_DATA_PORT 0xa1
-#define OCW2_EOI               0x20
-
-#define COM_FMT_8N1            LCTL_8N1
-#define COM_FMT_8N2            LCTL_8N2
-
-#define INBUF_SIZE     16
-#define BNEXT(x)       (((x) + 1) & (INBUF_SIZE - 1))
-#define BEMPTY(b)      (b##_ridx == b##_widx)
-
-struct serial_port {
-       int base, intr;
-       int blocking;
-       int ref;
-
-       char inbuf[INBUF_SIZE];
-       int inbuf_ridx, inbuf_widx;
-};
-
-
-static int have_recv(int base);
-static void recv_intr();
-
-static struct serial_port ports[2];
-static int num_open;
-
-static int uart_base[] = {UART1_BASE, UART2_BASE};
-static int uart_irq[] = {UART1_IRQ, UART2_IRQ};
-
-int ser_open(int pidx, int baud, unsigned int mode)
-{
-       unsigned short div = 115200 / baud;
-       int i, fd, base, intr;
-       unsigned int fmt;
-
-       if(pidx < 0 || pidx > 1) {
-               printf("ser_open: invalid serial port: %d\n", pidx);
-               return -1;
-       }
-
-       for(i=0; i<num_open; i++) {
-               if(ports[i].base == uart_base[pidx]) {
-                       /* the port is already open, return the same fd and increment ref */
-                       ports[i].ref++;
-                       return i;
-               }
-       }
-
-       fd = num_open++;
-       memset(ports + fd, 0, sizeof ports[pidx]);
-
-       base = uart_base[pidx];
-       intr = uart_irq[pidx];
-
-       if(mode & SER_8N2) {
-               fmt = COM_FMT_8N2;
-       } else {
-               fmt = COM_FMT_8N1;
-       }
-
-       interrupt(IRQ_TO_INTR(uart_irq[pidx]), recv_intr);
-
-       outp(base + UART_LCTL, LCTL_DLAB);
-       outp(base + UART_DIVLO, div & 0xff);
-       outp(base + UART_DIVHI, (div >> 8) & 0xff);
-       outp(base + UART_LCTL, fmt);    /* fmt should be LCTL_8N1, LCTL_8N2 etc */
-       outp(base + UART_FIFO, FIFO_ENABLE | FIFO_SEND_CLEAR | FIFO_RECV_CLEAR);
-       outp(base + UART_MCTL, MCTL_DTR | MCTL_RTS | MCTL_OUT2);
-       outp(base + UART_INTR, INTR_RECV);
-
-       ports[fd].base = base;
-       ports[fd].intr = intr;
-       ports[fd].blocking = 1;
-       ports[fd].ref = 1;
-       return fd;
-}
-
-void ser_close(int fd)
-{
-       if(!ports[fd].ref) return;
-
-       if(--ports[fd].ref == 0) {
-               outp(ports[fd].base + UART_INTR, 0);
-               outp(ports[fd].base + UART_MCTL, 0);
-               ports[fd].base = 0;
-       }
-}
-
-int ser_block(int fd)
-{
-       ports[fd].blocking = 1;
-       return 0;
-}
-
-int ser_nonblock(int fd)
-{
-       ports[fd].blocking = 0;
-       return 0;
-}
-
-int ser_pending(int fd)
-{
-       return !BEMPTY(ports[fd].inbuf);
-}
-
-/* if msec < 0: wait for ever */
-int ser_wait(int fd, long msec)
-{
-       int res;
-       while(!(res = ser_pending(fd))) {
-               /* TODO timeout */
-       }
-       return res;
-}
-
-static int can_send(int fd)
-{
-       int base = ports[fd].base;
-       return inp(base + UART_LSTAT) & LST_TREG_EMPTY;
-}
-
-void ser_putc(int fd, char c)
-{
-       int base = ports[fd].base;
-
-       if(c == '\n') {
-               ser_putc(fd, '\r');
-       }
-
-       while(!can_send(fd));
-       /*while((inp(base + UART_MSTAT) & MST_CTS) == 0);*/
-       outp(base + UART_DATA, c);
-}
-
-int ser_getc(int fd)
-{
-       struct serial_port *p = ports + fd;
-       int have, c = -1;
-
-       if(p->blocking) {
-               while(!(have = ser_pending(fd)));
-       } else {
-               have = ser_pending(fd);
-       }
-
-       if(have) {
-               c = p->inbuf[p->inbuf_ridx];
-               p->inbuf_ridx = BNEXT(p->inbuf_ridx);
-       }
-       return c;
-}
-
-int ser_write(int fd, const char *buf, int count)
-{
-       int n = count;
-       while(n--) {
-               ser_putc(fd, *buf++);
-       }
-       return count;
-}
-
-int ser_read(int fd, char *buf, int count)
-{
-       int c, n = 0;
-       while(n < count && (c = ser_getc(fd)) != -1) {
-               *buf++ = c;
-               ++n;
-       }
-       return n;
-}
-
-char *ser_getline(int fd, char *buf, int bsz)
-{
-       static int widx;
-       char linebuf[512];
-       int i, rd, size, offs;
-
-       size = sizeof linebuf - widx;
-       while(size && (rd = ser_read(fd, linebuf + widx, size)) > 0) {
-               widx += rd;
-               size -= rd;
-       }
-
-       linebuf[widx] = 0;
-
-       for(i=0; i<widx; i++) {
-               if(linebuf[i] == '\r' || linebuf[i] == '\n') {
-                       size = i >= bsz ? bsz - 1 : i;
-                       memcpy(buf, linebuf, size);
-                       buf[size] = 0;
-
-                       offs = i + 1;
-                       memmove(linebuf, linebuf + offs, widx - offs);
-                       widx -= offs;
-                       return buf;
-               }
-       }
-       return 0;
-}
-
-static int have_recv(int base)
-{
-       unsigned short stat = inp(base + UART_LSTAT);
-       if(stat & LST_ERROR) {
-               panic("serial receive error\n");
-       }
-       return stat & LST_DRDY;
-}
-
-static void recv_intr()
-{
-       int i, idreg, c;
-
-       for(i=0; i<2; i++) {
-               int base = uart_base[i];
-               struct serial_port *p = ports + i;
-
-               while(((idreg = inp(base + UART_IID)) & IID_PENDING) == 0) {
-                       while(have_recv(base)) {
-                               c = inp(base + UART_DATA);
-
-#ifdef ENABLE_GDB_STUB
-                               if(c == 3 && i == GDB_SERIAL_PORT) {
-                                       asm("int $3");
-                                       continue;
-                               }
-#endif
-
-                               p->inbuf[p->inbuf_widx] = c;
-                               p->inbuf_widx = BNEXT(p->inbuf_widx);
-
-                               if(p->inbuf_widx == p->inbuf_ridx) {
-                                       /* we overflowed, drop the oldest */
-                                       p->inbuf_ridx = BNEXT(p->inbuf_ridx);
-                               }
-                       }
-               }
-       }
-}
-
-#ifdef ENABLE_GDB_STUB
-void putDebugChar(int c)
-{
-       ser_putc(GDB_SERIAL_PORT, c);
-}
-
-int getDebugChar(void)
-{
-       return ser_getc(GDB_SERIAL_PORT);
-}
-#endif