diff --git a/kernel/include/utils.h b/kernel/include/utils.h index 7f41a16..14abeb3 100644 --- a/kernel/include/utils.h +++ b/kernel/include/utils.h @@ -32,6 +32,7 @@ void panic(int errno); #define ALIGN4(ptr) ALIGN(ptr, 2) #define ALIGN8(ptr) ALIGN(ptr, 3) +#define ALIGN16(ptr) ALIGN(ptr, 4) #define ALIGN4K(ptr) ALIGN(ptr, 12) #define BUMP(orig_type, bump_type, ptr) ( \ diff --git a/kernel/lib/mbox.c b/kernel/lib/mbox.c index 97ef397..a53e9a8 100644 --- a/kernel/lib/mbox.c +++ b/kernel/lib/mbox.c @@ -25,6 +25,11 @@ #include #include +#include +#include +#include +#include +#include /* mailbox message buffer */ // volatile unsigned int __attribute__((aligned(16))) mbox[36]; @@ -49,21 +54,30 @@ /** * Make a mailbox call. Returns 0 on failure, non-zero on success */ -int mbox_call(unsigned char ch, unsigned int *mbox) +int mbox_call(unsigned char ch, unsigned int *input) { - unsigned int r = (((unsigned int)((unsigned long)&mbox)&~0xF) | (ch&0xF)); + unsigned int *_mbox = kmalloc((size_t)input[0] + 0xf), *mbox = ALIGN16(_mbox); + LOG(_mbox); LOG(mbox); DEBUG((size_t)input[0]); + memcpy(mbox, input, (size_t)input[0]); + unsigned int r = (unsigned long)mbox | (unsigned int)(ch&0xf); /* wait until we can write to the mailbox */ - do{asm volatile("nop");}while(*MBOX_STATUS & MBOX_FULL); + do yield(); + while(*MBOX_STATUS & MBOX_FULL); /* write the address of our message to the mailbox with channel identifier */ *MBOX_WRITE = r; /* now wait for the response */ for (;;) { /* is there a response? */ - do{asm volatile("nop");}while(*MBOX_STATUS & MBOX_EMPTY); + do yield(); + while(*MBOX_STATUS & MBOX_EMPTY); /* is it a response to our message? */ - if(r == *MBOX_READ) + if(r == *MBOX_READ) { /* is it a valid successful response? */ - return mbox[1]==MBOX_RESPONSE; + if (mbox[1] == MBOX_RESPONSE) + memcpy(input, mbox, (size_t)input[0]); + kfree(_mbox); + return mbox[1] == MBOX_RESPONSE; + } } return 0; } diff --git a/kernel/lib/syscall.c b/kernel/lib/syscall.c index aec2ea0..7e12be5 100644 --- a/kernel/lib/syscall.c +++ b/kernel/lib/syscall.c @@ -49,10 +49,10 @@ int32_t sys_getpid(void) } size_t sys_uart_read(char buf[], size_t size) -{ return uart_getb_sync((uint8_t *)buf, size); } +{ return uart_getb((uint8_t *)buf, size); } size_t sys_uart_write(const char buf[], size_t size) -{ return uart_putb_sync((const uint8_t *)buf, size); } +{ return uart_putb((const uint8_t *)buf, size); } int32_t sys_exec(const char *name, char *const argv[]) { return run_process_by_name((uint64_t)name); /* ignore argv for now */ } diff --git a/kernel/lib/timer.c b/kernel/lib/timer.c index 0296e06..a770a6a 100644 --- a/kernel/lib/timer.c +++ b/kernel/lib/timer.c @@ -7,34 +7,8 @@ #define CORE0_TIMER_IRQ_CTRL ((volatile uint32_t *)0x40000040) -timer_t *global_timer = (timer_t *)0x0; - MMIO_W_HELPER(_enable_timer_irq, CORE0_TIMER_IRQ_CTRL, 0x1, 1); -static inline -task_t _make_timer_task(uint64_t interval_s, task_callback_func_t func, - uint64_t param) -{ - uint64_t cntpct_el0, cntfrq_el0; - R_SYSREG(cntpct_el0, cntpct_el0); - R_SYSREG(cntfrq_el0, cntfrq_el0); - - return (task_t){ - .firing_tick = cntpct_el0 + interval_s * cntfrq_el0, - .interval = interval_s * cntfrq_el0, - - .func = func, - .param = param, - }; -} - -static inline -void _scheduler_timeout(uint64_t) -{ - add_timer_task(_make_timer_task(1, _scheduler_timeout, 0x0)); - schedule(); -} - void timer_init() { uint64_t cntkctl_el1, cntfrq_el0; @@ -44,94 +18,7 @@ void timer_init() _enable_timer_irq(true); R_SYSREG(cntfrq_el0, cntfrq_el0); - W_SYSREG(cntp_tval_el0, cntfrq_el0 >> 1); - - return; - add_timer_task(_make_timer_task(1, _scheduler_timeout, 0x0)); -} - -static inline -uint32_t _d(timer_t *t) -{ return t ? t->_d : 0; } - -static inline -void _swap(timer_t **a, timer_t **b) -{ - timer_t *tmp = *a; - *a = *b, *b = tmp; -} - -static inline -timer_t *_merge(timer_t *a, timer_t *b) -{ - if (!a || !b) - return a ?: b; - - if (a->data.firing_tick > b->data.firing_tick) - _swap(&a, &b); - a->_r = _merge(a->_r, b); - - if (_d(a->_l) < _d(a->_r)) - _swap(&a->_l, &a->_r); - - a->_d = _d(a->_r) + 1; - return a; -} - -static inline -timer_t *_pop(timer_t *t) -{ - if (!t || (!t->_l && !t->_r)) { - kfree(t); - return (timer_t *)0x0; - } - return _merge(t->_l, t->_r); -} - -static inline -void _check_enable_timer() -{ - if (global_timer) { - uint64_t cntpct_el0; - R_SYSREG(cntpct_el0, cntpct_el0); - DEBUG_EXCEP(cntpct_el0); - - if (global_timer->data.firing_tick < cntpct_el0) - W_SYSREG(cntp_tval_el0, 1); - else - W_SYSREG(cntp_cval_el0, global_timer->data.firing_tick); - - W_SYSREG(cntp_ctl_el0, 1); - } else - W_SYSREG(cntp_ctl_el0, 0); -} - -static inline -void _traverse(timer_t *t) -{ - if (!t) return; - DEBUG_EXCEP(t->data.firing_tick); - t->data.func(t->data.param); - _traverse(t->_l); - _traverse(t->_r); -} - -void add_timer_task(task_t task) -{ - DEBUG_EXCEP("add timer task"); - timer_t *newtimer = kmalloc(sizeof(timer_t)); - *newtimer = (timer_t){ - ._l = (timer_t *)0x0, - ._r = (timer_t *)0x0, - ._d = 0, - - .data = task, - }; - - global_timer = _merge(global_timer, newtimer); - - // _traverse(global_timer); - _check_enable_timer(); + W_SYSREG(cntp_tval_el0, cntfrq_el0 >> 5); } void sleep(uint64_t ms) @@ -149,42 +36,10 @@ void sleep(uint64_t ms) } } -typedef struct { - interrupt_callback_func_t func; - uint64_t param; -} _timer_task_wrapper_param_t; - -static inline -void _timer_task_wrapper(uint64_t param) -{ - _timer_task_wrapper_param_t *data = (void *)param; - data->func(data->param); - kfree(data); - - _enable_timer_irq(true); -} - void timer_irq_handler(void) { - _enable_timer_irq(false); + uint64_t cntfrq_el0; + R_SYSREG(cntfrq_el0, cntfrq_el0); + W_SYSREG(cntp_tval_el0, cntfrq_el0 >> 5); schedule(); - _enable_timer_irq(true); - return; - - uint64_t cntpct_el0; - R_SYSREG(cntpct_el0, cntpct_el0); - LOG("timer irq"); DEBUG_EXCEP(cntpct_el0); - - if (global_timer) { - _timer_task_wrapper_param_t *param = - kmalloc(sizeof(_timer_task_wrapper_param_t)); - *param = (_timer_task_wrapper_param_t){ - .func = global_timer->data.func, - .param = global_timer->data.param, - }; - add_interrupt_task(20, _timer_task_wrapper, (uint64_t)param); - - global_timer = _pop(global_timer); - _check_enable_timer(); - } } diff --git a/kernel/lib/uart.c b/kernel/lib/uart.c index 3e6144b..f93502e 100644 --- a/kernel/lib/uart.c +++ b/kernel/lib/uart.c @@ -8,6 +8,7 @@ #include #include #include +#include /* Auxilary mini UART registers */ #define AUX_ENABLE ((volatile uint32_t*)(MMIO_BASE + 0x00215004)) @@ -81,8 +82,8 @@ void uart_init(void) _uart_enable_transmit_interrupt(false); // uint64_t ier = *AUX_MU_IER; - // uart_getb = uart_getb_async; - // uart_putb = uart_putb_async; + uart_getb = uart_getb_async; + uart_putb = uart_putb_async; is_uart_inited = true; } @@ -145,11 +146,12 @@ void uart_irq_handler(void) size_t uart_putb_async(const uint8_t *bytes, size_t len) { size_t sentlen = 0; - for (; sentlen < len; ++bytes, ++sentlen) - ringbuffer_push(uart_writebuf, *bytes); - - if (!is_uart_in_interrupt_queue && uart_writebuf) - _enable_uart_interrupt(); + for (; sentlen < len; ++bytes, ++sentlen) { + while(!_uart_transmitter_idle()) + yield(); + + _uart_write_data(*bytes); + } return sentlen; } @@ -171,10 +173,10 @@ size_t uart_getb_async(uint8_t *bytes, size_t len) { size_t recvlen = 0; for (; recvlen < len; ++bytes, ++recvlen) { - while (!uart_readbuf->size) - wfe(); // wait for interrupt - - *bytes = ringbuffer_bump(uart_readbuf); + while (!_uart_data_ready()) + yield(); + + *bytes = _uart_read_data(); } return recvlen; diff --git a/kernel/main.c b/kernel/main.c index 3b22926..7e32c3a 100644 --- a/kernel/main.c +++ b/kernel/main.c @@ -11,6 +11,7 @@ #include #include #include +#include static inline void _init(void *dtb)