Draft: lab 3 irq wtf
This commit is contained in:
@@ -44,10 +44,22 @@
|
||||
|
||||
_null_handler:
|
||||
save_all
|
||||
bl not_implemented_interrupt
|
||||
bl not_implemented_handler
|
||||
load_all
|
||||
eret
|
||||
|
||||
_synchronous_handler:
|
||||
save_all
|
||||
bl synchronous_handler
|
||||
load_all
|
||||
eret
|
||||
|
||||
_irq_handler:
|
||||
save_all
|
||||
bl irq_handler
|
||||
load_all
|
||||
eret
|
||||
|
||||
.align 11
|
||||
.global exception_vector_table
|
||||
exception_vector_table:
|
||||
@@ -60,18 +72,18 @@ exception_vector_table:
|
||||
b _null_handler
|
||||
.align 7
|
||||
|
||||
b _synchronous_handler
|
||||
.align 7
|
||||
b _irq_handler
|
||||
.align 7
|
||||
b _null_handler
|
||||
.align 7
|
||||
b _null_handler
|
||||
.align 7
|
||||
b _null_handler
|
||||
.align 7
|
||||
b _null_handler
|
||||
.align 7
|
||||
|
||||
b _null_handler
|
||||
.align 7
|
||||
b _null_handler
|
||||
.align 7
|
||||
|
||||
b _synchronous_handler
|
||||
.align 7
|
||||
b _irq_handler
|
||||
.align 7
|
||||
b _null_handler
|
||||
.align 7
|
||||
5
kernel/include/exception.h
Normal file
5
kernel/include/exception.h
Normal file
@@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
void init_exception(void);
|
||||
void not_implemented_handler(void);
|
||||
void synchronous_handler(void);
|
||||
3
kernel/include/exec.h
Normal file
3
kernel/include/exec.h
Normal file
@@ -0,0 +1,3 @@
|
||||
#pragma once
|
||||
|
||||
void user_exec(void *text, void *sp);
|
||||
17
kernel/include/interrupt.h
Normal file
17
kernel/include/interrupt.h
Normal file
@@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#define CORE0_TIMER_IRQ_CTRL ((volatile uint32_t *)0x40000040)
|
||||
#define CORE0_IRQ_SOURCE ((volatile uint32_t *)0x40000060)
|
||||
|
||||
enum :uint32_t {
|
||||
CNTPNSIRQ_INT = ((uint32_t)1 << 1),
|
||||
GPU_INT = ((uint32_t)1 << 8)
|
||||
};
|
||||
|
||||
void init_interrupt(void);
|
||||
void irq_handler(void);
|
||||
|
||||
void enable_interrupt(void);
|
||||
void disable_interrupt(void);
|
||||
@@ -1,15 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <initrd.h>
|
||||
#include <stddef.h>
|
||||
|
||||
void help(void);
|
||||
void hello(void);
|
||||
void hwinfo(void);
|
||||
void memalloc(size_t size);
|
||||
void ls(file_node_t *root);
|
||||
void cat(file_node_t *root, const char *filename);
|
||||
void reboot(void);
|
||||
#include <initrd.h>
|
||||
|
||||
int // is continue
|
||||
shell(file_node_t *);
|
||||
|
||||
@@ -43,8 +43,14 @@ void exit(int);
|
||||
: [a] "=r" (ret) \
|
||||
)
|
||||
|
||||
#define W_SYSREG(val, reg) \
|
||||
#define W_SYSREG(reg, val) \
|
||||
asm volatile( \
|
||||
"msr " #reg ", %[a]" \
|
||||
: [a] "r" (val) \
|
||||
:: [a] "r" (val) \
|
||||
)
|
||||
|
||||
#define R_REG(ret, reg) \
|
||||
asm volatile( \
|
||||
"mov %[a], " #reg \
|
||||
: [a] "=r" (ret) \
|
||||
)
|
||||
|
||||
@@ -28,8 +28,8 @@ void _memory_traverse()
|
||||
{
|
||||
dtb_reserved_entries = make_vector(0);
|
||||
while (fdt_memory_cur->address != 0 || fdt_memory_cur->size != 0) {
|
||||
DEBUG(ntoh64(fdt_memory_cur->address));
|
||||
DEBUG(ntoh64(fdt_memory_cur->size));
|
||||
DEBUG_DTB(ntoh64(fdt_memory_cur->address));
|
||||
DEBUG_DTB(ntoh64(fdt_memory_cur->size));
|
||||
|
||||
VEC_PUSH(dtb_reserved_entries, fdt_memory_cur++);
|
||||
}
|
||||
@@ -101,8 +101,8 @@ void fdt_traverse(const vector_t *struct_cbs)
|
||||
dtb_end = dtb_start +
|
||||
ntoh32(((fdt_header_t *)dtb_start)->totalsize);
|
||||
|
||||
DEBUG(fdt_memory_cur);
|
||||
DEBUG(fdt_struct_cur);
|
||||
DEBUG_DTB(fdt_memory_cur);
|
||||
DEBUG_DTB(fdt_struct_cur);
|
||||
_memory_traverse();
|
||||
DEBUG_DTB("memory traverse done");
|
||||
_struct_traverse("", struct_cbs);
|
||||
|
||||
42
kernel/lib/exception.c
Normal file
42
kernel/lib/exception.c
Normal file
@@ -0,0 +1,42 @@
|
||||
#include <exception.h>
|
||||
#include <errcode.h>
|
||||
#include <stddef.h>
|
||||
#include <logger.h>
|
||||
#include <utils.h>
|
||||
|
||||
void init_exception()
|
||||
{
|
||||
asm volatile(
|
||||
"adr x0, exception_vector_table" ENDL
|
||||
"msr vbar_el1, x0" ENDL
|
||||
::: "x0"
|
||||
);
|
||||
}
|
||||
|
||||
void not_implemented_handler()
|
||||
{
|
||||
DEBUG_EXCEP("not implemented caught");
|
||||
}
|
||||
|
||||
void synchronous_handler()
|
||||
{
|
||||
static int count = 0;
|
||||
if (count++ > 5)
|
||||
exit(ERR_ADMINKILL);
|
||||
DEBUG_EXCEP("synchronous caught");
|
||||
uint64_t x0 = 0x0;
|
||||
R_REG(x0, x0);
|
||||
LOG(x0);
|
||||
|
||||
uint64_t spsr_el1 = 0x0;
|
||||
R_SYSREG(spsr_el1, spsr_el1);
|
||||
LOG(spsr_el1);
|
||||
|
||||
uint64_t elr_el1 = 0x0;
|
||||
R_SYSREG(elr_el1, elr_el1);
|
||||
LOG(elr_el1);
|
||||
|
||||
uint64_t esr_el1 = 0x0;
|
||||
R_SYSREG(esr_el1, esr_el1);
|
||||
DEBUG_EXCEP(esr_el1);
|
||||
}
|
||||
16
kernel/lib/exec.c
Normal file
16
kernel/lib/exec.c
Normal file
@@ -0,0 +1,16 @@
|
||||
#include <exec.h>
|
||||
#include <utils.h>
|
||||
|
||||
void user_exec(void *text, void *sp)
|
||||
{
|
||||
// enable core timer
|
||||
uint64_t cntkctl_el1 = 0x0;
|
||||
R_SYSREG(cntkctl_el1, cntkctl_el1);
|
||||
W_SYSREG(cntkctl_el1, cntkctl_el1 | 1);
|
||||
W_SYSREG(cntp_ctl_el0, 1);
|
||||
|
||||
W_SYSREG(spsr_el1, 0);
|
||||
W_SYSREG(elr_el1, text);
|
||||
W_SYSREG(sp_el0, sp);
|
||||
asm volatile("eret");
|
||||
}
|
||||
58
kernel/lib/interrupt.c
Normal file
58
kernel/lib/interrupt.c
Normal file
@@ -0,0 +1,58 @@
|
||||
#include <interrupt.h>
|
||||
#include <utils.h>
|
||||
#include <logger.h>
|
||||
#include <errcode.h>
|
||||
|
||||
void init_interrupt(void)
|
||||
{
|
||||
uint64_t cntfrq_el0;
|
||||
R_SYSREG(cntfrq_el0, cntfrq_el0);
|
||||
W_SYSREG(cntp_tval_el0, cntfrq_el0);
|
||||
|
||||
*CORE0_TIMER_IRQ_CTRL = 0x2;
|
||||
}
|
||||
|
||||
static inline
|
||||
void _uart_irq_handler(void)
|
||||
{
|
||||
DEBUG_EXCEP("uart irq");
|
||||
}
|
||||
|
||||
static inline
|
||||
void _timer_irq_handler(void)
|
||||
{
|
||||
LOG("timer irq");
|
||||
|
||||
uint64_t cntpct_el0;
|
||||
R_SYSREG(cntpct_el0, cntpct_el0);
|
||||
DEBUG_EXCEP(cntpct_el0);
|
||||
|
||||
uint64_t cntfrq_el0;
|
||||
R_SYSREG(cntfrq_el0, cntfrq_el0);
|
||||
W_SYSREG(cntp_tval_el0, cntfrq_el0);
|
||||
}
|
||||
|
||||
void irq_handler(void)
|
||||
{
|
||||
LOG("irq caught");
|
||||
uint64_t irq_source = *CORE0_IRQ_SOURCE;
|
||||
DEBUG_EXCEP(irq_source);
|
||||
|
||||
*CORE0_TIMER_IRQ_CTRL = 0x0;
|
||||
if (irq_source & GPU_INT)
|
||||
_uart_irq_handler();
|
||||
if (irq_source & CNTPNSIRQ_INT)
|
||||
_timer_irq_handler();
|
||||
|
||||
*CORE0_TIMER_IRQ_CTRL = 0x2;
|
||||
}
|
||||
|
||||
void enable_interrupt(void)
|
||||
{
|
||||
asm volatile("msr DAIFClr, 0xf");
|
||||
}
|
||||
|
||||
void disable_interrupt(void)
|
||||
{
|
||||
asm volatile("msr DAIFSet, 0xf");
|
||||
}
|
||||
@@ -1,10 +1,13 @@
|
||||
#include <stddef.h>
|
||||
#include <errcode.h>
|
||||
#include <kmalloc.h>
|
||||
#include <utils.h>
|
||||
#include <string.h>
|
||||
#include <uart.h>
|
||||
#include <mbox.h>
|
||||
#include <shell.h>
|
||||
#include <exec.h>
|
||||
#include <mman.h>
|
||||
|
||||
#define INPUT_BUFLEN 1000
|
||||
|
||||
@@ -13,25 +16,29 @@
|
||||
#define PM_RSTC 0x3F10001c
|
||||
#define PM_WDOG 0x3F100024
|
||||
|
||||
void help (void)
|
||||
static inline
|
||||
void _help (void)
|
||||
{
|
||||
uart_puts(
|
||||
"help : print this help menu" ENDL
|
||||
"hello : print Hello World!" ENDL
|
||||
"hwinfo : print hardware info" ENDL
|
||||
"memalloc : alloate memory and print" ENDL
|
||||
"ls : list directory contents" ENDL
|
||||
"cat : concatenate files and print" ENDL
|
||||
"reboot : reboot the device" ENDL
|
||||
"help : print this help menu" ENDL
|
||||
"hello : print Hello World!" ENDL
|
||||
"hwinfo : print hardware info" ENDL
|
||||
"memalloc <size>: alloate memory and print" ENDL
|
||||
"ls : list directory contents" ENDL
|
||||
"cat <file>: concatenate files and print" ENDL
|
||||
"exec <file>: execute file in usermode" ENDL
|
||||
"reboot : reboot the device" ENDL
|
||||
);
|
||||
}
|
||||
|
||||
void hello (void)
|
||||
static inline
|
||||
void _hello (void)
|
||||
{
|
||||
uart_puts("hello, world" ENDL);
|
||||
}
|
||||
|
||||
void hwinfo (void)
|
||||
static inline
|
||||
void _hwinfo (void)
|
||||
{
|
||||
uart_puts(
|
||||
"hwinfo: " ENDL
|
||||
@@ -51,7 +58,8 @@ void hwinfo (void)
|
||||
uart_puts(ENDL);
|
||||
}
|
||||
|
||||
void memalloc(size_t size)
|
||||
static inline
|
||||
void _memalloc(size_t size)
|
||||
{
|
||||
void *addr = kmalloc(size);
|
||||
uart_puts("size: ");
|
||||
@@ -63,40 +71,60 @@ void memalloc(size_t size)
|
||||
uart_puts(ENDL);
|
||||
}
|
||||
|
||||
void ls_initrd_callback(file_node_t *tr)
|
||||
static inline
|
||||
void _ls_initrd_callback(file_node_t *tr)
|
||||
{
|
||||
uart_puts(tr->filename);
|
||||
uart_puts(ENDL);
|
||||
}
|
||||
|
||||
void ls(file_node_t *root)
|
||||
static inline
|
||||
void _ls(file_node_t *root)
|
||||
{
|
||||
initrd_traverse(root, ls_initrd_callback);
|
||||
initrd_traverse(root, _ls_initrd_callback);
|
||||
}
|
||||
|
||||
void cat(file_node_t *root, const char *filename)
|
||||
static inline
|
||||
void _cat(file_node_t *root, const char *filename)
|
||||
{
|
||||
file_node_t *tr = initrd_get(root, filename);
|
||||
if (tr) {
|
||||
uart_puts((char *)tr->filecontent);
|
||||
} else {
|
||||
uart_puts("FILE NOT EXIST!" ENDL);
|
||||
exit(ERR_NOT_EXIST);
|
||||
}
|
||||
}
|
||||
|
||||
void set(long addr, unsigned int value) {
|
||||
volatile unsigned int* point = (unsigned int*)addr;
|
||||
*point = value;
|
||||
}
|
||||
|
||||
void reset(int tick) { // reboot after watchdog timer expire
|
||||
set(PM_RSTC, PM_PASSWORD | 0x20); // full reset
|
||||
set(PM_WDOG, PM_PASSWORD | tick); // number of watchdog tick
|
||||
}
|
||||
|
||||
void reboot(void)
|
||||
static inline
|
||||
void _exec(file_node_t *root, const char *filename)
|
||||
{
|
||||
reset(1 << 16);
|
||||
file_node_t *tr = initrd_get(root, filename);
|
||||
if (tr) {
|
||||
void *userspace = allocate_page(1 << 6);
|
||||
memcpy(userspace, tr->filecontent, tr->filesize);
|
||||
user_exec(userspace, userspace + (1 << (12 + 6)) - 8);
|
||||
kfree(userspace);
|
||||
} else {
|
||||
exit(ERR_NOT_EXIST);
|
||||
}
|
||||
}
|
||||
|
||||
static inline
|
||||
void _set(long addr, unsigned int value) {
|
||||
volatile unsigned int* point = (unsigned int*)addr;
|
||||
*point = value;
|
||||
}
|
||||
|
||||
static inline
|
||||
void _reset(int tick) { // reboot after watchdog timer expire
|
||||
_set(PM_RSTC, PM_PASSWORD | 0x20); // full reset
|
||||
_set(PM_WDOG, PM_PASSWORD | tick); // number of watchdog tick
|
||||
}
|
||||
|
||||
static inline
|
||||
void _reboot(void)
|
||||
{
|
||||
_reset(1 << 16);
|
||||
}
|
||||
|
||||
int shell(file_node_t *initrd_root)
|
||||
@@ -127,19 +155,21 @@ int shell(file_node_t *initrd_root)
|
||||
*j = '\0';
|
||||
|
||||
if (!strcmp(bin, "help")) {
|
||||
help();
|
||||
_help();
|
||||
} else if (!strcmp(bin, "hello")) {
|
||||
hello();
|
||||
_hello();
|
||||
} else if (!strcmp(bin, "hwinfo")) {
|
||||
hwinfo();
|
||||
_hwinfo();
|
||||
} else if (!strcmp(bin, "memalloc")){
|
||||
memalloc((size_t)atoi32(param));
|
||||
_memalloc((size_t)atoi32(param));
|
||||
} else if (!strcmp(bin, "ls")) {
|
||||
ls(initrd_root);
|
||||
_ls(initrd_root);
|
||||
} else if (!strcmp(bin, "cat")) {
|
||||
cat(initrd_root, param);
|
||||
_cat(initrd_root, param);
|
||||
} else if (!strcmp(bin, "exec")) {
|
||||
_exec(initrd_root, param);
|
||||
} else if (!strcmp(bin, "reboot")) {
|
||||
reboot();
|
||||
_reboot();
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -7,23 +7,28 @@
|
||||
#include <shell.h>
|
||||
#include <vector.h>
|
||||
#include <utils.h>
|
||||
#include <exception.h>
|
||||
#include <interrupt.h>
|
||||
|
||||
void init(void *dtb, file_node_t **initrd_root)
|
||||
{
|
||||
init_exception();
|
||||
init_interrupt();
|
||||
|
||||
// UART
|
||||
uart_init();
|
||||
|
||||
// Device tree
|
||||
INFOR(dtb);
|
||||
DEBUG_DTB(dtb);
|
||||
dtb_start = dtb;
|
||||
vector_t *dtb_struct_cbs = make_vector(0);
|
||||
VEC_PUSH(dtb_struct_cbs, &initrd_dtb_cb);
|
||||
VEC_PUSH(dtb_struct_cbs, &mman_dtb_memory_cb);
|
||||
fdt_traverse(dtb_struct_cbs);
|
||||
DEBUG("device tree parse done");
|
||||
DEBUG_DTB("device tree parse done");
|
||||
|
||||
// Initramfs
|
||||
INFOR(initrd_start);
|
||||
DEBUG_INITRD(initrd_start);
|
||||
*initrd_root = initrd_init();
|
||||
|
||||
// Memory (Buddy system)
|
||||
|
||||
Reference in New Issue
Block a user