Subversion Repositories Kolibri OS

Rev

Rev 172 | Rev 198 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

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