Subversion Repositories Kolibri OS

Rev

Rev 557 | Rev 634 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
431 serge 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
3
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
4
;; Copyright (C) MenuetOS 2000-2004 Ville Mikael Turjanmaa      ;;
5
;; Distributed under terms of the GNU General Public License    ;;
6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7
 
593 mikedld 8
$Revision: 593 $
9
 
10
 
1 ha 11
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
12
;; IRQ0 HANDLER (TIMER INTERRUPT) ;;
13
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
14
 
465 serge 15
 
1 ha 16
align 32
17
irq0:
465 serge 18
   ;     pushfd
19
        pushad
20
        mov   ax, app_data  ;
21
        mov   ds, ax
22
        mov   es, ax
1 ha 23
 
24
        inc   dword [timer_ticks]
25
 
26
        mov   eax, [timer_ticks]
22 poddubny 27
        call  playNote           ; <<<--- Speaker driver
28
 
1 ha 29
        cmp   eax,[next_usage_update]
30
        jb    .nocounter
31
        add   eax,100
32
        mov   [next_usage_update],eax
33
        call  updatecputimes
465 serge 34
.nocounter:
381 serge 35
        cmp   [DONT_SWITCH], byte 1
101 poddubny 36
        jne   .change_task
37
 
38
        mov   al,0x20   ; send End Of Interrupt signal
39
        mov   dx,0x20
40
        out   dx,al
41
 
381 serge 42
        mov   [DONT_SWITCH], byte 0
101 poddubny 43
 
465 serge 44
        popad
45
 ;       popfd
46
        iretd
101 poddubny 47
 
465 serge 48
.change_task:
101 poddubny 49
        call  update_counters
50
 
51
        call  find_next_task
52
        mov   ecx, eax
53
 
54
        mov   al,0x20   ; send End Of Interrupt signal
55
        mov   dx,0x20
56
        out   dx,al
57
 
58
	test  ecx, ecx  ; if there is only one running process
59
        jnz   .return
60
 
61
        call  do_change_task
379 serge 62
 
465 serge 63
.return:
64
        popad
65
 ;       popfd
66
        iretd
101 poddubny 67
 
68
 
69
align 4
70
change_task:
71
 
72
        pushfd
73
        cli
74
        pushad
75
 
76
        call  update_counters
465 serge 77
 
78
if 0
79
 
187 diamond 80
; \begin{Mario79}
81
        cmp     [dma_task_switched], 1
82
        jne     .find_next_task
83
        mov     [dma_task_switched], 0
84
        mov     ebx, [dma_process]
379 serge 85
        cmp     [CURRENT_TASK], ebx
187 diamond 86
        je      .return
87
        mov     edi, [dma_slot_ptr]
379 serge 88
        mov     [CURRENT_TASK], ebx
89
        mov     [TASK_BASE], edi
187 diamond 90
        jmp     @f
91
.find_next_task:
92
; \end{Mario79}
465 serge 93
 
94
end if
95
 
101 poddubny 96
        call  find_next_task
97
        test  eax, eax    ; the same task -> skip switch
98
        jnz    .return
187 diamond 99
@@:
381 serge 100
        mov   [DONT_SWITCH],byte 1
101 poddubny 101
        call  do_change_task
102
 
465 serge 103
.return:
101 poddubny 104
        popad
105
        popfd
106
        ret
107
 
108
 
109
uglobal
110
   align 4
111
   far_jump:
112
    .offs dd ?
113
    .sel  dw ?
114
   context_counter     dd ? ;noname & halyavin
115
   next_usage_update   dd ?
116
   timer_ticks         dd ?
117
   prev_slot           dd ?
118
   event_sched         dd ?
119
endg
120
 
121
 
122
update_counters:
379 serge 123
        mov   edi, [TASK_BASE]
115 poddubny 124
        mov   ebx, [edi+TASKDATA.counter_add] ; time stamp counter add
465 serge 125
        rdtsc
1 ha 126
        sub   eax, ebx
115 poddubny 127
        add   eax, [edi+TASKDATA.counter_sum] ; counter sum
128
        mov   [edi+TASKDATA.counter_sum], eax
101 poddubny 129
ret
1 ha 130
 
101 poddubny 131
 
