aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Auvolat <alex@adnab.me>2015-03-11 16:22:40 +0100
committerAlex Auvolat <alex@adnab.me>2015-03-11 16:22:40 +0100
commit9b9ef5a2c0ec8e66c7da24c4229d89a90a10e914 (patch)
tree471cb88f003eb58ce84342f2e7ab7effda04ce2d
parenta7ff74cdf2835625282491242ede57b05ceaa782 (diff)
downloadkogata-9b9ef5a2c0ec8e66c7da24c4229d89a90a10e914.tar.gz
kogata-9b9ef5a2c0ec8e66c7da24c4229d89a90a10e914.zip
Bugfixing in progress. Strange bug: wait_on adds to waiters but later not in waiters.
-rw-r--r--src/common/include/proto/keyboard.h40
-rw-r--r--src/common/libalgo/hashtbl.c4
-rw-r--r--src/kernel/core/idt.c17
-rw-r--r--src/kernel/core/thread.c41
-rw-r--r--src/kernel/core/worker.c27
-rw-r--r--src/kernel/dev/pckbd.c2
-rw-r--r--src/kernel/include/thread.h2
-rw-r--r--src/kernel/user/syscall.c6
-rw-r--r--src/lib/include/gip.h3
-rw-r--r--src/lib/libkogata/gip.c4
-rw-r--r--src/lib/libkogata/mainloop.c4
-rw-r--r--src/sysbin/giosrv/main.c17
-rw-r--r--src/sysbin/login/main.c10
13 files changed, 127 insertions, 50 deletions
diff --git a/src/common/include/proto/keyboard.h b/src/common/include/proto/keyboard.h
index 044946d..8d9543f 100644
--- a/src/common/include/proto/keyboard.h
+++ b/src/common/include/proto/keyboard.h
@@ -14,7 +14,45 @@ typedef struct {
#define IOCTL_KBD_SET_LEDS 10
#define KBD_LED_SCROLLLOCK 1
-#define KBD_LED_NUMLOCK 1
+#define KBD_LED_NUMLOCK 2
#define KBD_LED_CAPSLOCK 4
+#define KBD_CODE_ESC 1
+#define KBD_CODE_RETURN 28
+#define KBD_CODE_BKSP 14
+#define KBD_CODE_UP 200
+#define KBD_CODE_DOWN 208
+#define KBD_CODE_LEFT 203
+#define KBD_CODE_RIGHT 205
+#define KBD_CODE_HOME 199
+#define KBD_CODE_END 207
+#define KBD_CODE_PGUP 201
+#define KBD_CODE_PGDOWN 209
+
+#define KBD_CODE_LSHIFT 42
+#define KBD_CODE_RSHIFT 54
+#define KBD_CODE_CAPSLOCK 58
+#define KBD_CODE_LCTRL 29
+#define KBD_CODE_RCTRL 157
+#define KBD_CODE_LALT 56
+#define KBD_CODE_RALT 184
+#define KBD_CODE_SUPER 219
+#define KBD_CODE_MENU 221
+#define KBD_CODE_TAB 15
+#define KBD_CODE_INS 210
+#define KBD_CODE_DEL 211
+
+#define KBD_CODE_F1 59
+#define KBD_CODE_F2 60
+#define KBD_CODE_F3 61
+#define KBD_CODE_F4 62
+#define KBD_CODE_F5 63
+#define KBD_CODE_F6 64
+#define KBD_CODE_F7 65
+#define KBD_CODE_F8 66
+#define KBD_CODE_F9 67
+#define KBD_CODE_F10 68
+#define KBD_CODE_F11 87
+#define KBD_CODE_F12 88
+
/* vim: set ts=4 sw=4 tw=0 noet :*/
diff --git a/src/common/libalgo/hashtbl.c b/src/common/libalgo/hashtbl.c
index f34c6d4..7192bd4 100644
--- a/src/common/libalgo/hashtbl.c
+++ b/src/common/libalgo/hashtbl.c
@@ -90,11 +90,11 @@ static void hashtbl_check_size(hashtbl_t *ht) {
}
bool hashtbl_add(hashtbl_t *ht, void* key, void* v) {
- size_t slot = SLOT_OF_HASH(ht->hf(key), ht->size);
-
hashtbl_item_t *i = (hashtbl_item_t*)malloc(sizeof(hashtbl_item_t));
if (i == 0) return false; // OOM
+ size_t slot = SLOT_OF_HASH(ht->hf(key), ht->size);
+
// make sure item is not already present
hashtbl_remove(ht, key);
diff --git a/src/kernel/core/idt.c b/src/kernel/core/idt.c
index f99460f..f3dd63b 100644
--- a/src/kernel/core/idt.c
+++ b/src/kernel/core/idt.c
@@ -91,6 +91,7 @@ static isr_handler_t ex_handlers[32] = {0};
/* Called in interrupt.s when an exception fires (interrupt 0 to 31) */
void idt_ex_handler(registers_t *regs) {
+ dbg_printf("Ex handler: %d\n", regs->int_no);
if (ex_handlers[regs->int_no] != 0) {
ex_handlers[regs->int_no](regs);
} else {
@@ -114,21 +115,21 @@ void idt_ex_handler(registers_t *regs) {
void idt_irq_handler(registers_t *regs) {
int st = enter_critical(CL_EXCL); // if someone tries to yield(), an assert will fail
+ dbg_printf("irq%d.", regs->err_code);
+
if (regs->err_code > 7) {
outb(0xA0, 0x20);
}
outb(0x20, 0x20);
- if (regs->err_code == 0) {
- irq0_handler(regs, st);
- } else {
- /*dbg_printf("irq%d.", regs->err_code);*/
+ if (irq_handlers[regs->err_code] != 0) {
+ irq_handlers[regs->err_code](regs);
+ }
- if (irq_handlers[regs->err_code] != 0) {
- irq_handlers[regs->err_code](regs);
- }
+ exit_critical(st);
- exit_critical(st);
+ if (regs->err_code == 0) {
+ threading_irq0_handler();
}
// maybe exit
diff --git a/src/kernel/core/thread.c b/src/kernel/core/thread.c
index 4e15c0e..ed2c185 100644
--- a/src/kernel/core/thread.c
+++ b/src/kernel/core/thread.c
@@ -19,7 +19,6 @@ void resume_context(saved_context_t *ctx);
thread_t *current_thread = 0;
static hashtbl_t *waiters = 0; // threads waiting on a ressource
-STATIC_MUTEX(waiters_mutex);
// ====================== //
// THE PROGRAMMABLE TIMER //
@@ -44,6 +43,8 @@ void set_pit_frequency(uint32_t freq) {
int enter_critical(int level) {
asm volatile("cli");
+ /*dbg_printf(" >%d< ", level);*/
+
if (current_thread == 0) return CL_EXCL;
int prev_level = current_thread->critical_level;
@@ -57,6 +58,8 @@ int enter_critical(int level) {
void exit_critical(int prev_level) {
asm volatile("cli");
+ /*dbg_printf(" <%d> ", prev_level);*/
+
if (current_thread == 0) return;
if (prev_level < current_thread->critical_level) current_thread->critical_level = prev_level;
@@ -117,6 +120,8 @@ void run_scheduler() {
// At this point, interrupts are disabled
// This function is expected NEVER TO RETURN
+ thread_t *prev_thread = current_thread;
+
if (current_thread != 0 && current_thread->state == T_STATE_RUNNING) {
current_thread->last_ran = get_kernel_time();
if (current_thread->proc) current_thread->proc->last_ran = current_thread->last_ran;
@@ -124,7 +129,7 @@ void run_scheduler() {
}
current_thread = dequeue_thread();
- /*dbg_printf("[0x%p]\n", current_thread);*/
+ if (current_thread != prev_thread) dbg_printf("[0x%p]\n", current_thread);
if (current_thread != 0) {
thread_t *ptr = current_thread;
@@ -221,11 +226,10 @@ void delete_thread(thread_t *t) {
// SETUP CODE //
// ========== //
-void irq0_handler(registers_t *regs, int crit_level) {
+void irq0_handler(registers_t *regs) {
notify_time_pass(1000000 / TASK_SWITCH_FREQUENCY);
-
- exit_critical(crit_level);
-
+}
+void threading_irq0_handler() {
if (current_thread != 0 && current_thread->critical_level == CL_USER) {
save_context_and_enter_scheduler(&current_thread->ctx);
}
@@ -235,7 +239,7 @@ void threading_setup(entry_t cont, void* arg) {
ASSERT(waiters != 0);
set_pit_frequency(TASK_SWITCH_FREQUENCY);
- // no need to set irq0 handler
+ idt_set_irq_handler(IRQ0, &irq0_handler);
thread_t *t = new_thread(cont, arg);
ASSERT(t != 0);
@@ -265,7 +269,8 @@ void start_thread(thread_t *t) {
}
void yield() {
- ASSERT(current_thread != 0 && current_thread->critical_level != CL_EXCL);
+ ASSERT(current_thread != 0);
+ ASSERT(current_thread->critical_level != CL_EXCL);
save_context_and_enter_scheduler(&current_thread->ctx);
}
@@ -275,10 +280,11 @@ bool wait_on(void* x) {
}
bool wait_on_many(void** x, size_t n) {
- ASSERT(current_thread != 0 && current_thread->critical_level != CL_EXCL);
+ ASSERT(current_thread != 0);
+ ASSERT(current_thread->critical_level != CL_EXCL);
ASSERT(n > 0);
- mutex_lock(&waiters_mutex);
+ int st = enter_critical(CL_NOINT);
// ---- Check we can wait on all the requested objects
bool ok = true;
@@ -291,34 +297,34 @@ bool wait_on_many(void** x, size_t n) {
}
} else if (prev_th != (void*)1) {
ok = false;
+ break;
}
}
if (!ok) {
- mutex_unlock(&waiters_mutex);
+ exit_critical(st);
return false;
}
// ---- Set ourselves as the waiting thread for all the requested objets
- int st = enter_critical(CL_NOSWITCH);
+ dbg_printf("Wait on many: ");
for (size_t i = 0; i < n; i++) {
ASSERT(hashtbl_change(waiters, x[i], current_thread));
+ dbg_printf("0x%p (0x%p) ", x[i], hashtbl_find(waiters, x[i]));
}
+ dbg_printf("\n");
// ---- Go to sleep
- mutex_unlock(&waiters_mutex);
current_thread->state = T_STATE_PAUSED;
save_context_and_enter_scheduler(&current_thread->ctx);
// ---- Remove ourselves from the list
- mutex_lock(&waiters_mutex);
for (size_t i = 0; i < n; i++) {
ASSERT(hashtbl_change(waiters, x[i], (void*)1));
}
- mutex_unlock(&waiters_mutex);
exit_critical(st);
// ---- Check that we weren't waked up because of a kill request
@@ -368,15 +374,17 @@ void exit() {
}
bool resume_on(void* x) {
+
thread_t *thread;
bool ret = false;
- mutex_lock(&waiters_mutex);
int st = enter_critical(CL_NOINT);
thread = hashtbl_find(waiters, x);
+ dbg_printf("Resume on 0x%p : 0x%p\n", x, thread);
+
if (thread != 0 && thread != (void*)1) {
if (thread->state == T_STATE_PAUSED) {
thread->state = T_STATE_RUNNING;
@@ -387,7 +395,6 @@ bool resume_on(void* x) {
}
}
- mutex_unlock(&waiters_mutex);
exit_critical(st);
return ret;
diff --git a/src/kernel/core/worker.c b/src/kernel/core/worker.c
index cb7bf34..6852329 100644
--- a/src/kernel/core/worker.c
+++ b/src/kernel/core/worker.c
@@ -49,21 +49,24 @@ void worker_thread(void* x) {
while (true) {
mutex_lock(&tasks_mutex);
- worker_task_t *t = btree_upper(tasks, &zero64);
- next_task_time = (t == 0 ? UINT64_MAX : t->time);
- if (t != 0 && t->time <= time) {
- btree_remove_v(tasks, &t->time, t);
+
+ worker_task_t *next_task = btree_upper(tasks, &zero64);
+ next_task_time = (next_task == 0 ? UINT64_MAX : next_task->time);
+
+ if (next_task != 0 && next_task->time <= time) {
+ btree_remove_v(tasks, &next_task->time, next_task);
} else {
- t = 0;
+ next_task = 0;
}
+
mutex_unlock(&tasks_mutex);
- if (t != 0) {
- prng_add_entropy((uint8_t*)&t, sizeof(t));
+ if (next_task != 0) {
+ prng_add_entropy((uint8_t*)&next_task, sizeof(next_task));
// do task :-)
- t->fun(t->data);
- free(t);
+ next_task->fun(next_task->data);
+ free(next_task);
} else {
ASSERT(wait_on(current_thread));
}
@@ -79,11 +82,12 @@ bool worker_push_in(int usecs, entry_t fun, void* data) {
t->data = data;
mutex_lock(&tasks_mutex);
+
btree_add(tasks, &t->time, t);
- mutex_unlock(&tasks_mutex);
-
if (t->time < next_task_time) next_task_time = t->time;
+ mutex_unlock(&tasks_mutex);
+
return true;
}
@@ -95,6 +99,7 @@ void notify_time_pass(int usecs) {
time += usecs;
if (next_task_time <= time) {
for (int i = 0; i < nworkers; i++) {
+ if (workers[i] == 0) continue;
if (resume_on(workers[i])) break;
}
}
diff --git a/src/kernel/dev/pckbd.c b/src/kernel/dev/pckbd.c
index a911b85..8a4c002 100644
--- a/src/kernel/dev/pckbd.c
+++ b/src/kernel/dev/pckbd.c
@@ -105,7 +105,7 @@ size_t pckbd_read(fs_handle_t *h, size_t offset, size_t len, char *buf) {
}
int pckbd_poll(fs_handle_t *h, void** out_wait_obj) {
- *out_wait_obj = &pckbd_buf;
+ if (out_wait_obj) *out_wait_obj = &pckbd_buf;
return (pckbd_buf_used > 0 ? SEL_READ : 0);
}
diff --git a/src/kernel/include/thread.h b/src/kernel/include/thread.h
index 4b140fa..698c4c6 100644
--- a/src/kernel/include/thread.h
+++ b/src/kernel/include/thread.h
@@ -46,7 +46,7 @@ thread_t *new_thread(entry_t entry, void* data); // thread is PAUSED, and must b
void start_thread(thread_t *t);
void delete_thread(thread_t *t);
-void irq0_handler(registers_t *regs, int crit_level);
+void threading_irq0_handler();
extern thread_t *current_thread;
diff --git a/src/kernel/user/syscall.c b/src/kernel/user/syscall.c
index 3a67350..606ab3f 100644
--- a/src/kernel/user/syscall.c
+++ b/src/kernel/user/syscall.c
@@ -311,7 +311,7 @@ static uint32_t select_sc(sc_args_t args) {
bool ret = false;
- int st = enter_critical(CL_NOSWITCH);
+ int st = enter_critical(CL_NOINT);
while (true) {
// ---- Poll FDs, if any is ok then return it
@@ -328,10 +328,10 @@ static uint32_t select_sc(sc_args_t args) {
uint64_t time = get_kernel_time();
- // ---- If none of the handles given is a valid handle, return false
- if (n_wait_objs == 0) break;
// ---- If any is ok, return true
if (ret) break;
+ // ---- If none of the handles given is a valid handle, return false
+ if (n_wait_objs == 0) break;
// ---- If the timeout is over, return false
if (timeout >= 0 && time - select_begin_time >= (uint64_t)timeout) break;
diff --git a/src/lib/include/gip.h b/src/lib/include/gip.h
index c2167c4..9c66091 100644
--- a/src/lib/include/gip.h
+++ b/src/lib/include/gip.h
@@ -16,7 +16,8 @@ typedef struct {
noarg_gip_callback_t
reset, initiate, ok, failure,
enable_features, disable_features,
- query_mode, set_mode, switch_buffer;
+ query_mode, set_mode, switch_buffer,
+ key_down, key_up;
void (*buffer_info)(gip_handler_t *s, gip_msg_header *m, gip_buffer_info_msg *i);
void (*mode_info)(gip_handler_t *s, gip_msg_header *m, gip_mode_info_msg *i);
void (*buffer_damage)(gip_handler_t *s, gip_msg_header *m, gip_buffer_damage_msg *i);
diff --git a/src/lib/libkogata/gip.c b/src/lib/libkogata/gip.c
index 7fa1cca..852cc05 100644
--- a/src/lib/libkogata/gip.c
+++ b/src/lib/libkogata/gip.c
@@ -167,6 +167,10 @@ void giph_msg_header(mainloop_fd_t *fd) {
mainloop_expect(fd, &h->mode_info_msg_buf, sizeof(gip_mode_info_msg), giph_mode_info);
} else if (code == GIPN_BUFFER_DAMAGE) {
mainloop_expect(fd, &h->buffer_damage_msg_buf, sizeof(gip_buffer_damage_msg), giph_buffer_damage);
+ } else if (code == GIPN_KEY_DOWN) {
+ use_cb = h->cb->key_down;
+ } else if (code == GIPN_KEY_UP) {
+ use_cb = h->cb->key_up;
} else {
use_cb = h->cb->unknown_msg;
}
diff --git a/src/lib/libkogata/mainloop.c b/src/lib/libkogata/mainloop.c
index d8890e7..e7fdfa4 100644
--- a/src/lib/libkogata/mainloop.c
+++ b/src/lib/libkogata/mainloop.c
@@ -88,12 +88,14 @@ void mainloop_run() {
}
// ---- Do the select
+ dbg_printf("(mainloop) begin select\n");
bool ok = select(sel_arg, nfds, -1);
if (!ok) {
dbg_printf("(mainloop) Failed to select.\n");
free(sel_arg);
return;
}
+ dbg_printf("(mainloop) end select\n");
{ // Parse result
int i = 0;
@@ -105,6 +107,7 @@ void mainloop_run() {
fd->rd_buf_filled +=
read(fd->fd, 0, fd->rd_buf_expect_size - fd->rd_buf_filled, fd->rd_buf + fd->rd_buf_filled);
if (fd->rd_buf_filled == fd->rd_buf_expect_size) {
+ dbg_printf("(mainloop) finish read %d\n", fd->rd_buf_expect_size);
fd->rd_buf_filled = 0;
ASSERT(fd->rd_on_full != 0);
fd->rd_on_full(fd);
@@ -116,6 +119,7 @@ void mainloop_run() {
fd->wr_bufs[0].written += write(fd->fd, 0, remain_size, write_ptr);
if (fd->wr_bufs[0].written == fd->wr_bufs[0].size) {
+ dbg_printf("(mainloop) finish write %d\n", fd->wr_bufs[0].size);
if (fd->wr_bufs[0].must_free) free(fd->wr_bufs[0].buf);
for (int i = 1; i < MAINLOOP_MAX_WR_BUFS; i++) {
fd->wr_bufs[i-1] = fd->wr_bufs[i];
diff --git a/src/sysbin/giosrv/main.c b/src/sysbin/giosrv/main.c
index c161bd6..6e3378b 100644
--- a/src/sysbin/giosrv/main.c
+++ b/src/sysbin/giosrv/main.c
@@ -39,9 +39,12 @@ gip_handler_callbacks_t giosrv_cb = {
.buffer_damage = 0,
.unknown_msg = unknown_msg,
.fd_error = fd_error,
+ .key_down = 0,
+ .key_up = 0,
};
giosrv_t srv;
+gip_handler_t *gipsrv;
// ---- KBD listener
@@ -80,11 +83,11 @@ int main(int argc, char **argv) {
dbg_printf("[giosrv] Running on FB %dx%d\n", srv.mode.width, srv.mode.height);
// ---- GIP server setup
- gip_handler_t *h = new_gip_handler(&giosrv_cb, &srv);
- ASSERT(h != 0);
+ gipsrv = new_gip_handler(&giosrv_cb, &srv);
+ ASSERT(gipsrv != 0);
- h->mainloop_item.fd = 1;
- mainloop_add_fd(&h->mainloop_item);
+ gipsrv->mainloop_item.fd = 1;
+ mainloop_add_fd(&gipsrv->mainloop_item);
// ---- Enter main loop
mainloop_run();
@@ -153,7 +156,11 @@ void fd_error(gip_handler_t *h) {
}
void kbd_handle_event(mainloop_fd_t *fd) {
- // TODO
+ gip_msg_header m;
+ m.arg = kbd.ev.scancode;
+ m.code = (kbd.ev.type == KBD_EVENT_KEYPRESS ? GIPN_KEY_DOWN : GIPN_KEY_UP);
+
+ gip_notify(gipsrv, &m, 0);
}
void kbd_on_error(mainloop_fd_t *fd) {
diff --git a/src/sysbin/login/main.c b/src/sysbin/login/main.c
index 294ad76..e6e5290 100644
--- a/src/sysbin/login/main.c
+++ b/src/sysbin/login/main.c
@@ -15,6 +15,8 @@ typedef struct {
} loginc_t;
void c_buffer_info(gip_handler_t *s, gip_msg_header *p, gip_buffer_info_msg *m);
+void c_key_down(gip_handler_t *s, gip_msg_header *p);
+void c_key_up(gip_handler_t *s, gip_msg_header *p);
void c_unknown_msg(gip_handler_t *s, gip_msg_header *p);
void c_fd_error(gip_handler_t *s);
@@ -32,6 +34,8 @@ gip_handler_callbacks_t loginc_cb = {
.buffer_info = c_buffer_info,
.mode_info = 0,
.buffer_damage = 0,
+ .key_down = c_key_down,
+ .key_up = c_key_up,
.unknown_msg = c_unknown_msg,
.fd_error = c_fd_error,
};
@@ -98,6 +102,12 @@ void c_buffer_info(gip_handler_t *s, gip_msg_header *p, gip_buffer_info_msg *m)
}
}
+void c_key_down(gip_handler_t *s, gip_msg_header *p) {
+}
+
+void c_key_up(gip_handler_t *s, gip_msg_header *p) {
+}
+
void c_unknown_msg(gip_handler_t *s, gip_msg_header *p) {
// TODO
}