Fix: mman behavior
This commit is contained in:
@@ -101,11 +101,11 @@ logger_cur = _Generic((msg), \
|
|||||||
// #define DEBUG_DTB(val) DEBUG(val)
|
// #define DEBUG_DTB(val) DEBUG(val)
|
||||||
#define DEBUG_DTB(val) CLEAN
|
#define DEBUG_DTB(val) CLEAN
|
||||||
|
|
||||||
#define DEBUG_EXCEP(val) DEBUG(val)
|
// #define DEBUG_EXCEP(val) DEBUG(val)
|
||||||
// #define DEBUG_EXCEP(val) CLEAN
|
#define DEBUG_EXCEP(val) CLEAN
|
||||||
|
|
||||||
// #define DEBUG_MEM(val) DEBUG(val)
|
#define DEBUG_MEM(val) DEBUG(val)
|
||||||
#define DEBUG_MEM(val) CLEAN
|
// #define DEBUG_MEM(val) CLEAN
|
||||||
|
|
||||||
// #define DEBUG_INITRD(val) DEBUG(val)
|
// #define DEBUG_INITRD(val) DEBUG(val)
|
||||||
#define DEBUG_INITRD(val) CLEAN
|
#define DEBUG_INITRD(val) CLEAN
|
||||||
|
|||||||
@@ -19,7 +19,11 @@ typedef enum :uint8_t {
|
|||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
page_state_t state;
|
page_state_t state;
|
||||||
uint64_t maxsz;
|
|
||||||
|
// 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;
|
||||||
} page_header_t;
|
} page_header_t;
|
||||||
|
|
||||||
void mman_init();
|
void mman_init();
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ typedef struct timer {
|
|||||||
task_t data;
|
task_t data;
|
||||||
} timer_t;
|
} timer_t;
|
||||||
|
|
||||||
void add_task(task_t task);
|
void add_timer_task(task_t task);
|
||||||
|
|
||||||
void timer_irq_handler(void);
|
void timer_irq_handler(void);
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,8 @@
|
|||||||
uint32_t msb32(uint32_t);
|
uint32_t msb32(uint32_t);
|
||||||
uint64_t msb64(uint64_t);
|
uint64_t msb64(uint64_t);
|
||||||
|
|
||||||
|
uint64_t lsb64(uint64_t);
|
||||||
|
|
||||||
uint32_t hton32(const uint32_t);
|
uint32_t hton32(const uint32_t);
|
||||||
uint32_t ntoh32(const uint32_t);
|
uint32_t ntoh32(const uint32_t);
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ void not_implemented_handler()
|
|||||||
void synchronous_handler()
|
void synchronous_handler()
|
||||||
{
|
{
|
||||||
static int poop = 0;
|
static int poop = 0;
|
||||||
if (poop++ > 5)
|
if (poop++ > 10)
|
||||||
exit(ERR_ADMINKILL);
|
exit(ERR_ADMINKILL);
|
||||||
DEBUG_EXCEP("synchronous caught");
|
DEBUG_EXCEP("synchronous caught");
|
||||||
uint64_t x0 = 0x0;
|
uint64_t x0 = 0x0;
|
||||||
|
|||||||
@@ -81,12 +81,7 @@ void add_interrupt_task(uint64_t priority,
|
|||||||
|
|
||||||
void init_interrupt(void)
|
void init_interrupt(void)
|
||||||
{
|
{
|
||||||
uint64_t cntfrq_el0;
|
|
||||||
W_SYSREG(cntp_ctl_el0, 1);
|
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();
|
_enable_interrupt();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
#include <uart.h>
|
#include <uart.h>
|
||||||
|
#include <logger.h>
|
||||||
#include <errcode.h>
|
#include <errcode.h>
|
||||||
#include <utils.h>
|
#include <utils.h>
|
||||||
#include <kmalloc.h>
|
#include <kmalloc.h>
|
||||||
|
|||||||
@@ -56,14 +56,14 @@ void _pull(int idx, size_t sz)
|
|||||||
CUR->state = PAGE_DIVIDED;
|
CUR->state = PAGE_DIVIDED;
|
||||||
switch (CUR->state) {
|
switch (CUR->state) {
|
||||||
case PAGE_FREE:
|
case PAGE_FREE:
|
||||||
CUR->maxsz = sz;
|
CUR->size = sz;
|
||||||
break;
|
break;
|
||||||
case PAGE_DIVIDED:
|
case PAGE_DIVIDED:
|
||||||
CUR->maxsz = MAX(LCH->maxsz, RCH->maxsz);
|
CUR->size = LCH->size | RCH->size;
|
||||||
break;
|
break;
|
||||||
case PAGE_ALLOCATED:
|
case PAGE_ALLOCATED:
|
||||||
case PAGE_RESERVED:
|
case PAGE_RESERVED:
|
||||||
CUR->maxsz = 0;
|
CUR->size = 0;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
exit(ERR_UNREACHABLE);
|
exit(ERR_UNREACHABLE);
|
||||||
@@ -85,7 +85,7 @@ void mman_init()
|
|||||||
|
|
||||||
mman_frame_array[0] = (page_header_t){
|
mman_frame_array[0] = (page_header_t){
|
||||||
.state = PAGE_FREE,
|
.state = PAGE_FREE,
|
||||||
.maxsz = msb64(mman_page_cnt),
|
.size = mman_page_cnt,
|
||||||
};
|
};
|
||||||
|
|
||||||
fdt_reserve_entry_t *entry = 0x0;
|
fdt_reserve_entry_t *entry = 0x0;
|
||||||
@@ -109,7 +109,7 @@ static inline
|
|||||||
uint64_t _allocate_page(size_t req, int idx, uint64_t l, uint64_t r)
|
uint64_t _allocate_page(size_t req, int idx, uint64_t l, uint64_t r)
|
||||||
{
|
{
|
||||||
uint64_t sz = r - l;
|
uint64_t sz = r - l;
|
||||||
if (req > sz || req > CUR->maxsz) {
|
if (req > sz || req > CUR->size) {
|
||||||
return MMAN_NO_PAGE;
|
return MMAN_NO_PAGE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -121,12 +121,12 @@ uint64_t _allocate_page(size_t req, int idx, uint64_t l, uint64_t r)
|
|||||||
LOG(l);
|
LOG(l);
|
||||||
DEBUG_MEM(r);
|
DEBUG_MEM(r);
|
||||||
CUR->state = PAGE_ALLOCATED;
|
CUR->state = PAGE_ALLOCATED;
|
||||||
CUR->maxsz = 0;
|
CUR->size = 0;
|
||||||
return l;
|
return l;
|
||||||
}
|
}
|
||||||
LCH->state = RCH->state = PAGE_FREE;
|
LCH->state = RCH->state = PAGE_FREE;
|
||||||
LCH->maxsz = msb64(m - l);
|
LCH->size = m - l;
|
||||||
RCH->maxsz = msb64(r - m);
|
RCH->size = r - m;
|
||||||
break;
|
break;
|
||||||
case PAGE_DIVIDED:
|
case PAGE_DIVIDED:
|
||||||
break;
|
break;
|
||||||
@@ -138,10 +138,25 @@ uint64_t _allocate_page(size_t req, int idx, uint64_t l, uint64_t r)
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint64_t ret = MMAN_NO_PAGE;
|
uint64_t ret = MMAN_NO_PAGE;
|
||||||
if (ret == MMAN_NO_PAGE && LCH->maxsz >= req)
|
|
||||||
|
// 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)
|
||||||
ret = _allocate_page(req, LIDX, l, m);
|
ret = _allocate_page(req, LIDX, l, m);
|
||||||
if (ret == MMAN_NO_PAGE && RCH->maxsz >= req)
|
if (ret == MMAN_NO_PAGE && RCH->size >= req)
|
||||||
ret = _allocate_page(req, RIDX, m, r);
|
ret = _allocate_page(req, RIDX, m, r);
|
||||||
|
|
||||||
_pull(idx, sz);
|
_pull(idx, sz);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -174,7 +189,7 @@ void _free_page(uint64_t req, int idx, uint64_t l, uint64_t r)
|
|||||||
LOG(l);
|
LOG(l);
|
||||||
DEBUG_MEM(r);
|
DEBUG_MEM(r);
|
||||||
CUR->state = PAGE_FREE;
|
CUR->state = PAGE_FREE;
|
||||||
CUR->maxsz = sz;
|
CUR->size = sz;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
case PAGE_DIVIDED:
|
case PAGE_DIVIDED:
|
||||||
@@ -218,15 +233,15 @@ void _reserve_page(uint64_t ql, uint64_t qr, int idx, uint64_t l, uint64_t r)
|
|||||||
LOG(l);
|
LOG(l);
|
||||||
DEBUG_MEM(r);
|
DEBUG_MEM(r);
|
||||||
CUR->state = PAGE_RESERVED;
|
CUR->state = PAGE_RESERVED;
|
||||||
CUR->maxsz = 0;
|
CUR->size = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t m = l + ((msb64(sz) == sz) ? (sz >> 1) : msb64(sz));
|
uint64_t m = l + ((msb64(sz) == sz) ? (sz >> 1) : msb64(sz));
|
||||||
if (CUR->state == PAGE_FREE) {
|
if (CUR->state == PAGE_FREE) {
|
||||||
LCH->state = RCH->state = PAGE_FREE;
|
LCH->state = RCH->state = PAGE_FREE;
|
||||||
LCH->maxsz = msb64(m - l);
|
LCH->size = m - l;
|
||||||
RCH->maxsz = msb64(r - m);
|
RCH->size = r - m;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ql < m)
|
if (ql < m)
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ void _help (void)
|
|||||||
"cat <file> : concatenate files and print" ENDL
|
"cat <file> : concatenate files and print" ENDL
|
||||||
"exec <file> : execute file in usermode" ENDL
|
"exec <file> : execute file in usermode" ENDL
|
||||||
"settimeout <sec> <message...>: pring message after a few seconds" ENDL
|
"settimeout <sec> <message...>: pring message after a few seconds" ENDL
|
||||||
|
"time : print current time tick" ENDL
|
||||||
"reboot : reboot the device" ENDL
|
"reboot : reboot the device" ENDL
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -74,6 +75,14 @@ void _memalloc(size_t size)
|
|||||||
uart_puts(ENDL);
|
uart_puts(ENDL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline
|
||||||
|
void _free(uint64_t ptr)
|
||||||
|
{
|
||||||
|
kfree((void *)ptr);
|
||||||
|
LOG(ptr);
|
||||||
|
INFOR("has been freed");
|
||||||
|
}
|
||||||
|
|
||||||
static inline
|
static inline
|
||||||
void _ls_initrd_callback(file_node_t *tr)
|
void _ls_initrd_callback(file_node_t *tr)
|
||||||
{
|
{
|
||||||
@@ -138,7 +147,22 @@ void _settimeout(int32_t sec, vector_t *args)
|
|||||||
.func = _settimeout_cb_func,
|
.func = _settimeout_cb_func,
|
||||||
.param = (uint64_t)args,
|
.param = (uint64_t)args,
|
||||||
};
|
};
|
||||||
add_task(task);
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline
|
static inline
|
||||||
@@ -209,9 +233,12 @@ int shell(file_node_t *initrd_root)
|
|||||||
_hello();
|
_hello();
|
||||||
} else if (!strcmp(cmd, "hwinfo")) {
|
} else if (!strcmp(cmd, "hwinfo")) {
|
||||||
_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);
|
char *p1 = VEC_AT(char, args, 1);
|
||||||
_memalloc((size_t)atoi32(p1));
|
_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")) {
|
} else if (!strcmp(cmd, "ls")) {
|
||||||
_ls(initrd_root);
|
_ls(initrd_root);
|
||||||
} else if (!strcmp(cmd, "cat") && args->size >= 2) {
|
} else if (!strcmp(cmd, "cat") && args->size >= 2) {
|
||||||
@@ -223,6 +250,8 @@ int shell(file_node_t *initrd_root)
|
|||||||
} else if (!strcmp(cmd, "settimeout") && args->size >= 2) {
|
} else if (!strcmp(cmd, "settimeout") && args->size >= 2) {
|
||||||
char *p1 = VEC_AT(char, args, 1);
|
char *p1 = VEC_AT(char, args, 1);
|
||||||
_settimeout(atoi32(p1), args);
|
_settimeout(atoi32(p1), args);
|
||||||
|
} else if (!strcmp(cmd, "time")) {
|
||||||
|
_time();
|
||||||
} else if (!strcmp(cmd, "reboot")) {
|
} else if (!strcmp(cmd, "reboot")) {
|
||||||
_reboot();
|
_reboot();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,15 +47,17 @@ timer_t *_pop(timer_t *t)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static inline
|
static inline
|
||||||
void _set_timer_interrrupt()
|
void _set_timer_interrupt()
|
||||||
{
|
{
|
||||||
if (global_timer) {
|
if (global_timer) {
|
||||||
uint64_t cntpct_el0;
|
uint64_t cntpct_el0;
|
||||||
R_SYSREG(cntpct_el0, cntpct_el0);
|
R_SYSREG(cntpct_el0, cntpct_el0);
|
||||||
DEBUG_EXCEP(cntpct_el0);
|
DEBUG_EXCEP(cntpct_el0);
|
||||||
|
|
||||||
uint64_t firing_tick = MAX(global_timer->data.firing_tick, cntpct_el0);
|
if (global_timer->data.firing_tick < cntpct_el0)
|
||||||
W_SYSREG(cntp_cval_el0, firing_tick);
|
W_SYSREG(cntp_tval_el0, 1);
|
||||||
|
else
|
||||||
|
W_SYSREG(cntp_cval_el0, global_timer->data.firing_tick);
|
||||||
|
|
||||||
_enable_timer_irq(true);
|
_enable_timer_irq(true);
|
||||||
}
|
}
|
||||||
@@ -71,9 +73,9 @@ void _traverse(timer_t *t)
|
|||||||
_traverse(t->_r);
|
_traverse(t->_r);
|
||||||
}
|
}
|
||||||
|
|
||||||
void add_task(task_t task)
|
void add_timer_task(task_t task)
|
||||||
{
|
{
|
||||||
DEBUG_EXCEP("add task");
|
DEBUG_EXCEP("add timer task");
|
||||||
timer_t *newtimer = kmalloc(sizeof(timer_t));
|
timer_t *newtimer = kmalloc(sizeof(timer_t));
|
||||||
*newtimer = (timer_t){
|
*newtimer = (timer_t){
|
||||||
._l = (timer_t *)0x0,
|
._l = (timer_t *)0x0,
|
||||||
@@ -86,7 +88,7 @@ void add_task(task_t task)
|
|||||||
global_timer = _merge(global_timer, newtimer);
|
global_timer = _merge(global_timer, newtimer);
|
||||||
|
|
||||||
_traverse(global_timer);
|
_traverse(global_timer);
|
||||||
_set_timer_interrrupt();
|
_set_timer_interrupt();
|
||||||
}
|
}
|
||||||
|
|
||||||
void timer_irq_handler(void)
|
void timer_irq_handler(void)
|
||||||
@@ -104,5 +106,5 @@ void timer_irq_handler(void)
|
|||||||
global_timer = _pop(global_timer);
|
global_timer = _pop(global_timer);
|
||||||
}
|
}
|
||||||
|
|
||||||
_set_timer_interrrupt();
|
_set_timer_interrupt();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,6 +24,19 @@ uint64_t msb64(uint64_t x)
|
|||||||
return res == 64 ? 0 : ((uint64_t)1 << (63 - res));
|
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)
|
uint32_t hton32(const uint32_t h)
|
||||||
{
|
{
|
||||||
const uint8_t *p = (const void *)&h;
|
const uint8_t *p = (const void *)&h;
|
||||||
@@ -106,7 +119,7 @@ uint32_t atoh32(const char *s)
|
|||||||
exit(ERR_CONVERSION);
|
exit(ERR_CONVERSION);
|
||||||
|
|
||||||
uint32_t ret = 0;
|
uint32_t ret = 0;
|
||||||
for (int i = 8; i--; ++s) {
|
for (int i = 8; i-- && *s != '\0'; ++s) {
|
||||||
if (!isxdigit(*s))
|
if (!isxdigit(*s))
|
||||||
exit(ERR_CONVERSION);
|
exit(ERR_CONVERSION);
|
||||||
ret <<= 4, ret |= (isdigit(*s) ? *s - '0' :
|
ret <<= 4, ret |= (isdigit(*s) ? *s - '0' :
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ void _print_time(uint64_t)
|
|||||||
.param = 0x0,
|
.param = 0x0,
|
||||||
};
|
};
|
||||||
|
|
||||||
add_task(task);
|
add_timer_task(task);
|
||||||
}
|
}
|
||||||
|
|
||||||
void main(void *dtb)
|
void main(void *dtb)
|
||||||
|
|||||||
Reference in New Issue
Block a user