Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
1159 hidnplayr 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
 
8
$Revision: 907 $
9
 
10
 
11
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
12
;; IRQ0 HANDLER (TIMER INTERRUPT) ;;
13
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
14
 
15
 
16
align 32
17
irq0:
1198 clevermous 18
        pushad
19
        Mov     ds, ax, app_data
20
        mov     es, ax
21
        inc     [timer_ticks]
22
        mov     eax, [timer_ticks]
23
        call    playNote       ; <<<--- Speaker driver
24
        sub     eax,[next_usage_update]
25
        cmp     eax,100
26
        jb      .nocounter
27
        add     [next_usage_update],100
28
        call    updatecputimes
29
  .nocounter:
30
        mov     al,0x20  ; send End Of Interrupt signal
31
        out     0x20,al
32
        btr     dword[DONT_SWITCH], 0
33
        jc      .return
34
        call    find_next_task
35
        jz      .return  ; if there is only one running process
36
        call    do_change_task
37
  .return:
38
        popad
39
        iretd
1159 hidnplayr 40
 
41
align 4
42
change_task:
1198 clevermous 43
        pushfd
44
        cli
45
        pushad
1159 hidnplayr 46
if 0
1198 clevermous 47
; \begin{Mario79} ; <- must be refractoried, if used...
48
        cmp     [dma_task_switched], 1
49
        jne     .find_next_task
50
        mov     [dma_task_switched], 0
51
        mov     ebx, [dma_process]
52
        cmp     [CURRENT_TASK], ebx
53
        je      .return
54
        mov     edi, [dma_slot_ptr]
55
        mov     [CURRENT_TASK], ebx
56
        mov     [TASK_BASE], edi
57
        jmp     @f
1159 hidnplayr 58
.find_next_task:
59
; \end{Mario79}
60
end if
1198 clevermous 61
        call    find_next_task
62
        jz      .return  ; the same task -> skip switch
63
  @@:   mov     byte[DONT_SWITCH], 1
64
        call    do_change_task
65
  .return:
66
        popad
67
        popfd
68
        ret
1159 hidnplayr 69
 
70
uglobal
1198 clevermous 71
align 4
72
;  far_jump:
73
;   .offs dd ?
74
;   .sel  dw ?
75
   context_counter     dd 0 ;noname & halyavin
76
   next_usage_update   dd 0
77
   timer_ticks         dd 0
78
;  prev_slot           dd ?
79
;  event_sched         dd ?
1159 hidnplayr 80
endg
81
 
1198 clevermous 82
align 4
1159 hidnplayr 83
update_counters:
1198 clevermous 84
        mov     edi, [TASK_BASE]
85
        rdtsc
86
        sub     eax, [edi+TASKDATA.counter_add] ; time stamp counter add
87
        add     [edi+TASKDATA.counter_sum], eax ; counter sum
88
        ret
89
align 4
90
updatecputimes:
91
        xor     eax,eax
92
        xchg    eax,[idleuse]
93
        mov     [idleusesec],eax
94
        mov     ecx, [TASK_COUNT]
95
        mov     edi, TASK_DATA
96
  .newupdate:
97
        xor     eax,eax
98
        xchg    eax,[edi+TASKDATA.counter_sum]
99
        mov     [edi+TASKDATA.cpu_usage],eax
100
        add     edi,0x20
101
        loop    .newupdate
102
        ret
1159 hidnplayr 103
 
1198 clevermous 104
align 4
1159 hidnplayr 105
find_next_task:
1198 clevermous 106
;info:
107
;   Find next task to execute
108
;retval:
109
;   ebx = address of the APPDATA for the selected task (slot-base)
110
;   esi = previous slot-base ([current_slot] at the begin)
111
;   edi = address of the TASKDATA for the selected task
112
;   ZF  = 1  if the task is the same
113
;warning:
114
;   [CURRENT_TASK] = bh , [TASK_BASE] = edi -- as result
115
;   [current_slot] is not set to new value (ebx)!!!
116
;scratched: eax,ecx
117
        call    update_counters ; edi := [TASK_BASE]
118
        Mov     esi, ebx, [current_slot]
119
  .loop:
120
        cmp     bh,[TASK_COUNT]
121
        jb      @f
122
        xor     bh, bh
123
        mov     edi,CURRENT_TASK
124
  @@:   inc     bh       ; ebx += APPDATA.size
125
        add     edi,0x20 ; edi += TASKDATA.size
126
        mov     al, [edi+TASKDATA.state]
127
        test    al, al
128
        jz      .found   ; state == 0
129
        cmp     al, 5
130
        jne     .loop    ; state == 1,2,3,4,9
131
      ; state == 5
132
        pushad  ; more freedom for [APPDATA.wait_test]
133
        call    [ebx+APPDATA.wait_test]
134
        mov     [esp+28],eax
135
        popad
136
        or      eax,eax
137
        jnz     @f
138
      ; testing for timeout
139
        mov     ecx, [timer_ticks]
140
        sub     ecx, [ebx+APPDATA.wait_begin]
141
        cmp     ecx, [ebx+APPDATA.wait_timeout]
142
        jb      .loop
143
  @@:   mov     [ebx+APPDATA.wait_param], eax  ; retval for wait
144
        mov     [edi+TASKDATA.state], 0
145
  .found:
146
        mov     [CURRENT_TASK],bh
147
        mov     [TASK_BASE],edi
148
        rdtsc   ;call  _rdtsc
149
        mov     [edi+TASKDATA.counter_add],eax ; for next using update_counters
150
        cmp     ebx, esi ;esi - previous slot-base
151
        ret
152
;TODO: Надо бы убрать использование do_change_task из V86...
153
; и после этого перенести обработку TASKDATA.counter_add/sum в do_change_task
1159 hidnplayr 154
 
