Subversion Repositories Kolibri OS

Rev

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

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