1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
|
;
; Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD").
;
; This library is free software; you can redistribute it and/or modify
; it under the terms of the GNU Lesser General Public License as
; published by the Free Software Foundation; either version 2.1 of the
; License, or (at your option) any later version.
;
; This code is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
; Lesser General Public License for more details.
;
; You should have received a copy of the GNU Lesser General
; Public License along with this library; if not, write to the
; Free Software Foundation, Inc., 59 Temple Place, Suite 330,
; Boston, MA 02111-1307 USA
;
;* Function: *
;* Implements message handling routines
include SYSMGR.INC
include VSA2.INC
.model tiny,c
.586p
.CODE
externdef SysMgr_VSM: dword
externdef MsgPacket: dword
externdef VSM_ListHead: dword
externdef Current_VSM: dword
externdef Events: EVENT_ENTRY
externdef Sys_Exit: proc
externdef pascal Schedule_VSM: proc
;***********************************************************************
; This routine is called from the System Manager to enter a message
; packet into a VSM's message queue.
;
; Input:
; To_VSM = Flat ptr to VSM to which message is to be sent
; MsgCode = Priority::Message
; From_VSM = value to be put in Async_VSM field
; MsgPacket contains the message parameters
;***********************************************************************
Send_Message proc pascal uses di si \
From_VSM: dword, \
To_VSM: dword, \
MsgCode: dword
mov edi, [To_VSM]
cmp edi, [SysMgr_VSM] ; Don't send messages to SysMgr
je short Exit
mov eax, [MsgCode]
lea si, [MsgPacket]
mov ebx, [From_VSM]
call Insert_Msg
Exit: ret
Send_Message endp
;***********************************************************************
; This routine enters a message packet into a VSM's message queue.
;
; Input:
; EAX = Priority::Message
; EBX = From_VSM
; EDI = To_VSM
; SI = Ptr to message packet
;***********************************************************************
Insert_Msg proc
cld
push ebx ; Save From_VSM
; Get ptr to the head of the message queue
movzx ebx, fs:(VSM_Header PTR [edi]).SysStuff.Qhead
; Compute ptr to the next available message queue entry
lea dx, [bx+sizeof(Message)]
cmp dx, fs:(VSM_Header PTR [edi]).SysStuff.EndMsgQ
jb short Check_Q_Overflow
mov dx, OFFSET VSM_Header.SysStuff.MsgQueue
Check_Q_Overflow:
; Is Qhead == Qtail ?
cmp dx, fs:(VSM_Header PTR [edi]).SysStuff.Qtail
jne short UpdateQueueHead
; Yes, then message queue has overflowed
mov [si+8], eax ; Store previous message into Param2
mov ax, MSG_QUEUE_OVERFLOW ; Replace previous message
mov dx, bx ; Qhead = old Qhead
UpdateQueueHead:
mov fs:(VSM_Header PTR [edi]).SysStuff.Qhead, dx
pop edx ; From_VSM
push edi ; Parameter to Schedule_VSM() below
; Store the message into the VSM's message queue.
; NOTE: This code is dependent on "#typedef Message"
add edi, ebx
stosd [edi] ; Priority::Message
mov eax, edx ; From_VSM
stosd [edi]
REPEAT MAX_MSG_PARAM
lodsd ; Copy parameters to message queue
stosd [edi]
ENDM
; Sort messages by Priority
if SUPPORT_PRIORITY
pop ebx ; To_VSM
push ebx
push fs:(VSM_Header PTR [ebx]).SysStuff.Qhead
BubbleSort:
; Get ptr to latest queue entry
movzx esi, fs:(VSM_Header PTR [ebx]).SysStuff.Qhead
sub esi, sizeof(Message)
cmp si, OFFSET VSM_Header.SysStuff.MsgQueue
jae short @f
mov si, fs:(VSM_Header PTR [ebx]).SysStuff.EndMsgQ
sub si, sizeof(Message)
@@:
cmp si, fs:(VSM_Header PTR [ebx]).SysStuff.Qtail
je Bail
; Get ptr to previous queue entry
lea edi, [esi-sizeof(Message)]
cmp di, OFFSET VSM_Header.SysStuff.MsgQueue
jae short @f
mov di, fs:(VSM_Header PTR [ebx]).SysStuff.EndMsgQ
sub di, sizeof(Message)
@@:
mov fs:(VSM_Header PTR [ebx]).SysStuff.Qhead, di
; Add VSM base to ptrs
add edi, ebx
add esi, ebx
; Compare their priorities
mov ax, fs:(Message PTR [esi]).Priority
cmp ax, fs:(Message PTR [edi]).Priority
jbe short Bail
; Swap the entries in the message queue
mov cx, sizeof(Message)/4 ; Assumes entry is multiple of dword
Interchange:
mov eax, fs:[edi]
xchg fs:[esi], eax
stosd [edi]
add esi, 4
loop Interchange
jmp BubbleSort
Bail:
pop fs:(VSM_Header PTR [ebx]).SysStuff.Qhead
endif
; Schedule the VSM to execute
pop eax
cmp eax, [SysMgr_VSM]
je short Exit
push eax
call Schedule_VSM
Exit:
ret
Insert_Msg endp
;************************************************************************
;
; Sends a message to each VSM of type VSM_Type (or all if VSM_ANY).
; Called from HANDLERS.C
;
;************************************************************************
Broadcast_Message proc pascal uses si di \
MsgCode: word, \
VSM_Type: word, \
From_VSM: dword
mov edi, [VSM_ListHead] ; Get ptr to list of VSMs
VSM_Loop:
or edi, edi ; End of VSM list ?
jz Exit_Broadcast
mov dx, [VSM_Type]
mov ah, fs:(VSM_Header PTR [edi]).VSM_Type
cmp dl, VSM_ANY ; Schedule all VSMs ?
je Schedule_It
test dh, (VSM_ALL_EXCEPT SHR 8)
jz CheckType
cmp dl, ah ; Skip the one that matches
je Skip_VSM
jmp Schedule_It
CheckType:
cmp dl, ah ; Is it the correct VSM ?
jne Skip_VSM
Schedule_It:
cmp edi, [From_VSM] ; Is it the requesting VSM ?
je Skip_VSM ; Yes, don't send to sender
push edi
movzx eax, [MsgCode] ; Send the message
xor ebx, ebx
lea si, [MsgPacket]
; EAX = Priority::Message
; EBX = 00000000h (a broadcast is not a synchronous event)
; SI = Ptr to message packet
; EDI = Ptr to VSM header where message is to be sent
call Insert_Msg
pop edi
Skip_VSM:
mov edi, fs:(VSM_Header PTR [edi]).SysStuff.Flink
jmp VSM_Loop
Exit_Broadcast:
ret
Broadcast_Message endp
;************************************************************************
; Broadcasts a message to one or more VSMs.
;
; Input:
; EBX = message code (16 MSBs)
; BH = Flags
; BL = VSM_Type
; ECX = Param1
; ESI = Param2
; EDI = Param3
;************************************************************************
Sys_Broadcast proc
mov dx, bx ; Put VSM_Type::Flags into DX
shr ebx, 16 ; Put message into BX
mov eax, esi
lea si, [MsgPacket]
mov [si+0], ecx
mov [si+4], eax
mov [si+8], edi
; Re-schedule the broadcasting VSM
; RunFlag will be changed from RUN_FLAG_ACTIVE to RUN_FLAG_READY
mov edi, [Current_VSM]
push edi
call Schedule_VSM
; If RunFlag == RUN_FLAG_READY, Insert_Msg() won't schedule it again
mov fs:(VSM_Header PTR [edi]).SysStuff.RunFlag, RUN_FLAG_BLOCKED
; Push parameters for call to Broadcast_Message()
push bx ; Message code
push dx ; VSM type
push edi ; From_VSM
; Normally, the message is sent to the broadcasting VSM
; after all VSMs have handled the broadcasted message.
; There are two exceptions to this rule:
; 1) VSM_NOT_SELF | <VSM type>
; 2) VSM_ALL_EXCEPT | <self>
test dh, (VSM_NOT_SELF SHR 8)
jnz short Broadcast
test dh, (VSM_ALL_EXCEPT SHR 8)
jz short SendToSelf
cmp dl, fs:(VSM_Header PTR [edi]).VSM_Type
je short Broadcast
SendToSelf:
; Put callback address onto the scheduler stack
mov eax, OFFSET BroadcastCallback
push eax
call Schedule_VSM
mov ax, BROADCAST_PRIORITY ; EAX = Priority::Message
shl eax, 16
mov ax, bx
mov edi, [SysMgr_VSM] ; EDI = To_VSM
mov ebx, [Current_VSM] ; EBX = From_VSM
call Insert_Msg
Broadcast:
call Broadcast_Message
jmp Sys_Exit ; Exit w/o scheduling current VSM
Sys_Broadcast endp
;************************************************************************
; Control comes here when all VSMs have processed the broadcasted message.
; Copies the broadcasted message from SysMgr's message queue to the
; broadcasting VSM's message queue.
;************************************************************************
BroadcastCallback proc
ASSUME DI: PTR VSM_Header
ASSUME BX: PTR Message
; Point BX to parameters in SysMgr's message queue head
xor di, di
mov bx, [di].SysStuff.Qhead
sub bx, sizeof(Message)
cmp bx, OFFSET VSM_Header.SysStuff.MsgQueue
jb short BadMsgStack
mov [di].SysStuff.Qhead, bx
mov eax, dword ptr [bx].Msg ; Get Priority::Message
mov edi, [bx].From_VSM ; To_VSM (the VSM it was originally from)
lea si, [bx].Param
xor ebx, ebx ; From_VSM (asynchronous)
call Insert_Msg
BadMsgStack:
ret
ASSUME BX: NOTHING
ASSUME DI: NOTHING
BroadcastCallback endp
;***********************************************************************
; Passes an event to the next VSM registered for this event
; NOTE: This system call is now obsolete.
;***********************************************************************
Sys_PassEvent proc
jmp Sys_Exit ; Exit to VSM dispatcher
Sys_PassEvent endp
END
|