Subversion Repositories Kolibri OS

Rev

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