Subversion Repositories Kolibri OS

Rev

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