Subversion Repositories Kolibri OS

Rev

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