Subversion Repositories Kolibri OS

Rev

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