Subversion Repositories Kolibri OS

Rev

Rev 188 | Rev 201 | 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.            cmp eax, 19
  977.            ja @f
  978.            add ebx, new_app_base
  979.            cmp ebx, new_app_base
  980.            jb .fail
  981.            stdcall load_library, ebx
  982.            mov [esp+36], eax
  983.            ret
  984. @@:
  985. .fail:
  986.            xor eax, eax
  987.            mov [esp+36], eax
  988.            ret
  989.  
  990. align 4
  991. proc strncmp stdcall, str1:dword, str2:dword, count:dword
  992.  
  993.           mov ecx,[count]
  994.           jecxz .end
  995.  
  996.           mov ebx,ecx
  997.  
  998.           mov edi,[str1]
  999.           mov esi,edi
  1000.           xor eax,eax
  1001.           repne scasb
  1002.           neg ecx             ; cx = count - strlen
  1003.           add ecx,ebx         ; strlen + count - strlen
  1004.  
  1005. .okay:
  1006.           mov edi,esi
  1007.           mov esi,[str2]
  1008.           repe cmpsb
  1009.           mov al,[esi-1]
  1010.           xor ecx,ecx
  1011.  
  1012.           cmp al,[edi-1]
  1013.           ja .str2_big
  1014.           je .end
  1015.  
  1016. .str1_big:
  1017.           sub ecx,2
  1018.  
  1019. .str2_big:
  1020.           not ecx
  1021. .end:
  1022.           mov eax,ecx
  1023.           ret
  1024. endp
  1025.  
  1026. align 4
  1027. proc fpu_save
  1028.            clts
  1029.            mov ebx, [fpu_owner]
  1030.            shl ebx, 8
  1031.            mov eax, [ebx+PROC_BASE+0x10]
  1032.            mov ebx, [CURRENT_TASK]
  1033.            mov [fpu_owner], ebx
  1034.  
  1035.            bt [cpu_caps], CAPS_FXSR
  1036.            jnc .no_SSE
  1037.  
  1038.            fxsave [eax]
  1039.            ret
  1040. .no_SSE:
  1041.            fnsave [eax]
  1042.            ret
  1043. endp
  1044.  
  1045. align 4
  1046. proc fpu_restore
  1047.            mov ebx, [CURRENT_TASK]
  1048.            shl ebx, 8
  1049.            mov eax, [ebx+PROC_BASE+0x10]
  1050.            bt [cpu_caps], CAPS_FXSR
  1051.            jnc .no_SSE
  1052.  
  1053.            fxrstor [eax]
  1054.            ret
  1055. .no_SSE:
  1056.            frstor [eax]
  1057.            ret
  1058. endp
  1059.  
  1060. align 4
  1061. proc test_cpu
  1062.            locals
  1063.               cpu_type   dd ?
  1064.               cpu_id     dd ?
  1065.               cpu_Intel  dd ?
  1066.               cpu_AMD    dd ?
  1067.            endl
  1068.  
  1069.            mov [cpu_type], 0
  1070.  
  1071.            pushfd
  1072.            pop eax
  1073.            mov ecx, eax
  1074.            xor eax, 0x40000
  1075.            push eax
  1076.            popfd
  1077.            pushfd
  1078.            pop eax
  1079.            xor eax, ecx
  1080.            mov [cpu_type], CPU_386
  1081.            jz .end_cpu
  1082.            push ecx
  1083.            popfd
  1084.  
  1085.            mov [cpu_type], CPU_486
  1086.            mov eax, ecx
  1087.            xor eax, 0x200000
  1088.            push eax
  1089.            popfd
  1090.            pushfd
  1091.            pop eax
  1092.            xor eax, ecx
  1093.            je .end_cpu
  1094.            mov [cpu_id], 1
  1095.  
  1096.            xor eax, eax
  1097.            cpuid
  1098.            mov [cpu_vendor], ebx
  1099.            mov [cpu_vendor+4], edx
  1100.            mov [cpu_vendor+8], ecx
  1101.            cmp ebx, dword [intel_str]
  1102.            jne .check_AMD
  1103.            cmp edx, dword [intel_str+4]
  1104.            jne .check_AMD
  1105.            cmp ecx, dword [intel_str+8]
  1106.            jne .check_AMD
  1107.            mov [cpu_Intel], 1
  1108.            cmp eax, 1
  1109.            jl .end_cpuid
  1110.            mov eax, 1
  1111.            cpuid
  1112.            mov [cpu_sign], eax
  1113.            mov [cpu_info],  ebx
  1114.            mov [cpu_caps],  edx
  1115.            mov [cpu_caps+4],ecx
  1116.  
  1117.            shr eax, 8
  1118.            and eax, 0x0f
  1119.            mov [cpu_type], eax
  1120.            ret
  1121.  
  1122. .end_cpuid:
  1123.            mov eax, [cpu_type]
  1124.            ret
  1125.  
  1126. .check_AMD:
  1127.            cmp ebx, dword [AMD_str]
  1128.            jne .end_cpu
  1129.            cmp edx, dword [AMD_str+4]
  1130.            jne .end_cpu
  1131.            cmp ecx, dword [AMD_str+8]
  1132.            jne .end_cpu
  1133.            mov [cpu_AMD], 1
  1134.            cmp eax, 1
  1135.            jl .end_cpuid
  1136.            mov eax, 1
  1137.            cpuid
  1138.            mov [cpu_sign], eax
  1139.            mov [cpu_info],  ebx
  1140.            mov [cpu_caps],  edx
  1141.            mov [cpu_caps+4],ecx
  1142.            shr eax, 8
  1143.            and eax, 0x0f
  1144.            mov [cpu_type], eax
  1145. .end_cpu:
  1146.            mov eax, [cpu_type]
  1147.            ret
  1148. endp
  1149.  
  1150. MEM_WB     equ 6               ;write-back memory
  1151. MEM_WC     equ 1               ;write combined memory
  1152. MEM_UC     equ 0               ;uncached memory
  1153.  
  1154. align 4
  1155. proc init_mtrr
  1156.  
  1157.            cmp [0x2f0000+0x901c],byte 2
  1158.            je  .exit
  1159.  
  1160.            mov eax, cr0
  1161.            or eax, 0x60000000   ;disable caching
  1162.            mov cr0, eax
  1163.            wbinvd               ;invalidate cache
  1164.  
  1165.            mov ecx, 0x2FF
  1166.            rdmsr                ;
  1167.            push eax
  1168.  
  1169.            xor edx, edx
  1170.            xor eax, eax
  1171.            mov ecx, 0x2FF
  1172.            wrmsr                ;disable all MTRR
  1173.  
  1174.            stdcall set_mtrr, dword 0,dword 0,[MEM_AMOUNT],MEM_WB
  1175.            stdcall set_mtrr, dword 1,[LFBAddress],[LFBSize],MEM_WC
  1176.            xor edx, edx
  1177.            xor eax, eax
  1178.            mov ecx, 0x204
  1179.            mov ebx, 6
  1180. @@:
  1181.            wrmsr                ;disable unused MTRR
  1182.            inc ecx
  1183.            wrmsr
  1184.            inc ecx
  1185.            dec ebx
  1186.            jnz @b
  1187.  
  1188.            wbinvd               ;again invalidate
  1189.  
  1190.            pop eax
  1191.            or eax, 0x800        ;set default memtype to UC
  1192.            and al, 0xF0
  1193.            mov ecx, 0x2FF
  1194.            wrmsr                ;and enable MTRR
  1195.  
  1196.            mov eax, cr0
  1197.            and eax, not 0x60000000
  1198.            mov cr0, eax         ; enable caching
  1199. .exit:
  1200.            ret
  1201. endp
  1202.  
  1203. align 4
  1204. proc set_mtrr stdcall, reg:dword,base:dword,size:dword,mem_type:dword
  1205.  
  1206.            xor edx, edx
  1207.            mov eax, [base]
  1208.            or eax, [mem_type]
  1209.            mov ecx, [reg]
  1210.            lea ecx, [0x200+ecx*2]
  1211.            wrmsr
  1212.  
  1213.            mov ebx, [size]
  1214.            dec ebx
  1215.            mov eax, 0xFFFFFFFF
  1216.            mov edx, 0x0000000F
  1217.            sub eax, ebx
  1218.            sbb edx, 0
  1219.            or eax, 0x800
  1220.            inc ecx
  1221.            wrmsr
  1222.            ret
  1223. endp
  1224.  
  1225. align 4
  1226. proc stall stdcall, delay:dword
  1227.            push ecx
  1228.            push edx
  1229.            push ebx
  1230.            push eax
  1231.  
  1232.            mov eax, [delay]
  1233.            mul [stall_mcs]
  1234.            mov ebx, eax       ;low
  1235.            mov ecx, edx       ;high
  1236.            rdtsc
  1237.            add ebx, eax
  1238.            adc ecx,edx
  1239. @@:
  1240.            rdtsc
  1241.            sub eax, ebx
  1242.            sbb edx, ecx
  1243.            jb @B
  1244.  
  1245.            pop eax
  1246.            pop ebx
  1247.            pop edx
  1248.            pop ecx
  1249.            ret
  1250. endp
  1251.  
  1252. iglobal
  1253. align 4
  1254.   intel_str    db "GenuineIntel",0
  1255.   AMD_str      db "AuthenticAMD",0
  1256. endg
  1257.  
  1258. uglobal
  1259. align 16
  1260.   irq_tab           rd 16
  1261.  
  1262.  
  1263.   MEM_FreeSpace     rd 1
  1264.  
  1265.   ipc_tmp           rd 1
  1266.   ipc_pdir          rd 1
  1267.   ipc_ptab          rd 1
  1268.  
  1269.   proc_mem_map      rd 1
  1270.   proc_mem_pdir     rd 1
  1271.   proc_mem_tab      rd 1
  1272.  
  1273.   tmp_task_pdir     rd 1
  1274.   tmp_task_ptab     rd 1
  1275.   tmp_task_data     rd 1
  1276.  
  1277. ;  current_pdir      rd 1
  1278.  
  1279.   fpu_data          rd 1
  1280.   fdd_buff          rd 1
  1281.  
  1282.   stall_mcs         rd 1
  1283. ;;CPUID information
  1284.  
  1285.   cpu_vendor        rd 3
  1286.   cpu_sign          rd 1
  1287.   cpu_info          rd 1
  1288.  
  1289. endg
  1290.  
  1291. uglobal
  1292. align 16
  1293.    dll_tab         rb 32*32
  1294.    srv_tab         rb 32*32
  1295.    dll_map         rd 1
  1296.    srv_map         rd 1
  1297.  
  1298.    mem_used_list   rd 1
  1299.    mem_block_list  rd 64
  1300.    mem_block_map   rb 512
  1301.    mem_block_arr   rd 1
  1302.    mem_block_start rd 1
  1303.    mem_block_end   rd 1
  1304.    mem_block_mask  rd 2
  1305.    heap_size       rd 1
  1306.    heap_free       rd 1
  1307.    heap_blocks     rd 1
  1308.    free_blocks     rd 1
  1309.  
  1310.    page_start      rd 1
  1311.    page_end        rd 1
  1312.    sys_page_map    rd 1
  1313. ;   app_load        rd 1
  1314. endg
  1315.  
  1316.  
  1317. ;     push eax
  1318. ;     push edx
  1319. ;     mov edx, 0x400   ;bocsh
  1320. ;     mov al,0xff      ;bocsh
  1321. ;     out dx, al       ;bocsh
  1322. ;     pop edx
  1323. ;     pop eax
  1324.  
  1325.