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

View File

@@ -50,5 +50,6 @@ static inline struct CPU* cur_cpu(void)
struct spinlock whole_kernel_lock;
void xizi_enter_kernel();
bool xizi_try_enter_kernel();
void xizi_leave_kernel();
bool xizi_is_in_kernel();

View File

@@ -64,6 +64,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;
@@ -80,7 +86,7 @@ int syscall(int sys_num, uintptr_t param1, uintptr_t param2, uintptr_t param3, u
int sys_spawn(char* img_start, char* name, char** argv);
int sys_exit(struct TaskMicroDescriptor* ptask);
int sys_yield();
int sys_yield(task_yield_reason reason);
int sys_kill(int id);
int sys_register_as_server(char* name);

View File

@@ -34,6 +34,7 @@ Modification:
#include "actracer.h"
#include "assert.h"
#include "ipc.h"
#include "kalloc.h"
#include "mmu_common.h"
#include "multicores.h"
#include "share_page.h"
@@ -52,9 +53,10 @@ static void send_irq_to_user(int irq_num)
struct Session* session = &irq_forward_table[irq_num].session;
int len = IPC_ARG_INFO_BASE_OFFSET;
len += sizeof(struct IpcArgInfo);
/* get message space and add session tail */
/* add session tail */
struct IpcMsg* buf = session->buf + session->tail;
void* session_kern_vaddr = P2V(xizi_pager.address_translate(&kernel_irq_proxy->pgdir, (uintptr_t)session->buf));
struct IpcMsg* buf = session_kern_vaddr + session->tail;
memset((void*)buf, 0, len);
session->tail = (session->tail + len) % session->capacity;
@@ -73,20 +75,13 @@ static void send_irq_to_user(int irq_num)
int user_irq_handler(int irq, void* tf, void* arg)
{
static struct MmuCommonDone* p_mmu_driver = NULL;
if (p_mmu_driver == NULL) {
struct TraceTag mmu_driver_tag;
AchieveResourceTag(&mmu_driver_tag, RequireRootTag(), "/hardkernel/mmu-ac-resource");
p_mmu_driver = (struct MmuCommonDone*)AchieveResource(&mmu_driver_tag);
}
if (irq_forward_table[irq].handle_task != NULL) {
p_mmu_driver->LoadPgdir((uintptr_t)V2P(kernel_irq_proxy->pgdir.pd_addr));
send_irq_to_user(irq);
p_mmu_driver->LoadPgdir((uintptr_t)V2P(cur_cpu()->task->pgdir.pd_addr));
next_task_emergency = irq_forward_table[irq].handle_task;
xizi_task_manager.task_yield_noschedule(cur_cpu()->task, false);
if (cur_cpu()->task != NULL) {
xizi_task_manager.task_yield_noschedule(cur_cpu()->task, false);
}
}
return 0;
}

View File

@@ -33,7 +33,7 @@ Modification:
#include "log.h"
int sys_yield()
int sys_yield(task_yield_reason reason)
{
xizi_task_manager.task_yield_noschedule(cur_cpu()->task, false);
return 0;

View File

@@ -48,7 +48,7 @@ int syscall(int sys_num, uintptr_t param1, uintptr_t param2, uintptr_t param3, u
ret = sys_exit(cur_cpu()->task);
break;
case SYSCALL_YIELD:
ret = sys_yield();
ret = sys_yield((task_yield_reason)param1);
break;
case SYSCALL_SERVER:
ret = sys_register_as_server((char*)param1);

View File

@@ -1,3 +1,3 @@
SRC_FILES := task.c scheduler.c
SRC_FILES := task.c schedule.c
include $(KERNEL_ROOT)/compiler.mk

View File

@@ -259,6 +259,7 @@ static void _scheduler(struct SchedulerRightGroup right_group)
cpu->task = next_task;
p_mmu_driver->LoadPgdir((uintptr_t)V2P(next_task->pgdir.pd_addr));
context_switch(&cpu->scheduler, next_task->main_thread.context);
assert(cur_cpu()->task == NULL);
assert(next_task->state != RUNNING);
}
}

View File

@@ -1,6 +1,7 @@
SRC_FILES := default_irq_handler.c \
clock_irq_handler.c \
software_irq_handler.c
software_irq_handler.c \
abort_handler.c
include $(KERNEL_ROOT)/compiler.mk

View File

@@ -0,0 +1,86 @@
/* Copyright (c) 2006-2018 Frans Kaashoek, Robert Morris, Russ Cox,
* Massachusetts Institute of Technology
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
/**
* @file abort_handler.c
* @brief handle program abort
* @version 3.0
* @author AIIT XUOS Lab
* @date 2023.11.23
*/
/*************************************************
File name: abort_handler.c
Description: handle program abort
Others:
History:
1. Date: 2023-11-23
Author: AIIT XUOS Lab
Modification:
1. Modify iabort and dabort handler(in dabort_handler() and iabort_handler())
*************************************************/
#include "core.h"
#include "memlayout.h"
#include "spinlock.h"
#include "trap_common.h"
#include "assert.h"
#include "multicores.h"
#include "syscall.h"
#include "task.h"
extern void context_switch(struct context**, struct context*);
void dabort_handler(struct trapframe* r)
{
if (r->pc >= DEV_VRTMEM_BASE && is_spinlock_hold_by_current_cpu(&whole_kernel_lock)) {
assert(is_spinlock_hold_by_current_cpu(&whole_kernel_lock));
dabort_reason(r);
panic("data abort exception\n");
}
xizi_enter_kernel();
struct TaskMicroDescriptor* cur_task = cur_cpu()->task;
ERROR("dabort in user space: %s\n", cur_task->name);
dabort_reason(r);
sys_exit(cur_task);
assert(cur_cpu()->task == NULL);
context_switch(&cur_task->main_thread.context, cur_cpu()->scheduler);
}
void iabort_handler(struct trapframe* r)
{
if (r->pc >= DEV_VRTMEM_BASE && is_spinlock_hold_by_current_cpu(&whole_kernel_lock)) {
assert(is_spinlock_hold_by_current_cpu(&whole_kernel_lock));
iabort_reason(r);
panic("kernel prefetch abort exception\n");
}
xizi_enter_kernel();
struct TaskMicroDescriptor* cur_task = cur_cpu()->task;
ERROR("iabort in user space: %s\n", cur_task->name);
iabort_reason(r);
sys_exit(cur_task);
assert(cur_cpu()->task == NULL);
context_switch(&cur_task->main_thread.context, cur_cpu()->scheduler);
}

View File

@@ -66,9 +66,8 @@ void intr_irq_dispatch(struct trapframe* tf)
}
struct TaskMicroDescriptor* current_task = cur_cpu()->task;
if (LIKELY(current_task != NULL)) {
current_task->main_thread.trapframe = tf;
}
assert(current_task != NULL);
current_task->main_thread.trapframe = tf;
unsigned cpu = p_intr_driver->hw_cur_int_cpu(int_info);
unsigned irq = p_intr_driver->hw_cur_int_num(int_info);
@@ -86,7 +85,7 @@ void intr_irq_dispatch(struct trapframe* tf)
p_intr_driver->curr_int[cpu] = 0;
p_intr_driver->hw_after_irq(int_info);
if ((cur_cpu()->task == NULL && current_task != NULL) || current_task->state != RUNNING) {
if (cur_cpu()->task == NULL || current_task->state != RUNNING) {
cur_cpu()->task = NULL;
context_switch(&current_task->main_thread.context, cur_cpu()->scheduler);
}
@@ -102,13 +101,18 @@ void xizi_enter_kernel()
spinlock_lock(&whole_kernel_lock);
}
bool xizi_try_enter_kernel()
{
p_intr_driver->cpu_irq_disable();
if (spinlock_try_lock(&whole_kernel_lock)) {
return true;
}
return false;
}
void xizi_leave_kernel()
{
spinlock_unlock(&whole_kernel_lock);
p_intr_driver->cpu_irq_enable();
}
bool xizi_is_in_kernel()
{
return is_spinlock_locked(&whole_kernel_lock);
}

View File

@@ -71,10 +71,10 @@ void software_irq_dispatch(struct trapframe* tf)
cur_cpu()->task = NULL;
context_switch(&cur_task->main_thread.context, cur_cpu()->scheduler);
}
assert(cur_task == cur_cpu()->task);
if (syscall_num == SYSCALL_EXIT) {
panic("Exit reaches");
}
assert(cur_task == cur_cpu()->task);
xizi_leave_kernel();
}