Subversion Repositories Kolibri OS

Rev

Rev 1298 | Rev 2137 | Go to most recent revision | Blame | Compare with Previous | 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: 1434 $
  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.  
  221.  
  222. struc MUTEX_WAITER
  223. {
  224.     .next   rd 1
  225.     .prev   rd 1
  226.     .task   rd 1
  227.     .sizeof:
  228. };
  229.  
  230. virtual at 0
  231.  MUTEX_WAITER MUTEX_WAITER
  232. end virtual
  233.  
  234. ;void  __fastcall mutex_init(struct mutex *lock)
  235.  
  236. align 4
  237. mutex_init:
  238.         lea eax, [ecx+MUTEX.next]
  239.         mov [ecx+MUTEX.count],1
  240.         mov [ecx+MUTEX.next], eax
  241.         mov [ecx+MUTEX.prev], eax
  242.         ret
  243.  
  244.  
  245. ;void  __fastcall mutex_lock(struct mutex *lock)
  246.  
  247. align 4
  248. mutex_lock:
  249.  
  250.         dec [ecx+MUTEX.count]
  251.         jns .done
  252.  
  253.         pushfd
  254.         cli
  255.  
  256.         push esi
  257.         sub esp, MUTEX_WAITER.sizeof
  258.  
  259.         mov eax, [ecx+MUTEX.prev]
  260.         lea esi, [ecx+MUTEX.next]
  261.  
  262.         mov [ecx+MUTEX.prev], esp
  263.         mov [esp+MUTEX_WAITER.next],  esi
  264.         mov [esp+MUTEX_WAITER.prev],  eax
  265.         mov [eax], esp
  266.  
  267.         mov edx, [TASK_BASE]
  268.         mov [esp+MUTEX_WAITER.task], edx
  269.  
  270. .forever:
  271.  
  272.         mov eax, -1
  273.         xchg eax, [ecx+MUTEX.count]
  274.         dec eax
  275.         jz @F
  276.  
  277.         mov [edx+TASKDATA.state], 1
  278.         call change_task
  279.         jmp .forever
  280. @@:
  281.         mov edx, [esp+MUTEX_WAITER.next]
  282.         mov eax, [esp+MUTEX_WAITER.prev]
  283.  
  284.         mov [eax+MUTEX_WAITER.next], edx
  285.         cmp [ecx+MUTEX.next], esi
  286.         mov [edx+MUTEX_WAITER.prev], eax
  287.         jne @F
  288.  
  289.         mov [ecx+MUTEX.count], 0
  290. @@:
  291.         add  esp, MUTEX_WAITER.sizeof
  292.  
  293.         pop esi
  294.         popfd
  295. .done:
  296.         ret
  297.  
  298. ;void  __fastcall mutex_unlock(struct mutex *lock)
  299.  
  300. align 4
  301. mutex_unlock:
  302.  
  303.         pushfd
  304.         cli
  305.  
  306.         lea eax, [ecx+MUTEX.next]
  307.         cmp eax, [ecx+MUTEX.next]
  308.         mov [ecx+MUTEX.count], 1
  309.         je @F
  310.  
  311.         mov eax, [eax+MUTEX_WAITER.task]
  312.         mov [eax+TASKDATA.state], 0
  313. @@:
  314.         popfd
  315.         ret
  316.  
  317.  
  318. purge MUTEX_WAITER
  319.  
  320. if 0
  321.  
  322. struc TIMER
  323. {
  324.   .next      dd ?
  325.   .exp_time  dd ?
  326.   .func      dd ?
  327.   .arg       dd ?
  328. }
  329.  
  330.  
  331. MAX_PROIRITY         0   ; highest, used for kernel tasks
  332. MAX_USER_PRIORITY    0   ; highest priority for user processes
  333. USER_PRIORITY        7   ; default (should correspond to nice 0)
  334. MIN_USER_PRIORITY   14   ; minimum priority for user processes
  335. IDLE_PRIORITY       15   ; lowest, only IDLE process goes here
  336. NR_SCHED_QUEUES     16   ; MUST equal IDLE_PRIORYTY + 1
  337.  
  338. uglobal
  339. rdy_head   rd 16
  340. endg
  341.  
  342. align 4
  343. pick_task:
  344.  
  345.        xor eax, eax
  346.   .pick:
  347.        mov ebx, [rdy_head+eax*4]
  348.        test ebx, ebx
  349.        jz .next
  350.  
  351.        mov [next_task], ebx
  352.        test [ebx+flags.billable]
  353.        jz @F
  354.        mov [bill_task], ebx
  355.   @@:
  356.        ret
  357.   .next:
  358.        inc eax
  359.        jmp .pick
  360.  
  361. ; param
  362. ;  eax= task
  363. ;
  364. ; retval
  365. ;  eax= task
  366. ;  ebx= queue
  367. ;  ecx= front if 1 or back if 0
  368. align 4
  369. shed:
  370.        cmp [eax+.tics_left], 0 ;signed compare
  371.        mov ebx, [eax+.priority]
  372.        setg ecx
  373.        jg @F
  374.  
  375.        mov edx, [eax+.tics_quantum]
  376.        mov [eax+.ticks_left], edx
  377.        cmp ebx, (IDLE_PRIORITY-1)
  378.        je @F
  379.        inc ebx
  380.   @@:
  381.        ret
  382.  
  383. ; param
  384. ;  eax= task
  385. align 4
  386. enqueue:
  387.       call shed  ;eax
  388.       cmp [rdy_head+ebx*4],0
  389.       jnz @F
  390.  
  391.       mov [rdy_head+ebx*4], eax
  392.       mov [rdy_tail+ebx*4], eax
  393.       mov [eax+.next_ready], 0
  394.       jmp .pick
  395.   @@:
  396.       test ecx, ecx
  397.       jz .back
  398.  
  399.       mov ecx, [rdy_head+ebx*4]
  400.       mov [eax+.next_ready], ecx
  401.       mov [rdy_head+ebx*4], eax
  402.       jmp .pick
  403.   .back:
  404.       mov ecx, [rdy_tail+ebx*4]
  405.       mov [ecx+.next_ready], eax
  406.       mov [rdy_tail+ebx*4], eax
  407.       mov [eax+.next_ready], 0
  408.   .pick:
  409.       call pick_proc     ;select next task
  410.       ret
  411.  
  412. end if
  413.