Subversion Repositories Kolibri OS

Rev

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