📄 swi.h62
字号:
;
.asg "b3,:SWI_F_enable$regs:", SWI_enable$regs
SWI_enable .macro
mvkl SWI_F_enable,b3 ; change to be FAR call
mvkh SWI_F_enable,b3
b b3 ; start branch to SWI_F_enable
mvkl sige?,b3 ; setup b3 pointer to come back here
mvkh sige?,b3
nop 3
sige?:
.endm
;
;# ======== SWI_end ========
; Invoked at the end of all other configuration
; declarations.
;
;#
;# Preconditions:
;# none
;#
;# Postconditions:
;# none
;#
.asg "", SWI_end$regs
SWI_end .macro
.endm
;
;# ======== SWI_getpri ========
;
;#
;# Preconditions:
;# a4 = address of the SWI object
;#
;# Postconditions:
;# a4 = priority mask of the SWI object
;#
.asg "a4", SWI_getpri$regs
SWI_getpri .macro dummy
CHK_void SWI_getpri, dummy
ldw *+a4(SWI_O_MASK), a4 ; load priority mask
nop 4
.endm
;
;# ======== SWI_inc ========
;
;#
;# Preconditions:
;# a4 = address of the SWI object
;#
;# Postconditions:
;# none
;#
;# Constraints and Calling Environment:
;# GIE must be 1, unless this macro is invoked from an interrupt context.
;# AMR = 0
;#
; Algorithm in pseudo-C:
; SWI_inc(SWI_Obj *swi)
; {
; atomic {
; swi->mailbox++;
; }
; SWI_F_post();
; }
;
.asg "a1,a2,b3,:SWI_F_post$regs:", SWI_inc$regs
SWI_inc .macro dummy
CHK_void SWI_inc, dummy
b inca? ; start ATOMIC
ldw *+a4(SWI_O_MAILBOX),a1 ; start load of mailbox value
mvkl incr?,b3 ; setup return pointer to come back
|| mvkl SWI_F_post,a2 ; make call to SWI_F_post FAR.
mvkh incr?,b3 ; from SWI_F_post
|| mvkh SWI_F_post,a2
nop
b a2 ; start branch to SWI_F_post, and
; initiate 5 more uninterruptible
; cycles
inca?:
add 1,a1,a1 ; mailbox + 1
stw a1,*+a4(SWI_O_MAILBOX) ; save new mailbox value
nop 3
; end atomic
incr?:
.endm
;
;# ======== SWI_init ========
; Runtime initialization for SWI
;
;#
;# Preconditions:
;# none
;#
;# Postconditions:
;# none
;#
;# Dependencies:
;# none
;#
;
.asg "", SWI_init$regs
SWI_init .macro
; only expand if the SWI module is configured by the user
.if (SWI$ = 1)
.endif
.endm
;
;# ======== SWI_or ========
;
;#
;# Preconditions:
;# a4 = address of the SWI object
;# b4 = mask
;#
;# Postconditions:
;# none
;#
;# Constraints and Calling Environment:
;# GIE must be 1, unless this macro is invoked from an interrupt context.
;# AMR = 0
;#
; Algorithm in pseudo-C:
; SWI_or(SWI_Obj *swi, Uns mask)
; {
; atomic {
; swi->mailbox = swi->mailbox | mask;
; }
; SWI_F_post();
; }
;
.asg "a1,a2,b3,:SWI_F_post$regs:", SWI_or$regs
SWI_or .macro dummy
CHK_void SWI_or, dummy
b ora? ; start ATOMIC
ldw *+a4(SWI_O_MAILBOX),a1 ; start load of mailbox value
mvkl orr?,b3 ; setup return pointer to come back
|| mvkl SWI_F_post,a2 ; make call to SWI_F_post FAR.
mvkh orr?,b3 ; from SWI_F_post
|| mvkh SWI_F_post,a2
nop
b a2 ; start branch to SWI_F_post, and
; initiate 5 more uninterruptible
; cycles
ora?: ; mailbox has now arrived in a1
or a1,b4,a1 ; mailbox | mask
stw a1,*+a4(SWI_O_MAILBOX) ; save new mailbox value
nop 3
; end atomic
orr?:
.endm
;
;# ======== SWI_pending ========
;
; Atomic test of SWI_D_pending
;
;#
;# Preconditions:
;#
;# Postconditions:
;# a4 = 1 if SWI_D_pending > 0
;# a4 = 0 if SWI_D_pending <= 0
;#
;
.asg "a4", SWI_pending$regs
SWI_pending .macro dummy
CHK_void SWI_pending, dummy
b pend? ; start ATOMIC
ldw *+b14(SWI_D_pending),a4 ; fetch SWI_D_pending
nop 3
b pend2? ; initiate 5 more uninterruptible
; cycles
pend?:
cmpgt a4,0,a4 ; a4 = 1 if SWI_D_pending > 0
; a4 = 0 if SWI_D_pending <= 0
nop 4
pend2?: ; end atomic
.endm
;
;# ======== SWI_post ========
;
;#
;# Preconditions:
;# a4 = address of the SWI object
;#
;# Postconditions:
;# none
;#
;# Constraints and Calling Environment:
;# Whenever this Macro (API) is not invoked from the interrupt context
;# such as an Interrupt Service Routine, GIE=1 must be ensured
;# as a precondition too.
;#
;# AMR = 0
;#
;
.asg "b3,:SWI_F_post$regs:", SWI_post$regs
SWI_post .macro dummy
CHK_void SWI_post, dummy
mvkl SWI_F_post,b3 ; change call to be FAR
mvkh SWI_F_post,b3
b b3
mvkl postr?,b3
mvkh postr?,b3
nop 3
postr?:
.endm
;
;# ======== SWI_raisepri ========
;
;#
;# Preconditions:
;# a4 = priority mask of desired priority
;# b14 = start of .bss
;#
;# Postconditions:
;# a4 = old priority mask
;#
;
; We OR the the old mask with the new mask to make
; sure we don't lower the priority.
;
.asg "a1,a2,a4", SWI_raisepri$regs
SWI_raisepri .macro dummy
CHK_void SWI_raisepri, dummy
ldw *+b14(SWI_D_curmask),a1 ; fetch SWI_D_curmask
shl a4,1,a4 ; a4 = mask << 1
nop 3
or a4,a1,a2 ; a2 = old OR new
lmbd 1,a2,a4 ; detect leftmost bit
neg a4,a2 ; negate bit count
add 31,a2,a2 ; add to 31 to get left shift count
mvk 1,a4 ; put seed in b4
shl a4,a2,a2 ; shift left to re-set leftmost bit
mv a1,a4 ; return old priority mask
|| stw a2,*+b14(SWI_D_curmask) ; save new pri mask
.endm
;
;# ======== SWI_restorepri ========
;
;#
;# Preconditions:
;# a4 = old priority mask
;# b14 = start of .bss
;# GIE = 1
;# SWI_D_lock < 0
;# not in an ISR
;#
;# Postconditions:
;# none
;#
;# Constraints and Calling Environment:
;# This macro must not be invoked from an ISR
;
.asg ":SWI_F_restorepri$regs:", SWI_restorepri$regs
SWI_restorepri .macro dummy
CHK_void SWI_restorepri, dummy
mvkl SWI_F_restorepri,b3 ; change call to be FAR
mvkh SWI_F_restorepri,b3
b b3
mvkl rpri?,b3
mvkh rpri?,b3
nop 3
rpri?:
.endm
;
;# ======== SWI_getmbox ========
;
; SWI_getmbox - get mailbox value for current swi
;
;#
;# Preconditions:
;# b14 = start of .bss
;#
;# Postconditions:
;# a4 = SWI_D_curmbox
;#
;
.asg "a4", SWI_getmbox$regs
SWI_getmbox .macro dummy
CHK_void SWI_getmbox, dummy
ldw *+b14(SWI_D_curmbox),a4 ; fetch SWI_D_curmbox
nop 4
.endm
;
;# ======== SWI_self ========
;
;#
;# Preconditions:
;# b14 = start of .bss
;#
;# Postconditions:
;# a4 = address of current swi object
;#
;
; What if SWI_D_curfxn is 0?
; This macro should be called only when current swi exists.
;
.asg "a4,b4", SWI_self$regs
SWI_self .macro dummy
CHK_void SWI_self, dummy
ldw *+b14(SWI_D_curfxn),a4 ; load *(SWI_D_curfxn)
mvkl SWI_O_FXNOBJ,b4 ; load SWI_O_FXNOBJ offset
mvkh SWI_O_FXNOBJ,b4
nop 2 ; wait for SWI_D_curfxn arrival
sub a4,b4,a4 ; a4 = SWI_D_curfxn - SWI_O_FXNOBJ
; = address of current SWI_Obj
.endm
;
;# ======== SWI_startup ========
;
;#
;# Preconditions:
;# SWI_D_lock = 0
;# GIE = 1
;#
;# Postconditions:
;# none
;#
;# Dependencies:
;# Must follow HWI_startup as GIE = 1 is a precondition to
;# SWI_startup and interrupts must be enabled before software interrupts
;# are allowed to run.
;
.asg "a4,:SWI_enable$regs:", SWI_startup$regs
SWI_startup .macro dummy
CHK_void SWI_startup, dummy
; only expand if the SWI module is configured by the user
.if (SWI$ = 1)
mvkl SWI_F_enable,a4 ; prepare for far branch
mvkh SWI_F_enable,a4
b a4 ; start branch to SWI_F_enable
mvkl swii?,b3 ; setup b3 pointer to come back here
mvkh swii?,b3
nop 3
swii?:
.endif
.endm
;
;# ======== SWI_unlocked ========
;
; Atomic test of SWI_D_lock
;
;#
;# Preconditions:
;#
;# Postconditions:
;# a4 = 1 if SWI_D_lock < 0
;# a4 = 0 if SWI_D_lock >= 0
;#
;
.asg "a4", SWI_unlocked$regs
SWI_unlocked .macro dummy
CHK_void SWI_unlocked, dummy
b unloc? ; start ATOMIC
ldw *+b14(SWI_D_lock),a4 ; fetch SWI_D_lock
nop 3
b unloc2? ; initiate 5 more uninterruptible
; cycles
unloc?:
cmplt a4,0,a4 ; a4 = 1 if SWI_D_lock < 0
; a4 = 0 if SWI_D_lock >= 0
nop 4
unloc2?: ; end atomic
.endm
.endif ; ($isdefed("SWI_") = 0)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -