X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?p=bootcensus;a=blobdiff_plain;f=src%2Fserial.c;h=164b806d1d755e63fad559d0363f1a15585413c7;hp=c7075914da3d190624dbf018246eb3b09a03e2ac;hb=81c11bdd80190ec319a82b0402173cfb65fcbf72;hpb=d1e8a437c1fab4535f82c4c214ec3330ac32e48d diff --git a/src/serial.c b/src/serial.c index c707591..164b806 100644 --- a/src/serial.c +++ b/src/serial.c @@ -1,7 +1,27 @@ +/* +pcboot - bootable PC demo/game kernel +Copyright (C) 2018 John Tsiombikas + +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 . +*/ #include #include +#include "config.h" #include "serial.h" #include "asmops.h" +#include "intr.h" +#include "panic.h" #define UART1_BASE 0x3f8 #define UART2_BASE 0x2f8 @@ -104,22 +124,20 @@ struct serial_port { #define BNEXT(x) (((x) + 1) & 0xff) #define BEMPTY(b) (b##_ridx == b##_widx) -/* static int have_recv(int base); -static void recv_intr(void);*/ +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};*/ +static int uart_irq[] = {UART1_IRQ, UART2_IRQ}; int ser_open(int pidx, int baud, unsigned int mode) { unsigned short div = 115200 / baud; - int base; /*intr*/ + int base, intr; unsigned int fmt; - /*int prev_if;*/ if(pidx < 0 || pidx > 1) { printf("ser_open: invalid serial port: %d\n", pidx); @@ -133,7 +151,7 @@ int ser_open(int pidx, int baud, unsigned int mode) memset(ports + pidx, 0, sizeof ports[pidx]); base = uart_base[pidx]; - /*intr = uart_irq[pidx] | 8;*/ + intr = uart_irq[pidx]; if(mode & SER_8N2) { fmt = COM_FMT_8N2; @@ -141,10 +159,7 @@ int ser_open(int pidx, int baud, unsigned int mode) fmt = COM_FMT_8N1; } - /*prev_if = disable_intr();*/ - /* TODO set interrupt handler */ - /* unmask the appropriate interrupt */ - /*outb(inb(PIC1_DATA_PORT) & ~(1 << uart_irq[pidx]), PIC1_DATA_PORT);*/ + interrupt(IRQ_TO_INTR(uart_irq[pidx]), recv_intr); outb(LCTL_DLAB, base + UART_LCTL); outb(div & 0xff, base + UART_DIVLO); @@ -152,12 +167,10 @@ int ser_open(int pidx, int baud, unsigned int mode) outb(fmt, base + UART_LCTL); /* fmt should be LCTL_8N1, LCTL_8N2 etc */ outb(FIFO_ENABLE | FIFO_SEND_CLEAR | FIFO_RECV_CLEAR, base + UART_FIFO); outb(MCTL_DTR | MCTL_RTS | MCTL_OUT2, base + UART_MCTL); - /*outb(INTR_RECV, base + UART_INTR); - - restore_intr(prev_if);*/ + outb(INTR_RECV, base + UART_INTR); ports[pidx].base = base; - /*ports[pidx].intr = intr;*/ + ports[pidx].intr = intr; ports[pidx].blocking = 1; ++num_open; return pidx; @@ -166,10 +179,8 @@ int ser_open(int pidx, int baud, unsigned int mode) void ser_close(int fd) { if(--num_open == 0) { - /*int prev_if = disable_intr();*/ - /*outb(0, ports[fd].base + UART_INTR);*/ + outb(0, ports[fd].base + UART_INTR); outb(0, ports[fd].base + UART_MCTL); - /*restore_intr(prev_if);*/ } ports[fd].base = 0; @@ -211,8 +222,13 @@ static int can_send(int fd) void ser_putc(int fd, char c) { int base = ports[fd].base; + + if(c == '\n') { + ser_putc(fd, '\r'); + } + while(!can_send(fd)); - while((inb(base + UART_MSTAT) & MST_CTS) == 0); + /*while((inb(base + UART_MSTAT) & MST_CTS) == 0);*/ outb(c, base + UART_DATA); } @@ -282,18 +298,16 @@ char *ser_getline(int fd, char *buf, int bsz) return 0; } -#if 0 static int have_recv(int base) { unsigned short stat = inb(base + UART_LSTAT); if(stat & LST_ERROR) { - printf("serial receive error\n"); - panic(); + panic("serial receive error\n"); } return stat & LST_DRDY; } -static void __interrupt __far recv_intr() +static void recv_intr() { int i, idreg, c; @@ -305,7 +319,14 @@ static void __interrupt __far recv_intr() while(have_recv(base)) { c = inb(base + UART_DATA); - p->inbuf[p->inbuf_widx] = inb(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) { @@ -315,7 +336,16 @@ static void __interrupt __far recv_intr() } } } +} - outb(OCW2_EOI, PIC1_CMD_PORT); +#ifdef ENABLE_GDB_STUB +void putDebugChar(int c) +{ + ser_putc(GDB_SERIAL_PORT, c); +} + +int getDebugChar(void) +{ + return ser_getc(GDB_SERIAL_PORT); } #endif