Subversion Repositories Kolibri OS

Rev

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

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