Subversion Repositories Kolibri OS

Rev

Rev 837 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

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