Subversion Repositories Kolibri OS

Rev

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

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