| 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 | ;
|
|---|
| 40 | RTC_ADDR = 70H
|
|---|
| 41 | RTC_DATA = 71H
|
|---|
| 42 |
|
|---|
| 43 |
|
|---|
| 44 | SV_DATA SEGMENT
|
|---|
| 45 | ;
|
|---|
| 46 | ; Number of processes being profiled. We don't need the RTC interrupt
|
|---|
| 47 | ; if the number is zero.
|
|---|
| 48 | ;
|
|---|
| 49 | PROFIL_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 | ;
|
|---|
| 55 | PROFIL_SUSPENDED DB FALSE
|
|---|
| 56 | PROFIL_RESUMED DB FALSE
|
|---|
| 57 |
|
|---|
| 58 | ;
|
|---|
| 59 | ; The original values of registers 0A and 0B of the RTC chip.
|
|---|
| 60 | ;
|
|---|
| 61 | OLD_RTC_REG0A DB ?
|
|---|
| 62 | OLD_RTC_REG0B DB ?
|
|---|
| 63 |
|
|---|
| 64 | SV_DATA ENDS
|
|---|
| 65 |
|
|---|
| 66 |
|
|---|
| 67 | SV_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
|
|---|
| 83 | DO_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
|
|---|
| 117 | PROFIL_OFF: XOR EAX, EAX
|
|---|
| 118 | XCHG EAX, [DI].P_PRF_SCALE
|
|---|
| 119 | TEST EAX, EAX
|
|---|
| 120 | JZ SHORT PROFIL_OK
|
|---|
| 121 | CALL PROFIL_STOP
|
|---|
| 122 | PROFIL_OK: XOR EAX, EAX
|
|---|
| 123 | RET
|
|---|
| 124 |
|
|---|
| 125 | PROFIL_EINVAL: MOV EAX, EINVAL
|
|---|
| 126 | RET
|
|---|
| 127 | DO_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
|
|---|
| 138 | PROFIL_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
|
|---|
| 146 | OK: STI
|
|---|
| 147 | DONE: RET
|
|---|
| 148 | PROFIL_START ENDP
|
|---|
| 149 |
|
|---|
| 150 | ;
|
|---|
| 151 | ; Stop profiling one process
|
|---|
| 152 | ;
|
|---|
| 153 | ASSUME DS:SV_DATA
|
|---|
| 154 | PROFIL_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
|
|---|
| 162 | DONE: RET
|
|---|
| 163 | PROFIL_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
|
|---|
| 172 | PROFIL_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
|
|---|
| 197 | DONE: MOV AL, 20H ; EOI
|
|---|
| 198 | OUT 0A0H, AL ; Slave PIC
|
|---|
| 199 | OUT 20H, AL ; Master PIC
|
|---|
| 200 | RET
|
|---|
| 201 | PROFIL_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
|
|---|
| 216 | PROFIL_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
|
|---|
| 242 | DONE: RET
|
|---|
| 243 | PROFIL_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
|
|---|
| 256 | PROFIL_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
|
|---|
| 305 | DONE: CLC
|
|---|
| 306 | RET
|
|---|
| 307 |
|
|---|
| 308 | FAIL: CALL RTC_CLEAN
|
|---|
| 309 | STC
|
|---|
| 310 | RET
|
|---|
| 311 | PROFIL_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
|
|---|
| 325 | RTC_READ PROC NEAR
|
|---|
| 326 | OUT RTC_ADDR, AL
|
|---|
| 327 | CALL IO_DELAY
|
|---|
| 328 | IN AL, RTC_DATA
|
|---|
| 329 | RET
|
|---|
| 330 | RTC_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
|
|---|
| 342 | RTC_WRITE PROC NEAR
|
|---|
| 343 | OUT RTC_ADDR, AL
|
|---|
| 344 | CALL IO_DELAY
|
|---|
| 345 | MOV AL, AH
|
|---|
| 346 | OUT RTC_DATA, AL
|
|---|
| 347 | RET
|
|---|
| 348 | RTC_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
|
|---|
| 358 | RTC_CLEAN PROC NEAR
|
|---|
| 359 | MOV AL, 0CH
|
|---|
| 360 | OUT RTC_ADDR, AL
|
|---|
| 361 | RET
|
|---|
| 362 | RTC_CLEAN ENDP
|
|---|
| 363 |
|
|---|
| 364 | ;
|
|---|
| 365 | ; Delay between two accesses to I/O ports of the same chip
|
|---|
| 366 | ;
|
|---|
| 367 | TALIGN 4
|
|---|
| 368 | IO_DELAY PROC NEAR
|
|---|
| 369 | MOV CX, 4
|
|---|
| 370 | TALIGN 4
|
|---|
| 371 | LOOP1: DEC CX
|
|---|
| 372 | JNZ LOOP1
|
|---|
| 373 | RET
|
|---|
| 374 | IO_DELAY ENDP
|
|---|
| 375 |
|
|---|
| 376 | SV_CODE ENDS
|
|---|
| 377 |
|
|---|
| 378 | END
|
|---|