Subversion Repositories Kolibri OS

Rev

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