Fully support userland interrupt handler. Use fixed common abort handler.

This commit is contained in:
TXuian
2024-04-28 14:44:49 +08:00
parent a7cbb0d041
commit a24d73f710
25 changed files with 260 additions and 154 deletions
@@ -23,7 +23,11 @@ INC_DIR = -I$(KERNEL_ROOT)/services/shell/letter-shell \
-I$(KERNEL_ROOT)/services/boards/$(BOARD) \
-I$(KERNEL_ROOT)/services/app
ifeq ($(BOARD), imx6q-sabrelite)
all: init test_fs simple_client simple_server shell fs_server test_priority test_irq_hdlr test_irq_send readme.txt | bin
else
all: init test_fs simple_client simple_server shell fs_server test_priority test_irq_hdlr readme.txt | bin
endif
../tools/mkfs/mkfs ./fs.img $^
@mv $(filter-out readme.txt, $^) bin
@mv *.o bin
@@ -32,9 +36,11 @@ all: init test_fs simple_client simple_server shell fs_server test_priority test
bin:
@mkdir -p bin
ifeq ($(BOARD), imx6q-sabrelite)
test_irq_send: test_irq_sender.o usyscall.o libserial.o
@${ld} ${user_ldflags} -e main -o $@ $^ ${board_specs}
@${objdump} -S $@ > $@.asm
endif
test_irq_hdlr: test_irq_handler.o libserial.o libipc.o session.o usyscall.o libmem.o
@${ld} ${user_ldflags} -e main -o $@ $^ ${board_specs}
@@ -35,7 +35,7 @@ signed short userShellRead(char* data, unsigned short len)
while (length--) {
cur_read = getc();
if (cur_read == 0xff) {
yield();
yield(SYS_TASK_YIELD_NO_REASON);
}
// *data++ = getc();
*data++ = cur_read;
@@ -89,7 +89,7 @@ int main()
mmap(ARM_PERIPHERAL_VIRT_BASE, ARM_PERIPHERAL_BASE, 0x2000, true);
printf("%s: Sending soft interrupt\n", prog_name);
gic_send_sgi(SW_INTERRUPT_3, 0, kGicSgiFilter_OnlyThisCPU);
gic_send_sgi(SW_INTERRUPT_3, 0xF, kGicSgiFilter_UseTargetList);
printf("%s: Soft interrupt send done\n", prog_name);
exit();
}
@@ -53,9 +53,9 @@ int exit()
return syscall(SYSCALL_EXIT, 0, 0, 0, 0);
}
int yield()
int yield(task_yield_reason reason)
{
return syscall(SYSCALL_YIELD, 0, 0, 0, 0);
return syscall(SYSCALL_YIELD, (uintptr_t)reason, 0, 0, 0);
}
int kill(int pid)
@@ -44,6 +44,12 @@ typedef enum {
SYS_STATE_SHOW_CPU_INFO,
} sys_state_option;
typedef enum {
SYS_TASK_YIELD_NO_REASON = 0x0,
SYS_TASK_YIELD_FOREVER = 0x1,
SYS_TASK_YIELD_BLOCK_IPC = 0x2,
} task_yield_reason;
typedef union {
struct {
uintptr_t memblock_start;
@@ -58,7 +64,7 @@ typedef int (*ipc_write_fn)(struct Session* session, int fd, char* src, int offs
int spawn(struct Session* session, int fd, ipc_read_fn ipc_read, ipc_fsize_fn ipc_fsize, char* name, char** argv);
int exit();
int yield();
int yield(task_yield_reason reason);
int kill(int pid);
int register_server(char* name);
int session(char* path, int capacity, struct Session* user_session);
@@ -53,9 +53,9 @@ int exit()
return syscall(SYSCALL_EXIT, 0, 0, 0, 0);
}
int yield()
int yield(task_yield_reason reason)
{
return syscall(SYSCALL_YIELD, 0, 0, 0, 0);
return syscall(SYSCALL_YIELD, (uintptr_t)reason, 0, 0, 0);
}
int kill(int pid)
@@ -44,6 +44,12 @@ typedef enum {
SYS_STATE_SHOW_CPU_INFO,
} sys_state_option;
typedef enum {
SYS_TASK_YIELD_NO_REASON = 0x0,
SYS_TASK_YIELD_FOREVER = 0x1,
SYS_TASK_YIELD_BLOCK_IPC = 0x2,
} task_yield_reason;
typedef union {
struct {
uintptr_t memblock_start;
@@ -58,7 +64,7 @@ typedef int (*ipc_write_fn)(struct Session* session, int fd, char* src, int offs
int spawn(struct Session* session, int fd, ipc_read_fn ipc_read, ipc_fsize_fn ipc_fsize, char* name, char** argv);
int exit();
int yield();
int yield(task_yield_reason reason);
int kill(int pid);
int register_server(char* name);
int session(char* path, int capacity, struct Session* user_session);
@@ -121,7 +121,7 @@ void ipc_msg_send_wait(struct IpcMsg* msg)
msg->header.done = 0;
while (msg->header.done == 0) {
/// @todo syscall yield with prio decrease
yield();
yield(SYS_TASK_YIELD_BLOCK_IPC);
}
assert(msg->header.done == 1);
}
@@ -138,7 +138,7 @@ int ipc_session_wait(struct Session* session)
struct IpcMsg* msg = IPCSESSION_MSG(session);
while (msg->header.done == 0) {
/// @todo syscall yield with prio decrease
yield();
yield(SYS_TASK_YIELD_BLOCK_IPC);
}
assert(msg->header.done == 1);
return msg->header.ret_val;
@@ -169,7 +169,7 @@ void ipc_server_loop(struct IpcNode* ipc_node)
/* handle each session */
for (int i = 0; i < NR_MAX_SESSION; i++) {
if (session_list[i].buf == NULL) {
yield();
yield(SYS_TASK_YIELD_NO_REASON);
break;
}
cur_sess_id = session_list[i].id;