Subversion Repositories Kolibri OS

Rev

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