Subversion Repositories Kolibri OS

Rev

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