diff --git a/kernel/amd64/proc.c b/kernel/amd64/proc.c index a9ab5bf..677f5fe 100644 --- a/kernel/amd64/proc.c +++ b/kernel/amd64/proc.c @@ -114,7 +114,7 @@ void proc_cleanup(struct proc* proc, struct reschedule_ctx* rctx) { struct proc_sq_entry* sq_entry = list_entry(node, struct proc_sq_entry, sq_link); struct proc* suspended_proc = sq_entry->proc; - proc_sq_resume(suspended_proc, sq_entry, rctx); + proc_sq_resume(suspended_proc, sq_entry, rctx, (uintptr_t)proc->pid); } proc_sqs_cleanup(proc); @@ -158,3 +158,5 @@ void proc_init_tls(struct proc* proc) { proc->pdata.fs_base = utcb; proc->pdata.tls_vaddr = tls_vaddr; } + +void proc_set_syscall_value(struct proc* proc, uintptr_t value) { proc->pdata.regs.rax = value; } diff --git a/kernel/device/ps2/ps2_kb.c b/kernel/device/ps2/ps2_kb.c index cf1ae01..86e8caf 100644 --- a/kernel/device/ps2/ps2_kb.c +++ b/kernel/device/ps2/ps2_kb.c @@ -154,17 +154,19 @@ static void ps2kb_irq(void* arg, void* regs, bool user, struct reschedule_ctx* r if (keycode <= 0 || keycode == 0xFA) return; - ringbuffer_push(uint8_t, &ps2kb_ringbuffer, (uint8_t)keycode); - struct list_node_link* node = ps2kb_sq.proc_list; if (node != NULL) { struct proc_sq_entry* sq_entry = list_entry(node, struct proc_sq_entry, sq_link); struct proc* resumed_proc = sq_entry->proc; - proc_sq_resume(resumed_proc, sq_entry, rctx); + *(uint8_t*)sq_entry->udata = (uint8_t)keycode; + + proc_sq_resume(resumed_proc, sq_entry, rctx, ST_OK); return; } + + ringbuffer_push(uint8_t, &ps2kb_ringbuffer, (uint8_t)keycode); } DEFINE_DEVICE_OP(ps2kb_read_key) { @@ -173,25 +175,13 @@ DEFINE_DEVICE_OP(ps2kb_read_key) { if (chbuf == NULL) return -ST_BAD_ADDRESS_SPACE; - size_t prev_count = ps2kb_ringbuffer.count; - - ringbuffer_pop(uint8_t, &ps2kb_ringbuffer, chbuf); - - size_t new_count = ps2kb_ringbuffer.count; - - /* didn't pop anything */ - if (prev_count == new_count) { - struct list_node_link* node = ps2kb_sq.proc_list; - - if (node != NULL) { - return -ST_PERMISSION_ERROR; - } - - proc_sq_suspend(proc, &ps2kb_sq, rctx, NULL, NULL); - + if (ps2kb_ringbuffer.count == 0) { + proc_sq_suspend(proc, &ps2kb_sq, rctx, chbuf, NULL); return ST_OK; } + ringbuffer_pop(uint8_t, &ps2kb_ringbuffer, chbuf); + return ST_OK; } diff --git a/kernel/fs/vfs.c b/kernel/fs/vfs.c index 1526bd6..e1ba570 100644 --- a/kernel/fs/vfs.c +++ b/kernel/fs/vfs.c @@ -213,7 +213,7 @@ int vfs_volume_close(struct proc* proc, const char* volume_name, struct reschedu volume->owner = resumed_proc; volume->locked = true; - proc_sq_resume(resumed_proc, sq_entry, rctx); + proc_sq_resume(resumed_proc, sq_entry, rctx, 0); return ST_OK; } diff --git a/kernel/proc/mail.c b/kernel/proc/mail.c index 805fad2..98ff349 100644 --- a/kernel/proc/mail.c +++ b/kernel/proc/mail.c @@ -20,7 +20,7 @@ void proc_cleanup_resource_mail(struct proc_resource* resource, struct reschedul struct proc_sq_entry* sq_entry = list_entry(node, struct proc_sq_entry, sq_link); struct proc* suspended_proc = sq_entry->proc; - proc_sq_resume(suspended_proc, sq_entry, rctx); + proc_sq_resume(suspended_proc, sq_entry, rctx, 0); } } @@ -48,7 +48,7 @@ void proc_mail_send(struct proc* proc, struct proc_mail* mail, struct reschedule size_t copy_size = min(data_size, saved_buffer->size); memcpy(saved_buffer->buffer, data, copy_size); - proc_sq_resume(resumed_proc, sq_entry, rctx); + proc_sq_resume(resumed_proc, sq_entry, rctx, copy_size); return; } @@ -80,7 +80,8 @@ void proc_mail_receive(struct proc* proc, struct proc_mail* mail, struct resched list_remove(mail->packets, &packet->packets_link); mail->packets_count--; - memcpy(recv_buffer, packet->packet_buffer, min(recv_size, packet->packet_size)); + size_t copy_size = min(recv_size, packet->packet_size); + memcpy(recv_buffer, packet->packet_buffer, copy_size); free(packet->packet_buffer); free(packet); @@ -90,7 +91,7 @@ void proc_mail_receive(struct proc* proc, struct proc_mail* mail, struct resched struct proc_sq_entry* sq_entry = list_entry(node, struct proc_sq_entry, sq_link); struct proc* resumed_proc = sq_entry->proc; - proc_sq_resume(resumed_proc, sq_entry, rctx); + proc_sq_resume(resumed_proc, sq_entry, rctx, copy_size); return; } diff --git a/kernel/proc/mutex.c b/kernel/proc/mutex.c index 89bb458..8b56af6 100644 --- a/kernel/proc/mutex.c +++ b/kernel/proc/mutex.c @@ -43,7 +43,7 @@ void proc_cleanup_resource_mutex(struct proc_resource* resource, struct reschedu struct proc_sq_entry* sq_entry = list_entry(node, struct proc_sq_entry, sq_link); struct proc* suspended_proc = sq_entry->proc; - proc_sq_resume(suspended_proc, sq_entry, rctx); + proc_sq_resume(suspended_proc, sq_entry, rctx, 0); } mutex->locked = false; @@ -74,7 +74,7 @@ void proc_mutex_unlock(struct proc* proc, struct proc_mutex* mutex, struct resch mutex->owner = resumed_proc; mutex->locked = true; - proc_sq_resume(resumed_proc, sq_entry, rctx); + proc_sq_resume(resumed_proc, sq_entry, rctx, 0); return; } diff --git a/kernel/proc/suspension_q.c b/kernel/proc/suspension_q.c index 70736eb..b77d509 100644 --- a/kernel/proc/suspension_q.c +++ b/kernel/proc/suspension_q.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include @@ -41,7 +42,8 @@ int proc_sq_suspend(struct proc* proc, struct proc_suspension_q* sq, struct resc return state; } -int proc_sq_resume(struct proc* proc, struct proc_sq_entry* sq_entry, struct reschedule_ctx* rctx) { +int proc_sq_resume(struct proc* proc, struct proc_sq_entry* sq_entry, struct reschedule_ctx* rctx, + uintptr_t value) { struct cpu* cpu = cpu_find_lightest(); struct proc_suspension_q* sq = sq_entry->sq; @@ -52,6 +54,7 @@ int proc_sq_resume(struct proc* proc, struct proc_sq_entry* sq_entry, struct res list_remove(proc->sq_entries, &sq_entry->proc_link); proc->cpu = cpu; + proc_set_syscall_value(proc, value); if (proc->sq_entries == NULL) proc->state = PROC_READY; diff --git a/kernel/proc/suspension_q.h b/kernel/proc/suspension_q.h index c73d4e9..b75d5a2 100644 --- a/kernel/proc/suspension_q.h +++ b/kernel/proc/suspension_q.h @@ -28,6 +28,7 @@ void proc_sqs_cleanup(struct proc* proc); int proc_sq_suspend(struct proc* proc, struct proc_suspension_q* sq, struct reschedule_ctx* rctx, void* udata, sq_entry_free_udata_func_t free_func); -int proc_sq_resume(struct proc* proc, struct proc_sq_entry* sq_entry, struct reschedule_ctx* rctx); +int proc_sq_resume(struct proc* proc, struct proc_sq_entry* sq_entry, struct reschedule_ctx* rctx, + uintptr_t value); #endif // _KERNEL_PROC_SUSPENTION_Q_H diff --git a/kernel/sys/proc.h b/kernel/sys/proc.h index 194520c..e3daa0e 100644 --- a/kernel/sys/proc.h +++ b/kernel/sys/proc.h @@ -16,4 +16,6 @@ void proc_cleanup(struct proc* proc, struct reschedule_ctx* rctx); void proc_init_tls(struct proc* proc); +void proc_set_syscall_value(struct proc* proc, uintptr_t value); + #endif // _KERNEL_SYS_PROC_H