From 6d87016287ea76afbdf7e16fb2cf9e4fa20cc0de Mon Sep 17 00:00:00 2001 From: Jake Mannens Date: Sat, 1 Sep 2018 02:27:36 +1000 Subject: Removed the sys_puts system call in favour of calls to tty_write(). Removed the rsputs() function in favour of calls to tty_write(). Corrected a bug in the serial driver and TTY subsystem where a full buffer wouldn't be detected. This was caused by a missing set of brackets on several operations involving the modulus operator. Added the ability for the serial driver to automatically take data from the TTY device's write buffer and push it to the serial port. This can happen in one of two ways; 1) the TTY subsystem notifies the serial driver of new data by calling the write() function pointer in the tty_struct or, 2) the serial port issues an interrupt signalling that it has finished sending data prompting the driver to check the buffers for any more pending data. --- include/kernel/serial.h | 2 -- include/kernel/sys.h | 28 +++++++++++------------ include/unistd.h | 23 +++++++++---------- kernel/sched.c | 2 +- kernel/serial.c | 60 ++++++++++++++++++++++++++----------------------- kernel/sys.c | 20 ----------------- kernel/tty.c | 18 +++++++++++---- usrbin/main.c | 17 ++++++++++++++ 8 files changed, 89 insertions(+), 81 deletions(-) diff --git a/include/kernel/serial.h b/include/kernel/serial.h index 6ac5d65..beb0891 100644 --- a/include/kernel/serial.h +++ b/include/kernel/serial.h @@ -6,8 +6,6 @@ extern struct tty_struct tty_rs; -int rsputs(char*); - ssize_t rsread(void*, size_t); void serial_init(void); diff --git a/include/kernel/sys.h b/include/kernel/sys.h index e5275cf..1b8be8e 100644 --- a/include/kernel/sys.h +++ b/include/kernel/sys.h @@ -1,6 +1,6 @@ typedef int (*syscall_t) (void); -extern int sys_puts(void); +extern int sys_time(void); extern int sys_time(void); extern int sys_getpid(void); extern int sys_getpdir(void); @@ -11,22 +11,22 @@ extern int sys_ctty(void); extern int sys_read(void); extern int sys_write(void); extern int sys_kill(void); -extern int sys_dummy(void); extern int sys_panic(void); +extern int sys_dummy(void); syscall_t call_table[256] = { - [0] = &sys_puts, - [1] = &sys_time, - [2] = &sys_getpid, - [3] = &sys_getpdir, - [4] = &sys_signal, - [5] = &sys_alarm, - [6] = &sys_pause, - [7] = &sys_ctty, - [8] = &sys_read, - [9] = &sys_write, - [10] = &sys_kill, - [11] = &sys_panic, + [0] = &sys_time, + [1] = &sys_getpid, + [2] = &sys_getpdir, + [3] = &sys_signal, + [4] = &sys_alarm, + [5] = &sys_pause, + [6] = &sys_ctty, + [7] = &sys_read, + [8] = &sys_write, + [9] = &sys_kill, + [10] = &sys_panic, + [11] = &sys_dummy, [12] = &sys_dummy, [13] = &sys_dummy, [14] = &sys_dummy, diff --git a/include/unistd.h b/include/unistd.h index a7e4f32..cc0f766 100644 --- a/include/unistd.h +++ b/include/unistd.h @@ -10,18 +10,17 @@ typedef int32_t ssize_t; typedef int16_t pid_t; -#define __SYS_puts 0 -#define __SYS_time 1 -#define __SYS_getpid 2 -#define __SYS_getpdir 3 -#define __SYS_signal 4 -#define __SYS_alarm 5 -#define __SYS_pause 6 -#define __SYS_ctty 7 -#define __SYS_read 8 -#define __SYS_write 9 -#define __SYS_kill 10 -#define __SYS_panic 11 +#define __SYS_time 0 +#define __SYS_getpid 1 +#define __SYS_getpdir 2 +#define __SYS_signal 3 +#define __SYS_alarm 4 +#define __SYS_pause 5 +#define __SYS_ctty 6 +#define __SYS_read 7 +#define __SYS_write 8 +#define __SYS_kill 9 +#define __SYS_panic 10 #define _syscall0(type, name) \ type name(void) { \ diff --git a/kernel/sched.c b/kernel/sched.c index da55fa3..a17b58c 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -209,7 +209,7 @@ void sched_init(void) { ctask = NULL; create_proc(&_usrbin_start, (size_t) &_usrbin_size); - create_proc(&_usrbin_start, (size_t) &_usrbin_size); + /* create_proc(&_usrbin_start, (size_t) &_usrbin_size); */ switch_to(0, &tasks[0]); } diff --git a/kernel/serial.c b/kernel/serial.c index a133865..e712e53 100644 --- a/kernel/serial.c +++ b/kernel/serial.c @@ -11,6 +11,9 @@ /* 115200 baud */ #define DIVISOR 1 +/* this shouldn't change */ +#define FIFOSZ 16 + #define RSBASE 0x3F8 #define RSDATA RSBASE @@ -23,9 +26,6 @@ #define RSMODEMS (RSBASE + 6) #define RSSCRATCH (RSBASE + 7) -#define rswait()\ - while((inb(RSLINES) & 0x20) == 0); - extern void rs_isr(void); /* internal function prototypes */ @@ -38,25 +38,6 @@ struct tty_struct tty_rs = { static char present; -int rsputs(char *s) { - if(!present) - return -ENXIO; - - while(*s) { - rswait(); - if(*s == '\n' || *s == '\r') { - outb(RSDATA, '\n'); - rswait(); - outb(RSDATA, '\r'); - s++; - } else { - outb(RSDATA, *s++); - } - } - - return 0; -} - void serial_init(void) { present = 0; @@ -91,7 +72,6 @@ void serial_init(void) { register_isr(0x24, 0, &rs_isr); irq_enable(0x10); - rsputs("[kernel] Serial monitor initialized!\n\r"); printk("[rs] Serial port COM0 initialized!\n"); present = 1; @@ -102,22 +82,46 @@ void rsint_rx(void) { if((inb(RSLINES) & 1) == 0) return; - if(q->pwrite == (q->pread - 1 % sizeof(q->buf))) + if(q->pwrite == ((q->pread - 1) % sizeof(q->buf))) return; q->buf[q->pwrite] = inb(RSDATA); - q->pwrite = q->pwrite + 1 % sizeof(q->buf); + q->pwrite = (q->pwrite + 1) % sizeof(q->buf); wake_up(&q->waiting); } +/* + * void rsint_tx(void) { + * int copied = 0; + * struct tty_queue *q = &tty_rs.wqueue; + * + * while(q->pread != q->pwrite) { + * [> we're done if the TX FIFO is full <] + * if((inb(RSLINES) & 0x20) == 0) + * break; + * + * outb(RSDATA, q->buf[q->pread]); + * q->pread = (q->pread + 1) % TTY_BUF_SIZE; + * + * copied = 1; + * } + * + * if(copied) + * wake_up(&q->waiting); + * } + */ + void rsint_tx(void) { + int i; int copied = 0; struct tty_queue *q = &tty_rs.wqueue; - while(q->pread != q->pwrite) { - /* we're done if the TX FIFO is full */ - if((inb(RSLINES) & 0x20) == 0) + if((inb(RSLINES) & 0x20) == 0) + return; + + for(i = 0; i < FIFOSZ; i++) { + if(q->pread == q->pwrite) break; outb(RSDATA, q->buf[q->pread]); diff --git a/kernel/sys.c b/kernel/sys.c index 8e28edd..b750072 100644 --- a/kernel/sys.c +++ b/kernel/sys.c @@ -11,26 +11,6 @@ #include #include -int sys_puts(char *s) { - char buf[8]; - - if(ctask->ctty < 0) - return EOF; - - sprintf(buf, "[%04x] ", ctask->pid); - - switch(ctask->ctty) { - case 1: - /* rsputs(buf); */ - return rsputs(s); - break; - default: - printk("%s", buf); - return printk(s); - break; - } -} - time_t sys_time(void) { return ticks / 100; } diff --git a/kernel/tty.c b/kernel/tty.c index 75c3701..bfbf775 100644 --- a/kernel/tty.c +++ b/kernel/tty.c @@ -35,14 +35,24 @@ static int sleep_while_empty(struct tty_queue *q) { } /* check if a buffer's full and if so, go to sleep */ -static int sleep_while_full(struct tty_queue *q) { +static int sleep_while_full(struct tty_queue *q, struct tty_struct *tty) { cli(); while(1) { - if(q->pwrite == (q->pread - 1 % sizeof(q->buf))) + /* + * if the buffer is full, first notify the + * driver so it can try to remove some + * data then, check again and if it's + * still full, go to sleep. + */ + if(q->pwrite == ((q->pread - 1) % sizeof(q->buf))) + if(tty->write) + tty->write(); + + if(q->pwrite == ((q->pread - 1) % sizeof(q->buf))) interruptible_sleep_on(&q->waiting); /* check again to see if anything was removed, or we were interrupted */ - if(q->pwrite == (q->pread - 1 % sizeof(q->buf))) { + if(q->pwrite == ((q->pread - 1) % sizeof(q->buf))) { sti(); return -1; } @@ -98,7 +108,7 @@ ssize_t tty_write(unsigned tty, void *buf, size_t len) { for(i = 0; i < len; i++) { /* check if the buffer's full and if so, go to sleep */ - if(sleep_while_full(q) < 0) { + if(sleep_while_full(q, ttys[tty]) < 0) { if(i == 0) return -EINTR; diff --git a/usrbin/main.c b/usrbin/main.c index 3b6dd97..70c0ab3 100644 --- a/usrbin/main.c +++ b/usrbin/main.c @@ -50,6 +50,23 @@ void pid2(void) { } void main(void) { + int i; + char c = 'a'; + char buf[2048]; + +/* + * for(i = 0; i < 2048; i++) { + * buf[i] = c; + * + * c++; + * if(c > 'z') + * c = 'a'; + * } + * ctty(1); + * write(buf, 2048); + * while(1); + */ + if(getpid() == 1) { ctty(1); pid1(); -- cgit v1.3