Fully support userland interrupt handler. Use fixed common abort handler.
This commit is contained in:
@@ -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();
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
SRC_FILES := task.c scheduler.c
|
||||
SRC_FILES := task.c schedule.c
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
86
Ubiquitous/XiZi_AIoT/softkernel/trap/abort_handler.c
Normal file
86
Ubiquitous/XiZi_AIoT/softkernel/trap/abort_handler.c
Normal 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);
|
||||
}
|
||||
@@ -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(¤t_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);
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
Reference in New Issue
Block a user