Fully support userland interrupt handler. Use fixed common abort handler.
This commit is contained in:
@@ -41,30 +41,13 @@ Modification:
|
||||
*************************************************/
|
||||
#include "core.h"
|
||||
#include "memlayout.h"
|
||||
|
||||
#include "log.h"
|
||||
#include "multicores.h"
|
||||
#include "spinlock.h"
|
||||
#include "syscall.h"
|
||||
#include "trap_common.h"
|
||||
|
||||
__attribute__((always_inline)) static inline void _abort_reason(uint32_t fault_status)
|
||||
{
|
||||
if ((fault_status & 0xd) == 0x1) // Alignment failure
|
||||
KPrintf("reason: alignment\n");
|
||||
else if ((fault_status & 0xd) == 0x5) // External abort "on translation"
|
||||
KPrintf("reason: ext. abort on trnslt.\n");
|
||||
else if ((fault_status & 0xd) == 0x5) // Translation
|
||||
KPrintf("reason: sect. translation\n");
|
||||
else if ((fault_status & 0xd) == 0x9) // Domain
|
||||
KPrintf("reason: sect. domain\n");
|
||||
else if ((fault_status & 0xd) == 0xd) // Permission
|
||||
KPrintf("reason: sect. permission\n");
|
||||
else if ((fault_status & 0xd) == 0x8) // External abort
|
||||
KPrintf("reason: ext. abort\n");
|
||||
else
|
||||
KPrintf("reason: unknown???\n");
|
||||
}
|
||||
#include "assert.h"
|
||||
#include "multicores.h"
|
||||
#include "syscall.h"
|
||||
#include "task.h"
|
||||
|
||||
void dump_tf(struct trapframe* tf)
|
||||
{
|
||||
@@ -86,6 +69,57 @@ void dump_tf(struct trapframe* tf)
|
||||
KPrintf(" pc: 0x%x\n", tf->pc);
|
||||
}
|
||||
|
||||
void dabort_reason(struct trapframe* r)
|
||||
{
|
||||
uint32_t fault_status, dfa;
|
||||
__asm__ __volatile__("mrc p15, 0, %0, c5, c0, 0" : "=r"(fault_status)::);
|
||||
__asm__ __volatile__("mrc p15, 0, %0, c6, c0, 0" : "=r"(dfa)::);
|
||||
LOG("program counter: 0x%x caused\n", r->pc);
|
||||
LOG("data abort at 0x%x, status 0x%x\n", dfa, fault_status);
|
||||
|
||||
if ((fault_status & 0xd) == 0x1) // Alignment failure
|
||||
KPrintf("reason: alignment\n");
|
||||
else if ((fault_status & 0xd) == 0x5) // External abort "on translation"
|
||||
KPrintf("reason: ext. abort on trnslt.\n");
|
||||
else if ((fault_status & 0xd) == 0x5) // Translation
|
||||
KPrintf("reason: sect. translation\n");
|
||||
else if ((fault_status & 0xd) == 0x9) // Domain
|
||||
KPrintf("reason: sect. domain\n");
|
||||
else if ((fault_status & 0xd) == 0xd) // Permission
|
||||
KPrintf("reason: sect. permission\n");
|
||||
else if ((fault_status & 0xd) == 0x8) // External abort
|
||||
KPrintf("reason: ext. abort\n");
|
||||
else
|
||||
KPrintf("reason: unknown???\n");
|
||||
|
||||
dump_tf(r);
|
||||
}
|
||||
|
||||
void iabort_reason(struct trapframe* r)
|
||||
{
|
||||
uint32_t fault_status, ifa;
|
||||
__asm__ __volatile__("mrc p15, 0, %0, c5, c0, 1" : "=r"(fault_status)::);
|
||||
__asm__ __volatile__("mrc p15, 0, %0, c6, c0, 2" : "=r"(ifa)::);
|
||||
LOG("prefetch abort at 0x%x, status 0x%x\n", ifa, fault_status);
|
||||
|
||||
if ((fault_status & 0xd) == 0x1) // Alignment failure
|
||||
KPrintf("reason: alignment\n");
|
||||
else if ((fault_status & 0xd) == 0x5) // External abort "on translation"
|
||||
KPrintf("reason: ext. abort on trnslt.\n");
|
||||
else if ((fault_status & 0xd) == 0x5) // Translation
|
||||
KPrintf("reason: sect. translation\n");
|
||||
else if ((fault_status & 0xd) == 0x9) // Domain
|
||||
KPrintf("reason: sect. domain\n");
|
||||
else if ((fault_status & 0xd) == 0xd) // Permission
|
||||
KPrintf("reason: sect. permission\n");
|
||||
else if ((fault_status & 0xd) == 0x8) // External abort
|
||||
KPrintf("reason: ext. abort\n");
|
||||
else
|
||||
KPrintf("reason: unknown???\n");
|
||||
|
||||
dump_tf(r);
|
||||
}
|
||||
|
||||
void handle_undefined_instruction(struct trapframe* tf)
|
||||
{
|
||||
// unimplemented trap handler
|
||||
@@ -105,61 +139,4 @@ void handle_fiq(void)
|
||||
{
|
||||
xizi_enter_kernel();
|
||||
panic("Unimplemented FIQ\n");
|
||||
}
|
||||
|
||||
extern void context_switch(struct context**, struct context*);
|
||||
void dabort_handler(struct trapframe* r)
|
||||
{
|
||||
if (xizi_is_in_kernel()) {
|
||||
uint32_t dfs, dfa;
|
||||
__asm__ __volatile__("mrc p15, 0, %0, c5, c0, 0" : "=r"(dfs)::);
|
||||
__asm__ __volatile__("mrc p15, 0, %0, c6, c0, 0" : "=r"(dfa)::);
|
||||
LOG("program counter: 0x%x caused\n", r->pc);
|
||||
LOG("data abort at 0x%x, status 0x%x\n", dfa, dfs);
|
||||
_abort_reason(dfs);
|
||||
dump_tf(r);
|
||||
panic("data abort exception\n");
|
||||
}
|
||||
|
||||
xizi_enter_kernel();
|
||||
|
||||
uint32_t dfs, dfa;
|
||||
__asm__ __volatile__("mrc p15, 0, %0, c5, c0, 0" : "=r"(dfs)::);
|
||||
__asm__ __volatile__("mrc p15, 0, %0, c6, c0, 0" : "=r"(dfa)::);
|
||||
|
||||
ERROR("dabort in user space: %s\n", cur_cpu()->task->name);
|
||||
LOG("program counter: 0x%x caused\n", r->pc);
|
||||
LOG("data abort at 0x%x, status 0x%x\n", dfa, dfs);
|
||||
_abort_reason(dfs);
|
||||
dump_tf(r);
|
||||
sys_exit(cur_cpu()->task);
|
||||
context_switch(&cur_cpu()->task->main_thread.context, cur_cpu()->scheduler);
|
||||
}
|
||||
|
||||
void iabort_handler(struct trapframe* r)
|
||||
{
|
||||
if (xizi_is_in_kernel()) {
|
||||
uint32_t ifs, ifa;
|
||||
__asm__ __volatile__("mrc p15, 0, %0, c5, c0, 1" : "=r"(ifs)::);
|
||||
__asm__ __volatile__("mrc p15, 0, %0, c6, c0, 2" : "=r"(ifa)::);
|
||||
LOG("program counter: 0x%x caused\n", r->pc);
|
||||
LOG("prefetch abort at 0x%x, status 0x%x\n", ifa, ifs);
|
||||
_abort_reason(ifs);
|
||||
dump_tf(r);
|
||||
panic("prefetch abort exception\n");
|
||||
}
|
||||
|
||||
xizi_enter_kernel();
|
||||
|
||||
uint32_t ifs, ifa;
|
||||
__asm__ __volatile__("mrc p15, 0, %0, c5, c0, 1" : "=r"(ifs)::);
|
||||
__asm__ __volatile__("mrc p15, 0, %0, c6, c0, 2" : "=r"(ifa)::);
|
||||
|
||||
ERROR("iabort in user space: %s\n", cur_cpu()->task->name);
|
||||
LOG("program counter: 0x%x(%s) caused\n", r->pc, cur_cpu()->task);
|
||||
LOG("prefetch abort at 0x%x, status 0x%x\n", ifa, ifs);
|
||||
_abort_reason(ifs);
|
||||
dump_tf(r);
|
||||
sys_exit(cur_cpu()->task);
|
||||
context_switch(&cur_cpu()->task->main_thread.context, cur_cpu()->scheduler);
|
||||
}
|
||||
}
|
||||
+14
-27
@@ -42,12 +42,13 @@ extern void trap_iabort(void);
|
||||
extern void trap_dabort(void);
|
||||
extern void trap_irq_enter(void);
|
||||
extern void trap_undefined_instruction(void);
|
||||
extern void handle_reserved(void);
|
||||
extern void handle_fiq(void);
|
||||
|
||||
static struct XiziTrapDriver xizi_trap_driver;
|
||||
|
||||
void panic(char* s)
|
||||
{
|
||||
xizi_trap_driver.cpu_irq_disable();
|
||||
KPrintf("panic: %s\n", s);
|
||||
for (;;)
|
||||
;
|
||||
@@ -55,7 +56,6 @@ void panic(char* s)
|
||||
|
||||
/* stack for different mode*/
|
||||
static char mode_stack_pages[NR_CPU][NR_MODE_STACKS][MODE_STACK_SIZE];
|
||||
|
||||
extern uint32_t _vector_jumper;
|
||||
extern uint32_t _vector_start;
|
||||
extern uint32_t _vector_end;
|
||||
@@ -72,19 +72,6 @@ void init_cpu_mode_stacks(int cpu_id)
|
||||
}
|
||||
}
|
||||
|
||||
void handle_reserved(void)
|
||||
{
|
||||
// unimplemented trap handler
|
||||
LOG("Unimplemented Reserved\n");
|
||||
panic("");
|
||||
}
|
||||
|
||||
void handle_fiq(void)
|
||||
{
|
||||
LOG("Unimplemented FIQ\n");
|
||||
panic("");
|
||||
}
|
||||
|
||||
static void _sys_irq_init(int cpu_id)
|
||||
{
|
||||
|
||||
@@ -101,18 +88,18 @@ static void _sys_irq_init(int cpu_id)
|
||||
vector_base[5] = (uint32_t)handle_reserved; // Reserved
|
||||
vector_base[6] = (uint32_t)trap_irq_enter; // IRQ
|
||||
vector_base[7] = (uint32_t)handle_fiq; // FIQ
|
||||
}
|
||||
|
||||
/* active hardware irq responser */
|
||||
XScuGic_Config* gic_config = XScuGic_LookupConfig(XPAR_PS7_SCUGIC_0_DEVICE_ID);
|
||||
if (NULL == gic_config) {
|
||||
ERROR("Error while looking up gic config\n");
|
||||
return;
|
||||
}
|
||||
int gic_init_status = XScuGic_CfgInitialize(&IntcInstance, gic_config, gic_config->CpuBaseAddress);
|
||||
if (gic_init_status != XST_SUCCESS) {
|
||||
ERROR("Error initializing gic\n");
|
||||
return;
|
||||
/* active hardware irq responser */
|
||||
XScuGic_Config* gic_config = XScuGic_LookupConfig(XPAR_PS7_SCUGIC_0_DEVICE_ID);
|
||||
if (NULL == gic_config) {
|
||||
ERROR("Error while looking up gic config\n");
|
||||
return;
|
||||
}
|
||||
int gic_init_status = XScuGic_CfgInitialize(&IntcInstance, gic_config, gic_config->CpuBaseAddress);
|
||||
if (gic_init_status != XST_SUCCESS) {
|
||||
ERROR("Error initializing gic\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
xizi_trap_driver.switch_hw_irqtbl((uint32_t*)&_vector_jumper);
|
||||
@@ -226,6 +213,6 @@ static struct XiziTrapDriver xizi_trap_driver = {
|
||||
struct XiziTrapDriver* hardkernel_intr_init(struct TraceTag* hardkernel_tag)
|
||||
{
|
||||
xizi_trap_driver.sys_irq_init(0);
|
||||
xizi_trap_driver.cpu_irq_enable();
|
||||
xizi_trap_driver.cpu_irq_disable();
|
||||
return &xizi_trap_driver;
|
||||
}
|
||||
@@ -27,8 +27,8 @@
|
||||
#include "multicores.h"
|
||||
|
||||
struct lock_node {
|
||||
int cpu_id;
|
||||
struct double_list_node node;
|
||||
int cpu_id;
|
||||
};
|
||||
|
||||
static struct double_list_node lock_request_guard;
|
||||
@@ -63,15 +63,18 @@ void _spinlock_unlock(struct spinlock* lock);
|
||||
|
||||
void spinlock_lock(struct spinlock* lock)
|
||||
{
|
||||
if (lock->owner_cpu != SPINLOCK_STATE_UNLOCK && lock->owner_cpu == cur_cpuid()) {
|
||||
int cur_cpu_id = cur_cpuid();
|
||||
if (lock->owner_cpu != SPINLOCK_STATE_UNLOCK && lock->owner_cpu == cur_cpu_id) {
|
||||
ERROR("spinlock %s lock double locked by core %d\n", lock->name, lock->owner_cpu);
|
||||
panic("");
|
||||
}
|
||||
|
||||
struct double_list_node* p_lock_node = &core_lock_request[cur_cpu_id].node;
|
||||
_spinlock_lock(&request_lock, SPINLOCK_LOCK_WAITFOREVER);
|
||||
doubleListAddOnBack(&core_lock_request[cur_cpuid()].node, &lock_request_guard);
|
||||
doubleListAddOnBack(p_lock_node, &lock_request_guard);
|
||||
_spinlock_unlock(&request_lock);
|
||||
|
||||
while (lock_request_guard.next != &core_lock_request[cur_cpuid()].node)
|
||||
while (lock_request_guard.next != p_lock_node)
|
||||
;
|
||||
|
||||
_spinlock_lock(lock, SPINLOCK_LOCK_WAITFOREVER);
|
||||
@@ -79,15 +82,38 @@ void spinlock_lock(struct spinlock* lock)
|
||||
|
||||
void spinlock_unlock(struct spinlock* lock)
|
||||
{
|
||||
assert(lock_request_guard.next == &core_lock_request[cur_cpuid()].node);
|
||||
struct double_list_node* p_lock_node = &core_lock_request[cur_cpuid()].node;
|
||||
assert(lock_request_guard.next == p_lock_node);
|
||||
_spinlock_lock(&request_lock, SPINLOCK_LOCK_WAITFOREVER);
|
||||
_double_list_del(core_lock_request[cur_cpuid()].node.prev, core_lock_request[cur_cpuid()].node.next);
|
||||
_double_list_del(p_lock_node->prev, p_lock_node->next);
|
||||
_spinlock_unlock(&request_lock);
|
||||
|
||||
_spinlock_unlock(lock);
|
||||
}
|
||||
|
||||
bool is_spinlock_locked(struct spinlock* lock)
|
||||
bool spinlock_try_lock(struct spinlock* lock)
|
||||
{
|
||||
return lock->owner_cpu != SPINLOCK_STATE_UNLOCK;
|
||||
int cur_cpu_id = cur_cpuid();
|
||||
if (lock->owner_cpu != SPINLOCK_STATE_UNLOCK && lock->owner_cpu == cur_cpu_id) {
|
||||
ERROR("spinlock %s lock double locked by core %d\n", lock->name, lock->owner_cpu);
|
||||
panic("");
|
||||
}
|
||||
|
||||
struct double_list_node* p_lock_node = &core_lock_request[cur_cpu_id].node;
|
||||
_spinlock_lock(&request_lock, SPINLOCK_LOCK_WAITFOREVER);
|
||||
doubleListAddOnBack(p_lock_node, &lock_request_guard);
|
||||
if (lock_request_guard.next != p_lock_node) {
|
||||
_double_list_del(p_lock_node->prev, p_lock_node->next);
|
||||
_spinlock_unlock(&request_lock);
|
||||
return false;
|
||||
}
|
||||
_spinlock_unlock(&request_lock);
|
||||
_spinlock_lock(lock, SPINLOCK_LOCK_WAITFOREVER);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool is_spinlock_hold_by_current_cpu(struct spinlock* lock)
|
||||
{
|
||||
return lock->owner_cpu;
|
||||
}
|
||||
@@ -42,4 +42,5 @@ bool module_spinlock_use_intr_init(void);
|
||||
void spinlock_init(struct spinlock* lock, char* name);
|
||||
void spinlock_lock(struct spinlock* lock);
|
||||
void spinlock_unlock(struct spinlock* lock);
|
||||
bool is_spinlock_locked(struct spinlock* lock);
|
||||
bool spinlock_try_lock(struct spinlock* lock);
|
||||
bool is_spinlock_hold_by_current_cpu(struct spinlock* lock);
|
||||
@@ -100,4 +100,7 @@ void panic(char* s);
|
||||
bool intr_distributer_init(struct IrqDispatcherRightGroup*);
|
||||
void intr_irq_dispatch(struct trapframe* tf);
|
||||
bool swi_distributer_init(struct SwiDispatcherRightGroup*);
|
||||
void software_irq_dispatch(struct trapframe* tf);
|
||||
void software_irq_dispatch(struct trapframe* tf);
|
||||
|
||||
void dabort_reason(struct trapframe* r);
|
||||
void iabort_reason(struct trapframe* r);
|
||||
Reference in New Issue
Block a user