Subversion Repositories Kolibri OS

Rev

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