132
; Find next task to execute
133
; result: ebx = number of the selected task
102 poddubny 134
;         eax = 1  if the task is the same
135
;         edi = address of the data for the task in ebx
136
;         [0x3000] = ebx and [0x3010] = edi
137
;         corrupts other regs
101 poddubny 138
find_next_task:
379 serge 139
        mov   ebx, [CURRENT_TASK]
140
        mov   edi, [TASK_BASE]
21 poddubny 141
        mov   [prev_slot], ebx
1 ha 142
 
465 serge 143
.waiting_for_termination:
144
.waiting_for_reuse:
145
.waiting_for_event:
146
.suspended:
379 serge 147
        cmp   ebx, [TASK_COUNT]
21 poddubny 148
        jb    @f
379 serge 149
        mov   edi, CURRENT_TASK
21 poddubny 150
        xor   ebx, ebx
465 serge 151
@@:
21 poddubny 152
 
1 ha 153
        add   edi,0x20
154
        inc   ebx
155
 
115 poddubny 156
        mov   al, byte [edi+TASKDATA.state]
101 poddubny 157
        test  al, al
158
        jz    .found
40 halyavin 159
	cmp   al, 1
160
	jz    .suspended
161
	cmp   al, 2
162
	jz    .suspended
1 ha 163
        cmp   al, 3
164
        je    .waiting_for_termination
165
        cmp   al, 4
166
        je    .waiting_for_termination
167
        cmp   al, 9
168
        je    .waiting_for_reuse
169
 
379 serge 170
        mov   [CURRENT_TASK],ebx
171
        mov   [TASK_BASE],edi
1 ha 172
 
21 poddubny 173
        cmp   al, 5
174
        jne   .noevents
175
        call  get_event_for_app
176
        test  eax, eax
531 diamond 177
        jnz   @f
178
        mov   eax, ebx
179
        shl   eax, 8
180
        mov   eax, [SLOT_BASE + APPDATA.wait_timeout + eax]
181
        cmp   eax, [timer_ticks]
182
        jae   .waiting_for_event
183
        xor   eax, eax
184
@@:
21 poddubny 185
        mov   [event_sched], eax
115 poddubny 186
        mov   [edi+TASKDATA.state], byte 0
465 serge 187
.noevents:
188
.found:
379 serge 189
        mov   [CURRENT_TASK],ebx
190
        mov   [TASK_BASE],edi
465 serge 191
        rdtsc                     ;call  _rdtsc
115 poddubny 192
        mov   [edi+TASKDATA.counter_add],eax
1 ha 193
 
465 serge 194
        mov esi, [prev_slot]
101 poddubny 195
	xor   eax, eax
465 serge 196
        cmp   ebx, esi
101 poddubny 197
        sete  al
198
ret
199
 
465 serge 200
; param
201
;  ebx = incoming task
202
;  esi = outcomig task
203
 
101 poddubny 204
do_change_task:
465 serge 205
 
206
        shl ebx, 8
207
        add ebx, SLOT_BASE
208
        mov [current_slot], ebx
209
 
210
        shl esi, 8
211
        add esi, SLOT_BASE
212
 
213
        mov [esi+APPDATA.saved_esp], esp
214
        mov esp, [ebx+APPDATA.saved_esp]
215
 
216
; set thread io map
217
 
218
        mov ecx, [ebx+APPDATA.io_map]
219
        mov edx, [ebx+APPDATA.io_map+4]
220
        mov dword [page_tabs+((tss._io_map_0 and -4096) shr 10)], ecx
221
        mov dword [page_tabs+((tss._io_map_1 and -4096) shr 10)], edx
222
 
223
        mov eax, [ebx+APPDATA.dir_table]
557 serge 224
        cmp eax, [esi+APPDATA.dir_table]
225
        je @F
465 serge 226
        mov cr3, eax
557 serge 227
@@:
465 serge 228
        mov ebx, [ebx+APPDATA.pl0_stack]
229
        add ebx, RING0_STACK_SIZE
230
        mov [tss._esp0], ebx
557 serge 231
        mov ax, graph_data
232
        mov gs, ax
465 serge 233
        mov ecx, cr0
234
        or ecx, CR0_TS   ;set task switch flag
235
        mov cr0, ecx
9 halyavin 236
        inc   [context_counter] ;noname & halyavin
1 ha 237
 
