Subversion Repositories Kolibri OS

Rev

Rev 1161 | 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: 907 $
  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.   @@: ; 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.
  204.  
  205. if 0
  206. struc TIMER
  207. {
  208.   .next      dd ?
  209.   .exp_time  dd ?
  210.   .func      dd ?
  211.   .arg       dd ?
  212. }
  213.  
  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
  220.  
  221. rdy_head   rd 16
  222.  
  223. align 4
  224. pick_task:
  225.  
  226.        xor eax, eax
  227.   .pick:
  228.        mov ebx, [rdy_head+eax*4]
  229.        test ebx, ebx
  230.        jz .next
  231.  
  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
  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:
  251.        cmp [eax+.tics_left], 0 ;signed compare
  252.        mov ebx, [eax+.priority]
  253.        setg ecx
  254.        jg @F
  255.  
  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
  263.  
  264. ; param
  265. ;  eax= task
  266. align 4
  267. enqueue:
  268.       call shed  ;eax
  269.       cmp [rdy_head+ebx*4],0
  270.       jnz @F
  271.  
  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
  279.  
  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
  292.  
  293. end if
  294.