1198 clevermous 155
align 4
1159 hidnplayr 156
do_change_task:
1198 clevermous 157
;param:
158
;   ebx = address of the APPDATA for incoming task (new)
159
;warning:
160
;   [CURRENT_TASK] and [TASK_BASE] must be changed before (e.g. in find_next_task)
161
;   [current_slot] is the outcoming (old), and set here to a new value (ebx)
162
;scratched: eax,ecx,esi
163
        mov     esi,ebx
164
        xchg    esi,[current_slot]
165
      ; set new stack after saving old
166
        mov     [esi+APPDATA.saved_esp], esp
167
        mov     esp, [ebx+APPDATA.saved_esp]
168
      ; set new thread io-map
169
        Mov     dword [page_tabs+((tss._io_map_0 and -4096) shr 10)],eax,[ebx+APPDATA.io_map]
170
        Mov     dword [page_tabs+((tss._io_map_1 and -4096) shr 10)],eax,[ebx+APPDATA.io_map+4]
171
      ; set new thread memory-map
172
        mov     ecx, APPDATA.dir_table
173
        mov     eax, [ebx+ecx]      ;offset>0x7F
174
        cmp     eax, [esi+ecx]      ;offset>0x7F
175
        je      @f
176
        mov     cr3, eax
177
  @@: ; set tss.esp0
178
        Mov     [tss._esp0],eax,[ebx+APPDATA.saved_esp0]
179
      ; set gs selector unconditionally
180
        Mov     gs,ax,graph_data
181
      ; set CR0.TS
182
        cmp     bh, byte[fpu_owner] ;bh == incoming task (new)
183
        clts                        ;clear a task switch flag
184
        je      @f
185
        mov     eax, cr0            ;and set it again if the owner
186
        or      eax, CR0_TS         ;of a fpu has changed
187
        mov     cr0, eax
188
  @@: ; set context_counter (only for user pleasure ???)
189
        inc     [context_counter]   ;noname & halyavin
190
      ; set debug-registers, if it's necessary
191
        test    byte[ebx+APPDATA.dbg_state], 1
192
        jz      @f
193
        xor     eax, eax
194
        mov     dr6, eax
195
        lea     esi,[ebx+ecx+APPDATA.dbg_regs-APPDATA.dir_table] ;offset>0x7F
196
        cld
197
  macro lodsReg [reg] {
198
        lodsd
199
        mov     reg,eax
200
  }     lodsReg dr0, dr1, dr2, dr3, dr7
201
  purge lodsReg
202
  @@:   ret
203
;end.
1159 hidnplayr 204
 
205
if 0
206
struc TIMER
207
{
208
  .next      dd ?
209
  .exp_time  dd ?
210
  .func      dd ?
1198 clevermous 211
  .arg       dd ?
1159 hidnplayr 212
}
213
 
1198 clevermous 214
MAX_PROIRITY         0   ; highest, used for kernel tasks
215
MAX_USER_PRIORITY    0   ; highest priority for user processes
216
USER_PRIORITY        7   ; default (should correspond to nice 0)
217
MIN_USER_PRIORITY   14   ; minimum priority for user processes
218
IDLE_PRIORITY       15   ; lowest, only IDLE process goes here
219
NR_SCHED_QUEUES     16   ; MUST equal IDLE_PRIORYTY + 1
1159 hidnplayr 220
 
221
rdy_head   rd 16
222
 
223
align 4
224
pick_task:
225
 
1198 clevermous 226
       xor eax, eax
227
  .pick:
228
       mov ebx, [rdy_head+eax*4]
229
       test ebx, ebx
230
       jz .next
1159 hidnplayr 231
 
1198 clevermous 232
       mov [next_task], ebx
233
       test [ebx+flags.billable]
234
       jz @F
235
       mov [bill_task], ebx
236
  @@:
237
       ret
238
  .next:
239
       inc eax
240
       jmp .pick
1159 hidnplayr 241
 
242
; param
243
;  eax= task
244
;
245
; retval
246
;  eax= task
247
;  ebx= queue
248
;  ecx= front if 1 or back if 0
249
align 4
250
shed:
1198 clevermous 251
       cmp [eax+.tics_left], 0 ;signed compare
252
       mov ebx, [eax+.priority]
253
       setg ecx
254
       jg @F
1159 hidnplayr 255
 
1198 clevermous 256
       mov edx, [eax+.tics_quantum]
257
       mov [eax+.ticks_left], edx
258
       cmp ebx, (IDLE_PRIORITY-1)
259
       je @F
260
       inc ebx
261
  @@:
262
       ret
1159 hidnplayr 263
 
264
; param
265
;  eax= task
266
align 4
267
enqueue:
1198 clevermous 268
      call shed  ;eax
269
      cmp [rdy_head+ebx*4],0
270
      jnz @F
1159 hidnplayr 271
 
1198 clevermous 272
      mov [rdy_head+ebx*4], eax
273
      mov [rdy_tail+ebx*4], eax
274
      mov [eax+.next_ready], 0
275
      jmp .pick
276
  @@:
277
      test ecx, ecx
278
      jz .back
1159 hidnplayr 279
 
1198 clevermous 280
      mov ecx, [rdy_head+ebx*4]
281
      mov [eax+.next_ready], ecx
282
      mov [rdy_head+ebx*4], eax
283
      jmp .pick
284
  .back:
285
      mov ecx, [rdy_tail+ebx*4]
286
      mov [ecx+.next_ready], eax
287
      mov [rdy_tail+ebx*4], eax
288
      mov [eax+.next_ready], 0
289
  .pick:
290
      call pick_proc     ;select next task
291
      ret
1159 hidnplayr 292
 
293
end if