Subversion Repositories Kolibri OS

Rev

Rev 536 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

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