source: vendor/emx/current/src/dos/profil.asm

Last change on this file was 18, checked in by bird, 22 years ago

Initial revision

  • Property cvs2svn:cvs-rev set to 1.1
  • Property svn:eol-style set to native
  • Property svn:executable set to *
File size: 10.1 KB
Line 
1;
2; PROFIL.ASM -- Implement profil()
3;
4; Copyright (c) 1995 by Eberhard Mattes
5;
6; This file is part of emx.
7;
8; emx is free software; you can redistribute it and/or modify it
9; under the terms of the GNU General Public License as published by
10; the Free Software Foundation; either version 2, or (at your option)
11; any later version.
12;
13; emx is distributed in the hope that it will be useful,
14; but WITHOUT ANY WARRANTY; without even the implied warranty of
15; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16; GNU General Public License for more details.
17;
18; You should have received a copy of the GNU General Public License
19; along with emx; see the file COPYING. If not, write to
20; the Free Software Foundation, 59 Temple Place - Suite 330,
21; Boston, MA 02111-1307, USA.
22;
23; See emx.asm for a special exception.
24;
25
26__PROFIL = 1
27 INCLUDE EMX.INC
28 INCLUDE SIGNAL.INC
29 INCLUDE PROCESS.INC
30 INCLUDE PMINT.INC
31 INCLUDE PROFIL.INC
32 INCLUDE ERRORS.INC
33
34 PUBLIC DO_PROFIL, PROFIL_SUSPEND, PROFIL_RESUME, PROFIL_TICK
35 PUBLIC PROFIL_COUNT
36
37;
38; I/O port addresses of the MC146818 RTC chip
39;
40RTC_ADDR = 70H
41RTC_DATA = 71H
42
43
44SV_DATA SEGMENT
45;
46; Number of processes being profiled. We don't need the RTC interrupt
47; if the number is zero.
48;
49PROFIL_COUNT DW 0
50
51;
52; The following two variables attempt to avoid lossage when using
53; the kernel debugge on the profiling code.
54;
55PROFIL_SUSPENDED DB FALSE
56PROFIL_RESUMED DB FALSE
57
58;
59; The original values of registers 0A and 0B of the RTC chip.
60;
61OLD_RTC_REG0A DB ?
62OLD_RTC_REG0B DB ?
63
64SV_DATA ENDS
65
66
67SV_CODE SEGMENT
68
69 ASSUME CS:SV_CODE, DS:NOTHING
70
71;
72; profil()
73;
74; In: ES:ESI Pointer to PROFIL structure
75; DI Pointer to process table entry
76;
77; Out: EAX errno
78;
79 TALIGN 4
80 ASSUME ESI:NEAR32 PTR PROFIL
81 ASSUME DI:PTR PROCESS
82 ASSUME DS:SV_DATA
83DO_PROFIL PROC NEAR
84 CMP ES:[ESI].PRF_CB, SIZE PROFIL
85 JNE SHORT PROFIL_EINVAL
86;
87; Turn off profiling if scale <= 2 or bufsiz = 0
88;
89 CMP ES:[ESI].PRF_SCALE, 1
90 JBE SHORT PROFIL_OFF
91 CMP ES:[ESI].PRF_BUFSIZ, 0
92 JE SHORT PROFIL_OFF
93;
94; Copy the values into the process table
95;
96 MOV EAX, ES:[ESI].PRF_BUFF
97 MOV [DI].P_PRF_BUFF, EAX
98 MOV EAX, ES:[ESI].PRF_BUFSIZ
99 AND EAX, NOT 3
100 MOV [DI].P_PRF_BUFSIZ, EAX
101 MOV EAX, ES:[ESI].PRF_OFFSET
102 MOV [DI].P_PRF_OFFSET, EAX
103 MOV EAX, ES:[ESI].PRF_SCALE
104 MOV [DI].P_PRF_SCALE, EAX
105;
106; Start profiling
107;
108 CALL PROFIL_START
109 JC SHORT PROFIL_EINVAL
110 XOR EAX, EAX
111 RET
112
113;
114; Stop profiling
115;
116 TALIGN 4
117PROFIL_OFF: XOR EAX, EAX
118 XCHG EAX, [DI].P_PRF_SCALE
119 TEST EAX, EAX
120 JZ SHORT PROFIL_OK
121 CALL PROFIL_STOP
122PROFIL_OK: XOR EAX, EAX
123 RET
124
125PROFIL_EINVAL: MOV EAX, EINVAL
126 RET
127DO_PROFIL ENDP
128
129 ASSUME ESI:NOTHING
130 ASSUME DI:NOTHING
131
132;
133; Start profiling one process
134;
135; Out: CY Error
136;
137 ASSUME DS:SV_DATA
138PROFIL_START PROC NEAR
139 INC PROFIL_COUNT
140 CMP PROFIL_COUNT, 1
141 JNE SHORT DONE
142 CLI
143 CALL PROFIL_RESUME
144 JNC SHORT OK
145 MOV PROFIL_COUNT, 0
146OK: STI
147DONE: RET
148PROFIL_START ENDP
149
150;
151; Stop profiling one process
152;
153 ASSUME DS:SV_DATA
154PROFIL_STOP PROC NEAR
155 CMP PROFIL_COUNT, 0
156 JE SHORT DONE
157 DEC PROFIL_COUNT
158 JNZ SHORT DONE
159 CLI
160 CALL PROFIL_SUSPEND
161 STI
162DONE: RET
163PROFIL_STOP ENDP
164
165;
166; Timer tick for profiler, called by PMINT for IRQ8 if PROFIL_COUNT
167; is non-zero
168;
169 TALIGN 4
170 ASSUME DS:SV_DATA
171 ASSUME BP:PTR ISTACKFRAME
172PROFIL_TICK PROC NEAR
173 MOV AL, 0CH ; Read status register
174 CALL RTC_READ
175 TEST AL, 40H ; Periodic interrupt pending?
176 JZ SHORT DONE ; No -> done
177 CMP I_CS, L_CODE_SEL ; Profile user code only
178 JNE SHORT DONE
179 MOV BX, PROCESS_PTR
180 CMP BX, NO_PROCESS ; User process active?
181 JE SHORT DONE ; No -> done
182 ASSUME BX:PTR PROCESS
183 CMP [BX].P_PRF_SCALE, 0 ; Profiling that process?
184 JE SHORT DONE ; No -> done
185 MOV EAX, I_EIP ; Compute counter offset
186 SUB EAX, [BX].P_PRF_OFFSET
187 JC SHORT DONE
188 MUL [BX].P_PRF_SCALE
189 SHRD EAX, EDX, 16
190 AND EAX, NOT 3
191 CMP EAX, [BX].P_PRF_BUFSIZ ; Within buffer?
192 JAE SHORT DONE ; No -> done
193 MOV EDX, [BX].P_PRF_BUFF
194 MOV CX, L_DATA_SEL
195 MOV ES, CX
196 INC DWORD PTR ES:[EDX+EAX] ; Increment counter
197DONE: MOV AL, 20H ; EOI
198 OUT 0A0H, AL ; Slave PIC
199 OUT 20H, AL ; Master PIC
200 RET
201PROFIL_TICK ENDP
202 ASSUME BP:NOTHING
203 ASSUME BX:NOTHING
204
205
206;
207; Suspend generating profiler interrupts.
208;
209; This should be done before executing real-mode-code. Call with
210; interrupts disabled!
211;
212; Important: PROFIL_RESUME must have been called at least once!
213;
214 ASSUME DS:SV_DATA
215 TALIGN 4
216PROFIL_SUSPEND PROC NEAR
217 MOV PROFIL_RESUMED, FALSE
218 CMP PROFIL_SUSPENDED, FALSE
219 JNE SHORT DONE
220 MOV PROFIL_SUSPENDED, NOT FALSE
221;
222; Disable the RTC interrupt (IRQ8) in the slave interrupt controller
223;
224 IN AL, 0A1H
225 OR AL, 01H
226 CALL IO_DELAY
227 OUT 0A1H, AL
228;
229; Stop the RTC from generating interrupts
230;
231 MOV AL, 0BH
232 MOV AH, OLD_RTC_REG0B
233 CALL RTC_WRITE
234;
235; Restore the original interrupt rate
236;
237 MOV AL, 0AH
238 MOV AH, OLD_RTC_REG0A
239 CALL RTC_WRITE
240 CALL IO_DELAY
241 CALL RTC_CLEAN
242DONE: RET
243PROFIL_SUSPEND ENDP
244
245
246;
247; Resume generating profiler interrupts.
248;
249; This should be done after executing real-mode-code. Call with
250; interrupts disabled!
251;
252; Out: CY Cannot enable profiler interrupts
253;
254 ASSUME DS:SV_DATA
255 TALIGN 4
256PROFIL_RESUME PROC NEAR
257 MOV PROFIL_SUSPENDED, FALSE
258 CMP PROFIL_RESUMED, FALSE
259 JNE SHORT DONE
260 MOV PROFIL_RESUMED, NOT FALSE
261;
262; Read and save the current values of RTC registers 0A and 0B
263;
264 MOV AL, 0AH
265 CALL RTC_READ
266 MOV OLD_RTC_REG0A, AL
267
268 MOV AL, 0BH
269 CALL RTC_READ
270 MOV OLD_RTC_REG0B, AL
271;
272; Don't profile if RTC interrupts are used by someone else
273; or if square-wave output is enabled
274;
275 TEST AL, 78H
276 JNZ SHORT FAIL
277;
278; Set the interrupt rate to 1024Hz
279;
280 MOV AH, OLD_RTC_REG0A
281 AND AH, 0F0H
282 OR AH, 06H
283 MOV AL, 0AH
284 CALL RTC_WRITE
285;
286; Enable the RTC's periodic interrupt
287;
288 MOV AH, OLD_RTC_REG0B
289 OR AH, 40H ; Enable periodic interrupt
290 AND AH, NOT 30H ; Disable alarm & update-ended
291 MOV AL, 0BH ; interrupts
292 CALL RTC_WRITE
293;
294; Clear pending interrupts
295;
296 MOV AL, 0CH
297 CALL RTC_READ
298;
299; Enable the RTC interrupt (IRQ8) in the slave interrupt controller
300;
301 IN AL, 0A1H
302 AND AL, NOT 01H
303 CALL IO_DELAY
304 OUT 0A1H, AL
305DONE: CLC
306 RET
307
308FAIL: CALL RTC_CLEAN
309 STC
310 RET
311PROFIL_RESUME ENDP
312
313
314;
315; Read an RTC register
316;
317; In: AL Register number
318;
319; Out: AL Register contents
320;
321; Note: This routine enables NMIs
322; Call with interrupts disabled!
323;
324 TALIGN 4
325RTC_READ PROC NEAR
326 OUT RTC_ADDR, AL
327 CALL IO_DELAY
328 IN AL, RTC_DATA
329 RET
330RTC_READ ENDP
331
332;
333; Write an RTC register
334;
335; In: AL Register number
336; AH Value
337;
338; Note: This routine enables NMIs
339; Call with interrupts disabled!
340;
341 TALIGN 4
342RTC_WRITE PROC NEAR
343 OUT RTC_ADDR, AL
344 CALL IO_DELAY
345 MOV AL, AH
346 OUT RTC_DATA, AL
347 RET
348RTC_WRITE ENDP
349
350;
351; Set the RTC address register to 0CH
352;
353; (BIOS does this after reading or writing a RTC register.)
354;
355; Note: This routine enables NMIs
356;
357 TALIGN 4
358RTC_CLEAN PROC NEAR
359 MOV AL, 0CH
360 OUT RTC_ADDR, AL
361 RET
362RTC_CLEAN ENDP
363
364;
365; Delay between two accesses to I/O ports of the same chip
366;
367 TALIGN 4
368IO_DELAY PROC NEAR
369 MOV CX, 4
370 TALIGN 4
371LOOP1: DEC CX
372 JNZ LOOP1
373 RET
374IO_DELAY ENDP
375
376SV_CODE ENDS
377
378 END
Note: See TracBrowser for help on using the repository browser.