Subversion Repositories Kolibri OS

Rev

Rev 453 | 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.  
  595. ;           iretd
  596.  
  597.            save_ring3_context     ;debugger support
  598.  
  599.            mov bl, 14
  600.            jmp exc_c
  601.            iretd
  602. endp
  603.  
  604. align 4
  605. proc map_mem stdcall, lin_addr:dword,pdir:dword,\
  606.                       ofs:dword,buf_size:dword
  607.            mov eax, [buf_size]
  608.            test eax, eax
  609.            jz .exit
  610.  
  611.            mov eax, [pdir]
  612.            and eax, 0xFFFFF000
  613.  
  614.            stdcall map_page,[ipc_pdir],eax,dword PG_UW
  615.            mov ebx, [ofs]
  616.            shr ebx, 22
  617.            mov esi, [ipc_pdir]
  618.            mov edi, [ipc_ptab]
  619.            mov eax, [esi+ebx*4]
  620.            and eax, 0xFFFFF000
  621.            test eax, eax
  622.            jz .exit
  623.            stdcall map_page,edi,eax,dword PG_UW
  624. ;           inc ebx
  625. ;           add edi, 0x1000
  626. ;           mov eax, [esi+ebx*4]
  627. ;           test eax, eax
  628. ;           jz @f
  629. ;          and eax, 0xFFFFF000
  630. ;           stdcall map_page, edi, eax
  631.  
  632. @@:        mov edi, [lin_addr]
  633.            and edi, 0xFFFFF000
  634.            mov ecx, [buf_size]
  635.            add ecx, 4095
  636.            shr ecx, 12
  637.            inc ecx
  638.  
  639.            mov edx, [ofs]
  640.            shr edx, 12
  641.            and edx, 0x3FF
  642.            mov esi, [ipc_ptab]
  643.  
  644. .map:      mov eax, [esi+edx*4]
  645.            and eax, 0xFFFFF000
  646.            test eax, eax
  647.            jz .exit
  648.            stdcall map_page,edi,eax,dword PG_UW
  649.            add edi, 0x1000
  650.            inc edx
  651.            dec ecx
  652.            jnz .map
  653.  
  654. .exit:
  655.            ret
  656. endp
  657.  
  658. align 4
  659. proc map_memEx stdcall, lin_addr:dword,pdir:dword,\
  660.                         ofs:dword,buf_size:dword
  661.            mov eax, [buf_size]
  662.            test eax, eax
  663.            jz .exit
  664.  
  665.            mov eax, [pdir]
  666.            and eax, 0xFFFFF000
  667.  
  668.            stdcall map_page,[proc_mem_pdir],eax,dword PG_UW
  669.            mov ebx, [ofs]
  670.            shr ebx, 22
  671.            mov esi, [proc_mem_pdir]
  672.            mov edi, [proc_mem_tab]
  673.            mov eax, [esi+ebx*4]
  674.            and eax, 0xFFFFF000
  675.            test eax, eax
  676.            jz .exit
  677.            stdcall map_page,edi,eax,dword PG_UW
  678.  
  679. @@:        mov edi, [lin_addr]
  680.            and edi, 0xFFFFF000
  681.            mov ecx, [buf_size]
  682.            add ecx, 4095
  683.            shr ecx, 12
  684.            inc ecx
  685.  
  686.            mov edx, [ofs]
  687.            shr edx, 12
  688.            and edx, 0x3FF
  689.            mov esi, [proc_mem_tab]
  690.  
  691. .map:      mov eax, [esi+edx*4]
  692. ;           and eax, 0xFFFFF000
  693. ;           test eax, eax
  694. ;           jz .exit
  695.            stdcall map_page,edi,eax,dword PG_UW
  696.            add edi, 0x1000
  697.            inc edx
  698.            dec ecx
  699.            jnz .map
  700. .exit:
  701.            ret
  702. endp
  703.  
  704.  
  705.  
  706.  
  707. sys_IPC:
  708. ;input:
  709. ;  eax=1 - set ipc buffer area
  710. ;    ebx=address of buffer
  711. ;    ecx=size of buffer
  712. ;  eax=2 - send message
  713. ;    ebx=PID
  714. ;    ecx=address of message
  715. ;    edx=size of message
  716.  
  717.            cmp  eax,1
  718.            jne @f
  719.            call set_ipc_buff
  720.            mov [esp+36], eax
  721.            ret
  722. @@:
  723.            cmp eax, 2
  724.            jne @f
  725.            stdcall sys_ipc_send, ebx, ecx, edx
  726.            mov [esp+36], eax
  727.            ret
  728. @@:
  729.            xor eax, eax
  730.            not eax
  731.            mov [esp+36], eax
  732.            ret
  733.  
  734. align 4
  735. proc set_ipc_buff
  736.  
  737.            mov  eax,[current_slot]
  738.            pushf
  739.            cli
  740.            mov  [eax+APPDATA.ipc_start],ebx     ;set fields in extended information area
  741.            mov  [eax+APPDATA.ipc_size],ecx
  742.  
  743.            add ecx, ebx
  744.            add ecx, 4095
  745.            and ecx, not 4095
  746.  
  747. .touch:    mov eax, [ebx]
  748.            add ebx, 0x1000
  749.            cmp ebx, ecx
  750.            jna .touch
  751.  
  752.            popf
  753.            xor eax, eax
  754.            ret
  755. endp
  756.  
  757. proc sys_ipc_send stdcall, PID:dword, msg_addr:dword, msg_size:dword
  758.            locals
  759.              dst_slot   dd ?
  760.              dst_offset dd ?
  761.              buf_size   dd ?
  762.            endl
  763.  
  764.            pushf
  765.            cli
  766.  
  767.            mov  eax, [PID]
  768.            call pid_to_slot
  769.            test eax,eax
  770.            jz   .no_pid
  771.  
  772.            mov [dst_slot], eax
  773.            shl  eax,8
  774.            mov  edi,[eax+SLOT_BASE+0xa0]  ;is ipc area defined?
  775.            test edi,edi
  776.            jz   .no_ipc_area
  777.  
  778.            mov ebx, edi
  779.        ;    add edi, new_app_base
  780.            and ebx, 0xFFF
  781.            mov [dst_offset], ebx
  782.  
  783.            mov esi, [eax+SLOT_BASE+0xa4]
  784.            mov [buf_size], esi
  785.  
  786.            stdcall map_mem, [ipc_tmp], [SLOT_BASE+eax+0xB8],\
  787.                              edi, esi
  788.  
  789.            mov edi, [dst_offset]
  790.            add edi, [ipc_tmp]
  791.            cmp dword [edi], 0
  792.            jnz  .ipc_blocked          ;if dword [buffer]<>0 - ipc blocked now
  793.  
  794.            mov ebx, dword [edi+4]
  795.            mov edx, ebx
  796.            add ebx, 8
  797.            add ebx, [msg_size]
  798.            cmp ebx, [buf_size]
  799.            ja .buffer_overflow         ;esi<0 - not enough memory in buffer
  800.  
  801.            mov dword [edi+4], ebx
  802.            mov eax,[TASK_BASE]
  803.            mov eax, [eax+0x04]         ;eax - our PID
  804.            mov edi, [dst_offset]
  805.            add edi, [ipc_tmp]
  806.            add edi, edx
  807.            mov [edi], eax
  808.            mov ecx, [msg_size]
  809.  
  810.            mov [edi+4], ecx
  811.            add edi, 8
  812.            mov esi, [msg_addr]
  813.        ;    add esi, new_app_base
  814.            cld
  815.            rep movsb
  816.  
  817.            mov ebx, [ipc_tmp]
  818.            mov edx, ebx
  819.            shr ebx, 12
  820.            xor eax, eax
  821.            mov [page_tabs+ebx*4], eax
  822.            invlpg [edx]
  823.  
  824.            mov ebx, [ipc_pdir]
  825.            mov edx, ebx
  826.            shr ebx, 12
  827.            xor eax, eax
  828.            mov [page_tabs+ebx*4], eax
  829.            invlpg [edx]
  830.  
  831.            mov ebx, [ipc_ptab]
  832.            mov edx, ebx
  833.            shr ebx, 12
  834.            xor eax, eax
  835.            mov [page_tabs+ebx*4], eax
  836.            invlpg [edx]
  837.  
  838.            mov  eax, [dst_slot]
  839.            shl eax, 8
  840.            or   [eax+SLOT_BASE+0xA8],dword 0x40
  841.            cmp  dword [check_idle_semaphore],20
  842.            jge  .ipc_no_cis
  843.  
  844.            mov  dword [check_idle_semaphore],5
  845. .ipc_no_cis:
  846.            popf
  847.            xor eax, eax
  848.            ret
  849. .no_pid:
  850.            popf
  851.            mov  eax, 4
  852.            ret
  853. .no_ipc_area:
  854.            popf
  855.            xor eax, eax
  856.            inc eax
  857.            ret
  858. .ipc_blocked:
  859.            popf
  860.            mov  eax, 2
  861.            ret
  862. .buffer_overflow:
  863.            popf
  864.            mov  eax, 3
  865.            ret
  866. endp
  867.  
  868. align 4
  869. sysfn_meminfo:
  870.  
  871.         ;   add ebx, new_app_base
  872.            cmp ebx, OS_BASE
  873.            jae .fail
  874.  
  875.            mov eax, [pg_data.pages_count]
  876.            mov [ebx], eax
  877.            shl eax, 12
  878.            mov [esp+36], eax
  879.            mov ecx, [pg_data.pages_free]
  880.            mov [ebx+4], ecx
  881.            mov edx, [pg_data.pages_faults]
  882.            mov [ebx+8], edx
  883.            mov esi, [heap_size]
  884.            mov [ebx+12], esi
  885.            mov edi, [heap_free]
  886.            mov [ebx+16], edi
  887.            mov eax, [heap_blocks]
  888.            mov [ebx+20], eax
  889.            mov ecx, [free_blocks]
  890.            mov [ebx+24], ecx
  891.            ret
  892. .fail:
  893.            mov dword [esp+36], -1
  894.            ret
  895.  
  896. align 4
  897. new_services:
  898.  
  899.            cmp  eax,4
  900.            jle  sys_sheduler
  901.  
  902.            cmp eax, 11
  903.            jb .fail
  904.            ja @f
  905.  
  906.            call init_heap
  907.            mov [esp+36], eax
  908.            ret
  909. @@:
  910.            cmp eax, 12
  911.            ja @f
  912.  
  913.            stdcall user_alloc, ebx
  914.            mov [esp+36], eax
  915.            ret
  916. @@:
  917.            cmp eax, 13
  918.            ja @f
  919.            stdcall user_free, ebx
  920.            mov [esp+36], eax
  921.            ret
  922. @@:
  923.            cmp eax, 14
  924.            ja @f
  925.            cmp ebx, OS_BASE
  926.            jae .fail
  927.            stdcall get_event_ex, ebx, ecx
  928.            mov [esp+36], eax
  929.            ret
  930. @@:
  931.            cmp eax, 15
  932.            ja @f
  933.            mov ecx, [current_slot]
  934.            mov eax, [ecx+APPDATA.fpu_handler]
  935.            mov [ecx+APPDATA.fpu_handler], ebx
  936.            mov [esp+36], eax
  937.            ret
  938. @@:
  939.            cmp eax, 16
  940.            ja @f
  941.  
  942.            test ebx, ebx
  943.            jz .fail
  944.            cmp ebx, OS_BASE
  945.            jae .fail
  946.            stdcall get_service, ebx
  947.            mov [esp+36], eax
  948.            ret
  949. @@:
  950.            cmp eax, 17
  951.            ja @f
  952.            call srv_handlerEx   ;ebx
  953.            mov [esp+36], eax
  954.            ret
  955. @@:
  956.            cmp eax, 18
  957.            ja @f
  958.            mov ecx, [current_slot]
  959.            mov eax, [ecx+APPDATA.sse_handler]
  960.            mov [ecx+APPDATA.sse_handler], ebx
  961.            mov [esp+36], eax
  962.            ret
  963. @@:
  964.            cmp eax, 19
  965.            ja @f
  966.            cmp ebx, OS_BASE
  967.            jae .fail
  968.            stdcall load_library, ebx
  969.            mov [esp+36], eax
  970.            ret
  971.  
  972. @@:
  973.         cmp     eax, 20
  974.         ja      .fail
  975.         mov     eax, ecx
  976.         call    user_realloc
  977.         mov     [esp+36], eax
  978.         ret
  979.  
  980. .fail:
  981.            xor eax, eax
  982.            mov [esp+36], eax
  983.            ret
  984.  
  985. align 4
  986. proc init_mtrr
  987.  
  988.            cmp [BOOT_VAR+0x901c],byte 2
  989.            je  .exit
  990.  
  991.            bt [cpu_caps], CAPS_MTRR
  992.            jnc .exit
  993.  
  994.            mov eax, cr0
  995.            or eax, 0x60000000   ;disable caching
  996.            mov cr0, eax
  997.            wbinvd               ;invalidate cache
  998.  
  999.            mov ecx, 0x2FF
  1000.            rdmsr                ;
  1001.            push eax
  1002.  
  1003.            xor edx, edx
  1004.            xor eax, eax
  1005.            mov ecx, 0x2FF
  1006.            wrmsr                ;disable all MTRR
  1007.  
  1008.            stdcall set_mtrr, dword 0,dword 0,[MEM_AMOUNT],MEM_WB
  1009.            stdcall set_mtrr, dword 1,[LFBAddress],[LFBSize],MEM_WC
  1010.            xor edx, edx
  1011.            xor eax, eax
  1012.            mov ecx, 0x204
  1013.            mov ebx, 6
  1014. @@:
  1015.            wrmsr                ;disable unused MTRR
  1016.            inc ecx
  1017.            wrmsr
  1018.            inc ecx
  1019.            dec ebx
  1020.            jnz @b
  1021.  
  1022.            wbinvd               ;again invalidate
  1023.  
  1024.            pop eax
  1025.            or eax, 0x800        ;set default memtype to UC
  1026.            and al, 0xF0
  1027.            mov ecx, 0x2FF
  1028.            wrmsr                ;and enable MTRR
  1029.  
  1030.            mov eax, cr0
  1031.            and eax, not 0x60000000
  1032.            mov cr0, eax         ; enable caching
  1033. .exit:
  1034.            ret
  1035. endp
  1036.  
  1037. align 4
  1038. proc set_mtrr stdcall, reg:dword,base:dword,size:dword,mem_type:dword
  1039.  
  1040.            xor edx, edx
  1041.            mov eax, [base]
  1042.            or eax, [mem_type]
  1043.            mov ecx, [reg]
  1044.            lea ecx, [0x200+ecx*2]
  1045.            wrmsr
  1046.  
  1047.            mov ebx, [size]
  1048.            dec ebx
  1049.            mov eax, 0xFFFFFFFF
  1050.            mov edx, 0x0000000F
  1051.            sub eax, ebx
  1052.            sbb edx, 0
  1053.            or eax, 0x800
  1054.            inc ecx
  1055.            wrmsr
  1056.            ret
  1057. endp
  1058.  
  1059.  
  1060. align 4
  1061. proc strncmp stdcall, str1:dword, str2:dword, count:dword
  1062.  
  1063.           mov ecx,[count]
  1064.           jecxz .end
  1065.  
  1066.           mov ebx,ecx
  1067.  
  1068.           mov edi,[str1]
  1069.           mov esi,edi
  1070.           xor eax,eax
  1071.           repne scasb
  1072.           neg ecx             ; cx = count - strlen
  1073.           add ecx,ebx         ; strlen + count - strlen
  1074.  
  1075. .okay:
  1076.           mov edi,esi
  1077.           mov esi,[str2]
  1078.           repe cmpsb
  1079.           mov al,[esi-1]
  1080.           xor ecx,ecx
  1081.  
  1082.           cmp al,[edi-1]
  1083.           ja .str2_big
  1084.           je .end
  1085.  
  1086. .str1_big:
  1087.           sub ecx,2
  1088.  
  1089. .str2_big:
  1090.           not ecx
  1091. .end:
  1092.           mov eax,ecx
  1093.           ret
  1094. endp
  1095.  
  1096. align 4
  1097. proc stall stdcall, delay:dword
  1098.            push ecx
  1099.            push edx
  1100.            push ebx
  1101.            push eax
  1102.  
  1103.            mov eax, [delay]
  1104.            mul [stall_mcs]
  1105.            mov ebx, eax       ;low
  1106.            mov ecx, edx       ;high
  1107.            rdtsc
  1108.            add ebx, eax
  1109.            adc ecx,edx
  1110. @@:
  1111.            rdtsc
  1112.            sub eax, ebx
  1113.            sbb edx, ecx
  1114.            jb @B
  1115.  
  1116.            pop eax
  1117.            pop ebx
  1118.            pop edx
  1119.            pop ecx
  1120.            ret
  1121. endp
  1122.  
  1123. align 4
  1124. k_strrchr:
  1125.         push eax
  1126.         xor eax,eax
  1127.         or  ecx,-1
  1128.         repne scasb
  1129.         add ecx,1
  1130.         neg ecx
  1131.         sub edi,1
  1132.         pop eax
  1133.         std
  1134.         repne scasb
  1135.         cld
  1136.         add edi,1
  1137.  
  1138.         cmp [edi],al
  1139.         jne @F
  1140.         mov eax,edi
  1141.         ret
  1142. @@:
  1143.         xor eax,eax
  1144.         ret
  1145.  
  1146. align 4
  1147. proc k_strncpy stdcall, dest:dword, src:dword, maxlen:dword
  1148.         mov eax, [dest]
  1149.         mov esi, [src]
  1150.         mov ecx, [maxlen]
  1151.         test eax, eax
  1152.         jz .L9
  1153.         test esi, esi
  1154.         jz .L9
  1155.         test ecx, ecx
  1156.         jz .L9
  1157.  
  1158.         sub  esi, eax
  1159.         jmp .L1
  1160.  
  1161. align 4
  1162. .L2:
  1163.         mov edx, [esi+eax]
  1164.         mov [eax], dl
  1165.         test dl, dl
  1166.         jz .L7
  1167.  
  1168.         mov [eax+1], dh
  1169.         test dh, dh
  1170.         jz .L6
  1171.  
  1172.         shr edx, 16
  1173.         mov [eax+2],dl
  1174.         test dl, dl
  1175.         jz .L5
  1176.  
  1177.         mov [eax+3], dh
  1178.         test dh, dh
  1179.         jz .L4
  1180.         add eax, 4
  1181. .L1:
  1182.         sub ecx, 4
  1183.         jae .L2
  1184.  
  1185.         add ecx, 4
  1186.         jz .L9
  1187.  
  1188.         mov dl, [eax+esi]
  1189.         mov [eax], dl
  1190.         test dl, dl
  1191.         jz .L3
  1192.  
  1193.         inc eax
  1194.         dec ecx
  1195.         jz .L9
  1196.  
  1197.         mov dl, [eax+esi]
  1198.         mov [eax], dl
  1199.         test dl, dl
  1200.         jz .L3
  1201.  
  1202.         inc eax
  1203.         dec ecx
  1204.         jz .L9
  1205.  
  1206.         mov dl, [eax+esi]
  1207.         mov [eax], dl
  1208.         test dl, dl
  1209.         jz .L3
  1210.  
  1211.         inc eax
  1212.         jmp .L9
  1213.  
  1214. .L4:    dec ecx
  1215.         inc eax
  1216.  
  1217. .L5:    dec ecx
  1218.         inc eax
  1219.  
  1220. .L6:    dec ecx
  1221.         inc eax
  1222. .L7:
  1223.         add ecx,3
  1224.         jz .L9
  1225. .L8:
  1226.         mov byte [ecx+eax], 0
  1227. .L3:
  1228.         dec ecx
  1229.         jnz .L8
  1230. .L9:
  1231.         ret
  1232. endp
  1233.  
  1234. if 0
  1235.  
  1236. magic equ 0xfefefeff
  1237.  
  1238. k_strlen:
  1239.         mov eax,[esp+4]
  1240.         mov edx, 3
  1241.  
  1242.         and edx, eax
  1243.         jz .L1
  1244.         jp .L0
  1245.  
  1246.         cmp dh, byte [eax]
  1247.         je .L2
  1248.  
  1249.         inc eax
  1250.         cmp dh, byte [eax]
  1251.  
  1252.         je .L2
  1253.  
  1254.         inc eax
  1255.         xor edx, 2
  1256.  
  1257.         jz .L1
  1258. .L0:
  1259.         cmp dh, [eax]
  1260.         je .L2
  1261.  
  1262.         inc eax
  1263.         xor edx, edx
  1264.  
  1265. .L1:
  1266.         mov ecx, [eax]
  1267.         add eax, 4
  1268.  
  1269.         sub edx, ecx
  1270.         add ecx, magic
  1271.  
  1272.         dec edx
  1273.         jnc .L3
  1274.  
  1275.         xor edx, ecx
  1276.         and edx, not magic
  1277.         jne .L3
  1278.  
  1279.         mov ecx, [eax]
  1280.         add eax, 4
  1281.  
  1282.         sub edx, ecx
  1283.         add ecx, magic
  1284.         dec edx
  1285.         jnc .L3
  1286.  
  1287.         xor edx, ecx
  1288.         and edx, not magic
  1289.         jne .L3
  1290.  
  1291.         mov ecx, [eax]
  1292.         add eax, 4
  1293.  
  1294.         sub edx, ecx
  1295.         add ecx, magic
  1296.  
  1297.         dec edx
  1298.         jnc .L3
  1299.  
  1300.         xor edx, ecx
  1301.  
  1302.         and edx, not magic
  1303.         jne .L3
  1304.  
  1305.         mov ecx, [eax]
  1306.         add eax, 4
  1307.  
  1308.         sub edx, ecx
  1309.         add ecx, magic
  1310.  
  1311.         dec edx
  1312.         jnc .L3
  1313.  
  1314.         xor edx, ecx
  1315.  
  1316.         and edx, not magic
  1317.         je .L1
  1318.  
  1319. .L3:    sub eax ,4
  1320.         sub ecx, magic
  1321.  
  1322.         cmp cl, 0
  1323.         jz .L2
  1324.  
  1325.         inc eax
  1326.         test ch, ch
  1327.         jz .L2
  1328.  
  1329.         shr ecx, 16
  1330.         inc eax
  1331.  
  1332.         cmp cl,0
  1333.         jz .L2
  1334.  
  1335.         inc eax
  1336.  
  1337. .L2:
  1338.         sub eax, [esp+4]
  1339.         ret
  1340.  
  1341. end if
  1342.  
  1343. if 0
  1344.      push eax
  1345.      push edx
  1346.      mov edx, 0x400   ;bochs
  1347.      mov al,0xff      ;bochs
  1348.      out dx, al       ;bochs
  1349.      pop edx
  1350.      pop eax
  1351. end if
  1352.  
  1353.  
  1354.