This commit is contained in:
liuqh
2024-05-08 15:36:46 +08:00
181 changed files with 10418 additions and 1429 deletions
@@ -41,32 +41,18 @@ 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)
{
KPrintf("sp_usr: 0x%x\n", tf->sp_usr);
KPrintf("lr_usr: 0x%x\n", tf->lr_usr);
KPrintf("lr_svc: 0x%x\n", tf->lr_svc);
KPrintf(" spsr: 0x%x\n", tf->spsr);
KPrintf(" r0: 0x%x\n", tf->r0);
@@ -85,64 +71,76 @@ 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
KPrintf("undefined instruction at %x\n", tf->pc);
ERROR("undefined instruction at %x\n", tf->pc);
xizi_enter_kernel();
panic("");
}
extern void context_switch(struct context**, struct context*);
void dabort_handler(struct trapframe* r)
void handle_reserved(void)
{
if (!is_spinlock_locked(&whole_kernel_lock) || whole_kernel_lock.owner_cpu != cur_cpuid()) {
spinlock_lock(&whole_kernel_lock);
}
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)::);
if (r->pc < KERN_MEM_BASE) { // Exception occured in User space: exit
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);
} else { // Exception occured in Kernel space: panic
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");
}
// unimplemented trap handler
ERROR("Unimplemented Reserved\n");
xizi_enter_kernel();
panic("");
}
void iabort_handler(struct trapframe* r)
void handle_fiq(void)
{
if (!is_spinlock_locked(&whole_kernel_lock) || whole_kernel_lock.owner_cpu != cur_cpuid()) {
spinlock_lock(&whole_kernel_lock);
}
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)::);
if (r->pc < KERN_MEM_BASE) { // Exception occured in User space: exit
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);
} else { // Exception occured in Kernel space: panic
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);
panic("prefetch abort exception\n");
}
}
ERROR("Unimplemented FIQ\n");
xizi_enter_kernel();
panic("");
}
@@ -45,6 +45,8 @@ Author: AIIT XUOS Lab
Modification:
1. take only gicd part of functions
*************************************************/
#include "string.h"
#include "gicv2_common_opa.h"
#include "gicv2_registers.h"
@@ -139,7 +141,7 @@ void gic_send_sgi(uint32_t irqID, uint32_t target_list, uint32_t filter_list)
void gic_init(void)
{
gicd_t* gicd = gic_get_gicd();
volatile gicd_t* gicd = gic_get_gicd();
// First disable the distributor.
gic_enable(false);
@@ -150,7 +152,9 @@ void gic_init(void)
for (uint32_t i = 0; i < 255; i++) {
*(uint32_t*)(&gicd->IPRIORITYRn[i * sizeof(uint32_t)]) = (uint32_t)0x80808080;
// memset((void*)&gicd->IPRIORITYRn[i * sizeof(uint32_t)], 0x80, sizeof(uint32_t));
*(uint32_t*)(&gicd->ITARGETSRn[i * sizeof(uint32_t)]) = (uint32_t)0x01010101;
// memset((void*)&gicd->IPRIORITYRn[i * sizeof(uint32_t)], 0x01, sizeof(uint32_t));
}
// Init the GIC CPU interface.
@@ -42,13 +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();
spinlock_unlock(&whole_kernel_lock);
KPrintf("panic: %s\n", s);
for (;;)
;
@@ -56,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;
@@ -71,19 +70,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)
{
/* load exception vectors */
@@ -99,9 +85,10 @@ 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
gic_init();
}
/* active hardware irq responser */
gic_init();
xizi_trap_driver.switch_hw_irqtbl((uint32_t*)&_vector_jumper);
}
@@ -153,29 +140,6 @@ static void _bind_irq_handler(int irq, irq_handler_t handler)
xizi_trap_driver.sw_irqtbl[irq].handler = handler;
}
static bool _send_sgi(uint32_t irq, uint32_t bitmask, enum SgiFilterType type)
{
if (bitmask > (1 << NR_CPU) - 1) {
return false;
}
enum _gicd_sgi_filter sgi_filter;
switch (type) {
case SgiFilter_TargetList:
sgi_filter = kGicSgiFilter_UseTargetList;
break;
case SgiFilter_AllOtherCPUs:
sgi_filter = kGicSgiFilter_AllOtherCPUs;
break;
default:
sgi_filter = kGicSgiFilter_OnlyThisCPU;
break;
}
gic_send_sgi(irq, bitmask, sgi_filter);
return true;
}
static uint32_t _hw_before_irq()
{
@@ -192,29 +156,11 @@ static uint32_t _hw_cur_int_num(uint32_t int_info)
return int_info & 0x1FF;
}
static uint32_t _hw_cur_int_cpu(uint32_t int_info)
{
return (int_info >> 10) & 0x7;
}
static void _hw_after_irq(uint32_t int_info)
{
gic_write_end_of_irq(int_info);
}
static int _is_interruptable(void)
{
uint32_t val;
__asm__ __volatile__(
"mrs %0, cpsr"
: "=r"(val)
:
:);
return !(val & DIS_INT);
}
int _cur_cpu_id()
{
return cpu_get_current();
@@ -231,12 +177,9 @@ static struct XiziTrapDriver xizi_trap_driver = {
.switch_hw_irqtbl = _switch_hw_irqtbl,
.bind_irq_handler = _bind_irq_handler,
.send_sgi = _send_sgi,
.is_interruptable = _is_interruptable,
.hw_before_irq = _hw_before_irq,
.hw_cur_int_num = _hw_cur_int_num,
.hw_cur_int_cpu = _hw_cur_int_cpu,
.hw_after_irq = _hw_after_irq,
};
@@ -47,43 +47,17 @@ trap_return:
ldmfd r13!, {r14}
ldmfd r13!, {r2}
msr spsr_cxsf, r2
ldr r0, [r13], #4
ldr r1, [r13], #4
ldr r2, [r13], #4
ldr r3, [r13], #4
ldr r4, [r13], #4
ldr r5, [r13], #4
ldr r6, [r13], #4
ldr r7, [r13], #4
ldr r8, [r13], #4
ldr r9, [r13], #4
ldr r10, [r13], #4
ldr r11, [r13], #4
ldr r12, [r13], #4
ldm r13!, {pc}^
ldmfd r13!, {r0-r12, pc}^ // restore context and return
user_trap_swi_enter:
# save trapframe to swi stack
sub sp, sp, #56
str r14, [sp, #52]
str r12, [sp, #48]
str r11, [sp, #44]
str r10, [sp, #40]
str r9, [sp, #36]
str r8, [sp, #32]
str r7, [sp, #28]
str r6, [sp, #24]
str r5, [sp, #20]
str r4, [sp, #16]
str r3, [sp, #12]
str r2, [sp, #8]
str r1, [sp, #4]
str r0, [sp]
# save trapframe to swi stack
cpsid i
stmfd sp!, {r0-r12, r14} // save context
mrs r2, spsr // copy spsr to r2
stmfd r13!, {r2} // save r2(spsr) to the stack
mrs r2, spsr
stmfd r13!, {r2}
stmfd r13!, {r14}
stmfd r13, {sp, lr}^
stmfd r13!, {r14} // save r14 again to have one uniform trapframe
stmfd r13, {sp, lr}^ // save user mode sp and lr
sub r13, r13, #8
# call syscall handler
@@ -92,17 +66,13 @@ user_trap_swi_enter:
b trap_return
trap_irq_enter:
# save context in irq stack
sub r14, r14, #4
sub sp, sp, #16
str r14, [sp, #12]
str r2, [sp, #8]
str r1, [sp, #4]
str r0, [sp]
mrs r1, spsr
mov r0, r13 // irq stack stop
add r13, r13, #16 // reset IRQ stack
# save it on the stack as r14 is banked
cpsid i
sub r14, r14, #4 // r14 (lr) contains the interrupted PC
stmfd r13!, {r0-r2, r14} //
mrs r1, spsr // save spsr_irq
mov r0, r13 // save stack stop (r13_irq)
add r13, r13, #16 // reset the IRQ stack
# switch to the SVC mode
mrs r2, cpsr
@@ -111,134 +81,110 @@ trap_irq_enter:
msr cpsr_cxsf, r2
# build the trap frame
ldr r2, [r0, #12]
ldr r2, [r0, #12] // read the r14_irq, then save it
stmfd r13!, {r2}
sub r13, r13, #40
str r12, [r13, #36]
str r11, [r13, #32]
str r10, [r13, #28]
str r9, [r13, #24]
str r8, [r13, #20]
str r7, [r13, #16]
str r6, [r13, #12]
str r5, [r13, #8]
str r4, [r13, #4]
str r3, [r13]
ldmfd r0, {r3-r5}
stmfd r13!, {r3-r12} // r4-r12 are preserved (non-banked)
ldmfd r0, {r3-r5} // copy r0-r2 over from irq stack
stmfd r13!, {r3-r5}
stmfd r13!, {r1}
stmfd r13!, {lr}
stmfd r13, {sp, lr}^
stmfd r13!, {r1} // save spsr
stmfd r13!, {lr} // save lr_svc
stmfd r13, {sp, lr}^ // save user mode sp and lr
sub r13, r13, #8
mov r0, r13 // trapframe as parameters
bl intr_irq_dispatch
b trap_return
trap_reset_enter:
mov r14, #0
sub r13, r13, #56
str r14, [r13, #52]
str r12, [r13, #48]
str r11, [r13, #44]
str r10, [r13, #40]
str r9, [r13, #36]
str r8, [r13, #32]
str r7, [r13, #28]
str r6, [r13, #24]
str r5, [r13, #20]
str r4, [r13, #16]
str r3, [r13, #12]
str r2, [r13, #8]
str r1, [r13, #4]
str r0, [r13]
mrs r2, spsr
stmfd r13!, {r2}
stmfd r13!, {r14}
stmfd r13, {sp, lr}^
sub r13, r13, #8
mov r0, r13
bl _vector_jumper
trap_dabort:
sub r14, r14, #8
sub r13, r13, #56
str r14, [r13, #52]
str r12, [r13, #48]
str r11, [r13, #44]
str r10, [r13, #40]
str r9, [r13, #36]
str r8, [r13, #32]
str r7, [r13, #28]
str r6, [r13, #24]
str r5, [r13, #20]
str r4, [r13, #16]
str r3, [r13, #12]
str r2, [r13, #8]
str r1, [r13, #4]
str r0, [r13]
# save it on the stack as r14 is banked
cpsid i
sub r14, r14, #8 // r14 (lr) contains the interrupted PC
stmfd r13!, {r0-r2, r14} //
mrs r1, spsr // save spsr_irq
mov r0, r13 // save stack stop (r13_irq)
add r13, r13, #16 // reset the IRQ stack
mrs r2, spsr
stmfd r13!, {r2}
stmfd r13!, {r14}
stmfd r13, {sp, lr}^
# switch to the SVC mode
mrs r2, cpsr
bic r2, r2, #ARM_CPSR_MODE_MASK
orr r2, r2, #ARM_MODE_SVC
msr cpsr_cxsf, r2
# build the trap frame
ldr r2, [r0, #12] // read the r14_irq, then save it
stmfd r13!, {r2}
stmfd r13!, {r3-r12} // r4-r12 are preserved (non-banked)
ldmfd r0, {r3-r5} // copy r0-r2 over from irq stack
stmfd r13!, {r3-r5}
stmfd r13!, {r1} // save spsr
stmfd r13!, {lr} // save lr_svc
stmfd r13, {sp, lr}^ // save user mode sp and lr
sub r13, r13, #8
mov r0, r13
mov r0, r13 // trapframe as parameters
bl dabort_handler
trap_iabort:
sub r14, r14, #4
sub r13, r13, #56
str r14, [r13, #52]
str r12, [r13, #48]
str r11, [r13, #44]
str r10, [r13, #40]
str r9, [r13, #36]
str r8, [r13, #32]
str r7, [r13, #28]
str r6, [r13, #24]
str r5, [r13, #20]
str r4, [r13, #16]
str r3, [r13, #12]
str r2, [r13, #8]
str r1, [r13, #4]
str r0, [r13]
# save it on the stack as r14 is banked
cpsid i
sub r14, r14, #4 // r14 (lr) contains the interrupted PC
stmfd r13!, {r0-r2, r14} //
mrs r1, spsr // save spsr_irq
mov r0, r13 // save stack stop (r13_irq)
add r13, r13, #16 // reset the IRQ stack
mrs r2, spsr
# switch to the SVC mode
mrs r2, cpsr
bic r2, r2, #ARM_CPSR_MODE_MASK
orr r2, r2, #ARM_MODE_SVC
msr cpsr_cxsf, r2
# build the trap frame
ldr r2, [r0, #12] // read the r14_irq, then save it
stmfd r13!, {r2}
stmfd r13!, {r14}
stmfd r13, {sp, lr}^
stmfd r13!, {r3-r12} // r4-r12 are preserved (non-banked)
ldmfd r0, {r3-r5} // copy r0-r2 over from irq stack
stmfd r13!, {r3-r5}
stmfd r13!, {r1} // save spsr
stmfd r13!, {lr} // save lr_svc
stmfd r13, {sp, lr}^ // save user mode sp and lr
sub r13, r13, #8
mov r0, r13
mov r0, r13 // trapframe as parameters
bl iabort_handler
trap_undefined_instruction:
sub r13, r13, #56
str r14, [r13, #52]
str r12, [r13, #48]
str r11, [r13, #44]
str r10, [r13, #40]
str r9, [r13, #36]
str r8, [r13, #32]
str r7, [r13, #28]
str r6, [r13, #24]
str r5, [r13, #20]
str r4, [r13, #16]
str r3, [r13, #12]
str r2, [r13, #8]
str r1, [r13, #4]
str r0, [r13]
# save it on the stack as r14 is banked
cpsid i
sub r14, r14, #4 // r14 (lr) contains the interrupted PC
stmfd r13!, {r0-r2, r14} //
mrs r1, spsr // save spsr_irq
mov r0, r13 // save stack stop (r13_irq)
add r13, r13, #16 // reset the IRQ stack
mrs r2, spsr
# switch to the SVC mode
mrs r2, cpsr
bic r2, r2, #ARM_CPSR_MODE_MASK
orr r2, r2, #ARM_MODE_SVC
msr cpsr_cxsf, r2
# build the trap frame
ldr r2, [r0, #12] // read the r14_irq, then save it
stmfd r13!, {r2}
stmfd r13!, {r14}
stmfd r13, {sp, lr}^
sub r13, r13, #8
mov r0, r13
bl handle_undefined_instruction
stmfd r13!, {r3-r12} // r4-r12 are preserved (non-banked)
ldmfd r0, {r3-r5} // copy r0-r2 over from irq stack
stmfd r13!, {r3-r5}
stmfd r13!, {r1} // save spsr
stmfd r13!, {lr} // save lr_svc
stmfd r13, {sp, lr}^ // save user mode sp and lr
sub r13, r13, #8
mov r0, r13 // trapframe as parameters
bl handle_undefined_instruction
init_stack:
# set the stack for Other mode
@@ -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);
@@ -164,24 +151,6 @@ static void _bind_irq_handler(int irq, irq_handler_t handler)
xizi_trap_driver.sw_irqtbl[irq].handler = handler;
}
static bool _send_sgi(uint32_t irq, uint32_t bitmask, enum SgiFilterType type)
{
if (bitmask > (1 << NR_CPU) - 1) {
return false;
}
int cpu_id = 0;
while (bitmask != 0) {
if ((bitmask & 0x1) != 0) {
XScuGic_SoftwareIntr(&IntcInstance, irq, cpu_id);
}
cpu_id++;
bitmask >>= 1;
}
return true;
}
static uint32_t _hw_before_irq()
{
@@ -194,29 +163,11 @@ static uint32_t _hw_cur_int_num(uint32_t int_info)
return int_info & XSCUGIC_ACK_INTID_MASK;
}
static uint32_t _hw_cur_int_cpu(uint32_t int_info)
{
return (int_info >> 5) & 0x3;
}
static void _hw_after_irq(uint32_t int_info)
{
XScuGic_CPUWriteReg(&IntcInstance, XSCUGIC_EOI_OFFSET, int_info);
}
static int _is_interruptable(void)
{
uint32_t val;
__asm__ __volatile__(
"mrs %0, cpsr"
: "=r"(val)
:
:);
return !(val & DIS_INT);
}
int _cur_cpu_id()
{
return cpu_get_current();
@@ -233,18 +184,15 @@ static struct XiziTrapDriver xizi_trap_driver = {
.switch_hw_irqtbl = _switch_hw_irqtbl,
.bind_irq_handler = _bind_irq_handler,
.send_sgi = _send_sgi,
.is_interruptable = _is_interruptable,
.hw_before_irq = _hw_before_irq,
.hw_cur_int_num = _hw_cur_int_num,
.hw_cur_int_cpu = _hw_cur_int_cpu,
.hw_after_irq = _hw_after_irq,
};
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;
}
+37 -11
View File
@@ -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;
@@ -52,7 +52,7 @@ enum {
SPINLOCK_LOCK_WAITFOREVER = 0xFFFFFFFF,
};
void spinlock_init(struct spinlock* lock, char* name)
__attribute__((optimize("O0"))) void spinlock_init(struct spinlock* lock, char* name)
{
lock->owner_cpu = SPINLOCK_STATE_UNLOCK;
strncpy(lock->name, name, 24);
@@ -61,33 +61,59 @@ void spinlock_init(struct spinlock* lock, char* name)
extern int _spinlock_lock(struct spinlock* lock, uint32_t timeout);
void _spinlock_unlock(struct spinlock* lock);
void spinlock_lock(struct spinlock* lock)
__attribute__((optimize("O0"))) 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);
}
void spinlock_unlock(struct spinlock* lock)
__attribute__((optimize("O0"))) 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)
__attribute__((optimize("O0"))) 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;
}
@@ -34,7 +34,7 @@ Modification:
#define STACK_DEPTH 32
struct spinlock { // Mutex.
uint32_t owner_cpu; // 1 for locked, 0 for unlocked
volatile uint32_t owner_cpu; // 1 for locked, 0 for unlocked
char name[28]; // The call stack (an array of program counters)
} __attribute__((aligned(32)));
@@ -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);
@@ -56,8 +56,6 @@ struct irq_table_entry {
struct XiziTrapDriver {
/* irq number table*/
struct irq_table_entry sw_irqtbl[NR_IRQS];
/* current irq number happening in cpu*/
uint32_t curr_int[NR_CPU];
void (*sys_irq_init)(int);
int (*cur_cpu_id)();
@@ -66,17 +64,14 @@ struct XiziTrapDriver {
void (*cpu_irq_disable)();
void (*single_irq_enable)(int irq, int cpu, int prio);
void (*single_irq_disable)(int irq, int cpu);
uint32_t* (*switch_hw_irqtbl)(uint32_t*);
bool (*send_sgi)(uint32_t, uint32_t, enum SgiFilterType);
uint32_t* (*switch_hw_irqtbl)(uint32_t*);
void (*bind_irq_handler)(int, irq_handler_t);
/* check if no if interruptable */
int (*is_interruptable)();
/* code runs before irq handling */
uint32_t (*hw_before_irq)();
uint32_t (*hw_cur_int_num)(uint32_t int_info);
uint32_t (*hw_cur_int_cpu)(uint32_t int_info);
/* code runs after irq handling */
void (*hw_after_irq)(uint32_t int_info);
};
@@ -101,4 +96,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);