diff options
| -rw-r--r-- | include/kernel/sys.h | 8 | ||||
| -rw-r--r-- | include/kernel/tty.h | 2 | ||||
| -rw-r--r-- | include/stdio.h | 5 | ||||
| -rw-r--r-- | include/string.h | 26 | ||||
| -rw-r--r-- | include/unistd.h | 6 | ||||
| -rw-r--r-- | kernel/rs.s | 34 | ||||
| -rw-r--r-- | kernel/serial.c | 39 | ||||
| -rw-r--r-- | kernel/sys.c | 9 | ||||
| -rw-r--r-- | kernel/tty.c | 64 | ||||
| -rw-r--r-- | lib/panic.c | 8 | ||||
| -rw-r--r-- | lib/stdio.c | 14 | ||||
| -rw-r--r-- | lib/string.c | 56 | ||||
| -rw-r--r-- | usrbin/main.c | 4 |
13 files changed, 213 insertions, 62 deletions
diff --git a/include/kernel/sys.h b/include/kernel/sys.h index 2cefd09..e5275cf 100644 --- a/include/kernel/sys.h +++ b/include/kernel/sys.h @@ -9,8 +9,10 @@ extern int sys_alarm(void); extern int sys_pause(void); 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); syscall_t call_table[256] = { [0] = &sys_puts, @@ -22,9 +24,9 @@ syscall_t call_table[256] = { [6] = &sys_pause, [7] = &sys_ctty, [8] = &sys_read, - [9] = &sys_kill, - [10] = &sys_dummy, - [11] = &sys_dummy, + [9] = &sys_write, + [10] = &sys_kill, + [11] = &sys_panic, [12] = &sys_dummy, [13] = &sys_dummy, [14] = &sys_dummy, diff --git a/include/kernel/tty.h b/include/kernel/tty.h index b3f3012..7c0fc6e 100644 --- a/include/kernel/tty.h +++ b/include/kernel/tty.h @@ -15,11 +15,13 @@ struct tty_queue { struct tty_struct { void (*init) (void); + void (*write) (void); struct tty_queue rqueue; struct tty_queue wqueue; }; ssize_t tty_read(unsigned, void*, size_t); +ssize_t tty_write(unsigned, void*, size_t); void tty_init(void); diff --git a/include/stdio.h b/include/stdio.h index f94e783..5387db0 100644 --- a/include/stdio.h +++ b/include/stdio.h @@ -14,8 +14,9 @@ int sprintf(char*, char*, ...); int vsprintf(char*, char*, va_list); -ssize_t read(void *buf, size_t len); +ssize_t read(void*, size_t); +ssize_t write(void*, size_t); -int ctty(int ctty); +int ctty(int); #endif diff --git a/include/string.h b/include/string.h index 72c2b2e..d2f738b 100644 --- a/include/string.h +++ b/include/string.h @@ -12,26 +12,26 @@ typedef uint32_t size_t; #endif -void* memchr(const void*, int, size_t); +void *memchr(const void*, int, size_t); int memcmp(const void*, const void*, size_t); -void* memcpy(void*, const void*, size_t); -void* memmove(void*, const void*, size_t); -void* memset(void*, int, size_t); +void *memcpy(void*, const void*, size_t); +void *memmove(void*, const void*, size_t); +void *memset(void*, int, size_t); size_t strlen(const char*); -char* strcat(char*, const char*); -char* strncat(char*, const char*, size_t); -char* strchr(const char*, int); -char* strrchr(char*, int); +char *strcat(char*, const char*); +char *strncat(char*, const char*, size_t); +char *strchr(const char*, int); +char *strrchr(char*, int); int strcmp(const char*, const char*); int strncmp(const char*, const char*, size_t); -char* strcpy(char*, const char*); -char* strncpy(char*, const char*, size_t); +char *strcpy(char*, const char*); +char *strncpy(char*, const char*, size_t); size_t strcspn(const char*, const char*); size_t strspn(const char*, const char*); -char* strpbrk(const char*, const char*); -char* strstr(const char*, const char*); -char* strtok(char*, const char*); +char *strpbrk(const char*, const char*); +char *strstr(const char*, const char*); +char *strtok(char*, const char*); size_t strxfrm(char*, const char*, size_t); #endif diff --git a/include/unistd.h b/include/unistd.h index c337e57..a7e4f32 100644 --- a/include/unistd.h +++ b/include/unistd.h @@ -19,7 +19,9 @@ typedef int16_t pid_t; #define __SYS_pause 6 #define __SYS_ctty 7 #define __SYS_read 8 -#define __SYS_kill 9 +#define __SYS_write 9 +#define __SYS_kill 10 +#define __SYS_panic 11 #define _syscall0(type, name) \ type name(void) { \ @@ -59,4 +61,6 @@ void *getpdir(void); int pause(void); +void panic(void); + #endif diff --git a/kernel/rs.s b/kernel/rs.s index 9f3d4a6..69d31ae 100644 --- a/kernel/rs.s +++ b/kernel/rs.s @@ -1,7 +1,20 @@ global rs_isr -extern rs_handler +extern rsint_rx +extern rsint_tx extern rsputs +%define RSBASE 0x3F8 + +%define RSDATA RSBASE +%define RSINTEN (RSBASE + 1) +%define RSFIFOC (RSBASE + 2) +%define RSINTID (RSBASE + 2) +%define RSLINEC (RSBASE + 3) +%define RSMODEMC (RSBASE + 4) +%define RSLINES (RSBASE + 5) +%define RSMODEMS (RSBASE + 6) +%define RSSCRATCH (RSBASE + 7) + rs_isr: pusha mov ax, ds @@ -12,7 +25,24 @@ rs_isr: mov fs, ax mov gs, ax - call rs_handler + mov dx, RSINTID + in al, dx + test al, 1 + jnz .skip + and al, 0x0E + cmp al, 0x04 + je .rx + cmp al, 0x0C + je .rx + cmp al, 0x02 + je .tx + jmp .skip +.tx: + call rsint_tx + jmp .skip +.rx: + call rsint_rx +.skip: mov al, 0x20 out 0x20, al diff --git a/kernel/serial.c b/kernel/serial.c index 39c5ee0..a133865 100644 --- a/kernel/serial.c +++ b/kernel/serial.c @@ -16,6 +16,7 @@ #define RSDATA RSBASE #define RSINTEN (RSBASE + 1) #define RSFIFOC (RSBASE + 2) +#define RSINTID (RSBASE + 2) #define RSLINEC (RSBASE + 3) #define RSMODEMC (RSBASE + 4) #define RSLINES (RSBASE + 5) @@ -27,8 +28,12 @@ extern void rs_isr(void); +/* internal function prototypes */ +void rsint_tx(void); + struct tty_struct tty_rs = { - .init = &serial_init + .init = &serial_init, + .write = &rsint_tx }; static char present; @@ -70,11 +75,18 @@ void serial_init(void) { /* restore access to the divisor */ outb(RSLINEC, inb(RSLINEC) & 0x7F); /* configure port parameters */ - outb(RSFIFOC, 0x06); + outb(RSFIFOC, 0x07); outb(RSLINEC, 0x03); outb(RSMODEMC, 0x0B); - outb(RSINTEN, 0x01); + outb(RSINTEN, 0x03); inb(RSDATA); + + /* test FIFO functionality */ + if(inb(RSINTID) & 0xC0 != 0xC0) { + printk("[rs] Failed to enable FIFO on COM0!\n"); + return; + } + /* register the interrupt handler */ register_isr(0x24, 0, &rs_isr); irq_enable(0x10); @@ -85,7 +97,7 @@ void serial_init(void) { present = 1; } -void rs_handler(void) { +void rsint_rx(void) { struct tty_queue *q = &tty_rs.rqueue; if((inb(RSLINES) & 1) == 0) @@ -98,3 +110,22 @@ void rs_handler(void) { 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); +} diff --git a/kernel/sys.c b/kernel/sys.c index 6127f58..8e28edd 100644 --- a/kernel/sys.c +++ b/kernel/sys.c @@ -1,5 +1,6 @@ #include <errno.h> #include <kernel/con.h> +#include <kernel/kernel.h> #include <kernel/sched.h> #include <kernel/serial.h> #include <kernel/tty.h> @@ -84,6 +85,14 @@ ssize_t sys_read(void *buf, size_t len) { return tty_read(ctask->ctty, buf, len); } +ssize_t sys_write(void *buf, size_t len) { + return tty_write(ctask->ctty, buf, len); +} + +void sys_panic(void) { + panic(); +} + int sys_dummy(void) { return -ENOSYS; } diff --git a/kernel/tty.c b/kernel/tty.c index 1946110..75c3701 100644 --- a/kernel/tty.c +++ b/kernel/tty.c @@ -16,11 +16,8 @@ static struct tty_struct *ttys[] = { &tty_rs }; -/* check if the buffer's empty and if so, go to sleep */ +/* check if a buffer's empty and if so, go to sleep */ static int sleep_while_empty(struct tty_queue *q) { - if(q->pread != q->pwrite) - return 0; - cli(); while(1) { if(q->pread == q->pwrite) @@ -37,6 +34,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) { + cli(); + while(1) { + 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))) { + sti(); + return -1; + } + + sti(); + return 0; + } +} + ssize_t tty_read(unsigned tty, void *buf, size_t len) { size_t i; char *b = buf; @@ -61,9 +76,45 @@ ssize_t tty_read(unsigned tty, void *buf, size_t len) { } *b++ = q->buf[q->pread]; - q->pread = q->pread + 1 % TTY_BUF_SIZE; + q->pread = (q->pread + 1) % TTY_BUF_SIZE; + } + + return len; +} + +ssize_t tty_write(unsigned tty, void *buf, size_t len) { + size_t i; + char *b = buf; + struct tty_queue *q = &ttys[tty]->wqueue; + + if(tty > NRTTY || ttys[tty] == NULL) + return -1; + + if(len == 0) + return 0; + + if(len > SSIZE_MAX) + len = SSIZE_MAX; + + 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(i == 0) + return -EINTR; + + return i; + } + + q->buf[q->pwrite] = *b++; + q->pwrite = (q->pwrite + 1) % TTY_BUF_SIZE; } + /* tell the driver that new data is available */ + cli(); + if(ttys[tty]->write) + ttys[tty]->write(); + sti(); + return len; } @@ -77,9 +128,6 @@ void tty_init(void) { memset(&ttys[i]->rqueue, 0, sizeof(struct tty_queue)); memset(&ttys[i]->wqueue, 0, sizeof(struct tty_queue)); - ttys[i]->rqueue.pwrite = 1; - ttys[i]->wqueue.pwrite = 1; - if(ttys[i]->init) ttys[i]->init(); } diff --git a/lib/panic.c b/lib/panic.c new file mode 100644 index 0000000..a3eb0af --- /dev/null +++ b/lib/panic.c @@ -0,0 +1,8 @@ +#include <unistd.h> + +void panic(void) { + __asm__ volatile ( + "int $0x80" + :: "a" (__SYS_panic) + ); +} diff --git a/lib/stdio.c b/lib/stdio.c index 7eac64c..b1c00ba 100644 --- a/lib/stdio.c +++ b/lib/stdio.c @@ -1,11 +1,23 @@ #include <stdarg.h> #include <stdio.h> +#include <string.h> #include <sys/types.h> #include <unistd.h> -_syscall1(int, puts, char*, s); _syscall1(int, ctty, int, ctty); _syscall2(ssize_t, read, void*, buf, size_t, len); +_syscall2(ssize_t, write, void*, buf, size_t, len); + +int puts(char *s) { + size_t len = strlen(s); + ssize_t ret; + + ret = write(s, len); + if(ret < 0) + return EOF; + + return 0; +} int printf(char *fmt, ...) { int ret; diff --git a/lib/string.c b/lib/string.c index 0e8fbeb..e8659ad 100644 --- a/lib/string.c +++ b/lib/string.c @@ -1,6 +1,6 @@ #include <string.h> -void* memchr(const void* s, int c, size_t n) { +void *memchr(const void *s, int c, size_t n) { unsigned char *p = (unsigned char*) s; while(n--) { if(*p != (unsigned char) c) { @@ -12,9 +12,9 @@ void* memchr(const void* s, int c, size_t n) { return 0; } -int memcmp(const void* s1, const void* s2, size_t n) { - const unsigned char* p1 = (const unsigned char*) s1; - const unsigned char* p2 = (const unsigned char*) s2; +int memcmp(const void *s1, const void *s2, size_t n) { + const unsigned char *p1 = (const unsigned char*) s1; + const unsigned char *p2 = (const unsigned char*) s2; while(n--) { if(*p1 != *p2) { return *p1 - *p2; @@ -25,33 +25,33 @@ int memcmp(const void* s1, const void* s2, size_t n) { return 0; } -void* memcpy(void* dest, const void* src, size_t n) { +void *memcpy(void *dest, const void *src, size_t n) { char *dp = (char*) dest; const char *sp = (const char*) src; while(n--) *dp++ = *sp++; return dest; } -void* memmove(void* dest, const void* src, size_t n) { +void *memmove(void *dest, const void *src, size_t n) { unsigned char tmp[n]; memcpy(tmp, src, n); memcpy(dest, tmp, n); return dest; } -void* memset(void* s, int c, size_t n) { - unsigned char* p = (unsigned char*) s; +void *memset(void *s, int c, size_t n) { + unsigned char *p = (unsigned char*) s; while(n--) *p++ = (unsigned char) c; return s; } -size_t strlen(const char* str) { - const char* s; +size_t strlen(const char *str) { + const char *s; for(s = str; *s; ++s) {} return (s - str); } -char* strcat(char* dest, const char* src) { +char *strcat(char *dest, const char *src) { size_t dest_len = strlen(dest); size_t i; @@ -62,7 +62,7 @@ char* strcat(char* dest, const char* src) { return dest; } -char* strncat(char* dest, const char* src, size_t n) { +char *strncat(char *dest, const char *src, size_t n) { size_t dest_len = strlen(dest); size_t i; @@ -73,27 +73,27 @@ char* strncat(char* dest, const char* src, size_t n) { return dest; } -char* strchr(const char* s, int c) { +char *strchr(const char *s, int c) { while(*s != (char) c) { if(!*s++) return 0; } return (char*) s; } -char* strrchr(char* s, int c) { - char* ret = 0; +char *strrchr(char *s, int c) { + char *ret = 0; do { if(*s == (char) c) ret = s; } while(*s++); return ret; } -int strcmp(const char* s1, const char* s2) { +int strcmp(const char *s1, const char *s2) { while(*s1 && (*s1 == *s2)) s1++, s2++; return *(const unsigned char*) s1 - *(const unsigned char*) s2; } -int strncmp(const char* s1, const char* s2, size_t n) { +int strncmp(const char *s1, const char *s2, size_t n) { while(n--) { if(*s1++ != *s2++) { return *(unsigned char*) (s1 - 1) - *(unsigned char*) (s2 - 1); @@ -102,14 +102,14 @@ int strncmp(const char* s1, const char* s2, size_t n) { return 0; } -char* strcpy(char* dest, const char* src) { - char* ret = dest; +char *strcpy(char *dest, const char *src) { + char *ret = dest; while(*dest++ = *src++); return ret; } -char* strncpy(char* dest, const char* src, size_t n) { - char* ret = dest; +char *strncpy(char *dest, const char *src, size_t n) { + char *ret = dest; do { if(!n--) return ret; } while (*dest++ = *src++); @@ -117,7 +117,7 @@ char* strncpy(char* dest, const char* src, size_t n) { return ret; } -size_t strcspn(const char* s1, const char* s2) { +size_t strcspn(const char *s1, const char *s2) { size_t ret = 0; while(*s1) { if(strchr(s2, *s1)) { @@ -129,20 +129,20 @@ size_t strcspn(const char* s1, const char* s2) { return ret; } -size_t strspn(const char* s1, const char* s2) { +size_t strspn(const char *s1, const char *s2) { size_t ret = 0; while(*s1 && strchr(s2, *s1++)) ret++; return ret; } -char* strpbrk(const char* s1, const char* s2) { +char *strpbrk(const char *s1, const char *s2) { while(*s1) { if(strchr(s2, *s1++)) return (char*) --s1; } return 0; } -char* strstr(const char* s1, const char* s2) { +char *strstr(const char *s1, const char *s2) { size_t n = strlen(s2); while(*s1) { if(!memcmp(s1++, s2, n)) { @@ -152,8 +152,8 @@ char* strstr(const char* s1, const char* s2) { return 0; } -char* strtok(char* str, const char* delim) { - static char* p = 0; +char *strtok(char *str, const char *delim) { + static char *p = 0; if(str) { p = str; } else if(!p) { @@ -166,7 +166,7 @@ char* strtok(char* str, const char* delim) { return str; } -size_t strxfrm(char* dest, const char* src, size_t n) { +size_t strxfrm(char *dest, const char *src, size_t n) { size_t n2 = strlen(src); if(n > n2) strcpy(dest, src); return n2; diff --git a/usrbin/main.c b/usrbin/main.c index a545a11..3b6dd97 100644 --- a/usrbin/main.c +++ b/usrbin/main.c @@ -27,6 +27,10 @@ void pid1(void) { kill(getpid(), SIGKILL); } } + if(in == 0) { + printf("EOF detected!\n"); + panic(); + } if(in > 0) puts(buf); } |
