Subversion Repositories Kolibri OS

Rev

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

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