forked from xuos/xiuos
Unify kernel entrance.
This commit is contained in:
parent
52b549c14c
commit
10cc7cc270
|
@ -41,6 +41,7 @@ static void _sys_clock_init()
|
||||||
uint32_t freq = get_main_clock(IPG_CLK);
|
uint32_t freq = get_main_clock(IPG_CLK);
|
||||||
gpt_init(CLKSRC_IPG_CLK, freq / 1000000, RESTART_MODE, WAIT_MODE_EN | STOP_MODE_EN);
|
gpt_init(CLKSRC_IPG_CLK, freq / 1000000, RESTART_MODE, WAIT_MODE_EN | STOP_MODE_EN);
|
||||||
gpt_set_compare_event(kGPTOutputCompare1, OUTPUT_CMP_DISABLE, 1000);
|
gpt_set_compare_event(kGPTOutputCompare1, OUTPUT_CMP_DISABLE, 1000);
|
||||||
|
gpt_counter_enable(kGPTOutputCompare1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t _get_clock_int()
|
static uint32_t _get_clock_int()
|
||||||
|
|
|
@ -46,6 +46,7 @@ Modification:
|
||||||
#include "multicores.h"
|
#include "multicores.h"
|
||||||
#include "spinlock.h"
|
#include "spinlock.h"
|
||||||
#include "syscall.h"
|
#include "syscall.h"
|
||||||
|
#include "trap_common.h"
|
||||||
|
|
||||||
__attribute__((always_inline)) static inline void _abort_reason(uint32_t fault_status)
|
__attribute__((always_inline)) static inline void _abort_reason(uint32_t fault_status)
|
||||||
{
|
{
|
||||||
|
@ -88,18 +89,30 @@ void dump_tf(struct trapframe* tf)
|
||||||
void handle_undefined_instruction(struct trapframe* tf)
|
void handle_undefined_instruction(struct trapframe* tf)
|
||||||
{
|
{
|
||||||
// unimplemented trap handler
|
// unimplemented trap handler
|
||||||
KPrintf("undefined instruction at %x\n", tf->pc);
|
xizi_enter_kernel();
|
||||||
|
ERROR("undefined instruction at %x\n", tf->pc);
|
||||||
panic("");
|
panic("");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void handle_reserved(void)
|
||||||
|
{
|
||||||
|
// unimplemented trap handler
|
||||||
|
xizi_enter_kernel();
|
||||||
|
panic("Unimplemented Reserved\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void handle_fiq(void)
|
||||||
|
{
|
||||||
|
xizi_enter_kernel();
|
||||||
|
panic("Unimplemented FIQ\n");
|
||||||
|
}
|
||||||
|
|
||||||
extern void context_switch(struct context**, struct context*);
|
extern void context_switch(struct context**, struct context*);
|
||||||
void dabort_handler(struct trapframe* r)
|
void dabort_handler(struct trapframe* r)
|
||||||
{
|
{
|
||||||
if (!is_spinlock_locked(&whole_kernel_lock) || whole_kernel_lock.owner_cpu != cur_cpuid()) {
|
xizi_enter_kernel();
|
||||||
spinlock_lock(&whole_kernel_lock);
|
|
||||||
}
|
|
||||||
uint32_t dfs, dfa;
|
|
||||||
|
|
||||||
|
uint32_t dfs, dfa;
|
||||||
__asm__ __volatile__("mrc p15, 0, %0, c5, c0, 0" : "=r"(dfs)::);
|
__asm__ __volatile__("mrc p15, 0, %0, c5, c0, 0" : "=r"(dfs)::);
|
||||||
__asm__ __volatile__("mrc p15, 0, %0, c6, c0, 0" : "=r"(dfa)::);
|
__asm__ __volatile__("mrc p15, 0, %0, c6, c0, 0" : "=r"(dfa)::);
|
||||||
|
|
||||||
|
@ -116,18 +129,13 @@ void dabort_handler(struct trapframe* r)
|
||||||
LOG("data abort at 0x%x, status 0x%x\n", dfa, dfs);
|
LOG("data abort at 0x%x, status 0x%x\n", dfa, dfs);
|
||||||
_abort_reason(dfs);
|
_abort_reason(dfs);
|
||||||
dump_tf(r);
|
dump_tf(r);
|
||||||
if (is_spinlock_locked(&whole_kernel_lock) && whole_kernel_lock.owner_cpu == cur_cpuid()) {
|
|
||||||
spinlock_unlock(&whole_kernel_lock);
|
|
||||||
}
|
|
||||||
panic("data abort exception\n");
|
panic("data abort exception\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void iabort_handler(struct trapframe* r)
|
void iabort_handler(struct trapframe* r)
|
||||||
{
|
{
|
||||||
if (!is_spinlock_locked(&whole_kernel_lock) || whole_kernel_lock.owner_cpu != cur_cpuid()) {
|
xizi_enter_kernel();
|
||||||
spinlock_lock(&whole_kernel_lock);
|
|
||||||
}
|
|
||||||
uint32_t ifs, ifa;
|
uint32_t ifs, ifa;
|
||||||
|
|
||||||
__asm__ __volatile__("mrc p15, 0, %0, c5, c0, 1" : "=r"(ifs)::);
|
__asm__ __volatile__("mrc p15, 0, %0, c5, c0, 1" : "=r"(ifs)::);
|
||||||
|
@ -146,9 +154,6 @@ void iabort_handler(struct trapframe* r)
|
||||||
LOG("prefetch abort at 0x%x, status 0x%x\n", ifa, ifs);
|
LOG("prefetch abort at 0x%x, status 0x%x\n", ifa, ifs);
|
||||||
_abort_reason(ifs);
|
_abort_reason(ifs);
|
||||||
dump_tf(r);
|
dump_tf(r);
|
||||||
if (is_spinlock_locked(&whole_kernel_lock) && whole_kernel_lock.owner_cpu == cur_cpuid()) {
|
|
||||||
spinlock_unlock(&whole_kernel_lock);
|
|
||||||
}
|
|
||||||
panic("prefetch abort exception\n");
|
panic("prefetch abort exception\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,15 +42,13 @@ extern void trap_iabort(void);
|
||||||
extern void trap_dabort(void);
|
extern void trap_dabort(void);
|
||||||
extern void trap_irq_enter(void);
|
extern void trap_irq_enter(void);
|
||||||
extern void trap_undefined_instruction(void);
|
extern void trap_undefined_instruction(void);
|
||||||
|
extern void handle_reserved(void);
|
||||||
|
extern void handle_fiq(void);
|
||||||
|
|
||||||
static struct XiziTrapDriver xizi_trap_driver;
|
static struct XiziTrapDriver xizi_trap_driver;
|
||||||
|
|
||||||
void panic(char* s)
|
void panic(char* s)
|
||||||
{
|
{
|
||||||
// xizi_trap_driver.cpu_irq_disable();
|
|
||||||
if (is_spinlock_locked(&whole_kernel_lock) && whole_kernel_lock.owner_cpu == cur_cpuid()) {
|
|
||||||
spinlock_unlock(&whole_kernel_lock);
|
|
||||||
}
|
|
||||||
KPrintf("panic: %s\n", s);
|
KPrintf("panic: %s\n", s);
|
||||||
for (;;)
|
for (;;)
|
||||||
;
|
;
|
||||||
|
@ -58,7 +56,6 @@ void panic(char* s)
|
||||||
|
|
||||||
/* stack for different mode*/
|
/* stack for different mode*/
|
||||||
static char mode_stack_pages[NR_CPU][NR_MODE_STACKS][MODE_STACK_SIZE];
|
static char mode_stack_pages[NR_CPU][NR_MODE_STACKS][MODE_STACK_SIZE];
|
||||||
|
|
||||||
extern uint32_t _vector_jumper;
|
extern uint32_t _vector_jumper;
|
||||||
extern uint32_t _vector_start;
|
extern uint32_t _vector_start;
|
||||||
extern uint32_t _vector_end;
|
extern uint32_t _vector_end;
|
||||||
|
@ -73,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)
|
static void _sys_irq_init(int cpu_id)
|
||||||
{
|
{
|
||||||
/* load exception vectors */
|
/* load exception vectors */
|
||||||
|
|
|
@ -95,106 +95,54 @@ trap_irq_enter:
|
||||||
b trap_return
|
b trap_return
|
||||||
|
|
||||||
trap_reset_enter:
|
trap_reset_enter:
|
||||||
mov r14, #0
|
mov r14, #0 // lr: not defined on reset
|
||||||
sub r13, r13, #56
|
stmfd r13!, {r0-r12, r14}
|
||||||
str r14, [r13, #52]
|
mrs r2, spsr // copy spsr to r2
|
||||||
str r12, [r13, #48]
|
stmfd r13!, {r2} // save r2(spsr) to the stack
|
||||||
str r11, [r13, #44]
|
stmfd r13!, {r14} // save r14 again (it is not really correct)
|
||||||
str r10, [r13, #40]
|
stmfd r13, {sp, lr}^ // save user mode sp and lr
|
||||||
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
|
sub r13, r13, #8
|
||||||
mov r0, r13
|
|
||||||
|
# call traps (trapframe *fp)
|
||||||
|
mov r0, r13 // copy r13_svc to r0
|
||||||
bl _vector_jumper
|
bl _vector_jumper
|
||||||
|
|
||||||
trap_dabort:
|
trap_dabort:
|
||||||
sub r14, r14, #8
|
sub r14, r14, #8 // lr: instruction causing the abort
|
||||||
sub r13, r13, #56
|
stmfd r13!, {r0-r12, r14}
|
||||||
str r14, [r13, #52]
|
mrs r2, spsr // copy spsr to r2
|
||||||
str r12, [r13, #48]
|
stmfd r13!, {r2} // save r2(spsr) to the stack
|
||||||
str r11, [r13, #44]
|
stmfd r13!, {r14} // save r14 again (it is not really correct)
|
||||||
str r10, [r13, #40]
|
stmfd r13, {sp, lr}^ // save user mode sp and lr
|
||||||
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
|
sub r13, r13, #8
|
||||||
mov r0, r13
|
|
||||||
|
# call traps (trapframe *fp)
|
||||||
|
mov r0, r13 // save trapframe as the first parameter
|
||||||
bl dabort_handler
|
bl dabort_handler
|
||||||
|
|
||||||
trap_iabort:
|
trap_iabort:
|
||||||
sub r14, r14, #4
|
sub r14, r14, #4 // lr: instruction causing the abort
|
||||||
sub r13, r13, #56
|
stmfd r13!, {r0-r12, r14}
|
||||||
str r14, [r13, #52]
|
mrs r2, spsr // copy spsr to r2
|
||||||
str r12, [r13, #48]
|
stmfd r13!, {r2} // save r2(spsr) to the stack
|
||||||
str r11, [r13, #44]
|
stmfd r13!, {r14} // save r14 again (it is not really correct)
|
||||||
str r10, [r13, #40]
|
stmfd r13, {sp, lr}^ // save user mode sp and lr
|
||||||
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
|
sub r13, r13, #8
|
||||||
mov r0, r13
|
|
||||||
|
# call traps (trapframe *fp)
|
||||||
|
mov r0, r13 // save trapframe as the first parameter
|
||||||
bl iabort_handler
|
bl iabort_handler
|
||||||
|
|
||||||
trap_undefined_instruction:
|
trap_undefined_instruction:
|
||||||
sub r13, r13, #56
|
stmfd r13!, {r0-r12, r14}
|
||||||
str r14, [r13, #52]
|
mrs r2, spsr // copy spsr to r2
|
||||||
str r12, [r13, #48]
|
stmfd r13!, {r2} // save r2(spsr) to the stack
|
||||||
str r11, [r13, #44]
|
stmfd r13!, {r14} // save r14 again (it is not really correct)
|
||||||
str r10, [r13, #40]
|
stmfd r13, {sp, lr}^ // save user mode sp and lr
|
||||||
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
|
sub r13, r13, #8
|
||||||
mov r0, r13
|
|
||||||
|
# call traps (trapframe *fp)
|
||||||
|
mov r0, r13 // save trapframe as the first parameter
|
||||||
bl handle_undefined_instruction
|
bl handle_undefined_instruction
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -47,4 +47,7 @@ static inline struct CPU* cur_cpu(void)
|
||||||
return &global_cpus[cur_cpuid()];
|
return &global_cpus[cur_cpuid()];
|
||||||
}
|
}
|
||||||
|
|
||||||
struct spinlock whole_kernel_lock;
|
struct spinlock whole_kernel_lock;
|
||||||
|
|
||||||
|
void xizi_enter_kernel();
|
||||||
|
void xizi_leave_kernel();
|
|
@ -171,10 +171,10 @@ struct TaskMicroDescriptor* next_task_emergency = NULL;
|
||||||
extern void context_switch(struct context**, struct context*);
|
extern void context_switch(struct context**, struct context*);
|
||||||
static void _scheduler(struct SchedulerRightGroup right_group)
|
static void _scheduler(struct SchedulerRightGroup right_group)
|
||||||
{
|
{
|
||||||
|
xizi_enter_kernel();
|
||||||
struct MmuCommonDone* p_mmu_driver = AchieveResource(&right_group.mmu_driver_tag);
|
struct MmuCommonDone* p_mmu_driver = AchieveResource(&right_group.mmu_driver_tag);
|
||||||
struct TaskMicroDescriptor* next_task;
|
struct TaskMicroDescriptor* next_task;
|
||||||
|
|
||||||
spinlock_lock(&whole_kernel_lock);
|
|
||||||
while (1) {
|
while (1) {
|
||||||
next_task = NULL;
|
next_task = NULL;
|
||||||
/* find next runnable task */
|
/* find next runnable task */
|
||||||
|
|
|
@ -56,16 +56,15 @@ void default_interrupt_routine(void)
|
||||||
extern void context_switch(struct context**, struct context*);
|
extern void context_switch(struct context**, struct context*);
|
||||||
void intr_irq_dispatch(struct trapframe* tf)
|
void intr_irq_dispatch(struct trapframe* tf)
|
||||||
{
|
{
|
||||||
assert(p_intr_driver != NULL);
|
xizi_enter_kernel();
|
||||||
|
|
||||||
p_intr_driver->cpu_irq_disable();
|
|
||||||
|
|
||||||
// enter irq
|
// enter irq
|
||||||
|
assert(p_intr_driver != NULL);
|
||||||
uintptr_t int_info = 0;
|
uintptr_t int_info = 0;
|
||||||
if ((int_info = p_intr_driver->hw_before_irq()) == 0) {
|
if ((int_info = p_intr_driver->hw_before_irq()) == 0) {
|
||||||
|
xizi_leave_kernel();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
spinlock_lock(&whole_kernel_lock);
|
|
||||||
|
|
||||||
struct TaskMicroDescriptor* current_task = cur_cpu()->task;
|
struct TaskMicroDescriptor* current_task = cur_cpu()->task;
|
||||||
if (LIKELY(current_task != NULL)) {
|
if (LIKELY(current_task != NULL)) {
|
||||||
|
@ -94,6 +93,17 @@ void intr_irq_dispatch(struct trapframe* tf)
|
||||||
}
|
}
|
||||||
assert(current_task == cur_cpu()->task);
|
assert(current_task == cur_cpu()->task);
|
||||||
|
|
||||||
|
xizi_leave_kernel();
|
||||||
|
}
|
||||||
|
|
||||||
|
void xizi_enter_kernel()
|
||||||
|
{
|
||||||
|
p_intr_driver->cpu_irq_disable();
|
||||||
|
spinlock_lock(&whole_kernel_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
void xizi_leave_kernel()
|
||||||
|
{
|
||||||
spinlock_unlock(&whole_kernel_lock);
|
spinlock_unlock(&whole_kernel_lock);
|
||||||
p_intr_driver->cpu_irq_enable();
|
p_intr_driver->cpu_irq_enable();
|
||||||
}
|
}
|
|
@ -48,12 +48,9 @@ bool swi_distributer_init(struct SwiDispatcherRightGroup* _right_group)
|
||||||
extern void context_switch(struct context**, struct context*);
|
extern void context_switch(struct context**, struct context*);
|
||||||
void software_irq_dispatch(struct trapframe* tf)
|
void software_irq_dispatch(struct trapframe* tf)
|
||||||
{
|
{
|
||||||
|
xizi_enter_kernel();
|
||||||
assert(p_intr_driver != NULL);
|
assert(p_intr_driver != NULL);
|
||||||
|
|
||||||
p_intr_driver->cpu_irq_disable();
|
|
||||||
spinlock_lock(&whole_kernel_lock);
|
|
||||||
|
|
||||||
// get current task
|
// get current task
|
||||||
struct TaskMicroDescriptor* cur_task = cur_cpu()->task;
|
struct TaskMicroDescriptor* cur_task = cur_cpu()->task;
|
||||||
/// @todo: Handle dead task
|
/// @todo: Handle dead task
|
||||||
|
@ -79,6 +76,5 @@ void software_irq_dispatch(struct trapframe* tf)
|
||||||
panic("Exit reaches");
|
panic("Exit reaches");
|
||||||
}
|
}
|
||||||
|
|
||||||
spinlock_unlock(&whole_kernel_lock);
|
xizi_leave_kernel();
|
||||||
p_intr_driver->cpu_irq_enable();
|
|
||||||
}
|
}
|
Loading…
Reference in New Issue