Subversion Repositories Kolibri OS

Rev

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