Subversion Repositories Kolibri OS

Rev

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