Subversion Repositories Kolibri OS

Rev

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

  1.  
  2. tmp_page_tab      equ 0x00C00000
  3.  
  4. align 4
  5. proc mem_test
  6.  
  7.            mov eax, cr0
  8.            and eax, not (CR0_CD+CR0_NW)
  9.            or eax, CR0_CD         ;disable caching
  10.            mov cr0, eax
  11.            wbinvd                 ;invalidate cache
  12.  
  13.            xor edi, edi
  14.            mov ebx, 'TEST'
  15. @@:
  16.            add edi, 0x400000
  17.            xchg ebx, dword [edi]
  18.            cmp dword [edi], 'TEST'
  19.            xchg ebx, dword [edi]
  20.            je @b
  21.  
  22.            and eax, not (CR0_CD+CR0_NW)  ;enable caching
  23.            mov cr0, eax
  24.            mov eax, edi
  25.            mov [LFBSize], 0x00800000
  26.            ret
  27. endp
  28.  
  29. align 4
  30. proc init_memEx
  31.            xor eax, eax
  32.            mov edi, sys_pgdir
  33.            mov ecx, 2048
  34.            rep stosd
  35.  
  36.            bt [cpu_caps], CAPS_PSE
  37.            jnc .no_PSE
  38.  
  39.            mov ebx, cr4
  40.            or ebx, CR4_PSE
  41.            mov eax, PG_LARGE+PG_SW
  42.            bt [cpu_caps], CAPS_PGE
  43.            jnc @F
  44.            or eax, PG_GLOBAL
  45.            or ebx, CR4_PGE
  46. @@:
  47.            mov cr4, ebx
  48.  
  49.            mov dword [sys_pgdir], eax
  50.            add eax, 0x00400000
  51.            mov dword [sys_pgdir+4], eax
  52.            add eax, 0x00400000
  53.            mov dword [sys_pgdir+8], eax
  54.  
  55.            mov dword [sys_pgdir+0x600], sys_pgdir+PG_SW
  56.  
  57.            mov ecx, [pg_data.kernel_tables]
  58.            sub ecx, 3 ;4
  59.            mov eax, tmp_page_tab+PG_SW
  60.            mov edi, sys_pgdir+12     ;16
  61.  
  62.            jmp .map_kernel_tabs
  63. .no_PSE:
  64.            mov eax, PG_SW
  65.            mov esi, tmp_page_tab
  66.            mov ecx, 3072/4;  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, 3072*4    ;4096*4  ;skip low kernel memory
  96. @@:
  97.            mov ecx, [pg_data.kernel_tables]
  98.            sub ecx, 3
  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, 384/4
  113.            xor eax,eax
  114.            cld
  115.            rep stosd
  116.  
  117.            not eax
  118.            mov ecx, [pg_data.pagemap_size]
  119.            sub ecx, 384
  120.            shr ecx, 2
  121.            rep stosd
  122.  
  123.            mov edi, sys_pgmap+384
  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, 3
  129. @@:
  130.            sub edx, 3072
  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+384
  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.            lea eax, [eax+ebx*8]
  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.            cmp dword [LFBAddress], -1
  285.            jne @f
  286.            mov [0x2f0000+0x901c],byte 2
  287.            stdcall kernel_alloc, 0x280000
  288.            mov [LFBAddress], eax
  289.            ret
  290. @@:
  291.            test [SCR_MODE],word 0100000000000000b
  292.            jnz @f
  293.            mov [0x2f0000+0x901c],byte 2
  294.            ret
  295. @@:
  296.            call map_LFB
  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.            mov dword [exp_lfb+4], esi
  309.  
  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.            bt [cpu_caps], CAPS_PGE
  328.            jnc @F
  329.            or dword [sys_pgdir+ecx], PG_GLOBAL
  330. @@:
  331.            mov eax, cr3       ;flush TLB
  332.            mov cr3, eax
  333.            ret
  334.  
  335. .map_page_tables:
  336.  
  337. @@:
  338.            call alloc_page
  339.            stdcall map_page_table, esi, eax
  340.            add esi, 0x00400000
  341.            dec edi
  342.            jnz @B
  343.  
  344.            mov eax, [LFBAddress]
  345.            mov esi, eax
  346.            shr esi, 10
  347.            add esi, pages_tab
  348.            or eax, PG_UW
  349.            mov ecx, [pg_count]
  350.            shr ecx, 2
  351. .map:
  352.            mov [esi], eax
  353.            add eax, 0x1000
  354.            mov [esi+4], eax
  355.            add eax, 0x1000
  356.            mov [esi+8], eax
  357.            add eax, 0x1000
  358.            mov [esi+12], eax
  359.            add eax, 0x1000
  360.            add esi, 16
  361.            sub ecx, 1
  362.            jnz .map
  363.  
  364.            mov eax, cr3       ;flush TLB
  365.            mov cr3, eax
  366.  
  367.            ret
  368. endp
  369.  
  370. align 4
  371. proc new_mem_resize stdcall, new_size:dword
  372.  
  373.            stdcall wait_mutex, pg_data.pg_mutex
  374.  
  375.            mov edi, [new_size]
  376.            add edi,4095
  377.            and edi,not 4095
  378.            mov [new_size], edi
  379.  
  380.            mov edx,[CURRENT_TASK]
  381.            shl edx,8
  382.            cmp [PROC_BASE+APPDATA.heap_base+edx],0
  383.            jne .exit
  384.  
  385.            mov esi, [PROC_BASE+APPDATA.mem_size+edx]
  386.            add esi, 4095
  387.            and esi, not 4095
  388.  
  389.            cmp edi, esi
  390.            jae .expand
  391.  
  392.            shr edi, 12
  393.            shr esi, 12
  394. @@:
  395.            mov eax, [pages_tab+0x00181000+edi*4]
  396.            test eax, 1
  397.            jz .next
  398.            mov dword [pages_tab+0x00181000+edi*4], 2
  399.            mov ebx, edi
  400.            shl ebx, 12
  401.            invlpg [ebx+std_application_base_address]
  402.            call free_page
  403.  
  404. .next:     add edi, 1
  405.            cmp edi, esi
  406.            jb @B
  407.  
  408. .update_size:
  409.  
  410.            mov ebx, [new_size]
  411.            mov    [PROC_BASE+0x8c+edx],ebx
  412.  
  413. ;search threads and update
  414. ;application memory size infomation
  415.            mov    ecx,[PROC_BASE+0xb8+edx]
  416.            mov    eax,2
  417.  
  418. .search_threads:
  419. ;eax = current slot
  420. ;ebx = new memory size
  421. ;ecx = page directory
  422.            cmp    eax,[TASK_COUNT]
  423.            jg     .search_threads_end
  424.            mov    edx,eax
  425.            shl    edx,5
  426.            cmp    word [CURRENT_TASK+edx+0xa],9 ;if slot empty?
  427.            jz     .search_threads_next
  428.            shl    edx,3
  429.            cmp    [PROC_BASE+edx+0xb8],ecx     ;if it is our thread?
  430.            jnz    .search_threads_next
  431.            mov    [PROC_BASE+edx+0x8c],ebx     ;update memory size
  432. .search_threads_next:
  433.            inc    eax
  434.            jmp    .search_threads
  435. .search_threads_end:
  436.            xor eax, eax
  437.            dec [pg_data.pg_mutex]
  438.            ret
  439.  
  440. .expand:
  441.            add edi, new_app_base
  442.            add esi, new_app_base
  443.  
  444.            push esi
  445.            push edi
  446.  
  447.            add edi, 0x3FFFFF
  448.            and edi, not(0x3FFFFF)
  449.            add esi, 0x3FFFFF
  450.            and esi, not(0x3FFFFF)
  451.  
  452.            cmp esi, edi
  453.            jae .grow
  454.  
  455.            xchg esi, edi
  456.  
  457. @@:
  458.            call alloc_page
  459.            test eax, eax
  460.            jz .exit
  461.  
  462.            stdcall map_page_table, edi, eax
  463.  
  464.            push edi
  465.            shr edi, 10
  466.            add edi, pages_tab
  467.            mov ecx, 1024
  468.            xor eax, eax
  469.            cld
  470.            rep stosd
  471.            pop edi
  472.  
  473.            add edi, 0x00400000
  474.            cmp edi, esi
  475.            jb @B
  476. .grow:
  477.            pop edi
  478.            pop esi
  479. @@:
  480.            call alloc_page
  481.            test eax, eax
  482.            jz .exit
  483.            stdcall map_page,esi,eax,dword PG_UW
  484.  
  485.            push edi
  486.            mov edi, esi
  487.            xor eax, eax
  488.            mov ecx, 1024
  489.            cld
  490.            rep stosd
  491.            pop edi
  492.  
  493.            add esi, 0x1000
  494.            cmp esi, edi
  495.            jna @B
  496.  
  497.            jmp .update_size
  498. .exit:
  499.            xor eax, eax
  500.            inc eax
  501.            dec [pg_data.pg_mutex]
  502.            ret
  503. endp
  504.  
  505. align 4
  506. proc get_pg_addr stdcall, lin_addr:dword
  507.            mov ebx, [lin_addr]
  508.            shr ebx, 12
  509.            mov eax, [pages_tab+ebx*4]
  510.            and eax, 0xFFFFF000
  511.            ret
  512. endp
  513.  
  514. align 4
  515. proc page_fault_handler
  516.            pushad
  517.  
  518.            mov ebp, esp
  519.            mov eax, cr2
  520.            push eax
  521.            push ds
  522.            push es
  523.  
  524.            mov ax, 0x10
  525.            mov ds, ax
  526.            mov es, ax
  527.  
  528.            inc [pg_data.pages_faults]
  529.  
  530.            mov ebx, [ebp-4]
  531.  
  532.            cmp ebx, 0xe0000000
  533.            jae .lfb_addr
  534.  
  535.            cmp ebx, 0x60400000
  536.            jae .user_space
  537.  
  538.            cmp ebx, master_tab+0x1000
  539.            jae .alloc
  540.  
  541.            cmp ebx, 0x60000000
  542.            jae .tab_space
  543.  
  544.            jmp .kernel_space
  545.  
  546. .user_space:
  547.            shr ebx, 12
  548.            mov ecx, ebx
  549.            shr ecx, 10
  550.            mov edx, [master_tab+ecx*4]
  551.            test edx, 1
  552.            jz .fail
  553.  
  554.            mov eax, [pages_tab+ebx*4]
  555.            test eax, 2
  556.            jz .fail
  557. .alloc:
  558.            call alloc_page
  559.            and eax, eax
  560.            jz .exit
  561.  
  562.            stdcall map_page,[ebp-4],eax,dword PG_UW
  563.  
  564.            mov edi, [ebp-4]
  565.            and edi, 0xFFFFF000
  566.            mov ecx, 1024
  567.            xor eax, eax
  568.            cld
  569.            rep stosd
  570. .exit:
  571.            pop es
  572.            pop ds
  573.            mov esp, ebp
  574.            popad
  575.            add esp, 4
  576.            iretd
  577. .fail:
  578.            pop es
  579.            pop ds
  580.            mov esp, ebp
  581.            popad
  582.            add esp, 4
  583.  
  584.            save_ring3_context     ;debugger support
  585.  
  586.            mov bl, 14
  587.            jmp exc_c
  588.            iretd
  589.  
  590. .kernel_space:
  591. ;           shr ebx, 12
  592. ;           mov eax, [pages_tab+ebx*4]
  593. ;           shr ebx, 10
  594. ;           mov eax, [master_tab+ebx*4]
  595.            jmp .exit
  596. .old_addr:
  597. ;           shr ebx, 12
  598. ;           mov eax, [pages_tab+ebx*4]
  599. ;           shr ebx, 10
  600. ;           mov eax, [master_tab+ebx*4]
  601.            jmp .exit
  602. .lfb_addr:
  603. ;           shr ebx, 22
  604. ;           ;mov ecx, [sys_page_dir]
  605. ;           mov eax, [master_tab+ebx*4]
  606.            jmp .exit
  607. .tab_space:
  608. ;           shr ebx, 12
  609. ;           mov eax, [pages_tab+ebx*4]
  610. ;           shr ebx, 10
  611. ;           ;mov ecx, [sys_page_dir]
  612. ;           mov eax, [master_tab+ebx*4]
  613.            jmp .exit
  614. endp
  615.  
  616. align 4
  617. proc map_mem stdcall, lin_addr:dword,pdir:dword,\
  618.                       ofs:dword,buf_size:dword
  619.            mov eax, [buf_size]
  620.            test eax, eax
  621.            jz .exit
  622.  
  623.            mov eax, [pdir]
  624.            and eax, 0xFFFFF000
  625.  
  626.            stdcall map_page,[ipc_pdir],eax,dword PG_UW
  627.            mov ebx, [ofs]
  628.            shr ebx, 22
  629.            mov esi, [ipc_pdir]
  630.            mov edi, [ipc_ptab]
  631.            mov eax, [esi+ebx*4]
  632.            and eax, 0xFFFFF000
  633.            test eax, eax
  634.            jz .exit
  635.            stdcall map_page,edi,eax,dword PG_UW
  636. ;           inc ebx
  637. ;           add edi, 0x1000
  638. ;           mov eax, [esi+ebx*4]
  639. ;           test eax, eax
  640. ;           jz @f
  641. ;          and eax, 0xFFFFF000
  642. ;           stdcall map_page, edi, eax
  643.  
  644. @@:        mov edi, [lin_addr]
  645.            and edi, 0xFFFFF000
  646.            mov ecx, [buf_size]
  647.            add ecx, 4095
  648.            shr ecx, 12
  649.            inc ecx
  650.  
  651.            mov edx, [ofs]
  652.            shr edx, 12
  653.            and edx, 0x3FF
  654.            mov esi, [ipc_ptab]
  655.  
  656. .map:      mov eax, [esi+edx*4]
  657.            and eax, 0xFFFFF000
  658.            test eax, eax
  659.            jz .exit
  660.            stdcall map_page,edi,eax,dword PG_UW
  661.            add edi, 0x1000
  662.            inc edx
  663.            dec ecx
  664.            jnz .map
  665.  
  666. .exit:
  667.            ret
  668. endp
  669.  
  670. align 4
  671. proc map_memEx stdcall, lin_addr:dword,pdir:dword,\
  672.                         ofs:dword,buf_size:dword
  673.            mov eax, [buf_size]
  674.            test eax, eax
  675.            jz .exit
  676.  
  677.            mov eax, [pdir]
  678.            and eax, 0xFFFFF000
  679.  
  680.            stdcall map_page,[proc_mem_pdir],eax,dword PG_UW
  681.            mov ebx, [ofs]
  682.            shr ebx, 22
  683.            mov esi, [proc_mem_pdir]
  684.            mov edi, [proc_mem_tab]
  685.            mov eax, [esi+ebx*4]
  686.            and eax, 0xFFFFF000
  687.            test eax, eax
  688.            jz .exit
  689.            stdcall map_page,edi,eax,dword PG_UW
  690.  
  691. @@:        mov edi, [lin_addr]
  692.            and edi, 0xFFFFF000
  693.            mov ecx, [buf_size]
  694.            add ecx, 4095
  695.            shr ecx, 12
  696.            inc ecx
  697.  
  698.            mov edx, [ofs]
  699.            shr edx, 12
  700.            and edx, 0x3FF
  701.            mov esi, [proc_mem_tab]
  702.  
  703. .map:      mov eax, [esi+edx*4]
  704. ;           and eax, 0xFFFFF000
  705. ;           test eax, eax
  706. ;           jz .exit
  707.            stdcall map_page,edi,eax,dword PG_UW
  708.            add edi, 0x1000
  709.            inc edx
  710.            dec ecx
  711.            jnz .map
  712. .exit:
  713.            ret
  714. endp
  715.  
  716.  
  717.  
  718.  
  719. sys_IPC:
  720. ;input:
  721. ;  eax=1 - set ipc buffer area
  722. ;    ebx=address of buffer
  723. ;    ecx=size of buffer
  724. ;  eax=2 - send message
  725. ;    ebx=PID
  726. ;    ecx=address of message
  727. ;    edx=size of message
  728.  
  729.            cmp  eax,1
  730.            jne @f
  731.            call set_ipc_buff
  732.            mov [esp+36], eax
  733.            ret
  734. @@:
  735.            cmp eax, 2
  736.            jne @f
  737.            stdcall sys_ipc_send, ebx, ecx, edx
  738.            mov [esp+36], eax
  739.            ret
  740. @@:
  741.            xor eax, eax
  742.            not eax
  743.            mov [esp+36], eax
  744.            ret
  745.  
  746. align 4
  747. proc set_ipc_buff
  748.  
  749.            mov  eax,[CURRENT_TASK]
  750.            shl  eax,8
  751.            add  eax, PROC_BASE
  752.            pushf
  753.            cli
  754.            mov  [eax+0xA0],ebx     ;set fields in extended information area
  755.            mov  [eax+0xA4],ecx
  756.  
  757.            add ebx,  new_app_base
  758.            add ecx, ebx
  759.            add ecx, 4095
  760.            and ecx, not 4095
  761.  
  762. .touch:    mov eax, [ebx]
  763.            add ebx, 0x1000
  764.            cmp ebx, ecx
  765.            jna .touch
  766.  
  767.            popf
  768.            xor eax, eax
  769.            ret
  770. endp
  771.  
  772. proc sys_ipc_send stdcall, PID:dword, msg_addr:dword, msg_size:dword
  773.            locals
  774.              dst_slot   dd ?
  775.              dst_offset dd ?
  776.              buf_size   dd ?
  777.            endl
  778.  
  779.            pushf
  780.            cli
  781.  
  782.            mov  eax, [PID]
  783.            call pid_to_slot
  784.            test eax,eax
  785.            jz   .no_pid
  786.  
  787.            mov [dst_slot], eax
  788.            shl  eax,8
  789.            mov  edi,[eax+PROC_BASE+0xa0]  ;is ipc area defined?
  790.            test edi,edi
  791.            jz   .no_ipc_area
  792.  
  793.            mov ebx, edi
  794.            add edi, new_app_base
  795.            and ebx, 0xFFF
  796.            mov [dst_offset], ebx
  797.  
  798.            mov esi, [eax+PROC_BASE+0xa4]
  799.            mov [buf_size], esi
  800.  
  801.            stdcall map_mem, [ipc_tmp], [PROC_BASE+eax+0xB8],\
  802.                              edi, esi
  803.  
  804.            mov edi, [dst_offset]
  805.            add edi, [ipc_tmp]
  806.            cmp dword [edi], 0
  807.            jnz  .ipc_blocked          ;if dword [buffer]<>0 - ipc blocked now
  808.  
  809.            mov ebx, dword [edi+4]
  810.            mov edx, ebx
  811.            add ebx, 8
  812.            add ebx, [msg_size]
  813.            cmp ebx, [buf_size]
  814.            ja .buffer_overflow         ;esi<0 - not enough memory in buffer
  815.  
  816.            mov dword [edi+4], ebx
  817.            mov eax,[TASK_BASE]
  818.            mov eax, [eax+0x04]         ;eax - our PID
  819.            mov edi, [dst_offset]
  820.            add edi, [ipc_tmp]
  821.            add edi, edx
  822.            mov [edi], eax
  823.            mov ecx, [msg_size]
  824.  
  825.            mov [edi+4], ecx
  826.            add edi, 8
  827.            mov esi, [msg_addr]
  828.            add esi, new_app_base
  829.            cld
  830.            rep movsb
  831.  
  832.            mov ebx, [ipc_tmp]
  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_pdir]
  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 ebx, [ipc_ptab]
  847.            mov edx, ebx
  848.            shr ebx, 12
  849.            xor eax, eax
  850.            mov [pages_tab+ebx*4], eax
  851.            invlpg [edx]
  852.  
  853.            mov  eax, [dst_slot]
  854.            shl eax, 8
  855.            or   [eax+PROC_BASE+0xA8],dword 0x40
  856.            cmp  dword [check_idle_semaphore],20
  857.            jge  .ipc_no_cis
  858.  
  859.            mov  dword [check_idle_semaphore],5
  860. .ipc_no_cis:
  861.            popf
  862.            xor eax, eax
  863.            ret
  864. .no_pid:
  865.            popf
  866.            mov  eax, 4
  867.            ret
  868. .no_ipc_area:
  869.            popf
  870.            xor eax, eax
  871.            inc eax
  872.            ret
  873. .ipc_blocked:
  874.            popf
  875.            mov  eax, 2
  876.            ret
  877. .buffer_overflow:
  878.            popf
  879.            mov  eax, 3
  880.            ret
  881. endp
  882.  
  883. align 4
  884. sysfn_meminfo:
  885.  
  886.            add ebx, new_app_base
  887.            cmp ebx, new_app_base
  888.            jb .fail
  889.  
  890.            mov eax, [pg_data.pages_count]
  891.            mov [ebx], eax
  892.            shl eax, 12
  893.            mov [esp+36], eax
  894.            mov ecx, [pg_data.pages_free]
  895.            mov [ebx+4], ecx
  896.            mov edx, [pg_data.pages_faults]
  897.            mov [ebx+8], edx
  898.            mov esi, [heap_size]
  899.            mov [ebx+12], esi
  900.            mov edi, [heap_free]
  901.            mov [ebx+16], edi
  902.            mov eax, [heap_blocks]
  903.            mov [ebx+20], eax
  904.            mov ecx, [free_blocks]
  905.            mov [ebx+24], ecx
  906.            ret
  907. .fail:
  908.            mov dword [esp+36], -1
  909.            ret
  910.  
  911. align 4
  912. new_services:
  913.  
  914.            cmp  eax,4
  915.            jle  sys_sheduler
  916.  
  917.            cmp eax, 11
  918.            jb .fail
  919.            ja @f
  920.  
  921.            call init_heap
  922.            mov [esp+36], eax
  923.            ret
  924. @@:
  925.            cmp eax, 12
  926.            ja @f
  927.  
  928.            stdcall user_alloc, ebx
  929.            mov [esp+36], eax
  930.            ret
  931. @@:
  932.            cmp eax, 13
  933.            ja @f
  934.            add ebx, new_app_base
  935.            stdcall user_free, ebx
  936.            mov [esp+36], eax
  937.            ret
  938. @@:
  939.            cmp eax, 14
  940.            ja @f
  941.            add ebx, new_app_base
  942.            cmp ebx, new_app_base
  943.            jb .fail
  944.            stdcall get_event_ex, ebx, ecx
  945.            mov [esp+36], eax
  946.            ret
  947. @@:
  948.            cmp eax, 15
  949.            ja @f
  950.            mov ecx, [CURRENT_TASK]
  951.            shl ecx, 8
  952.            mov eax, [ecx+PROC_BASE+APPDATA.fpu_handler]
  953.            mov [ecx+PROC_BASE+APPDATA.fpu_handler], ebx
  954.            mov [esp+36], eax
  955.            ret
  956. @@:
  957.            cmp eax, 16
  958.            ja @f
  959.  
  960.            test ebx, ebx
  961.            jz .fail
  962.            add ebx, new_app_base
  963.            cmp ebx, new_app_base
  964.            jb .fail
  965.            stdcall get_service, ebx
  966.            mov [esp+36], eax
  967.            ret
  968. @@:
  969.            cmp eax, 17
  970.            ja @f
  971.            stdcall srv_handlerEx, ebx
  972.            mov [esp+36], eax
  973.            ret
  974. @@:
  975.            cmp eax, 18
  976.            ja @f
  977.            mov ecx, [CURRENT_TASK]
  978.            shl ecx, 8
  979.            mov eax, [ecx+PROC_BASE+APPDATA.sse_handler]
  980.            mov [ecx+PROC_BASE+APPDATA.sse_handler], ebx
  981.            mov [esp+36], eax
  982.            ret
  983. @@:
  984.            cmp eax, 19
  985.            ja .fail
  986.            add ebx, new_app_base
  987.            cmp ebx, new_app_base
  988.            jb .fail
  989.            stdcall load_library, ebx
  990.            mov [esp+36], eax
  991.            ret
  992.  
  993. .fail:
  994.            xor eax, eax
  995.            mov [esp+36], eax
  996.            ret
  997.  
  998. align 4
  999. proc strncmp stdcall, str1:dword, str2:dword, count:dword
  1000.  
  1001.           mov ecx,[count]
  1002.           jecxz .end
  1003.  
  1004.           mov ebx,ecx
  1005.  
  1006.           mov edi,[str1]
  1007.           mov esi,edi
  1008.           xor eax,eax
  1009.           repne scasb
  1010.           neg ecx             ; cx = count - strlen
  1011.           add ecx,ebx         ; strlen + count - strlen
  1012.  
  1013. .okay:
  1014.           mov edi,esi
  1015.           mov esi,[str2]
  1016.           repe cmpsb
  1017.           mov al,[esi-1]
  1018.           xor ecx,ecx
  1019.  
  1020.           cmp al,[edi-1]
  1021.           ja .str2_big
  1022.           je .end
  1023.  
  1024. .str1_big:
  1025.           sub ecx,2
  1026.  
  1027. .str2_big:
  1028.           not ecx
  1029. .end:
  1030.           mov eax,ecx
  1031.           ret
  1032. endp
  1033.  
  1034. align 4
  1035. proc test_cpu
  1036.            locals
  1037.               cpu_type   dd ?
  1038.               cpu_id     dd ?
  1039.               cpu_Intel  dd ?
  1040.               cpu_AMD    dd ?
  1041.            endl
  1042.  
  1043.            mov [cpu_type], 0
  1044.            xor eax, eax
  1045.            mov [cpu_caps], eax
  1046.            mov [cpu_caps+4], eax
  1047.  
  1048.            pushfd
  1049.            pop eax
  1050.            mov ecx, eax
  1051.            xor eax, 0x40000
  1052.            push eax
  1053.            popfd
  1054.            pushfd
  1055.            pop eax
  1056.            xor eax, ecx
  1057.            mov [cpu_type], CPU_386
  1058.            jz .end_cpuid
  1059.            push ecx
  1060.            popfd
  1061.  
  1062.            mov [cpu_type], CPU_486
  1063.            mov eax, ecx
  1064.            xor eax, 0x200000
  1065.            push eax
  1066.            popfd
  1067.            pushfd
  1068.            pop eax
  1069.            xor eax, ecx
  1070.            je .end_cpuid
  1071.            mov [cpu_id], 1
  1072.  
  1073.            xor eax, eax
  1074.            cpuid
  1075.            mov [cpu_vendor], ebx
  1076.            mov [cpu_vendor+4], edx
  1077.            mov [cpu_vendor+8], ecx
  1078.            cmp ebx, dword [intel_str]
  1079.            jne .check_AMD
  1080.            cmp edx, dword [intel_str+4]
  1081.            jne .check_AMD
  1082.            cmp ecx, dword [intel_str+8]
  1083.            jne .check_AMD
  1084.            mov [cpu_Intel], 1
  1085.            cmp eax, 1
  1086.            jl .end_cpuid
  1087.            mov eax, 1
  1088.            cpuid
  1089.            mov [cpu_sign], eax
  1090.            mov [cpu_info],  ebx
  1091.            mov [cpu_caps],  edx
  1092.            mov [cpu_caps+4],ecx
  1093.  
  1094.            shr eax, 8
  1095.            and eax, 0x0f
  1096.            ret
  1097. .end_cpuid:
  1098.            mov eax, [cpu_type]
  1099.            ret
  1100.  
  1101. .check_AMD:
  1102.            cmp ebx, dword [AMD_str]
  1103.            jne .unknown
  1104.            cmp edx, dword [AMD_str+4]
  1105.            jne .unknown
  1106.            cmp ecx, dword [AMD_str+8]
  1107.            jne .unknown
  1108.            mov [cpu_AMD], 1
  1109.            cmp eax, 1
  1110.            jl .unknown
  1111.            mov eax, 1
  1112.            cpuid
  1113.            mov [cpu_sign], eax
  1114.            mov [cpu_info],  ebx
  1115.            mov [cpu_caps],  edx
  1116.            mov [cpu_caps+4],ecx
  1117.            shr eax, 8
  1118.            and eax, 0x0f
  1119.            ret
  1120. .unknown:
  1121.            mov eax, 1
  1122.            cpuid
  1123.            mov [cpu_sign], eax
  1124.            mov [cpu_info],  ebx
  1125.            mov [cpu_caps],  edx
  1126.            mov [cpu_caps+4],ecx
  1127.            shr eax, 8
  1128.            and eax, 0x0f
  1129.            ret
  1130. endp
  1131.  
  1132. MEM_WB     equ 6               ;write-back memory
  1133. MEM_WC     equ 1               ;write combined memory
  1134. MEM_UC     equ 0               ;uncached memory
  1135.  
  1136. align 4
  1137. proc init_mtrr
  1138.  
  1139.            cmp [0x2f0000+0x901c],byte 2
  1140.            je  .exit
  1141.  
  1142.            bt [cpu_caps], CAPS_MTRR
  1143.            jnc .exit
  1144.  
  1145.            mov eax, cr0
  1146.            or eax, 0x60000000   ;disable caching
  1147.            mov cr0, eax
  1148.            wbinvd               ;invalidate cache
  1149.  
  1150.            mov ecx, 0x2FF
  1151.            rdmsr                ;
  1152.            push eax
  1153.  
  1154.            xor edx, edx
  1155.            xor eax, eax
  1156.            mov ecx, 0x2FF
  1157.            wrmsr                ;disable all MTRR
  1158.  
  1159.            stdcall set_mtrr, dword 0,dword 0,[MEM_AMOUNT],MEM_WB
  1160.            stdcall set_mtrr, dword 1,[LFBAddress],[LFBSize],MEM_WC
  1161.            xor edx, edx
  1162.            xor eax, eax
  1163.            mov ecx, 0x204
  1164.            mov ebx, 6
  1165. @@:
  1166.            wrmsr                ;disable unused MTRR
  1167.            inc ecx
  1168.            wrmsr
  1169.            inc ecx
  1170.            dec ebx
  1171.            jnz @b
  1172.  
  1173.            wbinvd               ;again invalidate
  1174.  
  1175.            pop eax
  1176.            or eax, 0x800        ;set default memtype to UC
  1177.            and al, 0xF0
  1178.            mov ecx, 0x2FF
  1179.            wrmsr                ;and enable MTRR
  1180.  
  1181.            mov eax, cr0
  1182.            and eax, not 0x60000000
  1183.            mov cr0, eax         ; enable caching
  1184. .exit:
  1185.            ret
  1186. endp
  1187.  
  1188. align 4
  1189. proc set_mtrr stdcall, reg:dword,base:dword,size:dword,mem_type:dword
  1190.  
  1191.            xor edx, edx
  1192.            mov eax, [base]
  1193.            or eax, [mem_type]
  1194.            mov ecx, [reg]
  1195.            lea ecx, [0x200+ecx*2]
  1196.            wrmsr
  1197.  
  1198.            mov ebx, [size]
  1199.            dec ebx
  1200.            mov eax, 0xFFFFFFFF
  1201.            mov edx, 0x0000000F
  1202.            sub eax, ebx
  1203.            sbb edx, 0
  1204.            or eax, 0x800
  1205.            inc ecx
  1206.            wrmsr
  1207.            ret
  1208. endp
  1209.  
  1210. align 4
  1211. proc stall stdcall, delay:dword
  1212.            push ecx
  1213.            push edx
  1214.            push ebx
  1215.            push eax
  1216.  
  1217.            mov eax, [delay]
  1218.            mul [stall_mcs]
  1219.            mov ebx, eax       ;low
  1220.            mov ecx, edx       ;high
  1221.            rdtsc
  1222.            add ebx, eax
  1223.            adc ecx,edx
  1224. @@:
  1225.            rdtsc
  1226.            sub eax, ebx
  1227.            sbb edx, ecx
  1228.            jb @B
  1229.  
  1230.            pop eax
  1231.            pop ebx
  1232.            pop edx
  1233.            pop ecx
  1234.            ret
  1235. endp
  1236.  
  1237. iglobal
  1238. align 4
  1239.   intel_str    db "GenuineIntel",0
  1240.   AMD_str      db "AuthenticAMD",0
  1241. endg
  1242.  
  1243. uglobal
  1244. align 16
  1245.   irq_tab           rd 16
  1246.  
  1247.  
  1248.   MEM_FreeSpace     rd 1
  1249.  
  1250.   ipc_tmp           rd 1
  1251.   ipc_pdir          rd 1
  1252.   ipc_ptab          rd 1
  1253.  
  1254.   proc_mem_map      rd 1
  1255.   proc_mem_pdir     rd 1
  1256.   proc_mem_tab      rd 1
  1257.  
  1258.   tmp_task_pdir     rd 1
  1259.   tmp_task_ptab     rd 1
  1260.   tmp_task_data     rd 1
  1261.  
  1262.   fpu_data          rd 1
  1263.   fdd_buff          rd 1
  1264.   LFBSize           rd 1
  1265.  
  1266.   stall_mcs         rd 1
  1267. ;;CPUID information
  1268.  
  1269.   cpu_vendor        rd 3
  1270.   cpu_sign          rd 1
  1271.   cpu_info          rd 1
  1272.  
  1273. ;;;;;   cursors data
  1274.  
  1275. align 16
  1276. cur_saved_data   rb 4096
  1277.  
  1278. cursors          rb CURSOR_SIZE*64
  1279. cursor_map       rd 2
  1280. cursor_start     rd 1
  1281. cursor_end       rd 1
  1282.  
  1283. def_cursor       rd 1
  1284. hw_cursor        rd 1
  1285.  
  1286. scr_width        rd 1
  1287. scr_height       rd 1
  1288.  
  1289. cur_def_interl   rd 1
  1290. cur_saved_base   rd 1
  1291. cur_saved_interl rd 1
  1292. cur_saved_w      rd 1
  1293. cur_saved_h      rd 1
  1294.  
  1295. endg
  1296.  
  1297. uglobal
  1298. align 16
  1299.  
  1300.    dll_tab         rb 32*32
  1301.    srv_tab         rb 36*32
  1302.    mem_block_map   rb 512
  1303.    event_map       rb 128
  1304.    mem_block_list  rd 64
  1305.    mem_block_mask  rd 2
  1306.  
  1307.    dll_map         rd 1
  1308.    srv_map         rd 1
  1309.  
  1310.    mem_used_list   rd 1
  1311.    mem_block_arr   rd 1
  1312.    mem_block_start rd 1
  1313.    mem_block_end   rd 1
  1314.    heap_size       rd 1
  1315.    heap_free       rd 1
  1316.    heap_blocks     rd 1
  1317.    free_blocks     rd 1
  1318.  
  1319.    page_start      rd 1
  1320.    page_end        rd 1
  1321.    events          rd 1
  1322.    event_start     rd 1
  1323.    event_end       rd 1
  1324.  
  1325.    sys_page_map    rd 1
  1326. endg
  1327.  
  1328.  
  1329. ;     push eax
  1330. ;     push edx
  1331. ;     mov edx, 0x400   ;bocsh
  1332. ;     mov al,0xff      ;bocsh
  1333. ;     out dx, al       ;bocsh
  1334. ;     pop edx
  1335. ;     pop eax
  1336.  
  1337.  
  1338. align 4
  1339. k_strrchr:
  1340.         push eax
  1341.         xor eax,eax
  1342.         or  ecx,-1
  1343.         repne scasb
  1344.         add ecx,1
  1345.         neg ecx
  1346.         sub edi,1
  1347.         pop eax
  1348.         std
  1349.         repne scasb
  1350.         cld
  1351.         add edi,1
  1352.  
  1353.         cmp [edi],al
  1354.         jne @F
  1355.         mov eax,edi
  1356.         ret
  1357. @@:
  1358.         xor eax,eax
  1359.         ret
  1360.  
  1361. align 4
  1362. proc k_strncpy stdcall, dest:dword, src:dword, maxlen:dword
  1363.         mov eax, [dest]
  1364.         mov esi, [src]
  1365.         mov ecx, [maxlen]
  1366.         test eax, eax
  1367.         jz .L9
  1368.         test esi, esi
  1369.         jz .L9
  1370.         test ecx, ecx
  1371.         jz .L9
  1372.  
  1373.         sub  esi, eax
  1374.         jmp .L1
  1375.  
  1376. align 4
  1377. .L2:
  1378.         mov edx, [esi+eax]
  1379.         mov [eax], dl
  1380.         test dl, dl
  1381.         jz .L7
  1382.  
  1383.         mov [eax+1], dh
  1384.         test dh, dh
  1385.         jz .L6
  1386.  
  1387.         shr edx, 16
  1388.         mov [eax+2],dl
  1389.         test dl, dl
  1390.         jz .L5
  1391.  
  1392.         mov [eax+3], dh
  1393.         test dh, dh
  1394.         jz .L4
  1395.         add eax, 4
  1396. .L1:
  1397.         sub ecx, 4
  1398.         jae .L2
  1399.  
  1400.         add ecx, 4
  1401.         jz .L9
  1402.  
  1403.         mov dl, [eax+esi]
  1404.         mov [eax], dl
  1405.         test dl, dl
  1406.         jz .L3
  1407.  
  1408.         inc eax
  1409.         dec ecx
  1410.         jz .L9
  1411.  
  1412.         mov dl, [eax+esi]
  1413.         mov [eax], dl
  1414.         test dl, dl
  1415.         jz .L3
  1416.  
  1417.         inc eax
  1418.         dec ecx
  1419.         jz .L9
  1420.  
  1421.         mov dl, [eax+esi]
  1422.         mov [eax], dl
  1423.         test dl, dl
  1424.         jz .L3
  1425.  
  1426.         inc eax
  1427.         jmp .L9
  1428.  
  1429. .L4:    dec ecx
  1430.         inc eax
  1431.  
  1432. .L5:    dec ecx
  1433.         inc eax
  1434.  
  1435. .L6:    dec ecx
  1436.         inc eax
  1437. .L7:
  1438.         add ecx,3
  1439.         jz .L9
  1440. .L8:
  1441.         mov byte [ecx+eax], 0
  1442. .L3:
  1443.         dec ecx
  1444.         jnz .L8
  1445. .L9:
  1446.         ret
  1447. endp
  1448.  
  1449. if 0
  1450.  
  1451. magic equ 0xfefefeff
  1452.  
  1453. k_strlen:
  1454.         mov eax,[esp+4]
  1455.         mov edx, 3
  1456.  
  1457.         and edx, eax
  1458.         jz .L1
  1459.         jp .L0
  1460.  
  1461.         cmp dh, byte [eax]
  1462.         je .L2
  1463.  
  1464.         inc eax
  1465.         cmp dh, byte [eax]
  1466.  
  1467.         je .L2
  1468.  
  1469.         inc eax
  1470.         xor edx, 2
  1471.  
  1472.         jz .L1
  1473. .L0:
  1474.         cmp dh, [eax]
  1475.         je .L2
  1476.  
  1477.         inc eax
  1478.         xor edx, edx
  1479.  
  1480. .L1:
  1481.         mov ecx, [eax]
  1482.         add eax, 4
  1483.  
  1484.         sub edx, ecx
  1485.         add ecx, magic
  1486.  
  1487.         dec edx
  1488.         jnc .L3
  1489.  
  1490.         xor edx, ecx
  1491.         and edx, not magic
  1492.         jne .L3
  1493.  
  1494.         mov ecx, [eax]
  1495.         add eax, 4
  1496.  
  1497.         sub edx, ecx
  1498.         add ecx, magic
  1499.         dec edx
  1500.         jnc .L3
  1501.  
  1502.         xor edx, ecx
  1503.         and edx, not magic
  1504.         jne .L3
  1505.  
  1506.         mov ecx, [eax]
  1507.         add eax, 4
  1508.  
  1509.         sub edx, ecx
  1510.         add ecx, magic
  1511.  
  1512.         dec edx
  1513.         jnc .L3
  1514.  
  1515.         xor edx, ecx
  1516.  
  1517.         and edx, not magic
  1518.         jne .L3
  1519.  
  1520.         mov ecx, [eax]
  1521.         add eax, 4
  1522.  
  1523.         sub edx, ecx
  1524.         add ecx, magic
  1525.  
  1526.         dec edx
  1527.         jnc .L3
  1528.  
  1529.         xor edx, ecx
  1530.  
  1531.         and edx, not magic
  1532.         je .L1
  1533.  
  1534. .L3:    sub eax ,4
  1535.         sub ecx, magic
  1536.  
  1537.         cmp cl, 0
  1538.         jz .L2
  1539.  
  1540.         inc eax
  1541.         test ch, ch
  1542.         jz .L2
  1543.  
  1544.         shr ecx, 16
  1545.         inc eax
  1546.  
  1547.         cmp cl,0
  1548.         jz .L2
  1549.  
  1550.         inc eax
  1551.  
  1552. .L2:
  1553.         sub eax, [esp+4]
  1554.         ret
  1555.  
  1556. end if
  1557.