Subversion Repositories Kolibri OS

Rev

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