Feat: gura!!!
This commit is contained in:
@@ -32,6 +32,7 @@ void panic(int errno);
|
|||||||
|
|
||||||
#define ALIGN4(ptr) ALIGN(ptr, 2)
|
#define ALIGN4(ptr) ALIGN(ptr, 2)
|
||||||
#define ALIGN8(ptr) ALIGN(ptr, 3)
|
#define ALIGN8(ptr) ALIGN(ptr, 3)
|
||||||
|
#define ALIGN16(ptr) ALIGN(ptr, 4)
|
||||||
#define ALIGN4K(ptr) ALIGN(ptr, 12)
|
#define ALIGN4K(ptr) ALIGN(ptr, 12)
|
||||||
|
|
||||||
#define BUMP(orig_type, bump_type, ptr) ( \
|
#define BUMP(orig_type, bump_type, ptr) ( \
|
||||||
|
|||||||
@@ -25,6 +25,11 @@
|
|||||||
|
|
||||||
#include <gpio.h>
|
#include <gpio.h>
|
||||||
#include <mbox.h>
|
#include <mbox.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <kmalloc.h>
|
||||||
|
#include <thread.h>
|
||||||
|
#include <logger.h>
|
||||||
|
#include <utils.h>
|
||||||
|
|
||||||
/* mailbox message buffer */
|
/* mailbox message buffer */
|
||||||
// volatile unsigned int __attribute__((aligned(16))) mbox[36];
|
// volatile unsigned int __attribute__((aligned(16))) mbox[36];
|
||||||
@@ -49,21 +54,30 @@
|
|||||||
/**
|
/**
|
||||||
* Make a mailbox call. Returns 0 on failure, non-zero on success
|
* 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 */
|
/* 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 */
|
/* write the address of our message to the mailbox with channel identifier */
|
||||||
*MBOX_WRITE = r;
|
*MBOX_WRITE = r;
|
||||||
/* now wait for the response */
|
/* now wait for the response */
|
||||||
for (;;) {
|
for (;;) {
|
||||||
/* is there a response? */
|
/* 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? */
|
/* is it a response to our message? */
|
||||||
if(r == *MBOX_READ)
|
if(r == *MBOX_READ) {
|
||||||
/* is it a valid successful response? */
|
/* 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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,10 +49,10 @@ int32_t sys_getpid(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
size_t sys_uart_read(char buf[], size_t size)
|
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)
|
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[])
|
int32_t sys_exec(const char *name, char *const argv[])
|
||||||
{ return run_process_by_name((uint64_t)name); /* ignore argv for now */ }
|
{ return run_process_by_name((uint64_t)name); /* ignore argv for now */ }
|
||||||
|
|||||||
@@ -7,34 +7,8 @@
|
|||||||
|
|
||||||
#define CORE0_TIMER_IRQ_CTRL ((volatile uint32_t *)0x40000040)
|
#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);
|
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()
|
void timer_init()
|
||||||
{
|
{
|
||||||
uint64_t cntkctl_el1, cntfrq_el0;
|
uint64_t cntkctl_el1, cntfrq_el0;
|
||||||
@@ -44,94 +18,7 @@ void timer_init()
|
|||||||
_enable_timer_irq(true);
|
_enable_timer_irq(true);
|
||||||
|
|
||||||
R_SYSREG(cntfrq_el0, cntfrq_el0);
|
R_SYSREG(cntfrq_el0, cntfrq_el0);
|
||||||
W_SYSREG(cntp_tval_el0, cntfrq_el0 >> 1);
|
W_SYSREG(cntp_tval_el0, cntfrq_el0 >> 5);
|
||||||
|
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void sleep(uint64_t ms)
|
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)
|
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();
|
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();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
#include <gpio.h>
|
#include <gpio.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <ringbuffer.h>
|
#include <ringbuffer.h>
|
||||||
|
#include <thread.h>
|
||||||
|
|
||||||
/* Auxilary mini UART registers */
|
/* Auxilary mini UART registers */
|
||||||
#define AUX_ENABLE ((volatile uint32_t*)(MMIO_BASE + 0x00215004))
|
#define AUX_ENABLE ((volatile uint32_t*)(MMIO_BASE + 0x00215004))
|
||||||
@@ -81,8 +82,8 @@ void uart_init(void)
|
|||||||
_uart_enable_transmit_interrupt(false);
|
_uart_enable_transmit_interrupt(false);
|
||||||
// uint64_t ier = *AUX_MU_IER;
|
// uint64_t ier = *AUX_MU_IER;
|
||||||
|
|
||||||
// uart_getb = uart_getb_async;
|
uart_getb = uart_getb_async;
|
||||||
// uart_putb = uart_putb_async;
|
uart_putb = uart_putb_async;
|
||||||
|
|
||||||
is_uart_inited = true;
|
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 uart_putb_async(const uint8_t *bytes, size_t len)
|
||||||
{
|
{
|
||||||
size_t sentlen = 0;
|
size_t sentlen = 0;
|
||||||
for (; sentlen < len; ++bytes, ++sentlen)
|
for (; sentlen < len; ++bytes, ++sentlen) {
|
||||||
ringbuffer_push(uart_writebuf, *bytes);
|
while(!_uart_transmitter_idle())
|
||||||
|
yield();
|
||||||
if (!is_uart_in_interrupt_queue && uart_writebuf)
|
|
||||||
_enable_uart_interrupt();
|
_uart_write_data(*bytes);
|
||||||
|
}
|
||||||
|
|
||||||
return sentlen;
|
return sentlen;
|
||||||
}
|
}
|
||||||
@@ -171,10 +173,10 @@ size_t uart_getb_async(uint8_t *bytes, size_t len)
|
|||||||
{
|
{
|
||||||
size_t recvlen = 0;
|
size_t recvlen = 0;
|
||||||
for (; recvlen < len; ++bytes, ++recvlen) {
|
for (; recvlen < len; ++bytes, ++recvlen) {
|
||||||
while (!uart_readbuf->size)
|
while (!_uart_data_ready())
|
||||||
wfe(); // wait for interrupt
|
yield();
|
||||||
|
|
||||||
*bytes = ringbuffer_bump(uart_readbuf);
|
*bytes = _uart_read_data();
|
||||||
}
|
}
|
||||||
|
|
||||||
return recvlen;
|
return recvlen;
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
#include <timer.h>
|
#include <timer.h>
|
||||||
#include <exception.h>
|
#include <exception.h>
|
||||||
#include <interrupt.h>
|
#include <interrupt.h>
|
||||||
|
#include <mbox.h>
|
||||||
|
|
||||||
static inline
|
static inline
|
||||||
void _init(void *dtb)
|
void _init(void *dtb)
|
||||||
|
|||||||
Reference in New Issue
Block a user