Subversion Repositories Kolibri OS

Rev

Rev 1298 | Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  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: 1376 $
  9.  
  10.  
  11. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  12. ;; IRQ0 HANDLER (TIMER INTERRUPT) ;;
  13. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  14.  
  15.  
  16. align 32
  17. irq0:
  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
  40.  
  41. align 4
  42. change_task:
  43.         pushfd
  44.         cli
  45.         pushad
  46. if 0
  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
  58. .find_next_task:
  59. ; \end{Mario79}
  60. end if
  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
  69.  
  70. uglobal
  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 ?
  80. endg
  81.  
  82. align 4
  83. update_counters:
  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
  103.  
  104. align 4
  105. find_next_task:
  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
  154.  
  155. align 4
  156. do_change_task:
  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. @@:
  178. ; set tss.esp0
  179.  
  180.         Mov     [tss._esp0],eax,[ebx+APPDATA.saved_esp0]
  181.  
  182.         mov edx, [ebx+APPDATA.tls_base]
  183.         cmp edx, [esi+APPDATA.tls_base]
  184.         je @f
  185.  
  186.         mov     [tls_data_l+2],dx
  187.         shr     edx,16
  188.         mov     [tls_data_l+4],dl
  189.         mov     [tls_data_l+7],dh
  190.  
  191.         mov dx, app_tls
  192.         mov fs, dx
  193. @@:
  194. ; set gs selector unconditionally
  195.         Mov     gs,ax,graph_data
  196.       ; set CR0.TS
  197.         cmp     bh, byte[fpu_owner] ;bh == incoming task (new)
  198.         clts                        ;clear a task switch flag
  199.         je      @f
  200.         mov     eax, cr0            ;and set it again if the owner
  201.         or      eax, CR0_TS         ;of a fpu has changed
  202.         mov     cr0, eax
  203.   @@: ; set context_counter (only for user pleasure ???)
  204.         inc     [context_counter]   ;noname & halyavin
  205.       ; set debug-registers, if it's necessary
  206.         test    byte[ebx+APPDATA.dbg_state], 1
  207.         jz      @f
  208.         xor     eax, eax
  209.         mov     dr6, eax
  210.         lea     esi,[ebx+ecx+APPDATA.dbg_regs-APPDATA.dir_table] ;offset>0x7F
  211.         cld
  212.   macro lodsReg [reg] {
  213.         lodsd
  214.         mov     reg,eax
  215.   }     lodsReg dr0, dr1, dr2, dr3, dr7
  216.   purge lodsReg
  217.   @@:   ret
  218. ;end.
  219.  
  220. if 0
  221. struc TIMER
  222. {
  223.   .next      dd ?
  224.   .exp_time  dd ?
  225.   .func      dd ?
  226.   .arg       dd ?
  227. }
  228.  
  229.  
  230. MAX_PROIRITY         0   ; highest, used for kernel tasks
  231. MAX_USER_PRIORITY    0   ; highest priority for user processes
  232. USER_PRIORITY        7   ; default (should correspond to nice 0)
  233. MIN_USER_PRIORITY   14   ; minimum priority for user processes
  234. IDLE_PRIORITY       15   ; lowest, only IDLE process goes here
  235. NR_SCHED_QUEUES     16   ; MUST equal IDLE_PRIORYTY + 1
  236.  
  237. uglobal
  238. rdy_head   rd 16
  239. endg
  240.  
  241. align 4
  242. pick_task:
  243.  
  244.        xor eax, eax
  245.   .pick:
  246.        mov ebx, [rdy_head+eax*4]
  247.        test ebx, ebx
  248.        jz .next
  249.  
  250.        mov [next_task], ebx
  251.        test [ebx+flags.billable]
  252.        jz @F
  253.        mov [bill_task], ebx
  254.   @@:
  255.        ret
  256.   .next:
  257.        inc eax
  258.        jmp .pick
  259.  
  260. ; param
  261. ;  eax= task
  262. ;
  263. ; retval
  264. ;  eax= task
  265. ;  ebx= queue
  266. ;  ecx= front if 1 or back if 0
  267. align 4
  268. shed:
  269.        cmp [eax+.tics_left], 0 ;signed compare
  270.        mov ebx, [eax+.priority]
  271.        setg ecx
  272.        jg @F
  273.  
  274.        mov edx, [eax+.tics_quantum]
  275.        mov [eax+.ticks_left], edx
  276.        cmp ebx, (IDLE_PRIORITY-1)
  277.        je @F
  278.        inc ebx
  279.   @@:
  280.        ret
  281.  
  282. ; param
  283. ;  eax= task
  284. align 4
  285. enqueue:
  286.       call shed  ;eax
  287.       cmp [rdy_head+ebx*4],0
  288.       jnz @F
  289.  
  290.       mov [rdy_head+ebx*4], eax
  291.       mov [rdy_tail+ebx*4], eax
  292.       mov [eax+.next_ready], 0
  293.       jmp .pick
  294.   @@:
  295.       test ecx, ecx
  296.       jz .back
  297.  
  298.       mov ecx, [rdy_head+ebx*4]
  299.       mov [eax+.next_ready], ecx
  300.       mov [rdy_head+ebx*4], eax
  301.       jmp .pick
  302.   .back:
  303.       mov ecx, [rdy_tail+ebx*4]
  304.       mov [ecx+.next_ready], eax
  305.       mov [rdy_tail+ebx*4], eax
  306.       mov [eax+.next_ready], 0
  307.   .pick:
  308.       call pick_proc     ;select next task
  309.       ret
  310.  
  311. end if
  312.