Subversion Repositories Kolibri OS

Rev

Rev 593 | Rev 660 | 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: 659 $
  9.  
  10.  
  11. align 4
  12. proc alloc_page
  13.  
  14.            pushfd
  15.            cli
  16.            mov ebx, [page_start]
  17.            mov ecx, [page_end]
  18. .l1:
  19.            bsf eax,[ebx];
  20.            jnz .found
  21.            add ebx,4
  22.            cmp ebx, ecx
  23.            jb .l1
  24.            popfd
  25.            xor eax,eax
  26.            ret
  27. .found:
  28.            btr [ebx], eax
  29.            mov [page_start],ebx
  30.            sub ebx, sys_pgmap
  31.            lea eax, [eax+ebx*8]
  32.            shl eax, 12
  33.            dec [pg_data.pages_free]
  34.            popfd
  35.            ret
  36. endp
  37.  
  38. align 4
  39. proc alloc_pages stdcall, count:dword
  40.            pushfd
  41.            cli
  42.            mov eax, [count]
  43.            add eax, 7
  44.            shr eax, 3
  45.            mov [count], eax
  46.            cmp eax, [pg_data.pages_free]
  47.            ja .fail
  48.  
  49.            mov ecx, [page_start]
  50.            mov ebx, [page_end]
  51. .find:
  52.            mov edx, [count]
  53.            mov edi, ecx
  54. .match:
  55.            cmp byte [ecx], 0xFF
  56.            jne .next
  57.            dec edx
  58.            jz .ok
  59.            inc ecx
  60.            cmp ecx,ebx
  61.            jb .match
  62. .fail:     xor eax, eax
  63.            popfd
  64.            ret
  65. .next:
  66.            inc ecx
  67.            cmp ecx, ebx
  68.            jb .find
  69.            popfd
  70.            xor eax, eax
  71.            ret
  72. .ok:
  73.            sub ecx, edi
  74.            inc ecx
  75.            mov esi, edi
  76.            xor eax, eax
  77.            rep stosb
  78.            sub esi, sys_pgmap
  79.            shl esi, 3+12
  80.            mov eax, esi
  81.            mov ebx, [count]
  82.            shl ebx, 3
  83.            sub [pg_data.pages_free], ebx
  84.            popfd
  85.            ret
  86. endp
  87.  
  88. align 4
  89. proc map_page stdcall,lin_addr:dword,phis_addr:dword,flags:dword
  90.            push ebx
  91.            mov eax, [phis_addr]
  92.            and eax, not 0xFFF
  93.            or eax, [flags]
  94.            mov ebx, [lin_addr]
  95.            shr ebx, 12
  96.            mov [page_tabs+ebx*4], eax
  97.            mov eax, [lin_addr]
  98.            invlpg [eax]
  99.            pop ebx
  100.            ret
  101. endp
  102.  
  103. align 4
  104. map_space:    ;not implemented
  105.  
  106.  
  107.            ret
  108.  
  109.  
  110. align 4
  111. proc free_page
  112. ;arg:  eax  page address
  113.            pushfd
  114.            cli
  115.            shr eax, 12              ;page index
  116.            bts dword [sys_pgmap], eax           ;that's all!
  117.            cmc
  118.            adc [pg_data.pages_free], 0
  119.            shr eax, 3
  120.            and eax, not 3           ;dword offset from page_map
  121.            add eax, sys_pgmap
  122.            cmp [page_start], eax
  123.            ja @f
  124.            popfd
  125.            ret
  126. @@:
  127.            mov [page_start], eax
  128.            popfd
  129.            ret
  130. endp
  131.  
  132. ; param
  133. ;  eax= page base + page flags
  134. ;  ebx= liear address
  135. ;  ecx= count
  136.  
  137. align 4
  138. commit_pages:
  139.  
  140.            test ecx, ecx
  141.            jz .fail
  142.  
  143.            mov edi, ebx
  144.            mov ebx, pg_data.pg_mutex
  145.            call wait_mutex      ;ebx
  146.  
  147.            mov edx, 0x1000
  148.            mov ebx, edi
  149.            shr ebx, 12
  150. @@:
  151.            mov [page_tabs+ebx*4], eax
  152.            invlpg [edi]
  153.            add edi, edx
  154.            add eax, edx
  155.            inc ebx
  156.            dec ecx
  157.            jnz @B
  158.            mov [pg_data.pg_mutex],ecx
  159. .fail:
  160.            ret
  161.  
  162.  
  163. ; param
  164. ;  eax= base
  165. ;  ecx= count
  166.  
  167. align 4
  168. release_pages:
  169.  
  170.            pushad
  171.            mov ebx, pg_data.pg_mutex
  172.            call wait_mutex      ;ebx
  173.  
  174.            mov esi, eax
  175.            mov edi, eax
  176.  
  177.            shr esi, 10
  178.            add esi, page_tabs
  179.  
  180.            mov ebp, [pg_data.pages_free]
  181.            mov ebx, [page_start]
  182.            mov edx, sys_pgmap
  183. @@:
  184.            xor eax, eax
  185.            xchg eax, [esi]
  186.            invlpg [edi]
  187.  
  188.            test eax, 1
  189.            jz .next
  190.  
  191.            shr eax, 12
  192.            bts [edx], eax
  193.            cmc
  194.            adc ebp, 0
  195.            shr eax, 3
  196.            and eax, -4
  197.            add eax, edx
  198.            cmp eax, ebx
  199.            jae .next
  200.  
  201.            mov ebx, eax
  202. .next:
  203.            add edi, 0x1000
  204.            add esi, 4
  205.            dec ecx
  206.            jnz @B
  207.            mov [pg_data.pages_free], ebp
  208.            and [pg_data.pg_mutex],0
  209.            popad
  210.            ret
  211.  
  212. align 4
  213. proc map_page_table stdcall, lin_addr:dword, phis_addr:dword
  214.            push ebx
  215.            mov ebx, [lin_addr]
  216.            shr ebx, 22
  217.            mov eax, [phis_addr]
  218.            and eax, not 0xFFF
  219.            or eax, PG_UW          ;+PG_NOCACHE
  220.            mov dword [master_tab+ebx*4], eax
  221.            mov eax, [lin_addr]
  222.            shr eax, 10
  223.            add eax, page_tabs
  224.            invlpg [eax]
  225.            pop ebx
  226.            ret
  227. endp
  228.  
  229. align 4
  230. proc init_LFB
  231.            locals
  232.              pg_count dd ?
  233.            endl
  234.  
  235.            cmp dword [LFBAddress], -1
  236.            jne @f
  237.            mov [BOOT_VAR+0x901c],byte 2
  238.            stdcall kernel_alloc, 0x280000
  239.            mov [LFBAddress], eax
  240.            ret
  241. @@:
  242.            test [SCR_MODE],word 0100000000000000b
  243.            jnz @f
  244.            mov [BOOT_VAR+0x901c],byte 2
  245.            ret
  246. @@:
  247.            call init_mtrr
  248.  
  249.            mov edx, LFB_BASE
  250.            mov esi, [LFBAddress]
  251.            mov edi, 0x00800000
  252.            mov dword [exp_lfb+4], edx
  253.  
  254.            shr edi, 12
  255.            mov [pg_count], edi
  256.            shr edi, 10
  257.  
  258.            bt [cpu_caps], CAPS_PSE
  259.            jnc .map_page_tables
  260.            or esi, PG_LARGE+PG_UW
  261.            mov edx, sys_pgdir+(LFB_BASE shr 20)
  262. @@:
  263.            mov [edx], esi
  264.            add edx, 4
  265.            add esi, 0x00400000
  266.            dec edi
  267.            jnz @B
  268.  
  269.            bt [cpu_caps], CAPS_PGE
  270.            jnc @F
  271.            or dword [sys_pgdir+(LFB_BASE shr 20)], PG_GLOBAL
  272. @@:
  273.            mov dword [LFBAddress], LFB_BASE
  274.            mov eax, cr3       ;flush TLB
  275.            mov cr3, eax
  276.            ret
  277.  
  278. .map_page_tables:
  279.  
  280. @@:
  281.            call alloc_page
  282.            stdcall map_page_table, edx, eax
  283.            add edx, 0x00400000
  284.            dec edi
  285.            jnz @B
  286.  
  287.            mov eax, [LFBAddress]
  288.            mov edi, page_tabs + (LFB_BASE shr 10)
  289.            or eax, PG_UW
  290.            mov ecx, [pg_count]
  291.            cld
  292. @@:
  293.            stosd
  294.            add eax, 0x1000
  295.            dec ecx
  296.            jnz @B
  297.  
  298.            mov dword [LFBAddress], LFB_BASE
  299.            mov eax, cr3       ;flush TLB
  300.            mov cr3, eax
  301.  
  302.            ret
  303. endp
  304.  
  305. align 4
  306. proc new_mem_resize stdcall, new_size:dword
  307.  
  308.            mov ebx, pg_data.pg_mutex
  309.            call wait_mutex    ;ebx
  310.  
  311.            mov edi, [new_size]
  312.            add edi,4095
  313.            and edi,not 4095
  314.            mov [new_size], edi
  315.  
  316.            mov edx,[current_slot]
  317.            cmp [edx+APPDATA.heap_base],0
  318.            jne .exit
  319.  
  320.            mov esi, [edx+APPDATA.mem_size]
  321.            add esi, 4095
  322.            and esi, not 4095
  323.  
  324.            cmp edi, esi
  325.            jae .expand
  326.  
  327.            shr edi, 12
  328.            shr esi, 12
  329. @@:
  330.            mov eax, [app_page_tabs+edi*4]
  331.            test eax, 1
  332.            jz .next
  333.            mov dword [app_page_tabs+edi*4], 2
  334.            mov ebx, edi
  335.            shl ebx, 12
  336.            invlpg [ebx]
  337.            call free_page
  338.  
  339. .next:     add edi, 1
  340.            cmp edi, esi
  341.            jb @B
  342.  
  343. .update_size:
  344.            mov     ebx, [new_size]
  345.            call    update_mem_size
  346.  
  347.            xor eax, eax
  348.            dec [pg_data.pg_mutex]
  349.            ret
  350. .expand:
  351.  
  352.            push esi
  353.            push edi
  354.  
  355.            add edi, 0x3FFFFF
  356.            and edi, not(0x3FFFFF)
  357.            add esi, 0x3FFFFF
  358.            and esi, not(0x3FFFFF)
  359.  
  360.            cmp esi, edi
  361.            jae .grow
  362.  
  363.            xchg esi, edi
  364.  
  365. @@:
  366.            call alloc_page
  367.            test eax, eax
  368.            jz .exit
  369.  
  370.            stdcall map_page_table, edi, eax
  371.  
  372.            push edi
  373.            shr edi, 10
  374.            add edi, page_tabs
  375.            mov ecx, 1024
  376.            xor eax, eax
  377.            cld
  378.            rep stosd
  379.            pop edi
  380.  
  381.            add edi, 0x00400000
  382.            cmp edi, esi
  383.            jb @B
  384. .grow:
  385.            pop edi
  386.            pop esi
  387. @@:
  388.            call alloc_page
  389.            test eax, eax
  390.            jz .exit
  391.            stdcall map_page,esi,eax,dword PG_UW
  392.  
  393.            push edi
  394.            mov edi, esi
  395.            xor eax, eax
  396.            mov ecx, 1024
  397.            cld
  398.            rep stosd
  399.            pop edi
  400.  
  401.            add esi, 0x1000
  402.            cmp esi, edi
  403.            jb  @B
  404.  
  405.            jmp .update_size
  406. .exit:
  407.            xor eax, eax
  408.            inc eax
  409.            dec [pg_data.pg_mutex]
  410.            ret
  411. endp
  412.  
  413. update_mem_size:
  414. ; in: edx = slot base
  415. ;     ebx = new memory size
  416. ; destroys eax,ecx,edx
  417.  
  418.            mov    [APPDATA.mem_size+edx],ebx
  419. ;search threads and update
  420. ;application memory size infomation
  421.            mov    ecx,[APPDATA.dir_table+edx]
  422.            mov    eax,2
  423.  
  424. .search_threads:
  425. ;eax = current slot
  426. ;ebx = new memory size
  427. ;ecx = page directory
  428.            cmp    eax,[TASK_COUNT]
  429.            jg     .search_threads_end
  430.            mov    edx,eax
  431.            shl    edx,5
  432.            cmp    word [CURRENT_TASK+edx+TASKDATA.state],9 ;if slot empty?
  433.            jz     .search_threads_next
  434.            shl    edx,3
  435.            cmp    [SLOT_BASE+edx+APPDATA.dir_table],ecx     ;if it is our thread?
  436.            jnz    .search_threads_next
  437.            mov    [SLOT_BASE+edx+APPDATA.mem_size],ebx     ;update memory size
  438. .search_threads_next:
  439.            inc    eax
  440.            jmp    .search_threads
  441. .search_threads_end:
  442.            ret
  443.  
  444. ; param
  445. ;  eax= linear address
  446. ;
  447. ; retval
  448. ;  eax= phisical page address
  449.  
  450. align 4
  451. get_pg_addr:
  452.            shr eax, 12
  453.            mov eax, [page_tabs+eax*4]
  454.            and eax, 0xFFFFF000
  455.            ret
  456.  
  457.  
  458. align 4
  459. proc page_fault_handler
  460.  
  461.         .err_code equ ebp+32
  462.         .err_addr equ ebp-4
  463.  
  464.            pushad
  465.            mov ebp, esp
  466.            mov eax, cr2
  467.            push eax
  468.  
  469.            mov ax, app_data
  470.            mov ds, ax
  471.            mov es, ax
  472.  
  473.            inc [pg_data.pages_faults]
  474.  
  475. ;     push eax
  476. ;     push edx
  477. ;     mov edx, 0x400   ;bochs
  478. ;     mov al,0xff      ;bochs
  479. ;     out dx, al       ;bochs
  480. ;     pop edx
  481. ;     pop eax
  482.  
  483.            mov ebx, [.err_addr]
  484.            mov eax, [.err_code]
  485.  
  486.            cmp ebx, OS_BASE
  487.            jb .user_space      ;ñòðàíèöà â ïàìÿòè ïðèëîæåíèÿ ;
  488.  
  489.            cmp ebx, page_tabs
  490.            jb .kernel_space    ;ñòðàíèöà â ïàìÿòè ÿäðà
  491.  
  492.            cmp ebx, kernel_tabs
  493.            jb .alloc;.app_tabs ;òàáëèöû ñòðàíèö ïðèëîæåíèÿ ;
  494.                                ;ïðîñòî ñîçäàäèì îäíó
  495.  
  496.            cmp ebx, LFB_BASE
  497.            jb .core_tabs       ;òàáëèöû ñòðàíèö ÿäðà
  498.                                ;Îøèáêà
  499. .lfb:
  500.                                ;îáëàñòü LFB
  501.                                ;Îøèáêà
  502.            jmp .fail
  503.  
  504. align 4
  505. .user_space:
  506.            test eax, PG_MAP
  507.            jnz .err_access     ;Ñòðàíèöà ïðèñóòñòâóåò
  508.                                ;Îøèáêà äîñòóïà ?
  509.  
  510.            shr ebx, 12
  511.            mov ecx, ebx
  512.            shr ecx, 10
  513.            mov edx, [master_tab+ecx*4]
  514.            test edx, PG_MAP
  515.            jz .fail            ;òàáëèöà ñòðàíèö íå ñîçäàíà
  516.                                ;íåâåðíûé àäðåñ â ïðîãðàììå
  517.  
  518.            mov eax, [page_tabs+ebx*4]
  519.            test eax, 2
  520.            jz .fail            ;àäðåñ íå çàðåçåðâèðîâàí äëÿ ;
  521.                                ;èñïîëüçîâàíèÿ. Îøèáêà
  522. .alloc:
  523.            call alloc_page
  524.            test eax, eax
  525.            jz .fail
  526.  
  527.            stdcall map_page,[ebp-4],eax,dword PG_UW
  528.  
  529.            mov edi, [ebp-4]
  530.            and edi, 0xFFFFF000
  531.            mov ecx, 1024
  532.            xor eax, eax
  533.            cld
  534.            rep stosd
  535. .exit:
  536.            mov esp, ebp
  537.            popad
  538.            add esp, 4
  539.            iretd
  540.  
  541. .err_access:
  542. ;íèêîãäà íå ïðîèñõîäèò
  543.            jmp .fail
  544.  
  545. .kernel_space:
  546.            test eax, PG_MAP
  547.            jz .fail        ;ñòðàíèöà íå ïðèñóòñòâóåò
  548.  
  549.            test eax, 4     ;U/S
  550.            jnz .fail       ;ïðèëîæåíèå îáðàòèëîñü ê ïàìÿòè
  551.                            ;ÿäðà
  552.            test eax, 8
  553.            jnz .fail       ;óñòàíîâëåí çàðåçåðâèðîâàííûé áèò
  554.                            ;â òàáëèöàõ ñòðàíèö. äîáàâëåíî â P4/Xeon
  555.  
  556. ;ïîïûòêà çàïèñè â çàùèù¸ííóþ ñòðàíèöó ÿäðà
  557.  
  558.            cmp ebx, tss._io_map_0
  559.            jb .fail
  560.  
  561.            cmp ebx, tss._io_map_0+8192
  562.            jae .fail
  563.  
  564. ; io permission map
  565. ; copy-on-write protection
  566.  
  567.            call alloc_page
  568.            test eax, eax
  569.            jz .fail
  570.  
  571.            push eax
  572.            stdcall map_page,[ebp-4],eax,dword PG_SW
  573.            pop eax
  574.            mov edi, [.err_addr]
  575.            and edi, -4096
  576.            lea esi, [edi+(not tss._io_map_0)+1]; -tss._io_map_0
  577.  
  578.            mov ebx, esi
  579.            shr ebx, 12
  580.            mov edx, [current_slot]
  581.            or eax, PG_SW
  582.            mov [edx+APPDATA.io_map+ebx*4], eax
  583.  
  584.            add esi, [default_io_map]
  585.            mov ecx, 4096/4
  586.            cld
  587.            rep movsd
  588.            jmp .exit
  589.  
  590.  
  591. ;íå îáðàáàòûâàåì. Îøèáêà
  592.  
  593. .core_tabs:
  594. .fail:
  595.            mov esp, ebp
  596.            popad
  597.            add esp, 4
  598.  
  599. ;           iretd
  600.  
  601.            save_ring3_context     ;debugger support
  602.  
  603.            mov bl, 14
  604.            jmp exc_c
  605.            iretd
  606. endp
  607.  
  608. align 4
  609. proc map_mem stdcall, lin_addr:dword,pdir:dword,\
  610.                       ofs:dword,buf_size:dword
  611.            mov eax, [buf_size]
  612.            test eax, eax
  613.            jz .exit
  614.  
  615.            mov eax, [pdir]
  616.            and eax, 0xFFFFF000
  617.  
  618.            stdcall map_page,[ipc_pdir],eax,PG_UW
  619.            mov ebx, [ofs]
  620.            shr ebx, 22
  621.            mov esi, [ipc_pdir]
  622.            mov edi, [ipc_ptab]
  623.            mov eax, [esi+ebx*4]
  624.            and eax, 0xFFFFF000
  625.            jz .exit
  626.            stdcall map_page,edi,eax,PG_UW
  627. ;           inc ebx
  628. ;           add edi, 0x1000
  629. ;           mov eax, [esi+ebx*4]
  630. ;           test eax, eax
  631. ;           jz @f
  632. ;          and eax, 0xFFFFF000
  633. ;           stdcall map_page, edi, eax
  634.  
  635. @@:        mov edi, [lin_addr]
  636.            and edi, 0xFFFFF000
  637.            mov ecx, [buf_size]
  638.            add ecx, 4095
  639.            shr ecx, 12
  640.            inc ecx
  641.  
  642.            mov edx, [ofs]
  643.            shr edx, 12
  644.            and edx, 0x3FF
  645.            mov esi, [ipc_ptab]
  646.  
  647. .map:      mov eax, [esi+edx*4]
  648.            and eax, 0xFFFFF000
  649.            jz  .exit
  650.            stdcall map_page,edi,eax,PG_UW
  651.            dec ecx
  652.            jz  .exit
  653.            add edi, 0x1000
  654.            inc edx
  655.            cmp edx, 0x400
  656.            jnz .map
  657.            inc ebx
  658.            mov eax, [ipc_pdir]
  659.            mov eax, [eax+ebx*4]
  660.            and eax, 0xFFFFF000
  661.            jz  .exit
  662.            stdcall map_page,esi,eax,PG_UW
  663.            xor edx, edx
  664.            jmp .map
  665.  
  666. .exit:
  667.            ret
  668. endp
  669.  
  670. align 4
  671. proc map_memEx stdcall, lin_addr:dword,pdir:dword,\
  672.                         ofs:dword,buf_size:dword
  673.            mov eax, [buf_size]
  674.            test eax, eax
  675.            jz .exit
  676.  
  677.            mov eax, [pdir]
  678.            and eax, 0xFFFFF000
  679.  
  680.            stdcall map_page,[proc_mem_pdir],eax,dword PG_UW
  681.            mov ebx, [ofs]
  682.            shr ebx, 22
  683.            mov esi, [proc_mem_pdir]
  684.            mov edi, [proc_mem_tab]
  685.            mov eax, [esi+ebx*4]
  686.            and eax, 0xFFFFF000
  687.            test eax, eax
  688.            jz .exit
  689.            stdcall map_page,edi,eax,dword PG_UW
  690.  
  691. @@:        mov edi, [lin_addr]
  692.            and edi, 0xFFFFF000
  693.            mov ecx, [buf_size]
  694.            add ecx, 4095
  695.            shr ecx, 12
  696.            inc ecx
  697.  
  698.            mov edx, [ofs]
  699.            shr edx, 12
  700.            and edx, 0x3FF
  701.            mov esi, [proc_mem_tab]
  702.  
  703. .map:      mov eax, [esi+edx*4]
  704. ;           and eax, 0xFFFFF000
  705. ;           test eax, eax
  706. ;           jz .exit
  707.            stdcall map_page,edi,eax,dword PG_UW
  708.            add edi, 0x1000
  709.            inc edx
  710.            dec ecx
  711.            jnz .map
  712. .exit:
  713.            ret
  714. endp
  715.  
  716.  
  717.  
  718.  
  719. sys_IPC:
  720. ;input:
  721. ;  eax=1 - set ipc buffer area
  722. ;    ebx=address of buffer
  723. ;    ecx=size of buffer
  724. ;  eax=2 - send message
  725. ;    ebx=PID
  726. ;    ecx=address of message
  727. ;    edx=size of message
  728.  
  729.            cmp  eax,1
  730.            jne @f
  731.            call set_ipc_buff
  732.            mov [esp+36], eax
  733.            ret
  734. @@:
  735.            cmp eax, 2
  736.            jne @f
  737.            stdcall sys_ipc_send, ebx, ecx, edx
  738.            mov [esp+36], eax
  739.            ret
  740. @@:
  741.            xor eax, eax
  742.            not eax
  743.            mov [esp+36], eax
  744.            ret
  745.  
  746. align 4
  747. proc set_ipc_buff
  748.  
  749.            mov  eax,[current_slot]
  750.            pushf
  751.            cli
  752.            mov  [eax+APPDATA.ipc_start],ebx     ;set fields in extended information area
  753.            mov  [eax+APPDATA.ipc_size],ecx
  754.  
  755.            add ecx, ebx
  756.            add ecx, 4095
  757.            and ecx, not 4095
  758.  
  759. .touch:    mov eax, [ebx]
  760.            add ebx, 0x1000
  761.            cmp ebx, ecx
  762.            jb  .touch
  763.  
  764.            popf
  765.            xor eax, eax
  766.            ret
  767. endp
  768.  
  769. proc sys_ipc_send stdcall, PID:dword, msg_addr:dword, msg_size:dword
  770.            locals
  771.              dst_slot   dd ?
  772.              dst_offset dd ?
  773.              buf_size   dd ?
  774.              used_buf   dd ?
  775.            endl
  776.  
  777.            pushf
  778.            cli
  779.  
  780.            mov  eax, [PID]
  781.            call pid_to_slot
  782.            test eax,eax
  783.            jz   .no_pid
  784.  
  785.            mov [dst_slot], eax
  786.            shl  eax,8
  787.            mov  edi,[eax+SLOT_BASE+0xa0]  ;is ipc area defined?
  788.            test edi,edi
  789.            jz   .no_ipc_area
  790.  
  791.            mov ebx, edi
  792.            and ebx, 0xFFF
  793.            mov [dst_offset], ebx
  794.  
  795.            mov esi, [eax+SLOT_BASE+0xa4]
  796.            mov [buf_size], esi
  797.  
  798.            mov ecx, [ipc_tmp]
  799.            cmp esi, 0x40000-0x1000 ; size of [ipc_tmp] minus one page
  800.            jbe @f
  801.            push eax esi edi
  802.            add esi,0x1000
  803.            stdcall alloc_kernel_space,esi
  804.            mov ecx, eax
  805.            pop edi esi eax
  806. @@:
  807.            mov [used_buf], ecx
  808.            stdcall map_mem, ecx, [SLOT_BASE+eax+0xB8],\
  809.                              edi, esi
  810.  
  811.            mov edi, [dst_offset]
  812.            add edi, [used_buf]
  813.            cmp dword [edi], 0
  814.            jnz  .ipc_blocked          ;if dword [buffer]<>0 - ipc blocked now
  815.  
  816.            mov edx, dword [edi+4]
  817.            lea ebx, [edx+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.