Compare commits
12 Commits
hw4
..
5ae11ac062
| Author | SHA1 | Date | |
|---|---|---|---|
|
5ae11ac062
|
|||
|
96cfdc4de2
|
|||
|
c5fc7e3102
|
|||
|
6156975775
|
|||
|
a6dc454a4c
|
|||
|
eb7b9199f6
|
|||
|
4ca4239baa
|
|||
|
ac0bf1639e
|
|||
|
bfcb951628
|
|||
|
73c9fc1423
|
|||
|
9238177ad6
|
|||
| d1f60e7c82 |
@@ -1 +1 @@
|
||||
# osc2025/ytshih
|
||||
[](https://classroom.github.com/a/lAsr-c9M)
|
||||
|
||||
+5
-5
@@ -19,7 +19,7 @@ static inline char *_logger_string(char *dest, const char *src)
|
||||
}
|
||||
static inline char *_logger_hex(char *dest, uint64_t x)
|
||||
{
|
||||
for (int n, c = 60; c >= 0; c -= 4) {
|
||||
for (int n, c = 28; c >= 0; c -= 4) {
|
||||
n = (x >> c) & 0xf;
|
||||
n += (n > 9) ? 0x37 : 0x30;
|
||||
*dest++ = (char)n;
|
||||
@@ -101,11 +101,11 @@ logger_cur = _Generic((msg), \
|
||||
// #define DEBUG_DTB(val) DEBUG(val)
|
||||
#define DEBUG_DTB(val) CLEAN
|
||||
|
||||
// #define DEBUG_EXCEP(val) DEBUG(val)
|
||||
#define DEBUG_EXCEP(val) CLEAN
|
||||
#define DEBUG_EXCEP(val) DEBUG(val)
|
||||
// #define DEBUG_EXCEP(val) CLEAN
|
||||
|
||||
#define DEBUG_MEM(val) DEBUG(val)
|
||||
// #define DEBUG_MEM(val) CLEAN
|
||||
// #define DEBUG_MEM(val) DEBUG(val)
|
||||
#define DEBUG_MEM(val) CLEAN
|
||||
|
||||
// #define DEBUG_INITRD(val) DEBUG(val)
|
||||
#define DEBUG_INITRD(val) CLEAN
|
||||
|
||||
+11
-10
@@ -2,7 +2,7 @@
|
||||
|
||||
// save general registers to stack
|
||||
.macro save_all
|
||||
sub sp, sp, 34 * 8
|
||||
sub sp, sp, 36 * 8
|
||||
stp x0, x1, [sp, 16 * 0]
|
||||
stp x2, x3, [sp, 16 * 1]
|
||||
stp x4, x5, [sp, 16 * 2]
|
||||
@@ -18,22 +18,17 @@
|
||||
stp x24, x25, [sp, 16 * 12]
|
||||
stp x26, x27, [sp, 16 * 13]
|
||||
stp x28, x29, [sp, 16 * 14]
|
||||
stp x30, lr, [sp, 16 * 15]
|
||||
|
||||
mrs x0, spsr_el1
|
||||
mrs x1, elr_el1
|
||||
mrs x2, esr_el1
|
||||
stp x0, x1, [sp, 16 * 15]
|
||||
stp x2, lr, [sp, 16 * 16]
|
||||
stp x0, x1, [sp, 16 * 16]
|
||||
str x2, [sp, 16 * 17]
|
||||
.endm
|
||||
|
||||
// load general registers from stack
|
||||
.macro load_all
|
||||
ldp x0, x1, [sp, 16 * 15]
|
||||
ldp x2, lr, [sp, 16 * 16]
|
||||
msr spsr_el1, x0
|
||||
msr elr_el1, x1
|
||||
msr esr_el1, x2
|
||||
|
||||
ldp x0, x1, [sp, 16 * 0]
|
||||
ldp x2, x3, [sp, 16 * 1]
|
||||
ldp x4, x5, [sp, 16 * 2]
|
||||
@@ -49,8 +44,14 @@
|
||||
ldp x24, x25, [sp, 16 * 12]
|
||||
ldp x26, x27, [sp, 16 * 13]
|
||||
ldp x28, x29, [sp, 16 * 14]
|
||||
ldp x30, lr, [sp, 16 * 15]
|
||||
|
||||
add sp, sp, 34 * 8
|
||||
mrs x0, spsr_el1
|
||||
mrs x1, elr_el1
|
||||
mrs x2, esr_el1
|
||||
ldp x0, x1, [sp, 16 * 16]
|
||||
ldr x2, [sp, 16 * 17]
|
||||
add sp, sp, 36 * 8
|
||||
.endm
|
||||
|
||||
_null_handler:
|
||||
|
||||
@@ -11,8 +11,6 @@ typedef struct interrupt {
|
||||
uint64_t priority;
|
||||
interrupt_callback_func_t func;
|
||||
uint64_t param;
|
||||
|
||||
int is_start;
|
||||
} interrupt_t;
|
||||
|
||||
void add_interrupt_task(uint64_t priority,
|
||||
|
||||
@@ -19,11 +19,7 @@ typedef enum :uint8_t {
|
||||
|
||||
typedef struct {
|
||||
page_state_t state;
|
||||
|
||||
// when state == PAGE_ALLOCATED or PAGE_RESERVED, size = 0
|
||||
// when state == PAGE_FREE, size = r - l
|
||||
// when state == PAGE_DIVIDED, size = LCH->size | RCH->size
|
||||
uint64_t size;
|
||||
uint64_t maxsz;
|
||||
} page_header_t;
|
||||
|
||||
void mman_init();
|
||||
|
||||
@@ -20,7 +20,7 @@ typedef struct timer {
|
||||
task_t data;
|
||||
} timer_t;
|
||||
|
||||
void add_timer_task(task_t task);
|
||||
void add_task(task_t task);
|
||||
|
||||
void timer_irq_handler(void);
|
||||
|
||||
|
||||
@@ -6,8 +6,6 @@
|
||||
uint32_t msb32(uint32_t);
|
||||
uint64_t msb64(uint64_t);
|
||||
|
||||
uint64_t lsb64(uint64_t);
|
||||
|
||||
uint32_t hton32(const uint32_t);
|
||||
uint32_t ntoh32(const uint32_t);
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ void not_implemented_handler()
|
||||
void synchronous_handler()
|
||||
{
|
||||
static int poop = 0;
|
||||
if (poop++ > 10)
|
||||
if (poop++ > 5)
|
||||
exit(ERR_ADMINKILL);
|
||||
DEBUG_EXCEP("synchronous caught");
|
||||
uint64_t x0 = 0x0;
|
||||
|
||||
+8
-17
@@ -73,27 +73,21 @@ void add_interrupt_task(uint64_t priority,
|
||||
|
||||
.priority = priority,
|
||||
.func = func,
|
||||
.param = param,
|
||||
|
||||
.is_start = false,
|
||||
.param = param
|
||||
};
|
||||
|
||||
global_interrupt_pool = _merge(global_interrupt_pool, newint);
|
||||
|
||||
while (global_interrupt_pool) {
|
||||
// LOG("check interrupt"); DEBUG_EXCEP(global_interrupt_pool->priority);
|
||||
if (global_interrupt_pool->is_start)
|
||||
return;
|
||||
global_interrupt_pool->is_start = true;
|
||||
global_interrupt_pool->func(global_interrupt_pool->param);
|
||||
global_interrupt_pool = _pop(global_interrupt_pool);
|
||||
}
|
||||
}
|
||||
|
||||
void init_interrupt(void)
|
||||
{
|
||||
_enable_interrupt();
|
||||
uint64_t cntfrq_el0;
|
||||
W_SYSREG(cntp_ctl_el0, 1);
|
||||
R_SYSREG(cntfrq_el0, cntfrq_el0);
|
||||
W_SYSREG(cntp_tval_el0, cntfrq_el0);
|
||||
|
||||
_enable_timer_irq(true);
|
||||
_enable_interrupt();
|
||||
}
|
||||
|
||||
void irq_handler(void)
|
||||
@@ -110,11 +104,8 @@ void irq_handler(void)
|
||||
|
||||
void wfe(void)
|
||||
{
|
||||
return; // do nothing for now
|
||||
|
||||
if (!global_interrupt_pool) {
|
||||
// asm volatile("wfe");
|
||||
asm volatile("nop");
|
||||
asm volatile("wfe");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#include <logger.h>
|
||||
#include <uart.h>
|
||||
#include <errcode.h>
|
||||
#include <utils.h>
|
||||
#include <kmalloc.h>
|
||||
|
||||
+18
-35
@@ -47,24 +47,23 @@ void _pull(int idx, size_t sz)
|
||||
{
|
||||
if (LCH->state == PAGE_FREE && RCH->state == PAGE_FREE) {
|
||||
if (CUR->state != PAGE_FREE) {
|
||||
LOG("free page merged");
|
||||
LOG("node merged");
|
||||
DEBUG_MEM((uint64_t)idx);
|
||||
}
|
||||
CUR->state = PAGE_FREE;
|
||||
CUR->size = sz;
|
||||
}
|
||||
if (LCH->state != PAGE_FREE || RCH->state != PAGE_FREE)
|
||||
CUR->state = PAGE_DIVIDED;
|
||||
switch (CUR->state) {
|
||||
case PAGE_FREE:
|
||||
CUR->size = sz;
|
||||
CUR->maxsz = sz;
|
||||
break;
|
||||
case PAGE_DIVIDED:
|
||||
CUR->size = LCH->size | RCH->size;
|
||||
CUR->maxsz = MAX(LCH->maxsz, RCH->maxsz);
|
||||
break;
|
||||
case PAGE_ALLOCATED:
|
||||
case PAGE_RESERVED:
|
||||
CUR->size = 0;
|
||||
CUR->maxsz = 0;
|
||||
break;
|
||||
default:
|
||||
exit(ERR_UNREACHABLE);
|
||||
@@ -86,7 +85,7 @@ void mman_init()
|
||||
|
||||
mman_frame_array[0] = (page_header_t){
|
||||
.state = PAGE_FREE,
|
||||
.size = mman_page_cnt,
|
||||
.maxsz = msb64(mman_page_cnt),
|
||||
};
|
||||
|
||||
fdt_reserve_entry_t *entry = 0x0;
|
||||
@@ -110,7 +109,7 @@ static inline
|
||||
uint64_t _allocate_page(size_t req, int idx, uint64_t l, uint64_t r)
|
||||
{
|
||||
uint64_t sz = r - l;
|
||||
if (req > sz || req > CUR->size) {
|
||||
if (req > sz || req > CUR->maxsz) {
|
||||
return MMAN_NO_PAGE;
|
||||
}
|
||||
|
||||
@@ -118,15 +117,16 @@ uint64_t _allocate_page(size_t req, int idx, uint64_t l, uint64_t r)
|
||||
switch (CUR->state) {
|
||||
case PAGE_FREE:
|
||||
if (req == sz) {
|
||||
LOG("page allocated"); LOG(l); DEBUG_MEM(r);
|
||||
LOG("page allocated");
|
||||
LOG(l);
|
||||
DEBUG_MEM(r);
|
||||
CUR->state = PAGE_ALLOCATED;
|
||||
CUR->size = 0;
|
||||
CUR->maxsz = 0;
|
||||
return l;
|
||||
}
|
||||
LOG("page divided"); LOG(l); DEBUG_MEM(r);
|
||||
LCH->state = RCH->state = PAGE_FREE;
|
||||
LCH->size = m - l;
|
||||
RCH->size = r - m;
|
||||
LCH->maxsz = msb64(m - l);
|
||||
RCH->maxsz = msb64(r - m);
|
||||
break;
|
||||
case PAGE_DIVIDED:
|
||||
break;
|
||||
@@ -138,25 +138,10 @@ uint64_t _allocate_page(size_t req, int idx, uint64_t l, uint64_t r)
|
||||
}
|
||||
|
||||
uint64_t ret = MMAN_NO_PAGE;
|
||||
|
||||
// Goto child where size >= req
|
||||
// If both children can handle, choose the one that has the least significant
|
||||
// bit that can handle.
|
||||
// It both children are the same, choose the left one
|
||||
int is_lch_valid = (LCH->size >= req);
|
||||
int is_rch_valid = (RCH->size >= req);
|
||||
if (is_lch_valid && is_rch_valid) {
|
||||
if (lsb64(LCH->size & ~(req - 1)) <= lsb64(RCH->size & ~(req - 1)))
|
||||
ret = _allocate_page(req, LIDX, l, m);
|
||||
else
|
||||
ret = _allocate_page(req, RIDX, m, r);
|
||||
}
|
||||
|
||||
if (ret == MMAN_NO_PAGE && LCH->size >= req)
|
||||
if (ret == MMAN_NO_PAGE && LCH->maxsz >= req)
|
||||
ret = _allocate_page(req, LIDX, l, m);
|
||||
if (ret == MMAN_NO_PAGE && RCH->size >= req)
|
||||
if (ret == MMAN_NO_PAGE && RCH->maxsz >= req)
|
||||
ret = _allocate_page(req, RIDX, m, r);
|
||||
|
||||
_pull(idx, sz);
|
||||
return ret;
|
||||
}
|
||||
@@ -189,7 +174,7 @@ void _free_page(uint64_t req, int idx, uint64_t l, uint64_t r)
|
||||
LOG(l);
|
||||
DEBUG_MEM(r);
|
||||
CUR->state = PAGE_FREE;
|
||||
CUR->size = sz;
|
||||
CUR->maxsz = sz;
|
||||
return;
|
||||
}
|
||||
case PAGE_DIVIDED:
|
||||
@@ -233,17 +218,15 @@ void _reserve_page(uint64_t ql, uint64_t qr, int idx, uint64_t l, uint64_t r)
|
||||
LOG(l);
|
||||
DEBUG_MEM(r);
|
||||
CUR->state = PAGE_RESERVED;
|
||||
CUR->size = 0;
|
||||
CUR->maxsz = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
uint64_t m = l + ((msb64(sz) == sz) ? (sz >> 1) : msb64(sz));
|
||||
if (CUR->state == PAGE_FREE) {
|
||||
LOG("page divided"); LOG(l); DEBUG_MEM(r);
|
||||
CUR->state = PAGE_DIVIDED;
|
||||
LCH->state = RCH->state = PAGE_FREE;
|
||||
LCH->size = m - l;
|
||||
RCH->size = r - m;
|
||||
LCH->maxsz = msb64(m - l);
|
||||
RCH->maxsz = msb64(r - m);
|
||||
}
|
||||
|
||||
if (ql < m)
|
||||
|
||||
+2
-10
@@ -24,11 +24,11 @@ int ringbuffer_push(ringbuffer_t *buf, uint8_t val)
|
||||
return ERR_OUT_OF_BOUND;
|
||||
|
||||
*buf->write++ = val;
|
||||
++buf->size;
|
||||
|
||||
if (buf->write == buf->data + buf->cap)
|
||||
buf->write = buf->data;
|
||||
|
||||
++buf->size;
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
@@ -38,18 +38,10 @@ uint8_t ringbuffer_bump(ringbuffer_t *buf)
|
||||
exit(ERR_INVALID_OP);
|
||||
|
||||
uint8_t ret = *buf->read++;
|
||||
--buf->size;
|
||||
|
||||
if (buf->read == buf->data + buf->cap)
|
||||
buf->read = buf->data;
|
||||
|
||||
--buf->size;
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint8_t ringbuffer_peek(ringbuffer_t *buf)
|
||||
{
|
||||
if (buf->size == 0)
|
||||
exit(ERR_INVALID_OP);
|
||||
|
||||
return *buf->read;
|
||||
}
|
||||
|
||||
+7
-58
@@ -30,7 +30,6 @@ void _help (void)
|
||||
"cat <file> : concatenate files and print" ENDL
|
||||
"exec <file> : execute file in usermode" ENDL
|
||||
"settimeout <sec> <message...>: pring message after a few seconds" ENDL
|
||||
"time : print current time tick" ENDL
|
||||
"reboot : reboot the device" ENDL
|
||||
);
|
||||
}
|
||||
@@ -75,14 +74,6 @@ void _memalloc(size_t size)
|
||||
uart_puts(ENDL);
|
||||
}
|
||||
|
||||
static inline
|
||||
void _free(uint64_t ptr)
|
||||
{
|
||||
kfree((void *)ptr);
|
||||
LOG(ptr);
|
||||
INFOR("has been freed");
|
||||
}
|
||||
|
||||
static inline
|
||||
void _ls_initrd_callback(file_node_t *tr)
|
||||
{
|
||||
@@ -125,7 +116,6 @@ static inline
|
||||
void _settimeout_cb_func(uint64_t args)
|
||||
{
|
||||
vector_t *v = (void *)args;
|
||||
uart_puts("timeout: ");
|
||||
for (int i = 2; i < (int)v->size; ++i) {
|
||||
uart_puts(VEC_AT(char, v, i));
|
||||
uart_puts(" ");
|
||||
@@ -148,22 +138,7 @@ void _settimeout(int32_t sec, vector_t *args)
|
||||
.func = _settimeout_cb_func,
|
||||
.param = (uint64_t)args,
|
||||
};
|
||||
add_timer_task(task);
|
||||
}
|
||||
|
||||
static inline
|
||||
void _time()
|
||||
{
|
||||
uint64_t cntpct_el0, cntfrq_el0, cntp_cval_el0, cntp_tval_el0;
|
||||
R_SYSREG(cntpct_el0, cntpct_el0);
|
||||
R_SYSREG(cntfrq_el0, cntfrq_el0);
|
||||
R_SYSREG(cntp_cval_el0, cntp_cval_el0);
|
||||
R_SYSREG(cntp_tval_el0, cntp_tval_el0);
|
||||
|
||||
LOG(cntpct_el0);
|
||||
LOG(cntfrq_el0);
|
||||
LOG(cntp_cval_el0);
|
||||
INFOR(cntp_tval_el0);
|
||||
add_task(task);
|
||||
}
|
||||
|
||||
static inline
|
||||
@@ -184,41 +159,20 @@ void _reboot(void)
|
||||
_reset(1 << 16);
|
||||
}
|
||||
|
||||
char *_shell_buf = (char *)0x0;
|
||||
int _shell_sz = 0;
|
||||
|
||||
static inline
|
||||
int _shell_operations(char ch)
|
||||
{
|
||||
switch (ch) {
|
||||
case 0x7f:
|
||||
if (_shell_sz > 0) {
|
||||
--_shell_sz;
|
||||
uart_puts("\b \b");
|
||||
}
|
||||
return true;
|
||||
default:
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int shell(file_node_t *initrd_root)
|
||||
{
|
||||
uart_puts("# ");
|
||||
char ch;
|
||||
_shell_buf = kmalloc(INPUT_BUFLEN * sizeof(char));
|
||||
_shell_sz = 0;
|
||||
char *buf = kmalloc(INPUT_BUFLEN * sizeof(char)), ch;
|
||||
int sz = 0;
|
||||
while ((ch = uart_getc()) != '\n') {
|
||||
if (_shell_operations(ch))
|
||||
continue;
|
||||
_shell_buf[_shell_sz++] = ch;
|
||||
buf[sz++] = ch;
|
||||
uart_putb((const uint8_t *)&ch, 1);
|
||||
}
|
||||
uart_puts(ENDL);
|
||||
_shell_buf[_shell_sz] = ' ';
|
||||
buf[sz] = ' ';
|
||||
|
||||
vector_t *args = make_vector(0);
|
||||
for (char *saveptr = 0x0, *tok = strtok_r(_shell_buf, " ", &saveptr);
|
||||
for (char *saveptr = 0x0, *tok = strtok_r(buf, " ", &saveptr);
|
||||
tok; tok = strtok_r((char *)0x0, " ", &saveptr)) {
|
||||
VEC_PUSH(args, tok);
|
||||
LOG(tok);
|
||||
@@ -234,12 +188,9 @@ int shell(file_node_t *initrd_root)
|
||||
_hello();
|
||||
} else if (!strcmp(cmd, "hwinfo")) {
|
||||
_hwinfo();
|
||||
} else if (!strcmp(cmd, "memalloc") && args->size >= 2) {
|
||||
} else if (!strcmp(cmd, "memalloc") && args->size >= 2){
|
||||
char *p1 = VEC_AT(char, args, 1);
|
||||
_memalloc((size_t)atoi32(p1));
|
||||
} else if (!strcmp(cmd, "free") && args->size >= 2) {
|
||||
char *p1 = VEC_AT(char, args, 1);
|
||||
_free((uint64_t)atoh32(p1));
|
||||
} else if (!strcmp(cmd, "ls")) {
|
||||
_ls(initrd_root);
|
||||
} else if (!strcmp(cmd, "cat") && args->size >= 2) {
|
||||
@@ -251,8 +202,6 @@ int shell(file_node_t *initrd_root)
|
||||
} else if (!strcmp(cmd, "settimeout") && args->size >= 2) {
|
||||
char *p1 = VEC_AT(char, args, 1);
|
||||
_settimeout(atoi32(p1), args);
|
||||
} else if (!strcmp(cmd, "time")) {
|
||||
_time();
|
||||
} else if (!strcmp(cmd, "reboot")) {
|
||||
_reboot();
|
||||
}
|
||||
|
||||
+14
-48
@@ -47,36 +47,23 @@ timer_t *_pop(timer_t *t)
|
||||
}
|
||||
|
||||
static inline
|
||||
void _check_enable_timer()
|
||||
void _set_timer_interrrupt()
|
||||
{
|
||||
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);
|
||||
uint64_t firing_tick = MAX(global_timer->data.firing_tick, cntpct_el0);
|
||||
W_SYSREG(cntp_cval_el0, firing_tick);
|
||||
|
||||
W_SYSREG(cntp_ctl_el0, 1);
|
||||
} else
|
||||
W_SYSREG(cntp_ctl_el0, 0);
|
||||
_enable_timer_irq(true);
|
||||
}
|
||||
}
|
||||
|
||||
static inline
|
||||
void _traverse(timer_t *t)
|
||||
void add_task(task_t task)
|
||||
{
|
||||
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");
|
||||
DEBUG_EXCEP("add task");
|
||||
timer_t *newtimer = kmalloc(sizeof(timer_t));
|
||||
*newtimer = (timer_t){
|
||||
._l = (timer_t *)0x0,
|
||||
@@ -87,44 +74,23 @@ void add_timer_task(task_t task)
|
||||
};
|
||||
|
||||
global_timer = _merge(global_timer, newtimer);
|
||||
|
||||
// _traverse(global_timer);
|
||||
_check_enable_timer();
|
||||
}
|
||||
|
||||
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);
|
||||
_set_timer_interrrupt();
|
||||
}
|
||||
|
||||
void timer_irq_handler(void)
|
||||
{
|
||||
_enable_timer_irq(false);
|
||||
|
||||
LOG("timer irq");
|
||||
|
||||
uint64_t cntpct_el0;
|
||||
R_SYSREG(cntpct_el0, cntpct_el0);
|
||||
LOG("timer irq"); DEBUG_EXCEP(cntpct_el0);
|
||||
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);
|
||||
|
||||
add_interrupt_task(20, global_timer->data.func, global_timer->data.param);
|
||||
global_timer = _pop(global_timer);
|
||||
_check_enable_timer();
|
||||
}
|
||||
|
||||
_set_timer_interrrupt();
|
||||
}
|
||||
|
||||
+33
-42
@@ -29,8 +29,6 @@ size_t (*uart_putb)(const uint8_t *bytes, size_t len) = uart_putb_sync;
|
||||
size_t (*uart_getb)(uint8_t *bytes, size_t len) = uart_getb_sync;
|
||||
int is_uart_inited = false;
|
||||
|
||||
int is_uart_in_interrupt_queue = false;
|
||||
|
||||
ringbuffer_t *uart_readbuf;
|
||||
ringbuffer_t *uart_writebuf;
|
||||
|
||||
@@ -85,47 +83,37 @@ void uart_init(void)
|
||||
is_uart_inited = true;
|
||||
}
|
||||
|
||||
static inline
|
||||
void _enable_uart_interrupt()
|
||||
void uart_transmit_interrupt_handler()
|
||||
{
|
||||
_uart_enable_receive_interrupt(true);
|
||||
if (uart_writebuf->size > 0)
|
||||
_uart_enable_transmit_interrupt(true);
|
||||
_uart_write_data(ringbuffer_bump(uart_writebuf));
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
ringbuffer_t *buf;
|
||||
uint8_t val;
|
||||
} uart_interrupt_callback_payload_t;
|
||||
|
||||
static inline
|
||||
void _uart_transmit_interrupt_callback(uint64_t)
|
||||
void uart_receive_interrupt_callback(uint64_t param)
|
||||
{
|
||||
_uart_write_data(ringbuffer_bump(uart_writebuf));
|
||||
|
||||
is_uart_in_interrupt_queue = false;
|
||||
_enable_uart_interrupt();
|
||||
uart_interrupt_callback_payload_t *payload = (void *)param;
|
||||
ringbuffer_push(payload->buf, payload->val);
|
||||
kfree(payload);
|
||||
}
|
||||
|
||||
static inline
|
||||
void _uart_transmit_interrupt_handler()
|
||||
{
|
||||
if (uart_writebuf->size > 0) {
|
||||
is_uart_in_interrupt_queue = true;
|
||||
add_interrupt_task(11, _uart_transmit_interrupt_callback, 0x0);
|
||||
}
|
||||
}
|
||||
|
||||
static inline
|
||||
void _uart_receive_interrupt_callback(uint64_t)
|
||||
{
|
||||
ringbuffer_push(uart_readbuf, _uart_read_data());
|
||||
|
||||
is_uart_in_interrupt_queue = false;
|
||||
_enable_uart_interrupt();
|
||||
}
|
||||
|
||||
static inline
|
||||
void _uart_receive_interrupt_handler()
|
||||
void uart_receive_interrupt_handler()
|
||||
{
|
||||
if (uart_readbuf->size < uart_readbuf->cap) {
|
||||
is_uart_in_interrupt_queue = true;
|
||||
add_interrupt_task(12, _uart_receive_interrupt_callback, 0x0);
|
||||
uint8_t b = _uart_read_data();
|
||||
|
||||
uart_interrupt_callback_payload_t *param = kmalloc(
|
||||
sizeof(uart_interrupt_callback_payload_t));
|
||||
*param = (uart_interrupt_callback_payload_t){
|
||||
.buf = uart_readbuf,
|
||||
.val = b,
|
||||
};
|
||||
add_interrupt_task(10, uart_receive_interrupt_callback, (uint64_t)param);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -133,11 +121,14 @@ void uart_irq_handler(void)
|
||||
{
|
||||
_uart_enable_receive_interrupt(false);
|
||||
_uart_enable_transmit_interrupt(false);
|
||||
|
||||
if (_uart_receive_interrupt())
|
||||
_uart_receive_interrupt_handler();
|
||||
uart_receive_interrupt_handler();
|
||||
if (_uart_transmit_interrupt())
|
||||
_uart_transmit_interrupt_handler();
|
||||
uart_transmit_interrupt_handler();
|
||||
|
||||
_uart_enable_receive_interrupt(true);
|
||||
if (uart_writebuf->size > 0)
|
||||
_uart_enable_transmit_interrupt(true);
|
||||
}
|
||||
|
||||
size_t uart_putb_async(const uint8_t *bytes, size_t len)
|
||||
@@ -146,8 +137,8 @@ size_t uart_putb_async(const uint8_t *bytes, size_t len)
|
||||
for (; sentlen < len; ++bytes, ++sentlen)
|
||||
ringbuffer_push(uart_writebuf, *bytes);
|
||||
|
||||
if (!is_uart_in_interrupt_queue && uart_writebuf)
|
||||
_enable_uart_interrupt();
|
||||
if (uart_writebuf->size > 0)
|
||||
_uart_enable_transmit_interrupt(true);
|
||||
|
||||
return sentlen;
|
||||
}
|
||||
@@ -171,7 +162,6 @@ size_t uart_getb_async(uint8_t *bytes, size_t len)
|
||||
for (; recvlen < len; ++bytes, ++recvlen) {
|
||||
while (!uart_readbuf->size)
|
||||
wfe(); // wait for interrupt
|
||||
|
||||
*bytes = ringbuffer_bump(uart_readbuf);
|
||||
}
|
||||
|
||||
@@ -209,10 +199,11 @@ void uart_puts(const char *s)
|
||||
void uart_hex(uint64_t d)
|
||||
{
|
||||
char buf[0x11], *p = buf;
|
||||
for (int c = 28, n; c >= 0; c -= 4) {
|
||||
uint64_t n;
|
||||
for (int c = 28; c >= 0; c -= 4) {
|
||||
n = (d >> c) & 0xf;
|
||||
n += (n > 9) ? 0x37 : 0x30;
|
||||
*p++ = (char)n;
|
||||
n += n > 9 ? (char)'A' : (char)'0';
|
||||
*p++ = n;
|
||||
}
|
||||
*p = '\0';
|
||||
uart_puts(buf);
|
||||
|
||||
+1
-14
@@ -24,19 +24,6 @@ uint64_t msb64(uint64_t x)
|
||||
return res == 64 ? 0 : ((uint64_t)1 << (63 - res));
|
||||
}
|
||||
|
||||
uint64_t lsb64(uint64_t x)
|
||||
{
|
||||
uint64_t res = 0x0;
|
||||
asm volatile(
|
||||
"rbit x0, %[val]" ENDL
|
||||
"clz %[res], x0"
|
||||
: [res] "=r" (res)
|
||||
: [val] "r" (x)
|
||||
: "x0"
|
||||
);
|
||||
return res == 64 ? 0 : ((uint64_t)1 << res);
|
||||
}
|
||||
|
||||
uint32_t hton32(const uint32_t h)
|
||||
{
|
||||
const uint8_t *p = (const void *)&h;
|
||||
@@ -119,7 +106,7 @@ uint32_t atoh32(const char *s)
|
||||
exit(ERR_CONVERSION);
|
||||
|
||||
uint32_t ret = 0;
|
||||
for (int i = 8; i-- && *s != '\0'; ++s) {
|
||||
for (int i = 8; i--; ++s) {
|
||||
if (!isxdigit(*s))
|
||||
exit(ERR_CONVERSION);
|
||||
ret <<= 4, ret |= (isdigit(*s) ? *s - '0' :
|
||||
|
||||
+4
-5
@@ -14,6 +14,7 @@
|
||||
void init(void *dtb, file_node_t **initrd_root)
|
||||
{
|
||||
init_exception();
|
||||
init_interrupt();
|
||||
|
||||
// UART
|
||||
uart_init();
|
||||
@@ -33,8 +34,6 @@ void init(void *dtb, file_node_t **initrd_root)
|
||||
|
||||
// Memory (Buddy system)
|
||||
mman_init();
|
||||
|
||||
init_interrupt();
|
||||
}
|
||||
|
||||
static inline
|
||||
@@ -54,7 +53,7 @@ void _print_time(uint64_t)
|
||||
.param = 0x0,
|
||||
};
|
||||
|
||||
add_timer_task(task);
|
||||
add_task(task);
|
||||
}
|
||||
|
||||
void main(void *dtb)
|
||||
@@ -62,8 +61,8 @@ void main(void *dtb)
|
||||
file_node_t *initrd_root = 0x0;
|
||||
init(dtb, &initrd_root);
|
||||
|
||||
// LOG("system booting in");
|
||||
// _print_time(0x0);
|
||||
LOG("system booting in");
|
||||
_print_time(0x0);
|
||||
|
||||
uint64_t el;
|
||||
R_SYSREG(el, CurrentEL);
|
||||
|
||||
Reference in New Issue
Block a user