Subversion Repositories Kolibri OS

Rev

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