📄 swi.h62
字号:
;
; Copyright 2003 by Texas Instruments Incorporated.
; All rights reserved. Property of Texas Instruments Incorporated.
; Restricted rights to use, duplicate or disclose this code are
; granted through contract.
;
;
; "@(#) DSP/BIOS 4.90.270 12-18-03 (barracuda-o04)"
;
; ======== swi.h62 ========
;
;
.if ($isdefed("SWI_") = 0) ; prevent multiple includes of this file
SWI_ .set 1
.include chk.h62
.include fxn.h62
.include gbl.h62
.include hwi.h62
.include sts.h62
;
; ======== SWI_Obj ========
;
SWI_Obj .struct
lock .word 1 ; not posted: -1, posted: 0
ready .word 1 ; this points to rdy list
mask .word 1 ; priority bit-mask
link .word 1 ; to next element in rdy list. NULL(0) means END
initkey .word 1 ; the initial value for the mailbox
mailbox .word 1 ; the swi's mailbox
fxnobj .tag FXN_Obj ; the function (and its args) to execute
stslock .word 1 ; equals 0 <=> STS_set/delta "in progress"
sts .word 1 ; pointer to STS_Obj
SWI_A_OBJSIZE .endstruct
SWI_BASE .set SWI_Obj.lock
SWI_O_LOCK .set SWI_Obj.lock-SWI_BASE
SWI_O_READY .set SWI_Obj.ready-SWI_BASE
SWI_O_MASK .set SWI_Obj.mask-SWI_BASE
SWI_O_LINK .set SWI_Obj.link-SWI_BASE
SWI_O_INITKEY .set SWI_Obj.initkey-SWI_BASE
SWI_O_MAILBOX .set SWI_Obj.mailbox-SWI_BASE
SWI_O_FXNOBJ .set SWI_Obj.fxnobj-SWI_BASE
SWI_O_STSLOCK .set SWI_Obj.stslock-SWI_BASE
SWI_O_STS .set SWI_Obj.sts-SWI_BASE
.global SWI_D_curmask, SWI_D_curset, SWI_D_pending, SWI_D_curfxn
.global SWI_D_lock, SWI_D_execaddr, SWI_D_runaddr
.global SWI_D_rdytab, SWI_D_rdybeg
.global SWI_D_curmbox, SWI_D_ihook, SWI_D_ehook
.global SWI_F_enable, SWI_F_exec, SWI_F_iexec, SWI_F_post, SWI_F_run
.global SWI_F_restorepri
.global SWI_NULL
; symbols that also need to be accessed from C.
.global _SWI_D_curmask, _SWI_D_lock
.global _SWI_D_rdybeg
.global SWI_EHOOKFXN, SWI_IHOOKFXN ; defined by the Config Tool.
;
;# ======== SWI_Obj ========
;
;#
;# Preconditions:
;# none
;#
;# Postconditions:
;# none
;#
;
.asg ":FXN_Obj$regs:,:STS_Obj$regs:", SWI_Obj$regs
SWI_Obj .macro cflag, name, id, fxn, pri, mailbox, arg0, arg1, dorta
CHK_nargs "SWI_Obj", fxn
.if ($symcmp(":CHK_status:", "error") = 0)
.mexit
.endif
;
; pri, mailbox, arg0 and arg1 are optional -- defaults if necessary
;
.if ($symlen(":pri:") = 0)
.asg "0", pri
.asg "0", mailbox
.asg "0", arg0
.asg "0", arg1
.elseif ($symlen(":mailbox:") = 0)
.asg "0", mailbox
.asg "0", arg0
.asg "0", arg1
.elseif ($symlen(":arg0:") = 0)
.asg "0", arg0
.asg "0", arg1
.elseif ($symlen(":arg1:") = 0)
.asg "0", arg1
.else
CHK_nargs "SWI_Obj", arg1
.if ($symcmp(":CHK_status:", "error") = 0)
.mexit
.endif
.endif
.if (:cflag: = 0)
.mexit
.endif
.global :name:, fxn
:name: .tag SWI_Obj
:name: .usect ".swi", STD_TARGWORDMAUS * 6, STD_TARGWORDMAUS
.sect ".cinit"
.align 8
.field STD_TARGWORDMAUS * 6
.field :name:
.field -1 ; lock (not posted)
.field SWI_D_rdytab+(:pri:*2+1)*STD_TARGWORDMAUS; ready
.field 1 << :pri: ; mask
.field 0 ; link
.field :mailbox: ; initkey
.field :mailbox: ; mailbox
FXN_Obj :name:$fxn, :fxn:, :arg0:, :arg1:, ".swi"
:name:$aaa .usect ".swi", STD_TARGWORDMAUS * 2, STD_TARGWORDMAUS
.sect ".cinit"
.align 8
.field STD_TARGWORDMAUS * 2
.field :name:$aaa
.field -1 ; stslock
.if :dorta:
.field :name:$sts ; pointer to STS_Obj
.else
.field 0
.endif
; only allocate STS object if 'Do RTA' is TRUE
.if :dorta:
STS_Obj 1, :name:$sts, 0, 0, 0
.endif
.endm
;
;# ======== SWI_andn ========
;
;#
;# 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_andn(SWI_Obj *swi, Uns mask)
; {
; if(swi->mailbox != 0){
;
; atomic {
; swi->mailbox = swi->mailbox & ~mask
; }
;
; if(swi->mailbox == 0){
; SWI_F_post();
; }
; }
; }
.asg "a1,b2,b3,b4,b7,:SWI_F_post$regs:", SWI_andn$regs
SWI_andn .macro dummy
CHK_void SWI_andn, dummy
b andna?
mvc csr, b7 ; save current CSR
and ~1,b7,b2 ; mask GIE
mvc b2, csr ; store new CSR, GIE now 0
not b4,b4 ; mask = ~mask
nop
andna?: ; start ATOMIC
ldw *+a4(SWI_O_MAILBOX),a1 ; load of mailbox value
nop 4
[!a1] b andnr? ; if mailbox already 0 then done
[!a1] mvc b7,csr ; restore GIE (end atomic)
nop 4
; at this point the mailbox is not 0
and a1,b4,a1 ; new mailbox = old mbx & ~mask
[!a1] mvkl SWI_F_post,b3 ; change to be FAR call
[!a1] mvkh SWI_F_post,b3
[!a1] b b3 ; if mbx 0 start branch to SWI_F_post
[a1] b andnr? ; else start branch to done
stw a1,*+a4(SWI_O_MAILBOX) ; write new mailbox value
mvc b7,csr ; restore GIE (end atomic)
[!a1] mvkl andnr?,b3 ; setup return from SWI_F_post
[!a1] mvkh andnr?,b3
nop ; final slot for branch
andnr?:
.endm
;
;# ======== SWI_busy ========
;
; Atomic test of SWI_D_lock and SWI_D_pending
;
;#
;# Preconditions:
;#
;# Postconditions:
;# a4 = 1 if SWI_D_pending > 0 OR SWI_D_lock >= 0
;# a4 = 0 if SWI_D_pending <= 0 AND SWI_D_lock < 0
;#
;
; Algorithm in pseudo-C:
; start atomic {
; if (SWI is locked) {
; return (1);
; }
; if (SWI_pending) {
; return (1);
; }
; else {
; return (0);
; }
; } end atomic
;
.asg "a1,a4", SWI_busy$regs
SWI_busy .macro dummy
CHK_void SWI_busy, dummy
b pend? ; start ATOMIC
ldw *+b14(SWI_D_lock),a1 ; fetch SWI_D_lock
ldw *+b14(SWI_D_pending),a4 ; fetch SWI_D_pending
nop 2
b pend2? ; initiate 5 more uninterruptible
; cycles
pend?:
cmplt a1,0,a1 ; a1 = 1 if SWI_D_lock < 0
; a1 = 0 if SWI_D_lock >= 0
; if SWI_D_lock >= 0
[!a1] mvk 1,a4 ; return SWI_busy = 1
; else check SWI_D_pending
[a1] cmpgt a4,0,a4 ; a4 = 1 if SWI_D_pending > 0
; a4 = 0 if SWI_D_pending <= 0
; if SWI_D_pending > 0
; return SWI_busy = 1
; else
; return SWI_busy = 0
nop 2
pend2?: ; end atomic
.endm
;
;# ======== SWI_config ========
;
; Set the cinit record for the SWI hook functions.
;
;#
;# Preconditions:
;# none
;#
;# Postconditions:
;# none
;#
.asg "", SWI_config$regs
SWI_config .macro _ehook, _ihook, _execfxn, _runfxn
.endm
;
;# ======== SWI_dec ========
;
;#
;# 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_dec(SWI_Obj *swi)
; {
; if(swi->mailbox != 0){
;
; atomic {
; swi->mailbox--;
; }
;
; if(swi->mailbox == 0){
; SWI_F_post();
; }
; }
; }
;
.asg "a1,b2,b3,b4,b7,:SWI_F_post$regs:", SWI_dec$regs
SWI_dec .macro dummy
CHK_void SWI_dec, dummy
b deca?
mvc csr, b7 ; save current CSR
and ~1,b7,b2 ; mask GIE
mvc b2, csr ; store new CSR, GIE now 0
mvk 1,b4 ; load value for upcoming decrement
nop
deca?: ; start ATOMIC
ldw *+a4(SWI_O_MAILBOX),a1 ; load of mailbox value
nop 4
[!a1] b decr? ; if mailbox already 0 then done
[!a1] mvc b7,csr ; restore GIE (end atomic)
nop 4
; at this point the mailbox is not 0
sub a1,b4,a1 ; new mailbox = old mbx - 1
[!a1] mvkl SWI_F_post,b3 ; change to be FAR call
[!a1] mvkh SWI_F_post,b3
[!a1] b b3 ; if mbx 0 start branch to SWI_F_post
[a1] b decr? ; else start branch to done
stw a1,*+a4(SWI_O_MAILBOX) ; write new mailbox value
mvc b7,csr ; restore GIE (end atomic)
[!a1] mvkl decr?,b3 ; setup return from SWI_F_post
[!a1] mvkh decr?,b3
nop ; final slot for branch
decr?:
.endm
;
;# ======== SWI_disable ========
;
;#
;# Preconditions:
;# b14 = start of .bss
;# GIE = 1 (interrupts must be enabled)
;#
;# Postconditions:
;# none
;#
;# Constraints and Calling Environment:
;# The calls to HWI_enter and HWI_exit required at the beginning
;# and end of a hardware ISR automatically disable and reenable
;# swi handling. SWI_disable or SWI_enable should not be called
;# within a hardware ISR.
;#
;
; Algoritm:
; atomic {
; SWI_D_lock++
; }
;
.asg "a4", SWI_disable$regs
SWI_disable .macro dummy
CHK_void SWI_disable, dummy
b disa? ; start ATOMIC
ldw *+b14(SWI_D_lock),a4 ; fetch SWI_D_lock
nop 3
b disa2? ; initiate 5 more uninterruptible
; cycles
disa?:
add 1,a4,a4 ; SWI_D_lock + 1
stw a4,*+b14(SWI_D_lock) ; save new SWI_D_lock
nop 3
disa2?: ; end atomic
.endm
;
;# ======== SWI_enable ========
;
;#
;# Preconditions:
;# SWI_D_lock >= 0 (this means SWI execution is disabled, i.e. "locked")
;# GIE = 1 (interrupts must be enabled)
;#
;# Postconditions:
;# none
;#
;# Constraints and Calling Environment:
;# The calls to HWI_enter and HWI_exit required at the beginning
;# and end of a hardware ISR automatically disable and reenable
;# swi handling. SWI_disable or SWI_enable should not be called
;# within a hardware ISR.
;#
;# AMR = 0
;#
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -