From a2f9ae9d4ab678fa66a2ec5d1072ea22a36a18a1 Mon Sep 17 00:00:00 2001 From: dzwdz Date: Thu, 19 Jan 2023 23:36:11 +0100 Subject: kernel: user interrupts --- src/user/lib/_start2.c | 4 ++++ src/user/lib/include/unistd.h | 3 +++ src/user/lib/intr.s | 20 ++++++++++++++++++++ src/user/lib/syscall.c | 8 ++++++++ src/user/lib/unistd.c | 11 +++++++++++ 5 files changed, 46 insertions(+) create mode 100644 src/user/lib/intr.s (limited to 'src/user/lib') 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); +} -- cgit v1.2.3