Subversion Repositories Kolibri OS

Rev

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