Subversion Repositories Kolibri OS

Rev

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