summaryrefslogtreecommitdiff
path: root/src/user/lib
diff options
context:
space:
mode:
authordzwdz2023-01-19 23:36:11 +0100
committerdzwdz2023-01-19 23:36:11 +0100
commita2f9ae9d4ab678fa66a2ec5d1072ea22a36a18a1 (patch)
treec048e9165b27d27075d2c17ab943ac52b46a6a40 /src/user/lib
parentda546a0822b1995efe1832c9cc57aab62ccdcf65 (diff)
kernel: user interrupts
Diffstat (limited to 'src/user/lib')
-rw-r--r--src/user/lib/_start2.c4
-rw-r--r--src/user/lib/include/unistd.h3
-rw-r--r--src/user/lib/intr.s20
-rw-r--r--src/user/lib/syscall.c8
-rw-r--r--src/user/lib/unistd.c11
5 files changed, 46 insertions, 0 deletions
diff --git a/src/user/lib/_start2.c b/src/user/lib/_start2.c
index ba3b6b0..495f046 100644
--- a/src/user/lib/_start2.c
+++ b/src/user/lib/_start2.c
@@ -17,9 +17,13 @@ const char *shortname(const char *path) {
return path;
}
+void intr_trampoline(void); /* intr.s */
+
_Noreturn void _start2(struct execdata *ed) {
const char *progname;
elf_selfreloc();
+ _syscall_intr_set(intr_trampoline);
+ intr_set(intr_default);
__setinitialcwd(ed->cwd);
progname = shortname(ed->argv[0]);
diff --git a/src/user/lib/include/unistd.h b/src/user/lib/include/unistd.h
index f49c337..d13767b 100644
--- a/src/user/lib/include/unistd.h
+++ b/src/user/lib/include/unistd.h
@@ -26,3 +26,6 @@ size_t absolutepath(char *out, const char *in, size_t size);
// TODO put in an internal libc header
void __setinitialcwd(const char *c);
+
+void intr_set(void (*fn)(void));
+void intr_default(void);
diff --git a/src/user/lib/intr.s b/src/user/lib/intr.s
new file mode 100644
index 0000000..008387d
--- /dev/null
+++ b/src/user/lib/intr.s
@@ -0,0 +1,20 @@
+.section .text
+.global intr_trampoline
+.type intr_trampoline, @function
+intr_trampoline:
+ push %rax
+ push %rdx
+ call *_intr(%rip)
+ pop %rdx
+ pop %rax
+ pop tmprip(%rip)
+ pop %rsp
+ jmp *tmprip(%rip)
+
+.section .bss
+tmprip:
+ .skip 8
+
+.global _intr
+_intr:
+ .skip 8
diff --git a/src/user/lib/syscall.c b/src/user/lib/syscall.c
index d6ed0af..d42c2ee 100644
--- a/src/user/lib/syscall.c
+++ b/src/user/lib/syscall.c
@@ -74,6 +74,14 @@ void _syscall_filicide(void) {
return (void)_syscall(_SYSCALL_FILICIDE, 0, 0, 0, 0, 0);
}
+void _syscall_intr(void) {
+ return (void)_syscall(_SYSCALL_INTR, 0, 0, 0, 0, 0);
+}
+
+void _syscall_intr_set(void __user *ip) {
+ return (void)_syscall(_SYSCALL_INTR_SET, (long)ip, 0, 0, 0, 0);
+}
+
long _syscall_execbuf(void __user *buf, size_t len) {
return _syscall(_SYSCALL_EXECBUF, (long)buf, (long)len, 0, 0, 0);
}
diff --git a/src/user/lib/unistd.c b/src/user/lib/unistd.c
index 01aa94f..cb862f8 100644
--- a/src/user/lib/unistd.c
+++ b/src/user/lib/unistd.c
@@ -161,3 +161,14 @@ size_t absolutepath(char *out, const char *in, size_t size) {
void __setinitialcwd(const char *s) {
__initialcwd = s;
}
+
+static void intr_null(void) { }
+
+extern void (*volatile _intr)(void);
+void intr_set(void (*fn)(void)) {
+ _intr = fn ? fn : intr_null;
+}
+
+void intr_default(void) {
+ exit(-1);
+}