Subversion Repositories Kolibri OS

Rev

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