📄 tmrisr.asm
字号:
.section program;
#define IMASK_ADDR 0xFFE02104
#define CORE_TIMER 0xffe02018
#define CTCR 0xffe03000
#define TCOUNT 0xffe0300c
#define TPERIOD 0xffe03004
#define TSCALE 0xffe03008
.extern ldf_stack_end;
#define SYS_STACK ldf_stack_end
.extern _timer_handler;
_timer_initialize:
.global _timer_initialize;
[--sp] = p0;
[--sp] = r1;
p0.h = hi(IMASK_ADDR);
p0.l = lo(IMASK_ADDR);
r1 = [p0];
bitset(r1, 6);
[p0] = r1; // Enable core timer interrupt
p0.l = lo(CORE_TIMER);
r1.h = _timer_handler;
r1.l = _timer_handler;
[p0] = r1; // Set core timer interrupt vector
p0.l = lo(CTCR);
r1 = 0x1;
[p0] = r1; // Activate core timer
p0.l = lo(TCOUNT);
[p0] = r0; // Set core timer count
p0.l = lo(TPERIOD);
[p0] = r0; // Set core timer period
p0.l = lo(TSCALE);
r1 = 0;
[p0] = r1; // Set core timer scale
p0.l = lo(CTCR);
r1 = 0x7;
[p0] = r1; // Start timer and enable it auto-reload
r1 = [sp++];
p0 = [sp++];
rts;
_timer_initialize.end:
_pause_timer:
.global _pause_timer;
[--sp] = p0;
[--sp] = r0;
p0.h = hi(CTCR);
p0.l = lo(CTCR);
r0 = 0;
[p0] = r0;
r0 = [sp++];
p0 = [sp++];
rts;
_pause_timer.end:
_restore_timer:
.global _restore_timer;
[--sp] = p0;
[--sp] = r0;
p0.h = hi(CTCR);
p0.l = lo(CTCR);
r0 = 7;
[p0] = r0;
r0 = [sp++];
p0 = [sp++];
rts;
_restore_timer.end:
#include "saverestore.h"
#include "offset.h"
.extern _isig_tim, _btime_for_dispatch;
.extern __kernel_runtsk, __kernel_schedtsk;
.extern __kernel_search_schedtsk, __kernel_dispatch;
.extern _poll_dispatch;
#define ISIG_TIM() \
[--sp] = (r7:2, p5:1); \
[--sp] = lc0; \
[--sp] = lt0; \
[--sp] = lb0; \
call _isig_tim; \
lb0 = [sp++]; \
lt0 = [sp++]; \
lc0 = [sp++]; \
(r7:2, p5:1) = [sp++]
_timer_handler:
.global _timer_handler;
usp = sp; // Save user stack segment
sp.l = lo(SYS_STACK);
sp.h = hi(SYS_STACK);
link 0x0;
call _pause_timer; // Stop timer
[--sp] = astat;
[--sp] = r0;
[--sp] = p0;
[--sp] = r1;
/*
ISIG_TIM(); // Handle time events.
p0.l = lo(_btime_for_dispatch);
p0.h = hi(_btime_for_dispatch);
r0 = [p0];
cc = r0; // Judge whether it is necessary to dispatch tasks.
bittgl(r0, 0); // traverse btime_for_dispatch
[p0] = r0;
if !cc jump quit_handler;
*/
// Dispatch tasks:
// [--sp] = (r7:2, p5:1);
// .......
// (r7:2, p5:1) = [sp++];
// p0.h = hi(__kernel_schedtsk);
// p0.l = lo(__kernel_schedtsk);
// cc = r0; // Judge if enadsp is 0
// if !cc jump quit_handler;
// r0 = [p0];
p0.l = lo(__kernel_runtsk);
p0.h = hi(__kernel_runtsk);
r1 = [p0];
// cc = r1 == r0; // Judge if runtsk == schedtsk
// if cc jump quit_handler;
r0 = r1;
r1 = (TCB_tskctxb + (CTXB_nRegs * 4))(z);
r0 = r0 + r1;
r1 = [sp++];
p0 = [sp++];
sp = r0;
nop;
nop;
r0 = [fp - 8];
nop;
[--sp] = r0; // push r0
[--sp] = (r7:1, p5:0);
[--sp] = i3;
[--sp] = i2;
[--sp] = i1;
[--sp] = i0;
[--sp] = m3;
[--sp] = m2;
[--sp] = m1;
[--sp] = m0;
[--sp] = b3;
[--sp] = b2;
[--sp] = b1;
[--sp] = b0;
[--sp] = l3;
[--sp] = l2;
[--sp] = l1;
[--sp] = l0;
[--sp] = a0.x;
[--sp] = a0.w;
[--sp] = a1.x;
[--sp] = a1.w;
[--sp] = lc1;
[--sp] = lc0;
[--sp] = lt1;
[--sp] = lt0;
[--sp] = lb1;
[--sp] = lb0;
p1.l = lo(__kernel_runtsk);
p1.h = hi(__kernel_runtsk);
p2 = [p1]; // p2 = runtsk;
r4 = [p2 + TCB_initb]; // p4 = runtsk->initb;
r0 = [fp - 4];
[--sp] = r0; // push astat
r4 += TCB_pc;
p1 = r4; // p1 = &runtsk->initb->task;
r4 += (TCB_sp - TCB_pc);
p2 = r4; // p2 = &runtsk->initb->stk;
r0 = [fp + 4];
[--sp] = r0; // push rets
r0 = [fp];
[--sp] = r0; // push fp
r0 = reti;
[p1] = r0; // save reti
r0 = usp;
[p2] = r0; // save user sp;
// Saving finished
// Now the registers can be used casually. :) Cool!
// Get ready for the next running task.
sp.l = lo(SYS_STACK);
sp.h = hi(SYS_STACK);
call _poll_dispatch;
call _isig_tim;
p0.l = lo(__kernel_schedtsk);
p0.h = hi(__kernel_schedtsk);
r0 = [p0];
p1.l = lo(__kernel_runtsk);
p1.h = hi(__kernel_runtsk);
p2.l = lo(__kernel_schedtsk);
p2.h = hi(__kernel_schedtsk);
[p1] = r0; // __kernel_runtsk = __kernel_schedtsk;
r0 += TCB_tskctxb;
// Attention! During restoring context, any interrupt may be harmful.
// Take care of the context. It is for the coming task, not for Ya! :)
p0 = r0; // 0 = takctxb;
// Let's begin!
csync;
r0 = [p0];
fp = r0; // fp restored.
p3 = [p2]; // p3 = schedtsk
r4 = [p3 + TCB_initb]; // p4 = schedtsk->initb
r4 += TCB_pc;
p2 = r4; // p2 = schedtsk->initb->task
r4 += (TCB_sp - TCB_pc);
p3 = r4; // p3 = schedtsk->initb->stk;
sp.l = lo(SYS_STACK);
sp.h = hi(SYS_STACK);
p0 += 4;
r0 = [p2];
reti = r0;
r0 = [p3];
usp = r0;
// Next, fp will be used to restore the other registers.
[--sp] = fp; // Save fp
fp = sp; // Save sp
sp = p0; // fp now points to &ctx_regs[2]
rets = [sp++];
astat = [sp++];
lb0 = [sp++];
lb1 = [sp++];
lt0 = [sp++];
lt1 = [sp++];
lc0 = [sp++];
lc1 = [sp++];
a1.w = [sp++];
a1.x = [sp++];
a0.w = [sp++];
a0.x = [sp++];
l0 = [sp++];
l1 = [sp++];
l2 = [sp++];
l3 = [sp++];
b0 = [sp++];
b1 = [sp++];
b2 = [sp++];
b3 = [sp++];
m0 = [sp++];
m1 = [sp++];
m2 = [sp++];
m3 = [sp++];
i0 = [sp++];
i1 = [sp++];
i2 = [sp++];
i3 = [sp++];
(r7:0, p5:0) = [sp++];
sp = fp;
fp = [sp++];
[--sp] = rets;
call _restore_timer;
rets = [sp++];
sp = usp;
rti;
quit_handler:
r1 = [sp++];
p0 = [sp++];
r0 = [sp++];
astat = [sp++];
call _restore_timer;
unlink;
sp = usp;
rti;
_timer_handler.end:
.extern _preemption_insert;
_preemption_dispatch_call:
.global _preemption_dispatch_call;
[--sp] = r0;
[--sp] = r1;
cli r1;
[--sp] = rets;
call _pause_timer; // Stop timer
rets = [sp++];
[--sp] = p0;
p0.h = hi(CORE_TIMER);
p0.l = lo(CORE_TIMER);
r0.h = hi(preemption_call);
r0.l = lo(preemption_call);
[p0] = r0;
r0 = r1;
p0 = [sp++];
bitset(r1, 6);
sti r1;
r1 = [sp++];
raise 6;
preemption_call:
sti r0;
r0 = [sp++];
usp = sp; // Save user stack segment
sp.l = lo(SYS_STACK);
sp.h = hi(SYS_STACK);
link 0x0;
[--sp] = astat;
[--sp] = r0;
[--sp] = p0;
[--sp] = r1;
p0.h = hi(CORE_TIMER);
p0.l = lo(CORE_TIMER);
// [--sp] = (r7:1, p5:1);
r1.h = hi(_timer_handler);
r1.l = lo(_timer_handler);
[p0] = r1; // Restore timer handler
p0.l = lo(__kernel_runtsk);
p0.h = hi(__kernel_runtsk);
// csync;
r1 = [p0];
r0 = r1;
r1 = (TCB_tskctxb + (CTXB_nRegs * 4))(z);
r0 = r0 + r1;
// (r7:1, p5:1) = [sp++];
r1 = [sp++];
p0 = [sp++];
sp = r0;
r0 = [fp + 4];
reti = r0; // reti = rets;
r0 = [fp - 8];
nop;
[--sp] = r0; // push r0
[--sp] = (r7:1, p5:0);
[--sp] = i3;
[--sp] = i2;
[--sp] = i1;
[--sp] = i0;
[--sp] = m3;
[--sp] = m2;
[--sp] = m1;
[--sp] = m0;
[--sp] = b3;
[--sp] = b2;
[--sp] = b1;
[--sp] = b0;
[--sp] = l3;
[--sp] = l2;
[--sp] = l1;
[--sp] = l0;
[--sp] = a0.x;
[--sp] = a0.w;
[--sp] = a1.x;
[--sp] = a1.w;
[--sp] = lc1;
[--sp] = lc0;
[--sp] = lt1;
[--sp] = lt0;
[--sp] = lb1;
[--sp] = lb0;
p1.l = lo(__kernel_runtsk);
p1.h = hi(__kernel_runtsk);
p2 = [p1]; // p2 = runtsk;
r4 = [p2 + TCB_initb]; // p4 = runtsk->initb;
r0 = [fp - 4];
[--sp] = r0; // push astat
r4 += TCB_pc;
p1 = r4; // p1 = &runtsk->initb->task;
r4 += (TCB_sp - TCB_pc);
p2 = r4; // p2 = &runtsk->initb->stk;
r0 = [fp + 4];
[--sp] = r0; // push rets
r0 = [fp];
[--sp] = r0; // push fp
r0 = reti;
[p1] = r0; // save reti
r0 = usp;
[p2] = r0; // save user sp;
// Saving finished
// Now the registers can be used casually. :) Cool!
// Get ready for the next running task.
sp.l = lo(SYS_STACK);
sp.h = hi(SYS_STACK);
r0 = [fp - 8]; // r0 = old r0
// through instruction link, fp is still well being stored.
call _preemption_insert;
p0.l = lo(__kernel_schedtsk);
p0.h = hi(__kernel_schedtsk);
r0 = [p0];
p1.l = lo(__kernel_runtsk);
p1.h = hi(__kernel_runtsk);
p2.l = lo(__kernel_schedtsk);
p2.h = hi(__kernel_schedtsk);
[p1] = r0; // __kernel_runtsk = __kernel_schedtsk;
r0 += TCB_tskctxb;
// Attention! During restoring context, any interrupt may be harmful.
// Take care of the context. It is for the coming task, not for Ya! :)
p0 = r0; // p0 = takctxb;
// Let's begin!
csync;
r0 = [p0];
fp = r0; // fp restored.
p3 = [p2]; // p3 = schedtsk
r4 = [p3 + TCB_initb]; // p4 = schedtsk->initb
r4 += TCB_pc;
p2 = r4; // p2 = schedtsk->initb->task
r4 += (TCB_sp - TCB_pc);
p3 = r4; // p3 = schedtsk->initb->stk;
sp.l = lo(SYS_STACK);
sp.h = hi(SYS_STACK);
p0 += 4;
r0 = [p2];
reti = r0;
r0 = [p3];
usp = r0;
// Next, fp will be used to restore the other registers.
[--sp] = fp; // Save fp
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -