Subversion Repositories Kolibri OS

Rev

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

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