Subversion Repositories Kolibri OS

Rev

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