Subversion Repositories Kolibri OS

Rev

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