summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/kernel/sys.h8
-rw-r--r--include/kernel/tty.h2
-rw-r--r--include/stdio.h5
-rw-r--r--include/string.h26
-rw-r--r--include/unistd.h6
-rw-r--r--kernel/rs.s34
-rw-r--r--kernel/serial.c39
-rw-r--r--kernel/sys.c9
-rw-r--r--kernel/tty.c64
-rw-r--r--lib/panic.c8
-rw-r--r--lib/stdio.c14
-rw-r--r--lib/string.c56
-rw-r--r--usrbin/main.c4
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);
}