mirror of
https://github.com/elliotnunn/powermac-rom.git
synced 2024-06-06 17:29:32 +00:00
7fdc813d8f
Namely queues, semaphores, critical regions, event groups and "notifications". The MP calls implementing these services have been named after their MPLibrary wrapper functions. This convention will be followed in the future (no more NKCreateEvent).
3032 lines
73 KiB
ArmAsm
3032 lines
73 KiB
ArmAsm
####### ## ## ######## ## ## ######## ######
|
|
## ## ## ## ## ## ## ## ## ##
|
|
## ## ## ## ## ## ## ## ##
|
|
## ## ## ## ###### ## ## ###### ######
|
|
## ## ## ## ## ## ## ## ## ##
|
|
## ## ## ## ## ## ## ## ## ##
|
|
##### ## ####### ######## ####### ######## ######
|
|
|
|
|
|
|
|
## ######## ####### ###### ######## ######## ### ######## ########
|
|
#### ## ## ## ## ## ## ## ## ## ## ## ##
|
|
## ## ## ## ## ## ## ## ## ## ## ##
|
|
## ####### ## ## ## ######## ###### ## ## ## ######
|
|
## ## ## ## ## ## ## ## ## ######### ## ##
|
|
## ## ## ## ## ## ## ## ## ## ## ## ## ##
|
|
###### ###### ##### ## ###### ## ## ######## ## ## ## ########
|
|
|
|
; RET OSStatus r3, QueueID r4
|
|
|
|
DeclareMPCall 15, MPCreateQueue
|
|
|
|
MPCreateQueue
|
|
|
|
li r8, Queue.Size
|
|
bl PoolAlloc_with_crset
|
|
mr. r31, r8
|
|
beq+ ScrambleMPCall
|
|
|
|
; List of messages waiting for tasks
|
|
InitList r8, 'MSGQ', scratch=r16
|
|
|
|
; List of blocked tasks waiting to be notified of messages
|
|
addi r9, r8, Queue.Messages
|
|
InitList r9, 'NOTQ', scratch=r16
|
|
|
|
_Lock PSA.SchLock, scratch1=r16, scratch2=r17
|
|
|
|
li r9, Queue.kIDClass
|
|
bl MakeID
|
|
|
|
cmpwi r8, 0
|
|
bne+ @nofail
|
|
mr r8, r31
|
|
bl PoolFree
|
|
b ReleaseAndScrambleMPCall
|
|
@nofail
|
|
|
|
mfsprg r30, 0
|
|
lwz r30, EWA.PA_CurTask(r30)
|
|
|
|
stw r8, Queue.BlockedTasks + LLL.Freeform(r31)
|
|
|
|
lwz r17, Task.ProcessID(r30)
|
|
stw r17, Queue.ProcessID(r31)
|
|
|
|
mr r4, r8
|
|
|
|
li r17, 0
|
|
stw r17, Queue.ReserveCount(r31)
|
|
stw r17, Queue.ReservePtr(r31)
|
|
stw r17, Queue.BlockedTaskCount(r31)
|
|
stw r17, Queue.MessageCount(r31)
|
|
|
|
b ReleaseAndReturnZeroFromMPCall
|
|
|
|
|
|
|
|
## ####### ####### ######## ######## ## ######## ######## ########
|
|
#### ## ## ## ## ## ## ## ## ## ## ##
|
|
## ## ## ## ## ## ## ## ## ## ##
|
|
## ######## ## ## ## ## ###### ## ###### ## ######
|
|
## ## ## ## ## ## ## ## ## ## ## ## ##
|
|
## ## ## ## ## ## ## ## ## ## ## ##
|
|
###### ####### ##### ## ######## ######## ######## ######## ## ########
|
|
|
|
; Delete a message queue:
|
|
; 1. Delete its messages.
|
|
; 2. Call UnblockBlueIfCouldBePolling on the queue?
|
|
; 3. Unblock waiting tasks with kMPDeletedErr, calling FlagSchEvaluationIfTaskRequires on each.
|
|
; 4. Delete the queue structure and its ID.
|
|
|
|
; ARG QueueID r3
|
|
; RET OSStatus r3
|
|
|
|
DeclareMPCall 16, MPDeleteQueue
|
|
|
|
MPDeleteQueue
|
|
|
|
_Lock PSA.SchLock, scratch1=r16, scratch2=r17
|
|
|
|
mr r8, r3
|
|
bl LookupID
|
|
cmpwi r9, Queue.kIDClass
|
|
|
|
mr r31, r8
|
|
bne+ ReleaseAndReturnMPCallInvalidIDErr
|
|
|
|
|
|
; Delete all auto-allocated messages
|
|
@note_free_loop
|
|
addi r30, r31, Queue.Messages
|
|
lwz r8, Queue.Messages + LLL.Next(r31)
|
|
cmpw r8, r30
|
|
beq- @exit_note_free_loop
|
|
RemoveFromList r8, scratch1=r16, scratch2=r17
|
|
bl PoolFree
|
|
b @note_free_loop
|
|
@exit_note_free_loop
|
|
|
|
|
|
; Delete all pre-allocated messages
|
|
lwz r30, Queue.ReservePtr(r31)
|
|
@notr_free_loop
|
|
mr. r8, r30
|
|
beq- @exit_notr_free_loop
|
|
lwz r30, Message.LLL + LLL.Next(r30)
|
|
bl PoolFree
|
|
b @notr_free_loop
|
|
@exit_notr_free_loop
|
|
|
|
|
|
mr r8, r3
|
|
bl UnblockBlueIfCouldBePolling
|
|
|
|
|
|
; UNBLOCK the tasks that are blocked waiting on this queue.
|
|
; From the task's perspective, MPWaitOnQueue will return
|
|
; kMPDeletedErr, because we tweak the task's ContextBlock.
|
|
@task_unblock_loop
|
|
|
|
; Peek at our MSGQ queue of blocked tasks
|
|
addi r30, r31, Queue.BlockedTasks
|
|
lwz r16, Queue.BlockedTasks + LLL.Next(r31)
|
|
cmpw r16, r30
|
|
subi r8, r16, Task.QueueMember
|
|
beq- @exit_task_loop
|
|
|
|
; Manipulate its r3 from afar
|
|
lwz r17, Task.ContextBlockPtr(r8)
|
|
li r18, kMPDeletedErr
|
|
stw r18, ContextBlock.r3(r17)
|
|
|
|
; If blocked with timeout, dequeue task's internal timer
|
|
lbz r17, Task.Timer + Timer.Byte3(r8)
|
|
cmpwi r17, 1
|
|
bne- @no_timeout
|
|
addi r8, r8, Task.Timer
|
|
bl DequeueTimer
|
|
@no_timeout
|
|
|
|
; Remove from this MSGQ
|
|
lwz r16, Queue.BlockedTasks + LLL.Next(r31)
|
|
RemoveFromList r16, scratch1=r17, scratch2=r18
|
|
|
|
; Put RDYQ
|
|
subi r8, r16, Task.QueueMember
|
|
bl TaskReadyAsPrev
|
|
|
|
bl FlagSchEvaluationIfTaskRequires
|
|
|
|
b @task_unblock_loop
|
|
@exit_task_loop
|
|
|
|
|
|
; Delete the actual Queue structure and its ID
|
|
mr r8, r31
|
|
bl PoolFree
|
|
mr r8, r3
|
|
bl DeleteID
|
|
|
|
|
|
b ReleaseAndReturnZeroFromMPCall
|
|
|
|
|
|
|
|
####### ####### ####### ######## ######## ###### ######## ######## ## ## ########
|
|
## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ##
|
|
## ## ## ## ## ## ## ## ## ## ## ## ## ## ##
|
|
####### ######## ## ## ######## ###### ###### ###### ######## ## ## ######
|
|
## ## ## ## ## ## ## ## ## ## ## ## ## ## ##
|
|
## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ##
|
|
####### ####### ##### ## ## ## ######## ###### ######## ## ## ### ########
|
|
|
|
; Reserve space for messages for this queue.
|
|
; (guarantees message delivery)
|
|
|
|
; Reserved messages have signature 'notr' (vs. 'note').
|
|
|
|
; ARG QueueID r3, ItemCount r4
|
|
; RET OSStatus r3
|
|
|
|
DeclareMPCall 39, MPSetQueueReserve
|
|
|
|
MPSetQueueReserve
|
|
|
|
cmpwi r4, 0
|
|
blt+ ReturnMPCallOOM
|
|
|
|
_Lock PSA.SchLock, scratch1=r16, scratch2=r17
|
|
|
|
mr r8, r3
|
|
bl LookupID
|
|
cmpwi r9, Queue.kIDClass
|
|
mr r31, r8
|
|
bne+ ReleaseAndReturnMPCallInvalidIDErr
|
|
|
|
lwz r29, Queue.ReserveCount(r31)
|
|
lwz r30, Queue.ReservePtr(r31)
|
|
|
|
cmpw r29, r4
|
|
beq+ ReleaseAndReturnZeroFromMPCall
|
|
blt- @make_more
|
|
|
|
|
|
; NEW < OLD
|
|
@free_loop
|
|
mr. r8, r30
|
|
beq- @free_loop_failed
|
|
subi r29, r29, 1
|
|
lwz r30, LLL.Next(r30)
|
|
bl PoolFree
|
|
cmpw r29, r4
|
|
bgt+ @free_loop
|
|
|
|
;free loop succeeded
|
|
stw r4, Queue.ReserveCount(r31)
|
|
stw r30, Queue.ReservePtr(r31)
|
|
b ReleaseAndReturnZeroFromMPCall
|
|
|
|
@free_loop_failed
|
|
stw r29, Queue.ReserveCount(r31)
|
|
stw r30, Queue.ReservePtr(r31)
|
|
b ReleaseAndReturnMPCallOOM
|
|
|
|
|
|
; NEW > OLD
|
|
@make_more
|
|
@alloc_loop
|
|
li r8, Message.Size
|
|
bl PoolAlloc_with_crset
|
|
cmpwi r8, 0
|
|
beq+ ReleaseAndScrambleMPCall
|
|
|
|
addi r29, r29, 1
|
|
|
|
lisori r17, Message.kReservedSignature
|
|
stw r17, Message.LLL + LLL.Signature(r8)
|
|
|
|
stw r30, Message.LLL + LLL.Next(r8)
|
|
|
|
stw r29, Queue.ReserveCount(r31)
|
|
|
|
cmpw r29, r4
|
|
stw r8, Queue.ReservePtr(r31)
|
|
mr r30, r8
|
|
blt+ @alloc_loop
|
|
|
|
|
|
b ReleaseAndReturnZeroFromMPCall
|
|
|
|
|
|
|
|
## ######## ####### ## ## ####### ######## #### ######## ## ##
|
|
#### ## ## ## ## ### ## ## ## ## ## ## ## ##
|
|
## ## ## ## #### ## ## ## ## ## ## ####
|
|
## ## ## ## ## ## ## ## ## ## ## ###### ##
|
|
## ## ## ## ## ## #### ## ## ## ## ## ##
|
|
## ## ## ## ## ### ## ## ## ## ## ##
|
|
###### ## ##### ## ## ## ####### ## #### ## ##
|
|
|
|
; Sends a 12-byte message to the specified queue
|
|
|
|
; ARG QueueID r3, long r4, long r5, long r6
|
|
|
|
DeclareMPCall 17, MPNotifyQueue
|
|
|
|
MPNotifyQueue
|
|
|
|
_Lock PSA.SchLock, scratch1=r16, scratch2=r17
|
|
|
|
mr r8, r3
|
|
bl LookupID
|
|
cmpwi r9, Queue.kIDClass
|
|
|
|
mr r31, r8
|
|
bne+ ReleaseAndReturnMPCallInvalidIDErr
|
|
|
|
lwz r16, Queue.ReserveCount(r31)
|
|
li r8, Message.Size
|
|
cmpwi r16, 0
|
|
bne- @try_reserve
|
|
|
|
;no reservation available
|
|
bl PoolAlloc_with_crset
|
|
|
|
cmpwi r8, 0
|
|
beq+ ReleaseAndScrambleMPCall
|
|
|
|
lisori r17, Message.kSignature
|
|
stw r17, Message.LLL + LLL.Signature(r8)
|
|
|
|
b @common
|
|
|
|
@try_reserve
|
|
lwz r17, Queue.ReservePtr(r31)
|
|
mr. r8, r17
|
|
beq+ ReleaseAndReturnMPCallOOM
|
|
|
|
lwz r17, Message.LLL + LLL.Next(r17)
|
|
stw r17, Queue.ReservePtr(r31)
|
|
|
|
@common
|
|
; Got a message ptr in r8!
|
|
|
|
; Fill it with lies
|
|
lwz r16, ContextBlock.r6(r6)
|
|
stw r4, Message.Word1(r8)
|
|
stw r5, Message.Word2(r8)
|
|
stw r16, Message.Word3(r8)
|
|
|
|
bl EnqueueMessage ; Message *r8, Queue *r31
|
|
|
|
|
|
b ReleaseAndReturnZeroFromMPCall
|
|
|
|
|
|
|
|
### ####### ## ## ###### ###### ###
|
|
## ## ## ### ### ## ## ## ## ##
|
|
## ## ## #### #### ## ## ##
|
|
## ## ## ## ### ## ###### ## #### ##
|
|
## ## ## ## ## ## ## ## ## ##
|
|
## ## ## ## ## ## ## ## ## ##
|
|
### ##### ## ## ## ###### ###### ###
|
|
|
|
; Enqueue a note/notr object.
|
|
|
|
; Odd way of unblocking task (does not touch r3 directly):
|
|
; 1. Add message to queue.
|
|
; 2. If task waiting, unblock with rewound PC to retry syscall.
|
|
|
|
; ARG Message *r8, Queue *r31
|
|
|
|
EnqueueMessage
|
|
|
|
addi r17, r31, Queue.Messages
|
|
stw r17, LLL.Freeform(r8)
|
|
|
|
InsertAsPrev r8, r17, scratch=r16
|
|
|
|
lwz r18, Queue.MessageCount(r31)
|
|
addi r18, r18, 1
|
|
stw r18, Queue.MessageCount(r31)
|
|
|
|
mflr r27
|
|
|
|
lwz r8, Queue.BlockedTasks + LLL.Freeform(r31)
|
|
bl UnblockBlueIfCouldBePolling
|
|
|
|
; Got a task to unblock straight away?
|
|
lwz r16, Queue.BlockedTasks + LLL.Next(r31)
|
|
cmpw r16, r31
|
|
subi r8, r16, Task.QueueMember
|
|
beq- @no_task
|
|
|
|
; Saves us special-casing
|
|
lwz r17, Task.ContextBlockPtr(r8)
|
|
lwz r18, ContextBlock.CodePtr(r17)
|
|
subi r18, r18, 4
|
|
stw r18, ContextBlock.CodePtr(r17)
|
|
|
|
; De-fang the task's blocking timeout
|
|
lbz r17, Task.Timer + Timer.Byte3(r8)
|
|
cmpwi r17, 1
|
|
bne- @no_timeout
|
|
addi r8, r8, Task.Timer
|
|
bl DequeueTimer
|
|
@no_timeout
|
|
|
|
; Remove the task from this MSGQ
|
|
lwz r16, Queue.BlockedTasks + LLL.Next(r31)
|
|
RemoveFromList r16, scratch1=r17, scratch2=r18
|
|
|
|
lwz r18, Queue.BlockedTaskCount(r31)
|
|
subi r18, r18, 1
|
|
stw r18, Queue.BlockedTaskCount(r31)
|
|
|
|
subi r8, r16, Task.QueueMember
|
|
|
|
; And add it back to the latency-protection RDYQ
|
|
li r17, Task.kLatencyProtectPriority
|
|
stb r17, Task.Priority(r8)
|
|
|
|
bl TaskReadyAsPrev
|
|
bl CalculateTimeslice
|
|
|
|
bl FlagSchEvaluationIfTaskRequires
|
|
@no_task
|
|
|
|
mtlr r27
|
|
blr
|
|
|
|
|
|
|
|
## ####### ####### ## ## ### #### ########
|
|
#### ## ## ## ## ## ## ## ## ## ## ##
|
|
## ## ## ## ## ## ## ## ## ## ## ##
|
|
## ####### ## ## ## ## ## ## ## ## ##
|
|
## ## ## ## ## ## ## ## ## ######### ## ##
|
|
## ## ## ## ## ## ## ## ## ## ## ##
|
|
###### ####### ##### ## ### ### ## ## #### ##
|
|
|
|
; Get a message from the specified queue, or fail.
|
|
|
|
; Abbreviated summary of cases:
|
|
; 1. Return a pending message
|
|
; 2. Time out instantly
|
|
; 3. Move task to MSGQ from RDYQ and arm timer
|
|
; 4. Move task to MSGQ from RDYQ, no timeout
|
|
|
|
; ARG QueueID r3, Duration r7
|
|
; RET OSStatus r3, long r4, long r5, long r6
|
|
|
|
DeclareMPCall 18, MPWaitOnQueue
|
|
|
|
MPWaitOnQueue
|
|
|
|
_Lock PSA.SchLock, scratch1=r16, scratch2=r17
|
|
|
|
mr r8, r3
|
|
bl LookupID
|
|
cmpwi r9, Queue.kIDClass
|
|
bne+ ReleaseAndReturnMPCallInvalidIDErr
|
|
|
|
mr r31, r8
|
|
|
|
lwz r16, Queue.Messages + LLL.Next(r31)
|
|
addi r17, r31, Queue.Messages
|
|
cmpw r16, r17
|
|
beq- @no_messages_pending
|
|
|
|
;messages pending
|
|
lwz r4, Message.Word1(r16)
|
|
lwz r5, Message.Word2(r16)
|
|
lwz r17, Message.Word3(r16)
|
|
stw r17, ContextBlock.r6(r6)
|
|
|
|
RemoveFromList r16, scratch1=r17, scratch2=r18
|
|
|
|
lwz r18, Queue.MessageCount(r31)
|
|
subi r18, r18, 1
|
|
stw r18, Queue.MessageCount(r31)
|
|
|
|
lbz r17, Message.LLL + LLL.Signature + 3(r16) ; 'r' if mem-reserved message, else 'e'
|
|
mr r8, r16
|
|
cmpwi r17, Message.kReservedSignature & 0xFF
|
|
beq- @immediate_msg_was_reserved
|
|
|
|
;immediate message was not reserved ... return noErr
|
|
bl PoolFree
|
|
b ReleaseAndReturnZeroFromMPCall
|
|
|
|
@immediate_msg_was_reserved ; ... return noErr
|
|
lwz r17, Queue.ReservePtr(r31)
|
|
stw r16, Queue.ReservePtr(r31)
|
|
stw r17, LLL.Next(r16)
|
|
b ReleaseAndReturnZeroFromMPCall
|
|
|
|
|
|
; The blocking case (eew!)
|
|
|
|
@no_messages_pending
|
|
lwz r17, ContextBlock.r7(r6)
|
|
mfsprg r30, 0
|
|
|
|
;special case: zero timeout ... return
|
|
cmpwi r17, 0
|
|
lwz r19, EWA.PA_CurTask(r30)
|
|
beq+ ReleaseAndTimeoutMPCall
|
|
|
|
;special case: blue may not block
|
|
lwz r16, Task.Flags(r19)
|
|
rlwinm. r16, r16, 0, Task.kFlagBlue, Task.kFlagBlue
|
|
beq- @bot_blue
|
|
stw r3, PSA.BlueSpinningOn(r1)
|
|
b ReleaseAndReturnMPCallBlueBlocking
|
|
@bot_blue
|
|
|
|
;committed to blocking the calling task
|
|
|
|
; Remove from ready queue
|
|
mr r8, r19
|
|
bl TaskUnready
|
|
|
|
; Add to this queue
|
|
lwz r19, EWA.PA_CurTask(r30)
|
|
|
|
addi r16, r31, Queue.BlockedTasks
|
|
addi r17, r19, Task.QueueMember
|
|
|
|
stw r16, LLL.FreeForm(r17)
|
|
InsertAsPrev r17, r16, scratch=r18
|
|
|
|
lwz r18, Queue.BlockedTaskCount(r31)
|
|
addi r18, r18, 1
|
|
stw r18, Queue.BlockedTaskCount(r31)
|
|
|
|
; Decide whether call can time out
|
|
_lstart r16, 0x7fffffff ; "forever"
|
|
lwz r17, ContextBlock.r7(r6)
|
|
_lfinish
|
|
|
|
addi r30, r19, Task.Timer
|
|
cmpw r17, r16
|
|
|
|
li r16, 2
|
|
beq- @wait_forever
|
|
|
|
;committed to arming task's built-in timer (finite timeout)
|
|
stb r16, Timer.Kind(r30)
|
|
stw r19, Timer.ParentTaskPtr(r30)
|
|
mr r8, r17
|
|
|
|
; Convert that timeout to a tick count
|
|
bl TimebaseTicksPerPeriod
|
|
mr r27, r8
|
|
mr r28, r9
|
|
|
|
bl GetTime
|
|
mfxer r16
|
|
addc r9, r9, r28
|
|
adde r8, r8, r27
|
|
mtxer r16
|
|
|
|
; Now r8/r9 = absolute timeout date
|
|
stw r8, Timer.Time(r30)
|
|
stw r9, Timer.Time+4(r30)
|
|
|
|
mr r8, r30
|
|
bl EnqueueTimer
|
|
|
|
@wait_forever
|
|
b BlockMPCall
|
|
|
|
|
|
|
|
## ####### ####### ####### ## ## ######## ######## ## ##
|
|
#### ## ## ## ## ## ## ## ## ## ## ## ## ##
|
|
## ## ## ## ## ## ## ## ## ## ## ## ####
|
|
## ######## ## ## ## ## ## ## ###### ######## ##
|
|
## ## ## ## ## ## ## ## ## ## ## ## ## ##
|
|
## ## ## ## ## ## ## ## ## ## ## ## ##
|
|
###### ####### ##### ## ##### ## ####### ######## ## ## ##
|
|
|
|
; Non-blocking peek at contents of queue (undocumented)
|
|
; Returns timeout if empty, noErr if non-empty
|
|
|
|
; ARG QueueID r3
|
|
; RET OSStatus r3
|
|
|
|
DeclareMPCall 19, MPQueryQueue
|
|
|
|
MPQueryQueue
|
|
|
|
_Lock PSA.SchLock, scratch1=r16, scratch2=r17
|
|
|
|
mr r8, r3
|
|
bl LookupID
|
|
|
|
cmpwi r9, Queue.kIDClass
|
|
bne+ ReleaseAndReturnMPCallInvalidIDErr
|
|
|
|
mr r31, r8
|
|
lwz r16, Queue.Messages + LLL.Next(r31)
|
|
addi r17, r31, Queue.Messages
|
|
cmpw r16, r17
|
|
|
|
beq+ ReleaseAndTimeoutMPCall
|
|
|
|
b ReleaseAndReturnZeroFromMPCall
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
###### ######## ## ## ### ######## ## ## ####### ######## ######## ######
|
|
## ## ## ### ### ## ## ## ## ## ## ## ## ## ## ## ## ##
|
|
## ## #### #### ## ## ## ## ## ## ## ## ## ## ## ##
|
|
###### ###### ## ### ## ## ## ######## ######### ## ## ######## ###### ######
|
|
## ## ## ## ######### ## ## ## ## ## ## ## ## ##
|
|
## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ##
|
|
###### ######## ## ## ## ## ## ## ## ####### ## ## ######## ######
|
|
|
|
|
|
|
|
####### ##### ###### ###### ######## ######## ### ######## ########
|
|
## ## ## ## ## ## ## ## ## ## ## ## ## ## ##
|
|
## ## ## ## ## ## ## ## ## ## ## ##
|
|
####### ## ## ###### ## ######## ###### ## ## ## ######
|
|
## ## ## ## ## ## ## ## ######### ## ##
|
|
## ## ## ## ## ## ## ## ## ## ## ## ## ##
|
|
######### ##### ###### ###### ## ## ######## ## ## ## ########
|
|
|
|
; ARG maxValue r3, initialValue r4
|
|
; RET OSStatus r3, SemaphoreID r5
|
|
|
|
DeclareMPCall 20, MPCreateSemaphore
|
|
|
|
MPCreateSemaphore
|
|
|
|
cmpw r4, r3
|
|
bgt+ ReturnMPCallOOM
|
|
|
|
li r8, Semaphore.Size
|
|
bl PoolAlloc_with_crset
|
|
mr. r31, r8
|
|
beq+ ScrambleMPCall
|
|
|
|
InitList r31, Semaphore.kSignature, scratch=r16
|
|
|
|
_Lock PSA.SchLock, scratch1=r16, scratch2=r17
|
|
|
|
li r9, Semaphore.kIDClass
|
|
bl MakeID
|
|
cmpwi r8, 0
|
|
bne+ @nofail
|
|
|
|
mr r8, r31
|
|
bl PoolFree
|
|
b ReleaseAndScrambleMPCall
|
|
@nofail
|
|
|
|
li r18, 0x00
|
|
stw r8, 0x0000(r31)
|
|
|
|
mfsprg r30, 0
|
|
lwz r30, EWA.PA_CurTask(r30)
|
|
|
|
stw r3, Semaphore.MaxValue(r31)
|
|
stw r4, Semaphore.Value(r31)
|
|
lwz r17, Task.ProcessID(r30)
|
|
stw r18, Semaphore.BlockedTaskCount(r31)
|
|
stw r17, Semaphore.ProcessID(r31)
|
|
|
|
mr r5, r8
|
|
|
|
b ReleaseAndReturnZeroFromMPCall
|
|
|
|
|
|
|
|
####### ####### ###### ## ## ### #### ########
|
|
## ## ## ## ## ## ## ## ## ## ## ## ##
|
|
## ## ## ## ## ## ## ## ## ##
|
|
####### ####### ###### ## ## ## ## ## ## ##
|
|
## ## ## ## ## ## ######### ## ##
|
|
## ## ## ## ## ## ## ## ## ## ## ##
|
|
######### ####### ###### ### ### ## ## #### ##
|
|
|
|
; Wait on a semaphore, or fail (similar to MPWaitOnQueue)
|
|
|
|
; Abbreviated summary of cases:
|
|
; 1. Decrement and return instantly
|
|
; 2. Time out instantly
|
|
; 3. Move task to SEMA from RDYQ and arm timer
|
|
; 4. Move task to SEMA from RDYQ, no timeout
|
|
|
|
; ARG SemaphoreID r3, Duration r4
|
|
|
|
DeclareMPCall 23, MPWaitOnSemaphore
|
|
|
|
MPWaitOnSemaphore
|
|
|
|
_Lock PSA.SchLock, scratch1=r16, scratch2=r17
|
|
|
|
mr r8, r3
|
|
bl LookupID
|
|
cmpwi r9, Semaphore.kIDClass
|
|
bne+ ReleaseAndReturnMPCallInvalidIDErr
|
|
mr r31, r8
|
|
|
|
lwz r16, Semaphore.Value(r31)
|
|
cmpwi r16, 0
|
|
subi r16, r16, 1
|
|
ble- @must_wait
|
|
|
|
;easiest case ... decrement and return
|
|
stw r16, Semaphore.Value(r31)
|
|
b ReleaseAndReturnZeroFromMPCall
|
|
@must_wait
|
|
|
|
;next easiest case ... instant timeout
|
|
cmpwi r4, 0
|
|
mfsprg r30, 0
|
|
beq+ ReleaseAndTimeoutMPCall
|
|
|
|
lwz r8, EWA.PA_CurTask(r30)
|
|
|
|
;special case: blue may not block
|
|
lwz r16, Task.Flags(r8)
|
|
rlwinm. r16, r16, 0, Task.kFlagBlue, Task.kFlagBlue
|
|
beq- @bot_blue
|
|
stw r3, PSA.BlueSpinningOn(r1)
|
|
b ReleaseAndReturnMPCallBlueBlocking
|
|
@bot_blue
|
|
|
|
;committed to blocking the calling task
|
|
|
|
; Remove from ready queue
|
|
bl TaskUnready
|
|
|
|
; Add to this queue
|
|
addi r16, r31, Semaphore.BlockedTasks
|
|
addi r17, r8, Task.QueueMember
|
|
|
|
stw r16, LLL.FreeForm(r17)
|
|
InsertAsPrev r17, r16, scratch=r18
|
|
|
|
lwz r18, Semaphore.BlockedTaskCount(r31)
|
|
addi r18, r18, 1
|
|
stw r18, Semaphore.BlockedTaskCount(r31)
|
|
|
|
_lstart r16, 0x7fffffff
|
|
addi r30, r8, Task.Timer
|
|
_lfinish
|
|
cmpw r4, r16
|
|
|
|
li r17, 2
|
|
beq- @wait_forever
|
|
|
|
;committed to creating a timer (finite timeout)
|
|
stb r17, Timer.Kind(r30)
|
|
stw r8, Timer.ParentTaskPtr(r30)
|
|
mr r8, r4
|
|
|
|
; Convert that timeout to a tick count
|
|
bl TimebaseTicksPerPeriod
|
|
mr r27, r8
|
|
mr r28, r9
|
|
|
|
bl GetTime
|
|
mfxer r16
|
|
addc r9, r9, r28
|
|
adde r8, r8, r27
|
|
mtxer r16
|
|
|
|
; Now r8/r9 = absolute timeout date
|
|
stw r8, Timer.Time(r30)
|
|
stw r9, Timer.Time+4(r30)
|
|
|
|
mr r8, r30
|
|
bl EnqueueTimer
|
|
|
|
@wait_forever
|
|
li r3, 0x00
|
|
b BlockMPCall
|
|
|
|
|
|
|
|
####### ## ###### ####### ## ## ######## ######## ## ##
|
|
## ## ## ## ## ## ## ## ## ## ## ## ## ## ##
|
|
## ## ## ## ## ## ## ## ## ## ## ####
|
|
####### ## ## ###### ## ## ## ## ###### ######## ##
|
|
## ######### ## ## ## ## ## ## ## ## ## ##
|
|
## ## ## ## ## ## ## ## ## ## ## ##
|
|
######### ## ###### ##### ## ####### ######## ## ## ##
|
|
|
|
; Non-blocking peek at semaphore (undocumented)
|
|
; Returns timeout if empty, noErr if non-empty
|
|
|
|
; ARG SemaphoreID r3
|
|
; RET OSStatus r3
|
|
|
|
DeclareMPCall 24, MPQuerySemaphore
|
|
|
|
MPQuerySemaphore
|
|
|
|
_Lock PSA.SchLock, scratch1=r16, scratch2=r17
|
|
|
|
mr r8, r3
|
|
bl LookupID
|
|
|
|
cmpwi r9, Semaphore.kIDClass
|
|
bne+ ReleaseAndReturnMPCallInvalidIDErr
|
|
|
|
mr r31, r8
|
|
lwz r16, Semaphore.Value(r31)
|
|
cmpwi r16, 0
|
|
|
|
ble+ ReleaseAndTimeoutMPCall
|
|
|
|
b ReleaseAndReturnZeroFromMPCall
|
|
|
|
|
|
|
|
####### ####### ###### ###### #### ###### ## ## ### ##
|
|
## ## ## ## ## ## ## ## ## ## ## ### ## ## ## ##
|
|
## ## ## ## ## ## #### ## ## ## ##
|
|
####### ####### ###### ###### ## ## #### ## ## ## ## ## ##
|
|
## ## ## ## ## ## ## ## #### ######### ##
|
|
## ## ## ## ## ## ## ## ## ## ### ## ## ##
|
|
######### ######### ###### ###### #### ###### ## ## ## ## ########
|
|
|
|
; ARG SemaphoreID r3
|
|
; RET OSStatus r3
|
|
|
|
DeclareMPCall 22, MPSignalSemaphore
|
|
|
|
MPSignalSemaphore
|
|
|
|
_Lock PSA.SchLock, scratch1=r16, scratch2=r17
|
|
|
|
mr r8, r3
|
|
bl LookupID
|
|
|
|
cmpwi r9, Semaphore.kIDClass
|
|
mr r31, r8
|
|
bne+ ReleaseAndReturnMPCallInvalidIDErr
|
|
|
|
bl SignalSemaphore
|
|
|
|
mr r3, r8
|
|
b ReleaseAndReturnMPCall
|
|
|
|
|
|
|
|
### ###### ###### #### ###### ## ## ### ## ###
|
|
## ## ## ## ## ## ## ## ### ## ## ## ## ##
|
|
## ## ## ## ## #### ## ## ## ## ##
|
|
## ###### ###### ## ## #### ## ## ## ## ## ## ##
|
|
## ## ## ## ## ## ## #### ######### ## ##
|
|
## ## ## ## ## ## ## ## ## ### ## ## ## ##
|
|
### ###### ###### #### ###### ## ## ## ## ######## ###
|
|
|
|
; ARG Semaphore *r31
|
|
|
|
SignalSemaphore ; OUTSIDE REFERER
|
|
mflr r27
|
|
lwz r8, Semaphore.BlockedTasks + LLL.Freeform(r31)
|
|
bl UnblockBlueIfCouldBePolling
|
|
lwz r16, 0x0008(r31)
|
|
cmpw r16, r31
|
|
beq- SignalSemaphore_0x80
|
|
addi r8, r16, -0x08
|
|
lbz r17, 0x0037(r8)
|
|
cmpwi r17, 0x01
|
|
bne- SignalSemaphore_0x30
|
|
addi r8, r8, 0x20
|
|
bl DequeueTimer
|
|
|
|
SignalSemaphore_0x30
|
|
lwz r16, 0x0008(r31)
|
|
RemoveFromList r16, scratch1=r17, scratch2=r18
|
|
lwz r18, 0x001c(r31)
|
|
addi r18, r18, -0x01
|
|
stw r18, 0x001c(r31)
|
|
addi r8, r16, -0x08
|
|
li r17, 0x01
|
|
stb r17, 0x0019(r8)
|
|
bl TaskReadyAsPrev
|
|
bl CalculateTimeslice
|
|
bl FlagSchEvaluationIfTaskRequires
|
|
mtlr r27
|
|
li r8, 0x00
|
|
blr
|
|
|
|
SignalSemaphore_0x80
|
|
mtlr r27
|
|
lwz r16, 0x0010(r31)
|
|
lwz r17, 0x0014(r31)
|
|
cmpw r16, r17
|
|
addi r16, r16, 0x01
|
|
li r8, kMPInsufficientResourcesErr
|
|
bgelr-
|
|
stw r16, 0x0010(r31)
|
|
li r8, 0x00
|
|
blr
|
|
|
|
|
|
|
|
####### ## ###### ######## ######## ## ######## ######## ########
|
|
## ## #### ## ## ## ## ## ## ## ## ##
|
|
## ## ## ## ## ## ## ## ## ##
|
|
####### ## ###### ## ## ###### ## ###### ## ######
|
|
## ## ## ## ## ## ## ## ## ##
|
|
## ## ## ## ## ## ## ## ## ## ##
|
|
######### ###### ###### ######## ######## ######## ######## ## ########
|
|
|
|
DeclareMPCall 21, MPDeleteSemaphore
|
|
|
|
MPDeleteSemaphore
|
|
|
|
_Lock PSA.SchLock, scratch1=r16, scratch2=r17
|
|
|
|
mr r8, r3
|
|
bl LookupID
|
|
cmpwi r9, Semaphore.kIDClass
|
|
mr r31, r8
|
|
bne+ ReleaseAndReturnMPCallInvalidIDErr
|
|
|
|
mr r8, r3
|
|
bl UnblockBlueIfCouldBePolling
|
|
|
|
MPCall_21_0x34
|
|
addi r30, r31, Semaphore.BlockedTasks
|
|
lwz r16, LLL.Next(r31)
|
|
cmpw r16, r30
|
|
addi r8, r16, -0x08
|
|
beq- MPCall_21_0x98
|
|
lwz r17, 0x0088(r8)
|
|
li r18, kMPDeletedErr
|
|
stw r18, 0x011c(r17)
|
|
lbz r17, 0x0037(r8)
|
|
cmpwi r17, 0x01
|
|
bne- MPCall_21_0x68
|
|
addi r8, r8, 0x20
|
|
bl DequeueTimer
|
|
|
|
MPCall_21_0x68
|
|
lwz r16, 0x0008(r31)
|
|
RemoveFromList r16, scratch1=r17, scratch2=r18
|
|
addi r8, r16, -0x08
|
|
bl TaskReadyAsPrev
|
|
bl FlagSchEvaluationIfTaskRequires
|
|
b MPCall_21_0x34
|
|
|
|
MPCall_21_0x98
|
|
mr r8, r31
|
|
bl PoolFree
|
|
mr r8, r3
|
|
bl DeleteID
|
|
|
|
; r1 = kdp
|
|
b ReleaseAndReturnZeroFromMPCall
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
###### ######## #### ######## #### ###### ### ##
|
|
## ## ## ## ## ## ## ## ## ## ## ##
|
|
## ## ## ## ## ## ## ## ## ##
|
|
## ######## ## ## ## ## ## ## ##
|
|
## ## ## ## ## ## ## ######### ##
|
|
## ## ## ## ## ## ## ## ## ## ## ##
|
|
###### ## ## #### ## #### ###### ## ## ########
|
|
|
|
######## ######## ###### #### ####### ## ## ######
|
|
## ## ## ## ## ## ## ## ### ## ## ##
|
|
## ## ## ## ## ## ## #### ## ##
|
|
######## ###### ## #### ## ## ## ## ## ## ######
|
|
## ## ## ## ## ## ## ## ## #### ##
|
|
## ## ## ## ## ## ## ## ## ### ## ##
|
|
## ## ######## ###### #### ####### ## ## ######
|
|
|
|
|
|
|
|
####### ######## ######## ###### ######## ######## ### ######## ########
|
|
## ## ## ## ## ## ## ## ## ## ## ## ## ##
|
|
## ## ## ## ## ## ## ## ## ## ## ##
|
|
####### ####### ######## ## ######## ###### ## ## ## ######
|
|
## ## ## ## ## ## ## ## ######### ## ##
|
|
## ## ## ## ## ## ## ## ## ## ## ## ## ##
|
|
######### ###### ## ## ###### ## ## ######## ## ## ## ########
|
|
|
|
|
|
|
|
DeclareMPCall 25, MPCreateCriticalRegion
|
|
|
|
MPCreateCriticalRegion
|
|
li r8, 0x24
|
|
bl PoolAlloc_with_crset
|
|
mr. r31, r8
|
|
beq+ ScrambleMPCall
|
|
InitList r31, CriticalRegion.kSignature, scratch=r16
|
|
|
|
_Lock PSA.SchLock, scratch1=r16, scratch2=r17
|
|
|
|
li r9, 0x06
|
|
|
|
; r1 = kdp
|
|
; r9 = kind
|
|
bl MakeID
|
|
cmpwi r8, 0x00
|
|
bne+ MPCall_25_0x58
|
|
mr r8, r31
|
|
bl PoolFree
|
|
b ReleaseAndScrambleMPCall
|
|
|
|
MPCall_25_0x58
|
|
li r18, 0x00
|
|
mfsprg r30, 0
|
|
lwz r30, -0x0008(r30)
|
|
li r16, 0x00
|
|
stw r8, 0x0000(r31)
|
|
stw r16, 0x0014(r31)
|
|
stw r16, 0x001c(r31)
|
|
stw r16, 0x0018(r31)
|
|
lwz r17, 0x0060(r30)
|
|
stw r18, 0x0020(r31)
|
|
stw r17, 0x0010(r31)
|
|
mr r4, r8
|
|
|
|
; r1 = kdp
|
|
b ReleaseAndReturnZeroFromMPCall
|
|
|
|
|
|
|
|
####### ######## ######## ######## ## ## ######## ######## ########
|
|
## ## ## ## ## ## ## ### ## ## ## ## ##
|
|
## ## ## ## ## #### ## ## ## ## ##
|
|
####### ## ######## ###### ## ## ## ## ###### ########
|
|
## ## ## ## ## ## #### ## ## ## ##
|
|
## ## ## ## ## ## ### ## ## ## ##
|
|
######### ## ## ## ######## ## ## ## ######## ## ##
|
|
|
|
DeclareMPCall 27, MPEnterCriticalRegion
|
|
|
|
MPEnterCriticalRegion
|
|
|
|
_Lock PSA.SchLock, scratch1=r16, scratch2=r17
|
|
|
|
mr r8, r3
|
|
|
|
; r8 = id
|
|
bl LookupID
|
|
cmpwi r9, CriticalRegion.kIDClass
|
|
|
|
bne+ ReleaseAndReturnMPCallInvalidIDErr
|
|
mr r31, r8
|
|
mfsprg r17, 0
|
|
lwz r18, 0x0014(r31)
|
|
lwz r30, -0x0008(r17)
|
|
cmpwi r18, 0x00
|
|
lwz r16, 0x0018(r31)
|
|
beq- MPCall_27_0x64
|
|
lwz r17, 0x001c(r31)
|
|
cmpw r16, r30
|
|
cmpw cr1, r17, r5
|
|
bne- MPCall_27_0x78
|
|
bne- cr1, MPCall_27_0x78
|
|
addi r18, r18, 0x01
|
|
stw r18, 0x0014(r31)
|
|
|
|
; r1 = kdp
|
|
b ReleaseAndReturnZeroFromMPCall
|
|
|
|
MPCall_27_0x64
|
|
addi r18, r18, 0x01
|
|
stw r30, 0x0018(r31)
|
|
stw r5, 0x001c(r31)
|
|
stw r18, 0x0014(r31)
|
|
|
|
; r1 = kdp
|
|
b ReleaseAndReturnZeroFromMPCall
|
|
|
|
MPCall_27_0x78
|
|
lwz r8, 0x0000(r16)
|
|
|
|
; r8 = id
|
|
bl LookupID
|
|
cmpwi r9, Task.kIDClass
|
|
|
|
bne+ ReleaseAndReturnMPCallTaskAborted
|
|
lwz r8, 0x001c(r31)
|
|
|
|
; r8 = id
|
|
bl LookupID
|
|
cmpwi r9, Process.kIDClass
|
|
|
|
bne+ ReleaseAndReturnMPCallTaskAborted
|
|
cmpwi r4, 0x00
|
|
;special case: blue may not block
|
|
lwz r16, Task.Flags(r30)
|
|
beq+ ReleaseAndTimeoutMPCall
|
|
rlwinm. r16, r16, 0, Task.kFlagBlue, Task.kFlagBlue
|
|
beq- @bot_blue
|
|
stw r3, PSA.BlueSpinningOn(r1)
|
|
b ReleaseAndReturnMPCallBlueBlocking
|
|
@bot_blue
|
|
|
|
MPCall_27_0xb4
|
|
mr r8, r30
|
|
bl TaskUnready
|
|
lis r16, 0x7fff
|
|
addi r18, r30, 0x08
|
|
ori r16, r16, 0xffff
|
|
stw r31, 0x0000(r18)
|
|
InsertAsPrev r18, r31, scratch=r19
|
|
lwz r18, 0x0020(r31)
|
|
addi r18, r18, 0x01
|
|
stw r18, 0x0020(r31)
|
|
cmpw r4, r16
|
|
beq- MPCall_27_0x138
|
|
addi r29, r30, 0x20
|
|
li r8, 0x02
|
|
stw r30, 0x0018(r29)
|
|
stb r8, 0x0014(r29)
|
|
mr r8, r4
|
|
|
|
; r1 = kdp
|
|
; r8 = multiple (pos: /250; neg: /250000)
|
|
bl TimebaseTicksPerPeriod
|
|
; r8 = hi
|
|
; r9 = lo
|
|
|
|
mr r27, r8
|
|
mr r28, r9
|
|
bl GetTime
|
|
mfxer r16
|
|
addc r9, r9, r28
|
|
adde r8, r8, r27
|
|
mtxer r16
|
|
stw r8, 0x0038(r29)
|
|
stw r9, 0x003c(r29)
|
|
mr r8, r29
|
|
bl EnqueueTimer
|
|
|
|
MPCall_27_0x138
|
|
b BlockMPCall
|
|
|
|
|
|
|
|
####### ####### ######## ####### ## ## ######## ######## ## ##
|
|
## ## ## ## ## ## ## ## ## ## ## ## ## ## ##
|
|
## ## ## ## ## ## ## ## ## ## ## ## ####
|
|
####### ######## ######## ## ## ## ## ###### ######## ##
|
|
## ## ## ## ## ## ## ## ## ## ## ## ##
|
|
## ## ## ## ## ## ## ## ## ## ## ## ##
|
|
######### ####### ## ## ##### ## ####### ######## ## ## ##
|
|
|
|
DeclareMPCall 29, MPQueryCriticalRegion
|
|
|
|
MPQueryCriticalRegion
|
|
|
|
_Lock PSA.SchLock, scratch1=r16, scratch2=r17
|
|
|
|
mr r8, r3
|
|
|
|
; r8 = id
|
|
bl LookupID
|
|
cmpwi r9, CriticalRegion.kIDClass
|
|
|
|
bne+ ReleaseAndReturnMPCallInvalidIDErr
|
|
mr r31, r8
|
|
mfsprg r17, 0
|
|
lwz r18, 0x0014(r31)
|
|
cmpwi r18, 0x00
|
|
|
|
; r1 = kdp
|
|
beq+ ReleaseAndReturnZeroFromMPCall
|
|
lwz r30, -0x0008(r17)
|
|
lwz r16, 0x0018(r31)
|
|
lwz r17, 0x001c(r31)
|
|
cmpw r16, r30
|
|
cmpw cr1, r17, r4
|
|
bne+ ReleaseAndTimeoutMPCall
|
|
bne+ cr1, ReleaseAndTimeoutMPCall
|
|
|
|
; r1 = kdp
|
|
b ReleaseAndReturnZeroFromMPCall
|
|
|
|
|
|
|
|
####### ####### ######## ######## ## ## #### ########
|
|
## ## ## ## ## ## ## ## ## ## ##
|
|
## ## ## ## ## ## ## ## ## ##
|
|
####### ####### ######## ###### ### ## ##
|
|
## ## ## ## ## ## ## ## ## ##
|
|
## ## ## ## ## ## ## ## ## ##
|
|
######### ####### ## ## ######## ## ## #### ##
|
|
|
|
DeclareMPCall 28, MPExitCriticalRegion
|
|
|
|
MPExitCriticalRegion
|
|
|
|
_Lock PSA.SchLock, scratch1=r16, scratch2=r17
|
|
|
|
mr r8, r3
|
|
|
|
; r8 = id
|
|
bl LookupID
|
|
cmpwi r9, CriticalRegion.kIDClass
|
|
|
|
bne+ ReleaseAndReturnMPCallInvalidIDErr
|
|
mr r31, r8
|
|
mfsprg r17, 0
|
|
lwz r16, 0x0018(r31)
|
|
lwz r30, -0x0008(r17)
|
|
lwz r18, 0x0014(r31)
|
|
lwz r17, 0x001c(r31)
|
|
cmpw r16, r30
|
|
cmpw cr1, r17, r4
|
|
bne+ ReleaseAndReturnMPCallOOM
|
|
bne+ cr1, ReleaseAndReturnMPCallOOM
|
|
addi r18, r18, -0x01
|
|
cmpwi r18, 0x00
|
|
stw r18, 0x0014(r31)
|
|
|
|
; r1 = kdp
|
|
bne+ ReleaseAndReturnZeroFromMPCall
|
|
stw r18, 0x0018(r31)
|
|
stw r18, 0x001c(r31)
|
|
mr r8, r3
|
|
bl UnblockBlueIfCouldBePolling
|
|
lwz r16, 0x0008(r31)
|
|
cmpw r16, r31
|
|
|
|
; r1 = kdp
|
|
beq+ ReleaseAndReturnZeroFromMPCall
|
|
addi r8, r16, -0x08
|
|
lbz r17, 0x0037(r8)
|
|
cmpwi r17, 0x01
|
|
bne- MPCall_28_0x94
|
|
addi r8, r8, 0x20
|
|
bl DequeueTimer
|
|
|
|
MPCall_28_0x94
|
|
lwz r16, 0x0008(r31)
|
|
RemoveFromList r16, scratch1=r17, scratch2=r18
|
|
lwz r18, 0x0020(r31)
|
|
addi r18, r18, -0x01
|
|
stw r18, 0x0020(r31)
|
|
addi r8, r16, -0x08
|
|
lwz r17, 0x0088(r8)
|
|
lwz r18, 0x00fc(r17)
|
|
subi r18, r18, 4
|
|
stw r18, 0x00fc(r17)
|
|
li r17, 0x01
|
|
stb r17, 0x0019(r8)
|
|
bl TaskReadyAsPrev
|
|
bl CalculateTimeslice
|
|
bl FlagSchEvaluationIfTaskRequires
|
|
|
|
; r1 = kdp
|
|
b ReleaseAndReturnZeroFromMPCall
|
|
|
|
|
|
|
|
####### ####### ######## ######## ######## ## ######## ######## ########
|
|
## ## ## ## ## ## ## ## ## ## ## ## ##
|
|
## ## ## ## ## ## ## ## ## ## ##
|
|
####### ######## ######## ## ## ###### ## ###### ## ######
|
|
## ## ## ## ## ## ## ## ## ## ## ##
|
|
## ## ## ## ## ## ## ## ## ## ## ##
|
|
######### ####### ## ## ######## ######## ######## ######## ## ########
|
|
|
|
DeclareMPCall 26, MPDeleteCriticalRegion
|
|
|
|
MPDeleteCriticalRegion
|
|
|
|
_Lock PSA.SchLock, scratch1=r16, scratch2=r17
|
|
|
|
mr r8, r3
|
|
|
|
; r8 = id
|
|
bl LookupID
|
|
cmpwi r9, CriticalRegion.kIDClass
|
|
|
|
mr r31, r8
|
|
bne+ ReleaseAndReturnMPCallInvalidIDErr
|
|
mr r8, r3
|
|
bl UnblockBlueIfCouldBePolling
|
|
|
|
MPCall_26_0x34
|
|
addi r30, r31, 0x00
|
|
lwz r16, 0x0008(r31)
|
|
cmpw r16, r30
|
|
addi r8, r16, -0x08
|
|
beq- MPCall_26_0x98
|
|
lwz r17, 0x0088(r8)
|
|
li r18, kMPDeletedErr
|
|
stw r18, 0x011c(r17)
|
|
lbz r17, 0x0037(r8)
|
|
cmpwi r17, 0x01
|
|
bne- MPCall_26_0x68
|
|
addi r8, r8, 0x20
|
|
bl DequeueTimer
|
|
|
|
MPCall_26_0x68
|
|
lwz r16, 0x0008(r31)
|
|
RemoveFromList r16, scratch1=r17, scratch2=r18
|
|
addi r8, r16, -0x08
|
|
bl TaskReadyAsPrev
|
|
bl FlagSchEvaluationIfTaskRequires
|
|
b MPCall_26_0x34
|
|
|
|
MPCall_26_0x98
|
|
mr r8, r31
|
|
bl PoolFree
|
|
mr r8, r3
|
|
bl DeleteID
|
|
|
|
; r1 = kdp
|
|
b ReleaseAndReturnZeroFromMPCall
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
######## ## ## ######## ## ## ########
|
|
## ## ## ## ### ## ##
|
|
## ## ## ## #### ## ##
|
|
###### ## ## ###### ## ## ## ##
|
|
## ## ## ## ## #### ##
|
|
## ## ## ## ## ### ##
|
|
######## ### ######## ## ## ##
|
|
|
|
###### ######## ####### ## ## ######## ######
|
|
## ## ## ## ## ## ## ## ## ## ## ##
|
|
## ## ## ## ## ## ## ## ## ##
|
|
## #### ######## ## ## ## ## ######## ######
|
|
## ## ## ## ## ## ## ## ## ##
|
|
## ## ## ## ## ## ## ## ## ## ##
|
|
###### ## ## ####### ####### ## ######
|
|
|
|
|
|
|
|
;_______________________________________________________________________
|
|
; Lifted from docs:
|
|
;
|
|
; An event group is essentially a group of binary semaphores. You can use
|
|
; event groups to indicate a number of simple events. For example, a task
|
|
; running on a server may need to be aware of multiple message queues.
|
|
; Instead of trying to poll each one in turn, the server task can wait on
|
|
; an event group. Whenever a message is posted on a queue, the poster can
|
|
; also set the bit corresponding to that queue in the event group. Doing
|
|
; so notifies the task, and it then knows which queue to access to extract
|
|
; the message. In Multiprocessing Services, an event group consists of
|
|
; thirty-two 1-bit flags, each of which may be set independently. When a
|
|
; task receives an event group, it receives all 32-bits at once (that is,
|
|
; it cannot poll individual bits), and all the bits in the event group are
|
|
; subsequently cleared.
|
|
;_______________________________________________________________________
|
|
|
|
|
|
|
|
## ####### ######## ###### ######## ######## ### ######## ########
|
|
## ## ## ## ## ## ## ## ## ## ## ## ## ##
|
|
## ## ## ## ## ## ## ## ## ## ## ## ##
|
|
## ## ######## ###### ## ######## ###### ## ## ## ######
|
|
######### ## ## ## ## ## ## ######### ## ##
|
|
## ## ## ## ## ## ## ## ## ## ## ## ##
|
|
## ####### ######## ###### ## ## ######## ## ## ## ########
|
|
|
|
DeclareMPCall 49, MPCreateEvent
|
|
|
|
; RET OSStatus r3, MPEventID r4
|
|
|
|
; called using the FE1F trap by the 68k ROM
|
|
|
|
MPCreateEvent
|
|
|
|
li r8, EventGroup.Size
|
|
bl PoolAlloc
|
|
mr. r31, r8
|
|
beq+ ScrambleMPCall
|
|
|
|
InitList r8, EventGroup.kSignature, scratch=r16
|
|
|
|
_Lock PSA.SchLock, scratch1=r16, scratch2=r17
|
|
|
|
li r9, EventGroup.kIDClass
|
|
bl MakeID
|
|
cmpwi r8, 0
|
|
bne+ @success
|
|
|
|
mr r8, r31
|
|
bl PoolFree
|
|
b ReleaseAndScrambleMPCall
|
|
|
|
@success
|
|
mfsprg r30, 0
|
|
lwz r30, EWA.PA_CurTask(r30)
|
|
|
|
stw r8, EventGroup.LLL + LLL.Freeform(r31)
|
|
|
|
lwz r17, Task.ProcessID(r30)
|
|
stw r17, EventGroup.ProcessID(r31)
|
|
|
|
mr r4, r8
|
|
b ReleaseAndReturnZeroFromMPCall
|
|
|
|
|
|
|
|
######## ##### ######## ######## ######## ## ######## ######## ########
|
|
## ## ## ## ## ## ## ## ## ## ##
|
|
## ## ## ## ## ## ## ## ## ## ##
|
|
####### ## ## ###### ## ## ###### ## ###### ## ######
|
|
## ## ## ## ## ## ## ## ## ## ##
|
|
## ## ## ## ## ## ## ## ## ## ## ##
|
|
###### ##### ######## ######## ######## ######## ######## ## ########
|
|
|
|
DeclareMPCall 50, MPDeleteEvent
|
|
|
|
; ARG MPEventID r3
|
|
; RET OSStatus r3
|
|
|
|
MPDeleteEvent
|
|
|
|
_Lock PSA.SchLock, scratch1=r16, scratch2=r17
|
|
|
|
mr r8, r3
|
|
|
|
; r8 = id
|
|
bl LookupID
|
|
cmpwi r9, EventGroup.kIDClass
|
|
mr r31, r8
|
|
bne+ ReleaseAndReturnMPCallInvalidIDErr
|
|
|
|
mr r8, r3
|
|
bl UnblockBlueIfCouldBePolling
|
|
|
|
MPDeleteEvent_0x34
|
|
addi r30, r31, 0x00
|
|
lwz r16, 0x0008(r31)
|
|
cmpw r16, r30
|
|
addi r8, r16, -0x08
|
|
beq- MPDeleteEvent_0x98
|
|
lwz r17, 0x0088(r8)
|
|
li r18, kMPDeletedErr
|
|
stw r18, 0x011c(r17)
|
|
lbz r17, 0x0037(r8)
|
|
cmpwi r17, 0x01
|
|
bne- MPDeleteEvent_0x68
|
|
addi r8, r8, 0x20
|
|
bl DequeueTimer
|
|
|
|
MPDeleteEvent_0x68
|
|
lwz r16, 0x0008(r31)
|
|
RemoveFromList r16, scratch1=r17, scratch2=r18
|
|
addi r8, r16, -0x08
|
|
bl TaskReadyAsPrev
|
|
bl FlagSchEvaluationIfTaskRequires
|
|
b MPDeleteEvent_0x34
|
|
|
|
MPDeleteEvent_0x98
|
|
mr r8, r31
|
|
bl PoolFree
|
|
mr r8, r3
|
|
bl DeleteID
|
|
|
|
; r1 = kdp
|
|
b ReleaseAndReturnZeroFromMPCall
|
|
|
|
|
|
|
|
######## ## ######## ###### ######## ########
|
|
## #### ## ## ## ## ##
|
|
## ## ## ## ## ##
|
|
####### ## ###### ###### ###### ##
|
|
## ## ## ## ## ##
|
|
## ## ## ## ## ## ## ##
|
|
###### ###### ######## ###### ######## ##
|
|
|
|
DeclareMPCall 51, MPSetEvent
|
|
|
|
; ARG MPEventID r3, MPEventFlags r4
|
|
; RET OSStatus r3
|
|
|
|
MPSetEvent
|
|
|
|
_Lock PSA.SchLock, scratch1=r16, scratch2=r17
|
|
|
|
mr r8, r3
|
|
bl LookupID
|
|
cmpwi r9, EventGroup.kIDClass
|
|
mr r31, r8
|
|
bne+ ReleaseAndReturnMPCallInvalidIDErr
|
|
|
|
mr r8, r4
|
|
bl SetEvent
|
|
|
|
; r1 = kdp
|
|
b ReleaseAndReturnZeroFromMPCall
|
|
|
|
|
|
|
|
### ######## ###### ######## ######## ###
|
|
## ## ## ## ## ## ##
|
|
## ## ## ## ## ##
|
|
## ###### ###### ###### ## ##
|
|
## ## ## ## ## ##
|
|
## ## ## ## ## ## ##
|
|
### ######## ###### ######## ## ###
|
|
|
|
SetEvent ; OUTSIDE REFERER
|
|
lwz r16, 0x0010(r31)
|
|
or r16, r16, r8
|
|
stw r16, 0x0010(r31)
|
|
mflr r27
|
|
lwz r8, 0x0000(r31)
|
|
bl UnblockBlueIfCouldBePolling
|
|
lwz r16, 0x0008(r31)
|
|
cmpw r16, r31
|
|
addi r8, r16, -0x08
|
|
beq- SetEvent_0x90
|
|
lwz r17, 0x0088(r8)
|
|
lwz r18, 0x00fc(r17)
|
|
subi r18, r18, 4
|
|
stw r18, 0x00fc(r17)
|
|
lbz r17, 0x0037(r8)
|
|
cmpwi r17, 0x01
|
|
bne- SetEvent_0x4c
|
|
addi r8, r8, 0x20
|
|
bl DequeueTimer
|
|
|
|
SetEvent_0x4c
|
|
lwz r16, 0x0008(r31)
|
|
RemoveFromList r16, scratch1=r17, scratch2=r18
|
|
lwz r18, 0x001c(r31)
|
|
addi r18, r18, -0x01
|
|
stw r18, 0x001c(r31)
|
|
addi r8, r16, -0x08
|
|
li r17, 0x01
|
|
stb r17, 0x0019(r8)
|
|
bl TaskReadyAsPrev
|
|
bl CalculateTimeslice
|
|
bl FlagSchEvaluationIfTaskRequires
|
|
|
|
SetEvent_0x90
|
|
lwz r16, 0x0018(r31)
|
|
rlwinm. r17, r16, 0, 27, 27
|
|
beq- SetEvent_0x1a0
|
|
lwz r17, KDP.PA_ECB(r1)
|
|
lwz r26, -0x08f0(r1)
|
|
lwz r18, 0x00c8(r17)
|
|
lwz r19, 0x00d0(r17)
|
|
cmpwi cr1, r18, 0x00
|
|
cmpwi r19, 0x00
|
|
bne- cr1, SetEvent_0xc8
|
|
bne- SetEvent_0x1a0
|
|
lwz r8, 0x0000(r31)
|
|
stw r8, 0x00d0(r17)
|
|
b SetEvent_0x118
|
|
|
|
SetEvent_0xc8
|
|
lwz r9, 0x0634(r1)
|
|
rlwinm r16, r16, 2, 26, 29
|
|
add r18, r18, r9
|
|
lwzx r19, r16, r18
|
|
cmpwi r19, 0x00
|
|
bne- SetEvent_0x1a0
|
|
lwz r8, 0x0000(r31)
|
|
stwx r8, r16, r18
|
|
li r19, 0x1c
|
|
li r9, 0x04
|
|
|
|
SetEvent_0xf0
|
|
lwzx r8, r19, r18
|
|
cmpwi r8, 0x00
|
|
bne- SetEvent_0x108
|
|
subf. r19, r9, r19
|
|
bgt+ SetEvent_0xf0
|
|
bl panic
|
|
|
|
SetEvent_0x108
|
|
cmplw r16, r19
|
|
srwi r16, r16, 2
|
|
blt- SetEvent_0x1a0
|
|
stw r16, 0x00d0(r17)
|
|
|
|
SetEvent_0x118
|
|
lwz r16, 0x0064(r26)
|
|
lbz r19, 0x0018(r26)
|
|
ori r16, r16, 0x10
|
|
stw r16, 0x0064(r26)
|
|
lwz r17, -0x0440(r1)
|
|
lwz r16, 0x0674(r1)
|
|
lwz r8, 0x0678(r1)
|
|
and r16, r16, r8
|
|
or r17, r17, r16
|
|
stw r17, -0x0440(r1)
|
|
cmpwi r19, 0x00
|
|
addi r16, r26, 0x08
|
|
bne- SetEvent_0x198
|
|
RemoveFromList r16, scratch1=r17, scratch2=r18
|
|
lbz r17, 0x0037(r26)
|
|
cmpwi r17, 0x01
|
|
bne- SetEvent_0x17c
|
|
addi r8, r26, 0x20
|
|
bl DequeueTimer
|
|
|
|
SetEvent_0x17c
|
|
lwz r18, -0x08f0(r1)
|
|
li r16, 0x00
|
|
stb r16, 0x0019(r26)
|
|
mr r8, r26
|
|
bl TaskReadyAsNext
|
|
mr r8, r26
|
|
bl CalculateTimeslice
|
|
|
|
SetEvent_0x198
|
|
mr r8, r26
|
|
bl FlagSchEvaluationIfTaskRequires
|
|
|
|
SetEvent_0x1a0
|
|
mtlr r27
|
|
blr
|
|
|
|
|
|
|
|
######## ####### ######## ## ## ### #### ########
|
|
## ## ## ## ## ## ## ## ## ## ##
|
|
## ## ## ## ## ## ## ## ## ##
|
|
####### ####### ###### ## ## ## ## ## ## ##
|
|
## ## ## ## ## ## ######### ## ##
|
|
## ## ## ## ## ## ## ## ## ## ##
|
|
###### ######### ######## ### ### ## ## #### ##
|
|
|
|
DeclareMPCall 52, MPWaitForEvent
|
|
|
|
; ARG MPEventID r3, Duration r5
|
|
; RET OSStatus r3, MPEventFlags r4
|
|
|
|
; called using the FE1F trap by the 68k ROM
|
|
|
|
MPWaitForEvent
|
|
|
|
_Lock PSA.SchLock, scratch1=r16, scratch2=r17
|
|
|
|
mr r8, r3
|
|
|
|
; Check that the Event Group ID in r3 is valid.
|
|
bl LookupID
|
|
cmpwi r9, EventGroup.kIDClass
|
|
bne+ ReleaseAndReturnMPCallInvalidIDErr
|
|
mr r31, r8
|
|
|
|
lwz r16, 0x0010(r31)
|
|
cmpwi r16, 0
|
|
beq- MPWaitForEvent_field_10_was_zero
|
|
|
|
mr r4, r16
|
|
|
|
li r16, 0
|
|
stw r16, 0x0010(r31)
|
|
|
|
lwz r16, 0x0018(r31)
|
|
lwz r17, KDP.PA_ECB(r1)
|
|
rlwinm. r18, r16, 0, 27, 27
|
|
rlwinm r16, r16, 2, 26, 29
|
|
beq+ ReleaseAndReturnZeroFromMPCall
|
|
|
|
lwz r18, 0x00c8(r17)
|
|
lwz r9, 0x0634(r1)
|
|
cmpwi r18, 0x00
|
|
add r18, r18, r9
|
|
bne- MPWaitForEvent_0x84
|
|
lwz r18, 0x00d0(r17)
|
|
cmpw r18, r3
|
|
li r18, 0x00
|
|
|
|
; r1 = kdp
|
|
bne+ ReleaseAndReturnZeroFromMPCall
|
|
stw r18, 0x00d0(r17)
|
|
|
|
; r1 = kdp
|
|
b ReleaseAndReturnZeroFromMPCall
|
|
|
|
MPWaitForEvent_0x84
|
|
lwzx r19, r16, r18
|
|
cmpw r19, r3
|
|
li r19, 0x00
|
|
|
|
; r1 = kdp
|
|
bne+ ReleaseAndReturnZeroFromMPCall
|
|
stwx r19, r16, r18
|
|
li r19, 0x1c
|
|
li r9, 0x04
|
|
|
|
MPWaitForEvent_0xa0
|
|
lwzx r8, r19, r18
|
|
cmpwi r8, 0x00
|
|
bne- MPWaitForEvent_0xb4
|
|
subf. r19, r9, r19
|
|
bgt+ MPWaitForEvent_0xa0
|
|
|
|
MPWaitForEvent_0xb4
|
|
srwi r19, r19, 2
|
|
stw r19, 0x00d0(r17)
|
|
|
|
; r1 = kdp
|
|
b ReleaseAndReturnZeroFromMPCall
|
|
|
|
MPWaitForEvent_field_10_was_zero
|
|
mfsprg r30, 0
|
|
cmpwi r5, 0
|
|
lwz r19, EWA.PA_CurTask(r30)
|
|
beq+ ReleaseAndTimeoutMPCall
|
|
|
|
;special case: blue may not block
|
|
lwz r16, Task.Flags(r19)
|
|
rlwinm. r16, r16, 0, Task.kFlagBlue, Task.kFlagBlue
|
|
beq- @bot_blue
|
|
stw r3, PSA.BlueSpinningOn(r1)
|
|
b ReleaseAndReturnMPCallBlueBlocking
|
|
@bot_blue
|
|
|
|
; MOVE TASK OUT OF QUEUE AND INTO EVENT GROUP
|
|
mr r8, r19
|
|
bl TaskUnready
|
|
|
|
lwz r19, EWA.PA_CurTask(r30)
|
|
addi r16, r31, EventGroup.LLL
|
|
addi r17, r19, Task.QueueMember
|
|
stw r16, LLL.FreeForm(r17)
|
|
|
|
InsertAsPrev r17, r16, scratch=r18
|
|
|
|
lwz r18, EventGroup.Counter(r31)
|
|
addi r18, r18, 1
|
|
stw r18, EventGroup.Counter(r31)
|
|
|
|
lisori r16, 0x7fffffff ; LONG_MAX
|
|
addi r30, r19, Task.Timer
|
|
cmpw r5, r16
|
|
li r16, 2
|
|
beq- @wait_forever ; never trigger max-wait timers
|
|
|
|
stb r16, Timer.Kind(r30)
|
|
stw r19, Timer.ParentTaskPtr(r30)
|
|
mr r8, r5
|
|
|
|
bl TimebaseTicksPerPeriod
|
|
mr r27, r8
|
|
mr r28, r9
|
|
|
|
bl GetTime
|
|
mfxer r16
|
|
addc r9, r9, r28
|
|
adde r8, r8, r27
|
|
mtxer r16
|
|
|
|
stw r8, Timer.Time(r30)
|
|
stw r9, Timer.Time+4(r30)
|
|
|
|
mr r8, r30
|
|
bl EnqueueTimer
|
|
|
|
@wait_forever
|
|
b BlockMPCall
|
|
|
|
|
|
|
|
######## ####### ######## ####### ## ## ######## ######## ## ##
|
|
## ## ## ## ## ## ## ## ## ## ## ## ##
|
|
## ## ## ## ## ## ## ## ## ## ####
|
|
####### ####### ###### ## ## ## ## ###### ######## ##
|
|
## ## ## ## ## ## ## ## ## ## ## ##
|
|
## ## ## ## ## ## ## ## ## ## ## ## ##
|
|
###### ####### ######## ##### ## ####### ######## ## ## ##
|
|
|
|
DeclareMPCall 53, MPQueryEvent
|
|
|
|
; Returns Timeout if no flags are set, otherwise NoErr
|
|
|
|
; ARG MPEventID r3
|
|
; RET OSStatus r3
|
|
|
|
MPQueryEvent
|
|
|
|
_Lock PSA.SchLock, scratch1=r16, scratch2=r17
|
|
|
|
mr r8, r3
|
|
|
|
; r8 = id
|
|
bl LookupID
|
|
cmpwi r9, EventGroup.kIDClass
|
|
bne+ ReleaseAndReturnMPCallInvalidIDErr
|
|
|
|
mr r31, r8
|
|
lwz r16, 0x0010(r31)
|
|
cmpwi r16, 0x00
|
|
beq+ ReleaseAndTimeoutMPCall
|
|
|
|
; r1 = kdp
|
|
b ReleaseAndReturnZeroFromMPCall
|
|
|
|
|
|
|
|
######## ## ######## ###### ######## ######## ###### ## ## ####
|
|
## ## ## ## ## ## ## ## ## ## ## ## ## ##
|
|
## ## ## ## ## ## ## ## ## ## ## ##
|
|
####### ## ## ###### ###### ###### ## ###### ## ## ## ##
|
|
## ######### ## ## ## ## ## ## ## ## ##
|
|
## ## ## ## ## ## ## ## ## ## ## ## ## ##
|
|
###### ## ######## ###### ######## ## ###### ### ### ####
|
|
|
|
DeclareMPCall 54, MPSetSWIEvent
|
|
|
|
; ARG MPEventID r3, int r4 swi
|
|
|
|
; called using the FE1F trap by the 68k ROM
|
|
|
|
MPSetSWIEvent
|
|
|
|
_Lock PSA.SchLock, scratch1=r16, scratch2=r17
|
|
|
|
mr r8, r3
|
|
bl LookupID
|
|
cmpwi r9, EventGroup.kIDClass
|
|
bne+ ReleaseAndReturnMPCallInvalidIDErr
|
|
|
|
mr r31, r8
|
|
li r17, 1
|
|
|
|
cmpwi r4, 0
|
|
cmplwi cr1, r4, 8
|
|
|
|
lwz r16, EventGroup.SWI(r31)
|
|
|
|
beq- @use_1
|
|
bgt- cr1, @use_1
|
|
|
|
mr r17, r4
|
|
@use_1
|
|
|
|
; r17 = 1 if outside 1-8 (inc) range
|
|
|
|
ori r16, r16, 0x10
|
|
rlwimi r16, r17, 0, 28, 31
|
|
stw r16, EventGroup.SWI(r31)
|
|
|
|
; r1 = kdp
|
|
b ReleaseAndReturnZeroFromMPCall
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
######## #### ## ## ######## ######## ######
|
|
## ## ### ### ## ## ## ## ##
|
|
## ## #### #### ## ## ## ##
|
|
## ## ## ### ## ###### ######## ######
|
|
## ## ## ## ## ## ## ##
|
|
## ## ## ## ## ## ## ## ##
|
|
## #### ## ## ######## ## ## ######
|
|
|
|
|
|
|
|
## ##### ######## ###### ######## ######## ### ######## ########
|
|
## ## ## ## ## ## ## ## ## ## ## ## ## ##
|
|
## ## ## ## ## ## ## ## ## ## ## ## ##
|
|
## ## ## ## ## ## ######## ###### ## ## ## ######
|
|
######### ## ## ## ## ## ## ## ######### ## ##
|
|
## ## ## ## ## ## ## ## ## ## ## ## ##
|
|
## ##### ## ###### ## ## ######## ## ## ## ########
|
|
|
|
DeclareMPCall 40, NKCreateTimer
|
|
|
|
NKCreateTimer ; OUTSIDE REFERER
|
|
li r8, 0x40
|
|
|
|
; r1 = kdp
|
|
; r8 = size
|
|
bl PoolAlloc
|
|
; r8 = ptr
|
|
|
|
mr. r31, r8
|
|
beq+ ScrambleMPCall
|
|
|
|
_Lock PSA.SchLock, scratch1=r16, scratch2=r17
|
|
|
|
mr r8, r31
|
|
li r9, 0x03
|
|
|
|
; r1 = kdp
|
|
; r9 = kind
|
|
bl MakeID
|
|
cmpwi r8, 0x00
|
|
bne- NKCreateTimer_0x48
|
|
mr r8, r31
|
|
bl PoolFree
|
|
b ReleaseAndScrambleMPCall
|
|
|
|
NKCreateTimer_0x48
|
|
mfsprg r30, 0
|
|
stw r8, 0x0000(r31)
|
|
lwz r30, -0x0008(r30)
|
|
mr r4, r8
|
|
lwz r17, 0x0060(r30)
|
|
stw r17, 0x0010(r31)
|
|
bl GetTime
|
|
stw r8, 0x0038(r31)
|
|
stw r9, 0x003c(r31)
|
|
lis r17, 0x5449
|
|
ori r17, r17, 0x4d45
|
|
stw r17, 0x0004(r31)
|
|
li r17, 0x03
|
|
stb r17, 0x0014(r31)
|
|
li r17, 0x00
|
|
stb r17, 0x0016(r31)
|
|
|
|
; r1 = kdp
|
|
b ReleaseAndReturnZeroFromMPCall
|
|
|
|
|
|
|
|
## ## ######## ######## ######## ## ######## ######## ########
|
|
## ## #### ## ## ## ## ## ## ## ##
|
|
## ## ## ## ## ## ## ## ## ## ##
|
|
## ## ## ## ## ## ###### ## ###### ## ######
|
|
######### ## ## ## ## ## ## ## ## ##
|
|
## ## ## ## ## ## ## ## ## ##
|
|
## ###### ## ######## ######## ######## ######## ## ########
|
|
|
|
DeclareMPCall 41, NKDeleteTimer
|
|
|
|
NKDeleteTimer ; OUTSIDE REFERER
|
|
|
|
_Lock PSA.SchLock, scratch1=r16, scratch2=r17
|
|
|
|
mr r8, r3
|
|
|
|
; r8 = id
|
|
bl LookupID
|
|
cmpwi r9, Timer.kIDClass
|
|
|
|
mr r31, r8
|
|
bne+ ReleaseAndReturnMPCallInvalidIDErr
|
|
mr r8, r3
|
|
bl DeleteID
|
|
lwz r16, 0x0008(r31)
|
|
cmpwi r16, 0x00
|
|
beq- NKDeleteTimer_0x48
|
|
mr r8, r31
|
|
bl DequeueTimer
|
|
|
|
NKDeleteTimer_0x48
|
|
_AssertAndRelease PSA.SchLock, scratch=r16
|
|
lwz r8, 0x001c(r31)
|
|
cmpwi r8, 0x00
|
|
bnel- PoolFree
|
|
mr r8, r31
|
|
bl PoolFree
|
|
b ReturnZeroFromMPCall
|
|
|
|
|
|
|
|
####### ##### ######## ###### ######## ######## ## ## ####### ######## #### ######## ## ##
|
|
## ## ## ## ## ## ## ## ## ### ## ## ## ## ## ## ## ##
|
|
## ## ## ## ## ## ## #### ## ## ## ## ## ## ####
|
|
####### ## ## ## ###### ###### ## ## ## ## ## ## ## ## ###### ##
|
|
## ## ## ## ## ## ## ## #### ## ## ## ## ## ##
|
|
## ## ## ## ## ## ## ## ## ## ### ## ## ## ## ## ##
|
|
####### ##### ## ###### ######## ## ## ## ####### ## #### ## ##
|
|
|
|
; ARG TimerID r3, EventGroup/Queue/SemaphoreID r4, long r5, long r6, long r7
|
|
; RET OSStatus r3
|
|
|
|
DeclareMPCall 30, NKSetTimerNotify
|
|
|
|
NKSetTimerNotify
|
|
|
|
_Lock PSA.SchLock, scratch1=r16, scratch2=r17
|
|
|
|
mr r8, r3
|
|
bl LookupID
|
|
cmpwi r9, Timer.kIDClass
|
|
mr r31, r8
|
|
bne+ ReleaseAndReturnMPCallInvalidIDErr
|
|
|
|
lbz r16, Timer.Kind(r31)
|
|
cmpwi r16, 3
|
|
bne+ ReleaseAndReturnMPCallInvalidIDErr
|
|
|
|
mr r8, r4
|
|
bl LookupID
|
|
cmpwi r9, Semaphore.kIDClass
|
|
cmpwi cr2, r9, Queue.kIDClass
|
|
beq- @SEMAPHORE
|
|
cmpwi r9, EventGroup.kIDClass
|
|
beq- cr2, @QUEUE
|
|
bne+ ReleaseAndReturnMPCallInvalidIDErr
|
|
|
|
@EVENTGROUP
|
|
stw r4, Timer.EventGroupID(r31)
|
|
stw r5, Timer.EventGroupFlags(r31)
|
|
|
|
b ReleaseAndReturnZeroFromMPCall
|
|
|
|
@QUEUE
|
|
stw r4, Timer.MessageQueueID(r31)
|
|
lwz r16, ContextBlock.r6(r6)
|
|
lwz r17, ContextBlock.r7(r6)
|
|
stw r5, Timer.Message1(r31) ; notifyParam1
|
|
stw r16, Timer.Message2(r31) ; notifyParam2
|
|
stw r17, Timer.Message3(r31) ; notifyParam3
|
|
|
|
b ReleaseAndReturnZeroFromMPCall
|
|
|
|
@SEMAPHORE
|
|
stw r4, Timer.SemaphoreID(r31)
|
|
|
|
|
|
b ReleaseAndReturnZeroFromMPCall
|
|
|
|
|
|
|
|
####### ## ######## ### ######## ## ##
|
|
## ## #### ## ## ## ## ## ### ###
|
|
## ## ## ## ## ## ## #### ####
|
|
####### ## ## ## ## ######## ## ### ##
|
|
## ## ## ######### ## ## ## ##
|
|
## ## ## ## ## ## ## ## ## ##
|
|
####### ###### ## ## ## ## ## ## ##
|
|
|
|
; Time can be absolute or delta, and a duration (r4)
|
|
; or timebase time (r4/r5).
|
|
|
|
; ARG TimerID r3, long r4, long r5, OptionBits r6
|
|
; RET OSStatus r3
|
|
|
|
DeclareMPCall 31, MPArmTimer
|
|
|
|
MPArmTimer
|
|
|
|
_Lock PSA.SchLock, scratch1=r16, scratch2=r17
|
|
|
|
mr r8, r3
|
|
bl LookupID
|
|
cmpwi r9, Timer.kIDClass
|
|
mr r31, r8
|
|
bne+ ReleaseAndReturnMPCallInvalidIDErr
|
|
|
|
lbz r16, Timer.Kind(r31)
|
|
cmpwi r16, Timer.kKind3
|
|
bne+ ReleaseAndReturnMPCallInvalidIDErr
|
|
|
|
|
|
; Disarm if armed
|
|
lwz r16, Timer.QueueLLL + LLL.Freeform(r31)
|
|
cmpwi r16, 0
|
|
mr r8, r31
|
|
beq- @no_disarm
|
|
bl DequeueTimer
|
|
@no_disarm
|
|
|
|
|
|
; Ah... reserve a note if a message is to be sent
|
|
|
|
lwz r9, Timer.ReservedMessage(r31)
|
|
lwz r8, Timer.MessageQueueID(r31)
|
|
cmpwi r9, 0
|
|
cmpwi cr1, r8, 0
|
|
bne- @already_got_note
|
|
beq- cr1, @no_queue
|
|
|
|
bl LookupID
|
|
cmpwi r9, Queue.kIDClass
|
|
bne- @no_queue
|
|
|
|
lwz r9, Queue.ReserveCount(r8)
|
|
li r8, Message.Size
|
|
cmpwi r9, 0
|
|
bne- @already_got_notr
|
|
|
|
bl PoolAlloc
|
|
mr. r30, r8
|
|
beq+ ReleaseAndScrambleMPCall
|
|
|
|
lisori r8, 'note'
|
|
stw r8, Message.LLL + LLL.Signature(r30)
|
|
stw r30, 0x001c(r31)
|
|
@already_got_note
|
|
@already_got_notr
|
|
@no_queue
|
|
|
|
|
|
; Calculate firing solution
|
|
|
|
lwz r16, ContextBlock.r6(r6)
|
|
rlwinm. r9, r16, 0, kMPTimeIsDurationMask
|
|
mr r8, r4
|
|
beq- @not_duration
|
|
bl TimebaseTicksPerPeriod
|
|
mr r4, r8
|
|
mr r5, r9
|
|
@not_duration
|
|
|
|
lwz r16, ContextBlock.r6(r6)
|
|
rlwinm. r8, r16, 0, kMPTimeIsDeltaMask
|
|
mfxer r17
|
|
beq- @not_delta
|
|
lwz r19, Timer.Time + 4(r31)
|
|
lwz r18, Timer.Time(r31)
|
|
addc r5, r5, r19
|
|
adde r4, r4, r18
|
|
mtxer r17
|
|
@not_delta
|
|
|
|
stw r4, Timer.Time(r31)
|
|
stw r5, Timer.Time + 4(r31)
|
|
|
|
|
|
; Teensy little option: keep after firing?
|
|
lwz r16, ContextBlock.r6(r6)
|
|
rlwinm. r16, r16, 0, kMPPreserveTimerIDMask
|
|
li r17, 0
|
|
beq- @no_preserve
|
|
li r17, 1
|
|
@no_preserve
|
|
stb r17, Timer.KeepAfterFiring(r31)
|
|
|
|
|
|
mr r8, r31
|
|
bl EnqueueTimer
|
|
|
|
|
|
b ReleaseAndReturnZeroFromMPCall
|
|
|
|
|
|
|
|
####### ####### ######## ###### ### ## ## ###### ######## ##
|
|
## ## ## ## ## ## ## ## ## ### ## ## ## ## ##
|
|
## ## ## ## ## ## #### ## ## ## ##
|
|
####### ####### ## ## ## ## ## ## ## ## ###### ##
|
|
## ## ## ## ######### ## #### ## ## ##
|
|
## ## ## ## ## ## ## ## ## ### ## ## ## ##
|
|
####### ######### ## ###### ## ## ## ## ###### ######## ########
|
|
|
|
; ARG TimerID r3
|
|
; RET OSStatus r3, AbsoluteTime r4/r5
|
|
|
|
DeclareMPCall 32, MPCancelTimer
|
|
|
|
MPCancelTimer
|
|
|
|
_Lock PSA.SchLock, scratch1=r16, scratch2=r17
|
|
|
|
mr r8, r3
|
|
bl LookupID
|
|
cmpwi r9, Timer.kIDClass
|
|
mr r31, r8
|
|
bne+ ReleaseAndReturnMPCallInvalidIDErr
|
|
|
|
lbz r16, Timer.Byte3(r31)
|
|
cmpwi r16, 1
|
|
bne- @say_no_time_remained
|
|
|
|
lwz r4, Timer.Time(r31)
|
|
lwz r5, Timer.Time + 4(r31)
|
|
bl GetTime
|
|
mfxer r16
|
|
subfc r5, r9, r5
|
|
subfe. r4, r8, r4
|
|
mtxer r16
|
|
bge+ @can_return_time_remaining
|
|
@say_no_time_remained
|
|
|
|
li r4, 0
|
|
li r5, 0
|
|
@can_return_time_remaining
|
|
|
|
lwz r16, Timer.QueueLLL + LLL.Freeform(r31)
|
|
cmpwi r16, 0
|
|
mr r8, r31
|
|
beq- @not_queued
|
|
bl DequeueTimer
|
|
@not_queued
|
|
|
|
b ReleaseAndReturnZeroFromMPCall
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## ## ####### ######## #### ######## #### ###### ### ######## #### ####### ## ## ######
|
|
### ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ### ## ## ##
|
|
#### ## ## ## ## ## ## ## ## ## ## ## ## ## ## #### ## ##
|
|
## ## ## ## ## ## ## ###### ## ## ## ## ## ## ## ## ## ## ## ######
|
|
## #### ## ## ## ## ## ## ## ######### ## ## ## ## ## #### ##
|
|
## ### ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ### ## ##
|
|
## ## ####### ## #### ## #### ###### ## ## ## #### ####### ## ## ######
|
|
|
|
|
|
|
|
####### ## ## ## ###### ######## ######## ### ######## ########
|
|
## ## ## ## ### ## ## ## ## ## ## ## ## ## ##
|
|
## ## ## #### ## ## ## ## ## ## ## ## ##
|
|
######## ## ## ## ## ## ## ######## ###### ## ## ## ######
|
|
## ## ######### ## #### ## ## ## ## ######### ## ##
|
|
## ## ## ## ### ## ## ## ## ## ## ## ## ##
|
|
####### ## ## ## ###### ## ## ######## ## ## ## ########
|
|
|
|
; RET OSErr r3, NotificationID r4
|
|
|
|
DeclareMPCall 64, MPCreateNotification
|
|
|
|
MPCreateNotification
|
|
li r8, Notification.Size
|
|
bl PoolAlloc
|
|
mr. r31, r8
|
|
beq+ ScrambleMPCall
|
|
|
|
lisori r16, Notification.kSignature
|
|
stw r16, Notification.Signature(r31)
|
|
|
|
_Lock PSA.SchLock, scratch1=r16, scratch2=r17
|
|
|
|
li r9, Notification.kIDClass
|
|
bl MakeID
|
|
|
|
cmpwi r8, 0
|
|
bne+ @nofail
|
|
mr r8, r31
|
|
bl PoolFree
|
|
b ReleaseAndScrambleMPCall
|
|
@nofail
|
|
|
|
mfsprg r30, 0
|
|
lwz r30, EWA.PA_CurTask(r30)
|
|
stw r8, Notification.TaskPtr(r31)
|
|
lwz r17, Task.ProcessID(r30)
|
|
stw r17, Notification.ProcessID(r31)
|
|
|
|
mr r4, r8
|
|
b ReleaseAndReturnZeroFromMPCall
|
|
|
|
|
|
|
|
####### ######## ## ## ######## ######## ## ######## ######## ########
|
|
## ## ## ### ## ## ## ## ## ## ## ##
|
|
## ## #### ## ## ## ## ## ## ## ##
|
|
######## ####### ## ## ## ## ## ###### ## ###### ## ######
|
|
## ## ## ## #### ## ## ## ## ## ## ##
|
|
## ## ## ## ## ### ## ## ## ## ## ## ##
|
|
####### ###### ## ## ######## ######## ######## ######## ## ########
|
|
|
|
; ARG NotificationID r3
|
|
; RET OSErr r3
|
|
|
|
DeclareMPCall 65, MPDeleteNotification
|
|
|
|
MPDeleteNotification
|
|
|
|
_Lock PSA.SchLock, scratch1=r16, scratch2=r17
|
|
|
|
mr r8, r3
|
|
bl LookupID
|
|
cmpwi r9, Notification.kIDClass
|
|
|
|
mr r31, r8
|
|
bne+ ReleaseAndReturnMPCallInvalidIDErr
|
|
mr r8, r31
|
|
bl PoolFree
|
|
mr r8, r3
|
|
bl DeleteID
|
|
|
|
b ReleaseAndReturnZeroFromMPCall
|
|
|
|
|
|
|
|
####### ######## ## ## ###### ### ## ## ###### ########
|
|
## ## ## ## ### ## ## ## ## ## ## ## ## ## ##
|
|
## ## #### ## ## ## ## ## ## ## ##
|
|
######## ## ## ## ## ## ## ## ## ## ###### ######
|
|
## ## ## ## #### ## ######### ## ## ## ##
|
|
## ## ## ## ### ## ## ## ## ## ## ## ## ##
|
|
####### ## ## ## ###### ## ## ####### ###### ########
|
|
|
|
DeclareMPCall 67, MPCauseNotification
|
|
|
|
MPCauseNotification
|
|
|
|
_Lock PSA.SchLock, scratch1=r16, scratch2=r17
|
|
|
|
mr r8, r3
|
|
bl LookupID
|
|
cmpwi r9, Notification.kIDClass
|
|
mr r30, r8
|
|
bne+ ReleaseAndReturnMPCallInvalidIDErr
|
|
|
|
bl CauseNotification
|
|
|
|
mr r3, r8
|
|
b ReleaseAndReturnMPCall
|
|
|
|
|
|
|
|
### ## ## ###### ### ## ## ###### ######## ###
|
|
## ### ## ## ## ## ## ## ## ## ## ## ##
|
|
## #### ## ## ## ## ## ## ## ## ##
|
|
## ## ## ## ## ## ## ## ## ###### ###### ##
|
|
## ## #### ## ######### ## ## ## ## ##
|
|
## ## ### ## ## ## ## ## ## ## ## ## ##
|
|
### ## ## ###### ## ## ####### ###### ######## ###
|
|
|
|
; ARG Notification *r30
|
|
; RET OSStatus r8
|
|
|
|
CauseNotification
|
|
|
|
mflr r29
|
|
|
|
lwz r16, 0x000c(r30)
|
|
lwz r17, 0x0024(r30)
|
|
cmplwi r16, 0x00
|
|
cmplwi cr1, r17, 0x00
|
|
bne- @0x28
|
|
bne- cr1, @0x28
|
|
lwz r18, 0x001c(r30)
|
|
cmplwi r18, 0x00
|
|
beq- @fail_insufficient_resources
|
|
@0x28
|
|
|
|
|
|
; SEND MESSAGE TO QUEUE
|
|
|
|
lwz r8, Notification.QueueID(r30)
|
|
cmplwi r8, 0
|
|
beq- @NO_QUEUE
|
|
bl LookupID
|
|
cmpwi r9, Queue.kIDClass
|
|
mr r31, r8
|
|
bne- @fail_invalid_id
|
|
|
|
lwz r16, Queue.ReserveCount(r31)
|
|
cmpwi r16, 0
|
|
lwz r17, Queue.ReservePtr(r31)
|
|
beq- @no_notr
|
|
|
|
;use notr
|
|
mr. r8, r17
|
|
lwz r17, Message.LLL + LLL.Next(r17)
|
|
beq- @fail_insufficient_resources
|
|
stw r17, Queue.ReservePtr(r31)
|
|
b @queue_common
|
|
|
|
@no_notr ; ... allocate message anew
|
|
li r8, Message.Size
|
|
bl PoolAlloc_with_crset
|
|
cmpwi r8, 0
|
|
beq- @fail_unknown_err
|
|
|
|
@queue_common
|
|
lwz r16, Notification.MsgWord1(r30)
|
|
lwz r17, Notification.MsgWord2(r30)
|
|
lwz r18, Notification.MsgWord3(r30)
|
|
stw r16, Message.Word1(r8)
|
|
stw r17, Message.Word2(r8)
|
|
stw r18, Message.Word3(r8)
|
|
bl EnqueueMessage ; Message *r8, Queue *r31
|
|
@NO_QUEUE
|
|
|
|
|
|
; SIGNAL SEMAPHORE
|
|
|
|
lwz r8, Notification.SemaphoreID(r30)
|
|
cmplwi r8, 0
|
|
beq- @NO_SEMAPHORE
|
|
bl LookupID
|
|
cmpwi r9, Semaphore.kIDClass
|
|
mr r31, r8
|
|
bne- @fail_invalid_id
|
|
|
|
bl SignalSemaphore
|
|
@NO_SEMAPHORE
|
|
|
|
|
|
; SET EVENT
|
|
|
|
lwz r8, Notification.EventGroupID(r30)
|
|
cmplwi r8, 0
|
|
beq- @NO_EVENT_GROUP
|
|
bl LookupID
|
|
cmpwi r9, EventGroup.kIDClass
|
|
mr r31, r8
|
|
bne- @fail_invalid_id
|
|
|
|
lwz r8, Notification.EventFlags(r30)
|
|
bl SetEvent
|
|
@NO_EVENT_GROUP ; ... fall thru to success
|
|
|
|
|
|
@succeed
|
|
mtlr r29
|
|
li r8, 0x00
|
|
blr
|
|
|
|
@fail_unknown_err
|
|
mtlr r29
|
|
li r8, -29294
|
|
blr
|
|
|
|
@fail_insufficient_resources
|
|
mtlr r29
|
|
li r8, kMPInsufficientResourcesErr
|
|
blr
|
|
|
|
@fail_invalid_id
|
|
mtlr r29
|
|
li r8, kMPInvalidIDErr
|
|
blr
|
|
|
|
|
|
|
|
####### ####### ## ## ## ## ####### ######## #### ######## ## ##
|
|
## ## ## ## ### ## ### ### ## ## ## ## ## ## ## ##
|
|
## ## #### ## #### #### ## ## ## ## ## ## ####
|
|
######## ######## ## ## ## ## ### ## ## ## ## ## ## ###### ##
|
|
## ## ## ## ## #### ## ## ## ## ## ## ## ## ##
|
|
## ## ## ## ## ### ## ## ## ## ## ## ## ## ##
|
|
####### ####### ## ## ## ## ####### ######## #### ## ##
|
|
|
|
DeclareMPCall 66, MPModifyNotification
|
|
|
|
MPModifyNotification
|
|
|
|
_Lock PSA.SchLock, scratch1=r16, scratch2=r17
|
|
|
|
mr r8, r3
|
|
|
|
; r8 = id
|
|
bl LookupID
|
|
cmpwi r9, Notification.kIDClass
|
|
|
|
mr r31, r8
|
|
bne+ ReleaseAndReturnMPCallInvalidIDErr
|
|
mr r8, r4
|
|
|
|
; r8 = id
|
|
bl LookupID
|
|
cmpwi r9, Semaphore.kIDClass
|
|
|
|
cmpwi cr2, r9, 0x04
|
|
beq- MPCall_66_0x74
|
|
cmpwi r9, 0x09
|
|
beq- cr2, MPCall_66_0x58
|
|
bne+ ReleaseAndReturnMPCallInvalidIDErr
|
|
stw r4, 0x001c(r31)
|
|
stw r5, 0x0020(r31)
|
|
|
|
; r1 = kdp
|
|
b ReleaseAndReturnZeroFromMPCall
|
|
|
|
MPCall_66_0x58
|
|
stw r4, 0x000c(r31)
|
|
lwz r16, ContextBlock.r6(r6)
|
|
lwz r17, ContextBlock.r7(r6)
|
|
stw r5, 0x0010(r31)
|
|
stw r16, 0x0014(r31)
|
|
stw r17, 0x0018(r31)
|
|
|
|
; r1 = kdp
|
|
b ReleaseAndReturnZeroFromMPCall
|
|
|
|
MPCall_66_0x74
|
|
stw r4, 0x0024(r31)
|
|
|
|
; r1 = kdp
|
|
b ReleaseAndReturnZeroFromMPCall
|
|
|
|
|
|
|
|
## ####### ####### ## ## ## ## ####### ######## ######## ### ######## ### ## ## ######
|
|
#### ## ## ## ## ### ## ### ### ## ## ## ## ## ## ## ## ## ## ## ## ### ### ## ##
|
|
## ## ## ## #### ## #### #### ## ## ## ## ## ## ## ## ## ## ## ## #### #### ##
|
|
## ####### ####### ## ## ## ## ### ## ## ## ## ## ######## ## ## ######## ## ## ## ### ## ######
|
|
## ## ## ## ## #### ## ## ## ## ## ## ## ######### ## ## ######### ## ## ##
|
|
## ## ## ## ## ### ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ##
|
|
###### ######### ####### ## ## ## ## ####### ######## ## ## ## ## ## ## ## ## ## ######
|
|
|
|
DeclareMPCall 128, MPCall_128
|
|
|
|
MPCall_128 ; OUTSIDE REFERER
|
|
|
|
_Lock PSA.SchLock, scratch1=r16, scratch2=r17
|
|
|
|
mr r8, r3
|
|
|
|
; r8 = id
|
|
bl LookupID
|
|
cmpwi r9, Notification.kIDClass
|
|
|
|
mr r31, r8
|
|
bne+ ReleaseAndReturnMPCallInvalidIDErr
|
|
cmpwi r4, 0x04
|
|
cmpwi cr1, r4, 0x09
|
|
beq- MPCall_128_0x40
|
|
beq- cr1, MPCall_128_0x58
|
|
b ReleaseAndReturnParamErrFromMPCall
|
|
|
|
MPCall_128_0x40
|
|
lwz r16, ContextBlock.r6(r6)
|
|
lwz r17, ContextBlock.r7(r6)
|
|
stw r5, 0x0010(r31)
|
|
stw r16, 0x0014(r31)
|
|
stw r17, 0x0018(r31)
|
|
|
|
; r1 = kdp
|
|
b ReleaseAndReturnZeroFromMPCall
|
|
|
|
MPCall_128_0x58
|
|
stw r5, 0x0020(r31)
|
|
|
|
; r1 = kdp
|
|
b ReleaseAndReturnZeroFromMPCall
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### ######## ## ## ## ## ######## ## ## ## ######## ###
|
|
## ## ## ## ## ### ## ## ## ## ## ## ## ##
|
|
## ## ## ## ## #### ## ## ## ## ## ## ## ##
|
|
## ######## ## ## ## ## ## ######## ## ## ## ###### ##
|
|
## ## ## ## ## ## #### ## ## ## ## ## ## ##
|
|
## ## ## ## ## ## ### ## ## ## ## ## ## ##
|
|
### ## ## ####### ## ## ######## ######## ####### ######## ###
|
|
|
|
; ARG OpaqueID r8
|
|
|
|
; MP calls by blue return kMPBlueBlockingErr instead of blocking,
|
|
; in order to maintain system responsiveness. Blue might poll these
|
|
; calls, e.g. at SysTask time. This function, called when a
|
|
; blocking object becomes "available", unblocks blue to give it
|
|
; another shot.
|
|
|
|
UnblockBlueIfCouldBePolling
|
|
|
|
lwz r9, PSA.BlueSpinningOn(r1)
|
|
lwz r19, PSA.PA_BlueTask(r1)
|
|
cmpw r8, r9
|
|
bnelr-
|
|
|
|
li r9, -1
|
|
mflr r24
|
|
stw r9, PSA.BlueSpinningOn(r1)
|
|
|
|
lbz r17, Task.MysteryByte1(r19)
|
|
cmpwi r17, 0
|
|
|
|
addi r16, r19, Task.QueueMember
|
|
bne- major_0x0dce8_0x70
|
|
|
|
RemoveFromList r16, scratch1=r17, scratch2=r18
|
|
|
|
lbz r17, Task.Timer + Timer.Byte3(r19)
|
|
cmpwi r17, 1
|
|
bne- major_0x0dce8_0x60
|
|
addi r8, r19, Task.Timer
|
|
bl DequeueTimer
|
|
lwz r19, -0x08f0(r1)
|
|
major_0x0dce8_0x60
|
|
|
|
li r16, 0x01
|
|
stb r16, 0x0019(r19)
|
|
lwz r8, -0x08f0(r1)
|
|
bl TaskReadyAsPrev
|
|
major_0x0dce8_0x70
|
|
|
|
lwz r8, PSA.PA_BlueTask(r1)
|
|
mtlr r24
|
|
b FlagSchEvaluationIfTaskRequires
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## ####### ##### ######## #### ###### ###### ### ## ##
|
|
#### ## ## ## ## ## ## ## ## ## ## ## ## ## ## ##
|
|
## ## ## ## ## ## ## ## ## ## ## ## ##
|
|
## ####### ## ## ######## ## ## #### ## ## ## ## ##
|
|
## ## ## ## ## ## ## ## ## ## ######### ## ##
|
|
## ## ## ## ## ## ## ## ## ## ## ## ## ## ##
|
|
###### ######### ##### ######## #### ###### ###### ## ## ######## ########
|
|
|
|
DeclareMPCall 120, MPCall_120
|
|
|
|
MPCall_120
|
|
|
|
_Lock PSA.SchLock, scratch1=r16, scratch2=r17
|
|
|
|
mr r8, r3
|
|
bl LookupID
|
|
mr r31, r8
|
|
|
|
cmpwi r9, Semaphore.kIDClass
|
|
cmpwi cr1, r9, Queue.kIDClass
|
|
beq- @SEMAPHORE
|
|
beq- cr1, @QUEUE
|
|
|
|
cmpwi r9, EventGroup.kIDClass
|
|
cmpwi cr1, r9, CriticalRegion.kIDClass
|
|
beq- @EVENT_GROUP
|
|
beq- cr1, @CRITICAL_REGION
|
|
|
|
cmpwi r9, Notification.kIDClass
|
|
cmpwi cr1, r9, AddressSpace.kIDClass
|
|
beq- @NOTIFICATION
|
|
beq- cr1, @ADDRESS_SPACE
|
|
|
|
b ReleaseAndReturnParamErrFromMPCall
|
|
|
|
@NOTIFICATION
|
|
lisori r8, Notification.kFirstID
|
|
cmpw r8, r4
|
|
bne+ ReleaseAndReturnParamErrFromMPCall
|
|
|
|
cmplwi r5, 0
|
|
bne- @notification_not_0
|
|
|
|
; r5 == 0
|
|
lisori r16, Notification.kFirstID
|
|
|
|
stw r16, ContextBlock.r6(r6)
|
|
lwz r16, Notification.ProcessID(r31)
|
|
stw r16, ContextBlock.r7(r6)
|
|
lwz r16, Notification.Signature(r31)
|
|
stw r16, ContextBlock.r8(r6)
|
|
lwz r16, 0x000c(r31)
|
|
stw r16, ContextBlock.r9(r6)
|
|
li r16, 16
|
|
stw r16, ContextBlock.r10(r6)
|
|
|
|
b ReleaseAndReturnZeroFromMPCall
|
|
|
|
@notification_not_0
|
|
cmplwi r5, 16
|
|
bne- @notification_not_16
|
|
|
|
; r5 == 16
|
|
lwz r16, 0x0010(r31)
|
|
stw r16, ContextBlock.r6(r6)
|
|
lwz r16, 0x0014(r31)
|
|
stw r16, ContextBlock.r7(r6)
|
|
lwz r16, 0x0018(r31)
|
|
stw r16, ContextBlock.r8(r6)
|
|
lwz r16, 0x001c(r31)
|
|
stw r16, ContextBlock.r9(r6)
|
|
li r16, 16
|
|
stw r16, ContextBlock.r10(r6)
|
|
|
|
b ReleaseAndReturnZeroFromMPCall
|
|
|
|
@notification_not_16
|
|
|
|
cmplwi r5, 32
|
|
bne- @notification_not_32
|
|
|
|
; r5 == 32
|
|
lwz r16, 0x0020(r31)
|
|
stw r16, ContextBlock.r6(r6)
|
|
lwz r16, 0x0024(r31)
|
|
stw r16, ContextBlock.r7(r6)
|
|
li r16, 8
|
|
stw r16, ContextBlock.r10(r6)
|
|
|
|
b ReleaseAndReturnZeroFromMPCall
|
|
|
|
@notification_not_32
|
|
cmpwi r5, 40
|
|
bne+ ReleaseAndReturnParamErrFromMPCall
|
|
|
|
; r5 == 40
|
|
li r16, 0x00
|
|
stw r16, ContextBlock.r10(r6)
|
|
|
|
b ReleaseAndReturnZeroFromMPCall
|
|
|
|
|
|
@CRITICAL_REGION
|
|
lisori r8, 0x00060001
|
|
cmpw r8, r4
|
|
bne+ ReleaseAndReturnParamErrFromMPCall
|
|
cmplwi r5, 0x00
|
|
bne- @154
|
|
lis r16, 0x06
|
|
ori r16, r16, 0x01
|
|
stw r16, ContextBlock.r6(r6)
|
|
lwz r16, 0x0010(r31)
|
|
stw r16, ContextBlock.r7(r6)
|
|
lwz r16, 0x0004(r31)
|
|
stw r16, ContextBlock.r8(r6)
|
|
lwz r16, 0x0020(r31)
|
|
stw r16, ContextBlock.r9(r6)
|
|
li r16, 0x10
|
|
stw r16, ContextBlock.r10(r6)
|
|
|
|
; r1 = kdp
|
|
b ReleaseAndReturnZeroFromMPCall
|
|
|
|
@154
|
|
cmplwi r5, 0x10
|
|
bne- @1a0
|
|
addi r17, r31, 0x00
|
|
lwz r18, 0x0008(r31)
|
|
li r16, 0x00
|
|
cmpw r17, r18
|
|
beq- @174
|
|
lwz r16, -0x0008(r18)
|
|
|
|
@174
|
|
stw r16, ContextBlock.r6(r6)
|
|
lwz r16, 0x0018(r31)
|
|
cmpwi r16, 0x00
|
|
beq- @188
|
|
lwz r16, 0x0000(r16)
|
|
|
|
@188
|
|
stw r16, ContextBlock.r7(r6)
|
|
lwz r16, 0x0014(r31)
|
|
stw r16, ContextBlock.r8(r6)
|
|
li r16, 0x0c
|
|
stw r16, ContextBlock.r10(r6)
|
|
|
|
; r1 = kdp
|
|
b ReleaseAndReturnZeroFromMPCall
|
|
|
|
@1a0
|
|
cmpwi r5, 0x1c
|
|
bne+ ReleaseAndReturnParamErrFromMPCall
|
|
li r16, 0x00
|
|
stw r16, ContextBlock.r10(r6)
|
|
|
|
; r1 = kdp
|
|
b ReleaseAndReturnZeroFromMPCall
|
|
|
|
@EVENT_GROUP
|
|
lis r8, 0x09
|
|
ori r8, r8, 0x01
|
|
cmpw r8, r4
|
|
bne+ ReleaseAndReturnParamErrFromMPCall
|
|
cmplwi r5, 0x00
|
|
bne- @1fc
|
|
lis r16, 0x09
|
|
ori r16, r16, 0x01
|
|
stw r16, ContextBlock.r6(r6)
|
|
lwz r16, 0x0014(r31)
|
|
stw r16, ContextBlock.r7(r6)
|
|
lwz r16, 0x0004(r31)
|
|
stw r16, ContextBlock.r8(r6)
|
|
lwz r16, 0x001c(r31)
|
|
stw r16, ContextBlock.r9(r6)
|
|
li r16, 0x10
|
|
stw r16, ContextBlock.r10(r6)
|
|
|
|
; r1 = kdp
|
|
b ReleaseAndReturnZeroFromMPCall
|
|
|
|
@1fc
|
|
cmplwi r5, 0x10
|
|
bne- @234
|
|
addi r17, r31, 0x00
|
|
lwz r18, 0x0008(r31)
|
|
li r16, 0x00
|
|
cmpw r17, r18
|
|
beq- @21c
|
|
lwz r16, -0x0008(r18)
|
|
|
|
@21c
|
|
stw r16, ContextBlock.r6(r6)
|
|
lwz r16, 0x0010(r31)
|
|
stw r16, ContextBlock.r7(r6)
|
|
li r16, 0x08
|
|
stw r16, ContextBlock.r10(r6)
|
|
|
|
; r1 = kdp
|
|
b ReleaseAndReturnZeroFromMPCall
|
|
|
|
@234
|
|
cmpwi r5, 0x18
|
|
bne+ ReleaseAndReturnParamErrFromMPCall
|
|
li r16, 0x00
|
|
stw r16, ContextBlock.r10(r6)
|
|
|
|
; r1 = kdp
|
|
b ReleaseAndReturnZeroFromMPCall
|
|
|
|
@QUEUE
|
|
lis r8, 0x04
|
|
ori r8, r8, 0x01
|
|
cmpw r8, r4
|
|
bne+ ReleaseAndReturnParamErrFromMPCall
|
|
cmplwi r5, 0x00
|
|
bne- @290
|
|
lis r16, 0x04
|
|
ori r16, r16, 0x01
|
|
stw r16, ContextBlock.r6(r6)
|
|
lwz r16, 0x0020(r31)
|
|
stw r16, ContextBlock.r7(r6)
|
|
lwz r16, 0x0004(r31)
|
|
stw r16, ContextBlock.r8(r6)
|
|
lwz r16, 0x002c(r31)
|
|
stw r16, ContextBlock.r9(r6)
|
|
li r16, 0x10
|
|
stw r16, ContextBlock.r10(r6)
|
|
|
|
; r1 = kdp
|
|
b ReleaseAndReturnZeroFromMPCall
|
|
|
|
@290
|
|
cmplwi r5, 0x10
|
|
bne- @2ec
|
|
addi r17, r31, 0x00
|
|
lwz r18, 0x0008(r31)
|
|
li r16, 0x00
|
|
cmpw r17, r18
|
|
beq- @2b0
|
|
lwz r16, -0x0008(r18)
|
|
|
|
@2b0
|
|
stw r16, ContextBlock.r6(r6)
|
|
lwz r16, 0x0030(r31)
|
|
stw r16, ContextBlock.r7(r6)
|
|
lwz r16, 0x0024(r31)
|
|
stw r16, ContextBlock.r8(r6)
|
|
lwz r18, 0x0018(r31)
|
|
addi r17, r31, 0x10
|
|
li r16, 0x00
|
|
cmpw r17, r18
|
|
beq- @2dc
|
|
lwz r16, 0x0010(r18)
|
|
|
|
@2dc
|
|
stw r16, ContextBlock.r9(r6)
|
|
li r16, 0x10
|
|
stw r16, ContextBlock.r10(r6)
|
|
|
|
; r1 = kdp
|
|
b ReleaseAndReturnZeroFromMPCall
|
|
|
|
@2ec
|
|
cmplwi r5, 0x20
|
|
bne- @328
|
|
lwz r18, 0x0018(r31)
|
|
addi r17, r31, 0x10
|
|
li r16, 0x00
|
|
cmpw r17, r18
|
|
li r17, 0x00
|
|
beq- @314
|
|
lwz r16, 0x0014(r18)
|
|
lwz r17, 0x0018(r18)
|
|
|
|
@314
|
|
stw r16, ContextBlock.r6(r6)
|
|
stw r17, ContextBlock.r7(r6)
|
|
li r16, 0x08
|
|
stw r16, ContextBlock.r10(r6)
|
|
|
|
; r1 = kdp
|
|
b ReleaseAndReturnZeroFromMPCall
|
|
|
|
@328
|
|
cmpwi r5, 0x28
|
|
bne+ ReleaseAndReturnParamErrFromMPCall
|
|
li r16, 0x00
|
|
stw r16, ContextBlock.r10(r6)
|
|
|
|
; r1 = kdp
|
|
b ReleaseAndReturnZeroFromMPCall
|
|
|
|
@SEMAPHORE
|
|
lis r8, 0x05
|
|
ori r8, r8, 0x01
|
|
cmpw r8, r4
|
|
bne+ ReleaseAndReturnParamErrFromMPCall
|
|
cmplwi r5, 0x00
|
|
bne- @384
|
|
lis r16, 0x05
|
|
ori r16, r16, 0x01
|
|
stw r16, ContextBlock.r6(r6)
|
|
lwz r16, 0x0018(r31)
|
|
stw r16, ContextBlock.r7(r6)
|
|
lwz r16, 0x0004(r31)
|
|
stw r16, ContextBlock.r8(r6)
|
|
lwz r16, 0x001c(r31)
|
|
stw r16, ContextBlock.r9(r6)
|
|
li r16, 0x10
|
|
stw r16, ContextBlock.r10(r6)
|
|
|
|
; r1 = kdp
|
|
b ReleaseAndReturnZeroFromMPCall
|
|
|
|
@384
|
|
cmplwi r5, 0x10
|
|
bne- @3c4
|
|
addi r17, r31, 0x00
|
|
lwz r18, 0x0008(r31)
|
|
li r16, 0x00
|
|
cmpw r17, r18
|
|
beq- @3a4
|
|
lwz r16, -0x0008(r18)
|
|
|
|
@3a4
|
|
stw r16, ContextBlock.r6(r6)
|
|
lwz r16, 0x0014(r31)
|
|
stw r16, ContextBlock.r7(r6)
|
|
lwz r16, 0x0010(r31)
|
|
stw r16, ContextBlock.r8(r6)
|
|
li r16, 0x0c
|
|
stw r16, ContextBlock.r10(r6)
|
|
|
|
; r1 = kdp
|
|
b ReleaseAndReturnZeroFromMPCall
|
|
|
|
@3c4
|
|
cmpwi r5, 0x1c
|
|
bne+ ReleaseAndReturnParamErrFromMPCall
|
|
li r16, 0x00
|
|
stw r16, ContextBlock.r10(r6)
|
|
|
|
; r1 = kdp
|
|
b ReleaseAndReturnZeroFromMPCall
|
|
|
|
@ADDRESS_SPACE
|
|
lisori r8, 0x00080001
|
|
cmpw r8, r4
|
|
bne+ ReleaseAndReturnParamErrFromMPCall
|
|
cmplwi r5, 0x00
|
|
bne- @420
|
|
lisori r16, 0x00080001
|
|
stw r16, ContextBlock.r6(r6)
|
|
lwz r16, 0x0074(r31)
|
|
stw r16, ContextBlock.r7(r6)
|
|
lwz r16, 0x0070(r31)
|
|
stw r16, ContextBlock.r8(r6)
|
|
lwz r16, 0x000c(r31)
|
|
stw r16, ContextBlock.r9(r6)
|
|
li r16, 0x10
|
|
stw r16, ContextBlock.r10(r6)
|
|
|
|
; r1 = kdp
|
|
b ReleaseAndReturnZeroFromMPCall
|
|
|
|
@420
|
|
cmplwi r5, 0x10
|
|
bne- @454
|
|
lwz r16, 0x0030(r31)
|
|
stw r16, ContextBlock.r6(r6)
|
|
lwz r16, 0x0034(r31)
|
|
stw r16, ContextBlock.r7(r6)
|
|
lwz r16, 0x0038(r31)
|
|
stw r16, ContextBlock.r8(r6)
|
|
lwz r16, 0x003c(r31)
|
|
stw r16, ContextBlock.r9(r6)
|
|
li r16, 0x10
|
|
stw r16, ContextBlock.r10(r6)
|
|
|
|
; r1 = kdp
|
|
b ReleaseAndReturnZeroFromMPCall
|
|
|
|
@454
|
|
cmplwi r5, 0x20
|
|
bne- @488
|
|
lwz r16, 0x0040(r31)
|
|
stw r16, ContextBlock.r6(r6)
|
|
lwz r16, 0x0044(r31)
|
|
stw r16, ContextBlock.r7(r6)
|
|
lwz r16, 0x0048(r31)
|
|
stw r16, ContextBlock.r8(r6)
|
|
lwz r16, 0x004c(r31)
|
|
stw r16, ContextBlock.r9(r6)
|
|
li r16, 0x10
|
|
stw r16, ContextBlock.r10(r6)
|
|
|
|
; r1 = kdp
|
|
b ReleaseAndReturnZeroFromMPCall
|
|
|
|
@488
|
|
cmplwi r5, 0x30
|
|
bne- @4bc
|
|
lwz r16, 0x0050(r31)
|
|
stw r16, ContextBlock.r6(r6)
|
|
lwz r16, 0x0054(r31)
|
|
stw r16, ContextBlock.r7(r6)
|
|
lwz r16, 0x0058(r31)
|
|
stw r16, ContextBlock.r8(r6)
|
|
lwz r16, 0x005c(r31)
|
|
stw r16, ContextBlock.r9(r6)
|
|
li r16, 0x10
|
|
stw r16, ContextBlock.r10(r6)
|
|
|
|
; r1 = kdp
|
|
b ReleaseAndReturnZeroFromMPCall
|
|
|
|
@4bc
|
|
cmplwi r5, 0x40
|
|
bne- @4f0
|
|
lwz r16, 0x0060(r31)
|
|
stw r16, ContextBlock.r6(r6)
|
|
lwz r16, 0x0064(r31)
|
|
stw r16, ContextBlock.r7(r6)
|
|
lwz r16, 0x0068(r31)
|
|
stw r16, ContextBlock.r8(r6)
|
|
lwz r16, 0x006c(r31)
|
|
stw r16, ContextBlock.r9(r6)
|
|
li r16, 0x10
|
|
stw r16, ContextBlock.r10(r6)
|
|
|
|
; r1 = kdp
|
|
b ReleaseAndReturnZeroFromMPCall
|
|
|
|
@4f0
|
|
cmpwi r5, 0x50
|
|
bne+ ReleaseAndReturnParamErrFromMPCall
|
|
li r16, 0x00
|
|
stw r16, ContextBlock.r10(r6)
|
|
|
|
; r1 = kdp
|
|
b ReleaseAndReturnZeroFromMPCall
|