Subversion Repositories Kolibri OS

Rev

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

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