465 serge 238
        test [ebx+APPDATA.dbg_state], 1
239
        jnz @F
240
        ret
241
@@:
242
        mov eax, [ebx+APPDATA.dbg_regs.dr0]
243
        mov dr0, eax
244
        mov eax, [ebx+APPDATA.dbg_regs.dr1]
245
        mov dr1, eax
246
        mov eax, [ebx+APPDATA.dbg_regs.dr2]
247
        mov dr2, eax
248
        mov eax, [ebx+APPDATA.dbg_regs.dr3]
249
        mov dr3, eax
250
        xor eax, eax
251
        mov dr6, eax
252
        mov eax, [ebx+APPDATA.dbg_regs.dr7]
253
        mov dr7, eax
254
        ret
8 poddubny 255
 
1 ha 256
align 4
257
updatecputimes:
258
 
259
        mov  eax,[idleuse]
260
        mov  [idleusesec],eax
261
        mov  [idleuse],dword 0
379 serge 262
        mov  ecx, [TASK_COUNT]
263
        mov  edi, TASK_DATA
465 serge 264
.newupdate:
115 poddubny 265
        mov  ebx,[edi+TASKDATA.counter_sum]
266
        mov  [edi+TASKDATA.cpu_usage],ebx
267
        mov  [edi+TASKDATA.counter_sum],dword 0
1 ha 268
        add  edi,0x20
269
        dec  ecx
270
        jnz  .newupdate
271
 
272
        ret
465 serge 273
 
274
if 0
275
 
276
 
277
struc TIMER
278
{
279
  .next      dd ?
280
  .exp_time  dd ?
281
  .func      dd ?
282
  .arg       dd ?
283
}
284
 
285
 
286
 
287
 
288
 
289
 
290
 
291
 
292
 
293
MAX_PROIRITY         0   ; highest, used for kernel tasks
294
MAX_USER_PRIORITY    0   ; highest priority for user processes
295
USER_PRIORITY        7   ; default (should correspond to nice 0)
296
MIN_USER_PRIORITY   14   ; minimum priority for user processes
297
IDLE_PRIORITY       15   ; lowest, only IDLE process goes here
298
NR_SCHED_QUEUES     16   ; MUST equal IDLE_PRIORYTY + 1
299
 
300
rdy_head   rd 16
301
 
302
 
303
align 4
304
pick_task:
305
 
306
           xor eax, eax
307
.pick:
308
           mov ebx, [rdy_head+eax*4]
309
           test ebx, ebx
310
           jz .next
311
 
312
           mov [next_task], ebx
313
           test [ebx+flags.billable]
314
           jz @F
315
           mov [bill_task], ebx
316
@@:
317
           ret
318
.next:
319
           inc eax
320
           jmp .pick
321
 
322
 
323
; param
324
;  eax= task
325
;
326
; retval
327
;  eax= task
328
;  ebx= queue
329
;  ecx= front if 1 or back if 0
330
 
331
align 4
332
shed:
333
           cmp [eax+.tics_left], 0 ;signed compare
334
           mov ebx, [eax+.priority]
335
           setg ecx
336
           jg @F
337
 
338
           mov edx, [eax+.tics_quantum]
339
           mov [eax+.ticks_left], edx
340
           cmp ebx, (IDLE_PRIORITY-1)
341
           je @F
342
           inc ebx
343
@@:
344
           ret
345
 
346
; param
347
;  eax= task
348
 
349
align 4
350
enqueue:
351
          call shed  ;eax
352
          cmp [rdy_head+ebx*4],0
353
          jnz @F
354
 
355
          mov [rdy_head+ebx*4], eax
356
          mov [rdy_tail+ebx*4], eax
357
          mov [eax+.next_ready], 0
358
          jmp .pick
359
@@:
360
          test ecx, ecx
361
          jz .back
362
 
363
          mov ecx, [rdy_head+ebx*4]
364
          mov [eax+.next_ready], ecx
365
          mov [rdy_head+ebx*4], eax
366
          jmp .pick
367
.back:
368
          mov ecx, [rdy_tail+ebx*4]
369
          mov [ecx+.next_ready], eax
370
          mov [rdy_tail+ebx*4], eax
371
          mov [eax+.next_ready], 0
372
.pick:
373
          call pick_proc     ;select next task
374
          ret
375
 
376
end if
377