Subversion Repositories Kolibri OS

Rev

Rev 417 | Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1.  
  2. align 4
  3. proc alloc_page
  4.  
  5.            pushfd
  6.            cli
  7.            mov ebx, [page_start]
  8.            mov ecx, [page_end]
  9. .l1:
  10.            bsf eax,[ebx];
  11.            jnz .found
  12.            add ebx,4
  13.            cmp ebx, ecx
  14.            jb .l1
  15.            popfd
  16.            xor eax,eax
  17.            ret
  18. .found:
  19.            btr [ebx], eax
  20.            mov [page_start],ebx
  21.            sub ebx, sys_pgmap
  22.            lea eax, [eax+ebx*8]
  23.            shl eax, 12
  24.            dec [pg_data.pages_free]
  25.            popfd
  26.            ret
  27. endp
  28.  
  29. align 4
  30. proc alloc_pages stdcall, count:dword
  31.            pushfd
  32.            cli
  33.            mov eax, [count]
  34.            add eax, 7
  35.            shr eax, 3
  36.            mov [count], eax
  37.            cmp eax, [pg_data.pages_free]
  38.            ja .fail
  39.  
  40.            mov ecx, [page_start]
  41.            mov ebx, [page_end]
  42. .find:
  43.            mov edx, [count]
  44.            mov edi, ecx
  45. .match:
  46.            cmp byte [ecx], 0xFF
  47.            jne .next
  48.            dec edx
  49.            jz .ok
  50.            inc ecx
  51.            cmp ecx,ebx
  52.            jb .match
  53. .fail:     xor eax, eax
  54.            popfd
  55.            ret
  56. .next:
  57.            inc ecx
  58.            cmp ecx, ebx
  59.            jb .find
  60.            popfd
  61.            xor eax, eax
  62.            ret
  63. .ok:
  64.            sub ecx, edi
  65.            inc ecx
  66.            mov esi, edi
  67.            xor eax, eax
  68.            rep stosb
  69.            sub esi, sys_pgmap
  70.            shl esi, 3+12
  71.            mov eax, esi
  72.            mov ebx, [count]
  73.            shl ebx, 3
  74.            sub [pg_data.pages_free], ebx
  75.            popfd
  76.            ret
  77. endp
  78.  
  79. align 4
  80. proc map_page stdcall,lin_addr:dword,phis_addr:dword,flags:dword
  81.            push ebx
  82.            mov eax, [phis_addr]
  83.            and eax, not 0xFFF
  84.            or eax, [flags]
  85.            mov ebx, [lin_addr]
  86.            shr ebx, 12
  87.            mov [page_tabs+ebx*4], eax
  88.            mov eax, [lin_addr]
  89.            invlpg [eax]
  90.            pop ebx
  91.            ret
  92. endp
  93.  
  94. align 4
  95. map_space:    ;not implemented
  96.  
  97.  
  98.            ret
  99.  
  100.  
  101. align 4
  102. proc free_page
  103. ;arg:  eax  page address
  104.            pushfd
  105.            cli
  106.            shr eax, 12              ;page index
  107.            mov ebx, sys_pgmap
  108.            bts [ebx], eax           ;that's all!
  109.            cmc
  110.            adc [pg_data.pages_free], 0
  111.            shr eax, 3
  112.            and eax, not 3           ;dword offset from page_map
  113.            add eax, ebx
  114.            cmp [page_start], eax
  115.            ja @f
  116.            popfd
  117.            ret
  118. @@:
  119.            mov [page_start], eax
  120.            popfd
  121.            ret
  122. endp
  123.  
  124. ; param
  125. ;  eax= page base + page flags
  126. ;  ebx= liear address
  127. ;  ecx= count
  128.  
  129. align 4
  130. commit_pages:
  131.  
  132.            test ecx, ecx
  133.            jz .fail
  134.  
  135.            mov edi, ebx
  136.            mov ebx, pg_data.pg_mutex
  137.            call wait_mutex      ;ebx
  138.  
  139.            mov edx, 0x1000
  140.            mov ebx, edi
  141.            shr ebx, 12
  142. @@:
  143.            mov [page_tabs+ebx*4], eax
  144.            invlpg [edi]
  145.            add edi, edx
  146.            add eax, edx
  147.            inc ebx
  148.            dec ecx
  149.            jnz @B
  150.            mov [pg_data.pg_mutex],ecx
  151. .fail:
  152.            ret
  153.  
  154.  
  155. ; param
  156. ;  eax= base
  157. ;  ecx= count
  158.  
  159. align 4
  160. release_pages:
  161.  
  162.            pushad
  163.            mov ebx, pg_data.pg_mutex
  164.            call wait_mutex      ;ebx
  165.  
  166.            mov esi, eax
  167.            mov edi, eax
  168.  
  169.            shr esi, 10
  170.            add esi, page_tabs
  171.  
  172.            mov ebp, [pg_data.pages_free]
  173.            mov ebx, [page_start]
  174.            mov edx, sys_pgmap
  175. @@:
  176.            xor eax, eax
  177.            xchg eax, [esi]
  178.            invlpg [edi]
  179.  
  180.            test eax, 1
  181.            jz .next
  182.  
  183.            shr eax, 12
  184.            bts [edx], eax
  185.            cmc
  186.            adc ebp, 0
  187.            shr eax, 3
  188.            and eax, -4
  189.            add eax, edx
  190.            cmp eax, ebx
  191.            jae .next
  192.  
  193.            mov ebx, eax
  194. .next:
  195.            add edi, 0x1000
  196.            add esi, 4
  197.            dec ecx
  198.            jnz @B
  199.            mov [pg_data.pages_free], ebp
  200.            and [pg_data.pg_mutex],0
  201.            popad
  202.            ret
  203.  
  204. align 4
  205. proc map_page_table stdcall, lin_addr:dword, phis_addr:dword
  206.            push ebx
  207.            mov ebx, [lin_addr]
  208.            shr ebx, 22
  209.            mov eax, [phis_addr]
  210.            and eax, not 0xFFF
  211.            or eax, PG_UW          ;+PG_NOCACHE
  212.            mov dword [master_tab+ebx*4], eax
  213.            mov eax, [lin_addr]
  214.            shr eax, 10
  215.            add eax, page_tabs
  216.            invlpg [eax]
  217.            pop ebx
  218.            ret
  219. endp
  220.  
  221. align 4
  222. proc init_LFB
  223.            locals
  224.              pg_count dd ?
  225.            endl
  226.  
  227.            cmp dword [LFBAddress], -1
  228.            jne @f
  229.            mov [BOOT_VAR+0x901c],byte 2
  230.            stdcall kernel_alloc, 0x280000
  231.            mov [LFBAddress], eax
  232.            ret
  233. @@:
  234.            test [SCR_MODE],word 0100000000000000b
  235.            jnz @f
  236.            mov [BOOT_VAR+0x901c],byte 2
  237.            ret
  238. @@:
  239.            mov edx, LFB_BASE
  240.            mov esi, [LFBAddress]
  241.            mov edi, 0x00800000
  242.            mov dword [exp_lfb+4], edx
  243.  
  244.            shr edi, 12
  245.            mov [pg_count], edi
  246.            shr edi, 10
  247.  
  248.            bt [cpu_caps], CAPS_PSE
  249.            jnc .map_page_tables
  250.            or esi, PG_LARGE+PG_UW
  251.            mov edx, sys_pgdir+(LFB_BASE shr 20)
  252. @@:
  253.            mov [edx], esi
  254.            add edx, 4
  255.            add esi, 0x00400000
  256.            dec edi
  257.            jnz @B
  258.  
  259.            bt [cpu_caps], CAPS_PGE
  260.            jnc @F
  261.            or dword [sys_pgdir+(LFB_BASE shr 20)], PG_GLOBAL
  262. @@:
  263.            mov dword [LFBAddress], LFB_BASE
  264.            mov eax, cr3       ;flush TLB
  265.            mov cr3, eax
  266.            ret
  267.  
  268. .map_page_tables:
  269.  
  270. @@:
  271.            call alloc_page
  272.            stdcall map_page_table, edx, eax
  273.            add edx, 0x00400000
  274.            dec edi
  275.            jnz @B
  276.  
  277.            mov eax, [LFBAddress]
  278.            mov edi, page_tabs + (LFB_BASE shr 10)
  279.            or eax, PG_UW
  280.            mov ecx, [pg_count]
  281.            cld
  282. @@:
  283.            stosd
  284.            add eax, 0x1000
  285.            dec ecx
  286.            jnz @B
  287.  
  288.            mov dword [LFBAddress], LFB_BASE
  289.            mov eax, cr3       ;flush TLB
  290.            mov cr3, eax
  291.  
  292.            ret
  293. endp
  294.  
  295. align 4
  296. proc new_mem_resize stdcall, new_size:dword
  297.  
  298.            mov ebx, pg_data.pg_mutex
  299.            call wait_mutex    ;ebx
  300.  
  301.            mov edi, [new_size]
  302.            add edi,4095
  303.            and edi,not 4095
  304.            mov [new_size], edi
  305.  
  306.            mov edx,[CURRENT_TASK]
  307.            shl edx,8
  308.            cmp [SLOT_BASE+APPDATA.heap_base+edx],0
  309.            jne .exit
  310.  
  311.            mov esi, [SLOT_BASE+APPDATA.mem_size+edx]
  312.            add esi, 4095
  313.            and esi, not 4095
  314.  
  315.            cmp edi, esi
  316.            jae .expand
  317.  
  318.            shr edi, 12
  319.            shr esi, 12
  320. @@:
  321.            mov eax, [app_page_tabs+edi*4]
  322.            test eax, 1
  323.            jz .next
  324.            mov dword [app_page_tabs+edi*4], 2
  325.            mov ebx, edi
  326.            shl ebx, 12
  327.            invlpg [ebx+std_application_base_address]
  328.            call free_page
  329.  
  330. .next:     add edi, 1
  331.            cmp edi, esi
  332.            jb @B
  333.  
  334. .update_size:
  335.         mov     ebx, [new_size]
  336.         call    update_mem_size
  337.  
  338.            xor eax, eax
  339.            dec [pg_data.pg_mutex]
  340.            ret
  341.  
  342. .expand:
  343.            add edi, new_app_base
  344.            add esi, new_app_base
  345.  
  346.            push esi
  347.            push edi
  348.  
  349.            add edi, 0x3FFFFF
  350.            and edi, not(0x3FFFFF)
  351.            add esi, 0x3FFFFF
  352.            and esi, not(0x3FFFFF)
  353.  
  354.            cmp esi, edi
  355.            jae .grow
  356.  
  357.            xchg esi, edi
  358.  
  359. @@:
  360.            call alloc_page
  361.            test eax, eax
  362.            jz .exit
  363.  
  364.            stdcall map_page_table, edi, eax
  365.  
  366.            push edi
  367.            shr edi, 10
  368.            add edi, page_tabs
  369.            mov ecx, 1024
  370.            xor eax, eax
  371.            cld
  372.            rep stosd
  373.            pop edi
  374.  
  375.            add edi, 0x00400000
  376.            cmp edi, esi
  377.            jb @B
  378. .grow:
  379.            pop edi
  380.            pop esi
  381. @@:
  382.            call alloc_page
  383.            test eax, eax
  384.            jz .exit
  385.            stdcall map_page,esi,eax,dword PG_UW
  386.  
  387.            push edi
  388.            mov edi, esi
  389.            xor eax, eax
  390.            mov ecx, 1024
  391.            cld
  392.            rep stosd
  393.            pop edi
  394.  
  395.            add esi, 0x1000
  396.            cmp esi, edi
  397.            jb  @B
  398.  
  399.            jmp .update_size
  400. .exit:
  401.            xor eax, eax
  402.            inc eax
  403.            dec [pg_data.pg_mutex]
  404.            ret
  405. endp
  406.  
  407. update_mem_size:
  408. ; in: edx = slot shl 8
  409. ;     ebx = new memory size
  410. ; destroys eax,ecx,edx
  411.  
  412.            mov    [SLOT_BASE+APPDATA.mem_size+edx],ebx
  413. ;search threads and update
  414. ;application memory size infomation
  415.            mov    ecx,[SLOT_BASE+APPDATA.dir_table+edx]
  416.            mov    eax,2
  417.  
  418. .search_threads:
  419. ;eax = current slot
  420. ;ebx = new memory size
  421. ;ecx = page directory
  422.            cmp    eax,[TASK_COUNT]
  423.            jg     .search_threads_end
  424.            mov    edx,eax
  425.            shl    edx,5
  426.            cmp    word [CURRENT_TASK+edx+TASKDATA.state],9 ;if slot empty?
  427.            jz     .search_threads_next
  428.            shl    edx,3
  429.            cmp    [SLOT_BASE+edx+APPDATA.dir_table],ecx     ;if it is our thread?
  430.            jnz    .search_threads_next
  431.            mov    [SLOT_BASE+edx+APPDATA.mem_size],ebx     ;update memory size
  432. .search_threads_next:
  433.            inc    eax
  434.            jmp    .search_threads
  435. .search_threads_end:
  436.            ret
  437.  
  438. ; param
  439. ;  eax= linear address
  440. ;
  441. ; retval
  442. ;  eax= phisical page address
  443.  
  444. align 4
  445. get_pg_addr:
  446.            shr eax, 12
  447.            mov eax, [page_tabs+eax*4]
  448.            and eax, 0xFFFFF000
  449.            ret
  450.  
  451.  
  452. align 4
  453. proc page_fault_handler
  454.  
  455.         .err_code equ ebp+32
  456.         .err_addr equ ebp-4
  457.  
  458.            pushad
  459.  
  460.      push eax
  461.      push edx
  462.      mov edx, 0x400   ;bocsh
  463.      mov al,0xff      ;bocsh
  464.      out dx, al       ;bocsh
  465.      pop edx
  466.      pop eax
  467.  
  468.            mov ebp, esp
  469.            mov eax, cr2
  470.            push eax
  471.            push ds
  472.            push es
  473.  
  474.            mov ax, 0x10
  475.            mov ds, ax
  476.            mov es, ax
  477.  
  478.            inc [pg_data.pages_faults]
  479.  
  480.            mov ebx, [.err_addr]
  481.  
  482.            cmp ebx, 0x80000000
  483.            jae .kernel_space
  484.  
  485.            cmp ebx, page_tabs+0x200000
  486.            jae .tab_space
  487.  
  488.            cmp ebx, app_page_tabs
  489.            jae .alloc
  490.  
  491.            cmp ebx, 0x7DC00000
  492.            jae .lfb_addr
  493.  
  494. ;           cmp ebx, 0x1000000
  495. ;           jb .exit
  496.  
  497. .user_space:
  498.            shr ebx, 12
  499.            mov ecx, ebx
  500.            shr ecx, 10
  501.            mov edx, [master_tab+ecx*4]
  502.            test edx, 1
  503.            jz .fail
  504.  
  505.            mov eax, [page_tabs+ebx*4]
  506.            test eax, 2
  507.            jz .fail
  508. .alloc:
  509.            call alloc_page
  510.            and eax, eax
  511.            jz .exit
  512.  
  513.            stdcall map_page,[ebp-4],eax,dword PG_UW
  514.  
  515.            mov edi, [ebp-4]
  516.            and edi, 0xFFFFF000
  517.            mov ecx, 1024
  518.            xor eax, eax
  519.            cld
  520.            rep stosd
  521. .exit:
  522.            pop es
  523.            pop ds
  524.            mov esp, ebp
  525.            popad
  526.            add esp, 4
  527.            iretd
  528. .fail:
  529.            pop es
  530.            pop ds
  531.            mov esp, ebp
  532.            popad
  533.            add esp, 4
  534.            iretd
  535.  
  536.            save_ring3_context     ;debugger support
  537.  
  538.            mov bl, 14
  539.            jmp exc_c
  540.            iretd
  541.  
  542. .kernel_space:
  543. ;           shr ebx, 12
  544. ;           mov eax, [page_tabs+ebx*4]
  545. ;           shr ebx, 10
  546. ;           mov eax, [master_tab+ebx*4]
  547.            jmp .exit
  548. .old_addr:
  549. ;           shr ebx, 12
  550. ;           mov eax, [page_tabs+ebx*4]
  551. ;           shr ebx, 10
  552. ;           mov eax, [master_tab+ebx*4]
  553.            jmp .exit
  554. .lfb_addr:
  555. ;           shr ebx, 22
  556. ;           ;mov ecx, [sys_page_dir]
  557. ;           mov eax, [master_tab+ebx*4]
  558.            jmp .exit
  559. .tab_space:
  560. ;           shr ebx, 12
  561. ;           mov eax, [page_tabs+ebx*4]
  562. ;           shr ebx, 10
  563. ;           ;mov ecx, [sys_page_dir]
  564. ;           mov eax, [master_tab+ebx*4]
  565.            jmp .exit
  566. endp
  567.  
  568. align 4
  569. proc map_mem stdcall, lin_addr:dword,pdir:dword,\
  570.                       ofs:dword,buf_size:dword
  571.            mov eax, [buf_size]
  572.            test eax, eax
  573.            jz .exit
  574.  
  575.            mov eax, [pdir]
  576.            and eax, 0xFFFFF000
  577.  
  578.            stdcall map_page,[ipc_pdir],eax,dword PG_UW
  579.            mov ebx, [ofs]
  580.            shr ebx, 22
  581.            mov esi, [ipc_pdir]
  582.            mov edi, [ipc_ptab]
  583.            mov eax, [esi+ebx*4]
  584.            and eax, 0xFFFFF000
  585.            test eax, eax
  586.            jz .exit
  587.            stdcall map_page,edi,eax,dword PG_UW
  588. ;           inc ebx
  589. ;           add edi, 0x1000
  590. ;           mov eax, [esi+ebx*4]
  591. ;           test eax, eax
  592. ;           jz @f
  593. ;          and eax, 0xFFFFF000
  594. ;           stdcall map_page, edi, eax
  595.  
  596. @@:        mov edi, [lin_addr]
  597.            and edi, 0xFFFFF000
  598.            mov ecx, [buf_size]
  599.            add ecx, 4095
  600.            shr ecx, 12
  601.            inc ecx
  602.  
  603.            mov edx, [ofs]
  604.            shr edx, 12
  605.            and edx, 0x3FF
  606.            mov esi, [ipc_ptab]
  607.  
  608. .map:      mov eax, [esi+edx*4]
  609.            and eax, 0xFFFFF000
  610.            test eax, eax
  611.            jz .exit
  612.            stdcall map_page,edi,eax,dword PG_UW
  613.            add edi, 0x1000
  614.            inc edx
  615.            dec ecx
  616.            jnz .map
  617.  
  618. .exit:
  619.            ret
  620. endp
  621.  
  622. align 4
  623. proc map_memEx stdcall, lin_addr:dword,pdir:dword,\
  624.                         ofs:dword,buf_size:dword
  625.            mov eax, [buf_size]
  626.            test eax, eax
  627.            jz .exit
  628.  
  629.            mov eax, [pdir]
  630.            and eax, 0xFFFFF000
  631.  
  632.            stdcall map_page,[proc_mem_pdir],eax,dword PG_UW
  633.            mov ebx, [ofs]
  634.            shr ebx, 22
  635.            mov esi, [proc_mem_pdir]
  636.            mov edi, [proc_mem_tab]
  637.            mov eax, [esi+ebx*4]
  638.            and eax, 0xFFFFF000
  639.            test eax, eax
  640.            jz .exit
  641.            stdcall map_page,edi,eax,dword PG_UW
  642.  
  643. @@:        mov edi, [lin_addr]
  644.            and edi, 0xFFFFF000
  645.            mov ecx, [buf_size]
  646.            add ecx, 4095
  647.            shr ecx, 12
  648.            inc ecx
  649.  
  650.            mov edx, [ofs]
  651.            shr edx, 12
  652.            and edx, 0x3FF
  653.            mov esi, [proc_mem_tab]
  654.  
  655. .map:      mov eax, [esi+edx*4]
  656. ;           and eax, 0xFFFFF000
  657. ;           test eax, eax
  658. ;           jz .exit
  659.            stdcall map_page,edi,eax,dword PG_UW
  660.            add edi, 0x1000
  661.            inc edx
  662.            dec ecx
  663.            jnz .map
  664. .exit:
  665.            ret
  666. endp
  667.  
  668.  
  669.  
  670.  
  671. sys_IPC:
  672. ;input:
  673. ;  eax=1 - set ipc buffer area
  674. ;    ebx=address of buffer
  675. ;    ecx=size of buffer
  676. ;  eax=2 - send message
  677. ;    ebx=PID
  678. ;    ecx=address of message
  679. ;    edx=size of message
  680.  
  681.            cmp  eax,1
  682.            jne @f
  683.            call set_ipc_buff
  684.            mov [esp+36], eax
  685.            ret
  686. @@:
  687.            cmp eax, 2
  688.            jne @f
  689.            stdcall sys_ipc_send, ebx, ecx, edx
  690.            mov [esp+36], eax
  691.            ret
  692. @@:
  693.            xor eax, eax
  694.            not eax
  695.            mov [esp+36], eax
  696.            ret
  697.  
  698. align 4
  699. proc set_ipc_buff
  700.  
  701.            mov  eax,[CURRENT_TASK]
  702.            shl  eax,8
  703.            add  eax, SLOT_BASE
  704.            pushf
  705.            cli
  706.            mov  [eax+0xA0],ebx     ;set fields in extended information area
  707.            mov  [eax+0xA4],ecx
  708.  
  709.            add ebx,  new_app_base
  710.            add ecx, ebx
  711.            add ecx, 4095
  712.            and ecx, not 4095
  713.  
  714. .touch:    mov eax, [ebx]
  715.            add ebx, 0x1000
  716.            cmp ebx, ecx
  717.            jna .touch
  718.  
  719.            popf
  720.            xor eax, eax
  721.            ret
  722. endp
  723.  
  724. proc sys_ipc_send stdcall, PID:dword, msg_addr:dword, msg_size:dword
  725.            locals
  726.              dst_slot   dd ?
  727.              dst_offset dd ?
  728.              buf_size   dd ?
  729.            endl
  730.  
  731.            pushf
  732.            cli
  733.  
  734.            mov  eax, [PID]
  735.            call pid_to_slot
  736.            test eax,eax
  737.            jz   .no_pid
  738.  
  739.            mov [dst_slot], eax
  740.            shl  eax,8
  741.            mov  edi,[eax+SLOT_BASE+0xa0]  ;is ipc area defined?
  742.            test edi,edi
  743.            jz   .no_ipc_area
  744.  
  745.            mov ebx, edi
  746.            add edi, new_app_base
  747.            and ebx, 0xFFF
  748.            mov [dst_offset], ebx
  749.  
  750.            mov esi, [eax+SLOT_BASE+0xa4]
  751.            mov [buf_size], esi
  752.  
  753.            stdcall map_mem, [ipc_tmp], [SLOT_BASE+eax+0xB8],\
  754.                              edi, esi
  755.  
  756.            mov edi, [dst_offset]
  757.            add edi, [ipc_tmp]
  758.            cmp dword [edi], 0
  759.            jnz  .ipc_blocked          ;if dword [buffer]<>0 - ipc blocked now
  760.  
  761.            mov ebx, dword [edi+4]
  762.            mov edx, ebx
  763.            add ebx, 8
  764.            add ebx, [msg_size]
  765.            cmp ebx, [buf_size]
  766.            ja .buffer_overflow         ;esi<0 - not enough memory in buffer
  767.  
  768.            mov dword [edi+4], ebx
  769.            mov eax,[TASK_BASE]
  770.            mov eax, [eax+0x04]         ;eax - our PID
  771.            mov edi, [dst_offset]
  772.            add edi, [ipc_tmp]
  773.            add edi, edx
  774.            mov [edi], eax
  775.            mov ecx, [msg_size]
  776.  
  777.            mov [edi+4], ecx
  778.            add edi, 8
  779.            mov esi, [msg_addr]
  780.            add esi, new_app_base
  781.            cld
  782.            rep movsb
  783.  
  784.            mov ebx, [ipc_tmp]
  785.            mov edx, ebx
  786.            shr ebx, 12
  787.            xor eax, eax
  788.            mov [page_tabs+ebx*4], eax
  789.            invlpg [edx]
  790.  
  791.            mov ebx, [ipc_pdir]
  792.            mov edx, ebx
  793.            shr ebx, 12
  794.            xor eax, eax
  795.            mov [page_tabs+ebx*4], eax
  796.            invlpg [edx]
  797.  
  798.            mov ebx, [ipc_ptab]
  799.            mov edx, ebx
  800.            shr ebx, 12
  801.            xor eax, eax
  802.            mov [page_tabs+ebx*4], eax
  803.            invlpg [edx]
  804.  
  805.            mov  eax, [dst_slot]
  806.            shl eax, 8
  807.            or   [eax+SLOT_BASE+0xA8],dword 0x40
  808.            cmp  dword [check_idle_semaphore],20
  809.            jge  .ipc_no_cis
  810.  
  811.            mov  dword [check_idle_semaphore],5
  812. .ipc_no_cis:
  813.            popf
  814.            xor eax, eax
  815.            ret
  816. .no_pid:
  817.            popf
  818.            mov  eax, 4
  819.            ret
  820. .no_ipc_area:
  821.            popf
  822.            xor eax, eax
  823.            inc eax
  824.            ret
  825. .ipc_blocked:
  826.            popf
  827.            mov  eax, 2
  828.            ret
  829. .buffer_overflow:
  830.            popf
  831.            mov  eax, 3
  832.            ret
  833. endp
  834.  
  835. align 4
  836. sysfn_meminfo:
  837.  
  838.            add ebx, new_app_base
  839.            cmp ebx, new_app_base
  840.            jb .fail
  841.  
  842.            mov eax, [pg_data.pages_count]
  843.            mov [ebx], eax
  844.            shl eax, 12
  845.            mov [esp+36], eax
  846.            mov ecx, [pg_data.pages_free]
  847.            mov [ebx+4], ecx
  848.            mov edx, [pg_data.pages_faults]
  849.            mov [ebx+8], edx
  850.            mov esi, [heap_size]
  851.            mov [ebx+12], esi
  852.            mov edi, [heap_free]
  853.            mov [ebx+16], edi
  854.            mov eax, [heap_blocks]
  855.            mov [ebx+20], eax
  856.            mov ecx, [free_blocks]
  857.            mov [ebx+24], ecx
  858.            ret
  859. .fail:
  860.            mov dword [esp+36], -1
  861.            ret
  862.  
  863. align 4
  864. new_services:
  865.  
  866.            cmp  eax,4
  867.            jle  sys_sheduler
  868.  
  869.            cmp eax, 11
  870.            jb .fail
  871.            ja @f
  872.  
  873.            call init_heap
  874.            mov [esp+36], eax
  875.            ret
  876. @@:
  877.            cmp eax, 12
  878.            ja @f
  879.  
  880.            stdcall user_alloc, ebx
  881.            mov [esp+36], eax
  882.            ret
  883. @@:
  884.            cmp eax, 13
  885.            ja @f
  886.            add ebx, new_app_base
  887.            stdcall user_free, ebx
  888.            mov [esp+36], eax
  889.            ret
  890. @@:
  891.            cmp eax, 14
  892.            ja @f
  893.            add ebx, new_app_base
  894.            cmp ebx, new_app_base
  895.            jb .fail
  896.            stdcall get_event_ex, ebx, ecx
  897.            mov [esp+36], eax
  898.            ret
  899. @@:
  900.            cmp eax, 15
  901.            ja @f
  902.            mov ecx, [CURRENT_TASK]
  903.            shl ecx, 8
  904.            mov eax, [ecx+SLOT_BASE+APPDATA.fpu_handler]
  905.            mov [ecx+SLOT_BASE+APPDATA.fpu_handler], ebx
  906.            mov [esp+36], eax
  907.            ret
  908. @@:
  909.            cmp eax, 16
  910.            ja @f
  911.  
  912.            test ebx, ebx
  913.            jz .fail
  914.            add ebx, new_app_base
  915.            cmp ebx, new_app_base
  916.            jb .fail
  917.            stdcall get_service, ebx
  918.            mov [esp+36], eax
  919.            ret
  920. @@:
  921.            cmp eax, 17
  922.            ja @f
  923.            call srv_handlerEx   ;ebx
  924.            mov [esp+36], eax
  925.            ret
  926. @@:
  927.            cmp eax, 18
  928.            ja @f
  929.            mov ecx, [CURRENT_TASK]
  930.            shl ecx, 8
  931.            mov eax, [ecx+SLOT_BASE+APPDATA.sse_handler]
  932.            mov [ecx+SLOT_BASE+APPDATA.sse_handler], ebx
  933.            mov [esp+36], eax
  934.            ret
  935. @@:
  936.            cmp eax, 19
  937.            ja .fail
  938.            add ebx, new_app_base
  939.            cmp ebx, new_app_base
  940.            jb .fail
  941.            stdcall load_library, ebx
  942.            mov [esp+36], eax
  943.            ret
  944.  
  945. .fail:
  946.            xor eax, eax
  947.            mov [esp+36], eax
  948.            ret
  949.  
  950. align 4
  951. proc init_mtrr
  952.  
  953.            cmp [BOOT_VAR+0x901c],byte 2
  954.            je  .exit
  955.  
  956.            bt [cpu_caps], CAPS_MTRR
  957.            jnc .exit
  958.  
  959.            mov eax, cr0
  960.            or eax, 0x60000000   ;disable caching
  961.            mov cr0, eax
  962.            wbinvd               ;invalidate cache
  963.  
  964.            mov ecx, 0x2FF
  965.            rdmsr                ;
  966.            push eax
  967.  
  968.            xor edx, edx
  969.            xor eax, eax
  970.            mov ecx, 0x2FF
  971.            wrmsr                ;disable all MTRR
  972.  
  973.            stdcall set_mtrr, dword 0,dword 0,[MEM_AMOUNT],MEM_WB
  974.            stdcall set_mtrr, dword 1,[LFBAddress],[LFBSize],MEM_WC
  975.            xor edx, edx
  976.            xor eax, eax
  977.            mov ecx, 0x204
  978.            mov ebx, 6
  979. @@:
  980.            wrmsr                ;disable unused MTRR
  981.            inc ecx
  982.            wrmsr
  983.            inc ecx
  984.            dec ebx
  985.            jnz @b
  986.  
  987.            wbinvd               ;again invalidate
  988.  
  989.            pop eax
  990.            or eax, 0x800        ;set default memtype to UC
  991.            and al, 0xF0
  992.            mov ecx, 0x2FF
  993.            wrmsr                ;and enable MTRR
  994.  
  995.            mov eax, cr0
  996.            and eax, not 0x60000000
  997.            mov cr0, eax         ; enable caching
  998. .exit:
  999.            ret
  1000. endp
  1001.  
  1002. align 4
  1003. proc set_mtrr stdcall, reg:dword,base:dword,size:dword,mem_type:dword
  1004.  
  1005.            xor edx, edx
  1006.            mov eax, [base]
  1007.            or eax, [mem_type]
  1008.            mov ecx, [reg]
  1009.            lea ecx, [0x200+ecx*2]
  1010.            wrmsr
  1011.  
  1012.            mov ebx, [size]
  1013.            dec ebx
  1014.            mov eax, 0xFFFFFFFF
  1015.            mov edx, 0x0000000F
  1016.            sub eax, ebx
  1017.            sbb edx, 0
  1018.            or eax, 0x800
  1019.            inc ecx
  1020.            wrmsr
  1021.            ret
  1022. endp
  1023.  
  1024.  
  1025. align 4
  1026. proc strncmp stdcall, str1:dword, str2:dword, count:dword
  1027.  
  1028.           mov ecx,[count]
  1029.           jecxz .end
  1030.  
  1031.           mov ebx,ecx
  1032.  
  1033.           mov edi,[str1]
  1034.           mov esi,edi
  1035.           xor eax,eax
  1036.           repne scasb
  1037.           neg ecx             ; cx = count - strlen
  1038.           add ecx,ebx         ; strlen + count - strlen
  1039.  
  1040. .okay:
  1041.           mov edi,esi
  1042.           mov esi,[str2]
  1043.           repe cmpsb
  1044.           mov al,[esi-1]
  1045.           xor ecx,ecx
  1046.  
  1047.           cmp al,[edi-1]
  1048.           ja .str2_big
  1049.           je .end
  1050.  
  1051. .str1_big:
  1052.           sub ecx,2
  1053.  
  1054. .str2_big:
  1055.           not ecx
  1056. .end:
  1057.           mov eax,ecx
  1058.           ret
  1059. endp
  1060.  
  1061. align 4
  1062. proc stall stdcall, delay:dword
  1063.            push ecx
  1064.            push edx
  1065.            push ebx
  1066.            push eax
  1067.  
  1068.            mov eax, [delay]
  1069.            mul [stall_mcs]
  1070.            mov ebx, eax       ;low
  1071.            mov ecx, edx       ;high
  1072.            rdtsc
  1073.            add ebx, eax
  1074.            adc ecx,edx
  1075. @@:
  1076.            rdtsc
  1077.            sub eax, ebx
  1078.            sbb edx, ecx
  1079.            jb @B
  1080.  
  1081.            pop eax
  1082.            pop ebx
  1083.            pop edx
  1084.            pop ecx
  1085.            ret
  1086. endp
  1087.  
  1088. align 4
  1089. k_strrchr:
  1090.         push eax
  1091.         xor eax,eax
  1092.         or  ecx,-1
  1093.         repne scasb
  1094.         add ecx,1
  1095.         neg ecx
  1096.         sub edi,1
  1097.         pop eax
  1098.         std
  1099.         repne scasb
  1100.         cld
  1101.         add edi,1
  1102.  
  1103.         cmp [edi],al
  1104.         jne @F
  1105.         mov eax,edi
  1106.         ret
  1107. @@:
  1108.         xor eax,eax
  1109.         ret
  1110.  
  1111. align 4
  1112. proc k_strncpy stdcall, dest:dword, src:dword, maxlen:dword
  1113.         mov eax, [dest]
  1114.         mov esi, [src]
  1115.         mov ecx, [maxlen]
  1116.         test eax, eax
  1117.         jz .L9
  1118.         test esi, esi
  1119.         jz .L9
  1120.         test ecx, ecx
  1121.         jz .L9
  1122.  
  1123.         sub  esi, eax
  1124.         jmp .L1
  1125.  
  1126. align 4
  1127. .L2:
  1128.         mov edx, [esi+eax]
  1129.         mov [eax], dl
  1130.         test dl, dl
  1131.         jz .L7
  1132.  
  1133.         mov [eax+1], dh
  1134.         test dh, dh
  1135.         jz .L6
  1136.  
  1137.         shr edx, 16
  1138.         mov [eax+2],dl
  1139.         test dl, dl
  1140.         jz .L5
  1141.  
  1142.         mov [eax+3], dh
  1143.         test dh, dh
  1144.         jz .L4
  1145.         add eax, 4
  1146. .L1:
  1147.         sub ecx, 4
  1148.         jae .L2
  1149.  
  1150.         add ecx, 4
  1151.         jz .L9
  1152.  
  1153.         mov dl, [eax+esi]
  1154.         mov [eax], dl
  1155.         test dl, dl
  1156.         jz .L3
  1157.  
  1158.         inc eax
  1159.         dec ecx
  1160.         jz .L9
  1161.  
  1162.         mov dl, [eax+esi]
  1163.         mov [eax], dl
  1164.         test dl, dl
  1165.         jz .L3
  1166.  
  1167.         inc eax
  1168.         dec ecx
  1169.         jz .L9
  1170.  
  1171.         mov dl, [eax+esi]
  1172.         mov [eax], dl
  1173.         test dl, dl
  1174.         jz .L3
  1175.  
  1176.         inc eax
  1177.         jmp .L9
  1178.  
  1179. .L4:    dec ecx
  1180.         inc eax
  1181.  
  1182. .L5:    dec ecx
  1183.         inc eax
  1184.  
  1185. .L6:    dec ecx
  1186.         inc eax
  1187. .L7:
  1188.         add ecx,3
  1189.         jz .L9
  1190. .L8:
  1191.         mov byte [ecx+eax], 0
  1192. .L3:
  1193.         dec ecx
  1194.         jnz .L8
  1195. .L9:
  1196.         ret
  1197. endp
  1198.  
  1199. if 0
  1200.  
  1201. magic equ 0xfefefeff
  1202.  
  1203. k_strlen:
  1204.         mov eax,[esp+4]
  1205.         mov edx, 3
  1206.  
  1207.         and edx, eax
  1208.         jz .L1
  1209.         jp .L0
  1210.  
  1211.         cmp dh, byte [eax]
  1212.         je .L2
  1213.  
  1214.         inc eax
  1215.         cmp dh, byte [eax]
  1216.  
  1217.         je .L2
  1218.  
  1219.         inc eax
  1220.         xor edx, 2
  1221.  
  1222.         jz .L1
  1223. .L0:
  1224.         cmp dh, [eax]
  1225.         je .L2
  1226.  
  1227.         inc eax
  1228.         xor edx, edx
  1229.  
  1230. .L1:
  1231.         mov ecx, [eax]
  1232.         add eax, 4
  1233.  
  1234.         sub edx, ecx
  1235.         add ecx, magic
  1236.  
  1237.         dec edx
  1238.         jnc .L3
  1239.  
  1240.         xor edx, ecx
  1241.         and edx, not magic
  1242.         jne .L3
  1243.  
  1244.         mov ecx, [eax]
  1245.         add eax, 4
  1246.  
  1247.         sub edx, ecx
  1248.         add ecx, magic
  1249.         dec edx
  1250.         jnc .L3
  1251.  
  1252.         xor edx, ecx
  1253.         and edx, not magic
  1254.         jne .L3
  1255.  
  1256.         mov ecx, [eax]
  1257.         add eax, 4
  1258.  
  1259.         sub edx, ecx
  1260.         add ecx, magic
  1261.  
  1262.         dec edx
  1263.         jnc .L3
  1264.  
  1265.         xor edx, ecx
  1266.  
  1267.         and edx, not magic
  1268.         jne .L3
  1269.  
  1270.         mov ecx, [eax]
  1271.         add eax, 4
  1272.  
  1273.         sub edx, ecx
  1274.         add ecx, magic
  1275.  
  1276.         dec edx
  1277.         jnc .L3
  1278.  
  1279.         xor edx, ecx
  1280.  
  1281.         and edx, not magic
  1282.         je .L1
  1283.  
  1284. .L3:    sub eax ,4
  1285.         sub ecx, magic
  1286.  
  1287.         cmp cl, 0
  1288.         jz .L2
  1289.  
  1290.         inc eax
  1291.         test ch, ch
  1292.         jz .L2
  1293.  
  1294.         shr ecx, 16
  1295.         inc eax
  1296.  
  1297.         cmp cl,0
  1298.         jz .L2
  1299.  
  1300.         inc eax
  1301.  
  1302. .L2:
  1303.         sub eax, [esp+4]
  1304.         ret
  1305.  
  1306. end if
  1307.  
  1308. if 0
  1309.      push eax
  1310.      push edx
  1311.      mov edx, 0x400   ;bocsh
  1312.      mov al,0xff      ;bocsh
  1313.      out dx, al       ;bocsh
  1314.      pop edx
  1315.      pop eax
  1316. end if
  1317.  
  1318.  
  1319.