Subversion Repositories Kolibri OS

Rev

Rev 843 | Rev 848 | 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: 846 $
  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_pgdir+(LFB_BASE shr 20)], eax
  249.            add eax, 0x00400000
  250.            mov [sys_pgdir+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_pgdir+(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_pgdir + 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.            shr ebx, 22
  481.            mov edx, [master_tab + ebx*4]
  482.            test edx, PG_MAP
  483.            jz .check_ptab      ;òàáëèöà ñòðàíèö íå ñîçäàíà
  484.  
  485. .check_ptab:
  486.            mov edx, [sys_pgdir + ebx*4]
  487.            test edx, PG_MAP
  488.            jnz @F
  489.  
  490.            call alloc_page
  491.            test eax, eax
  492.            jz .fail
  493.  
  494.            lea edx, [eax + PG_UW]
  495.            lea edi, [eax + OS_BASE]
  496.            mov ecx, 1024
  497.            xor eax, eax
  498.            cld
  499.            rep stosd
  500.  
  501.            mov [sys_pgdir + ebx*4], edx
  502. @@:
  503.            mov [master_tab + ebx*4], edx
  504.            jmp .exit
  505.  
  506. align 4
  507. .user_space:
  508.            test eax, PG_MAP
  509.            jnz .err_access     ;Ñòðàíèöà ïðèñóòñòâóåò
  510.                                ;Îøèáêà äîñòóïà ?
  511.  
  512.            shr ebx, 12
  513.            mov ecx, ebx
  514.            shr ecx, 10
  515.            mov edx, [master_tab + ecx*4]
  516.            test edx, PG_MAP
  517.            jz .fail            ;òàáëèöà ñòðàíèö íå ñîçäàíà
  518.                                ;íåâåðíûé àäðåñ â ïðîãðàììå
  519.  
  520.            mov eax, [page_tabs+ebx*4]
  521.            test eax, 2
  522.            jz .fail            ;àäðåñ íå çàðåçåðâèðîâàí äëÿ ;
  523.                                ;èñïîëüçîâàíèÿ. Îøèáêà
  524. .alloc:
  525.            call alloc_page
  526.            test eax, eax
  527.            jz .fail
  528.  
  529.            stdcall map_page,[ebp-4],eax,dword PG_UW
  530.  
  531.            mov edi, [ebp-4]
  532.            and edi, 0xFFFFF000
  533.            mov ecx, 1024
  534.            xor eax, eax
  535.            cld
  536.            rep stosd
  537. .exit:
  538.            mov esp, ebp
  539.            popad
  540.            add esp, 4
  541.            iretd
  542.  
  543. .err_access:
  544. ;íèêîãäà íå ïðîèñõîäèò
  545.            jmp .fail
  546.  
  547. .kernel_space:
  548.            test eax, PG_MAP
  549.            jz .fail        ;ñòðàíèöà íå ïðèñóòñòâóåò
  550.  
  551.            test eax, 4     ;U/S
  552.            jnz .fail       ;ïðèëîæåíèå îáðàòèëîñü ê ïàìÿòè
  553.                            ;ÿäðà
  554.            test eax, 8
  555.            jnz .fail       ;óñòàíîâëåí çàðåçåðâèðîâàííûé áèò
  556.                            ;â òàáëèöàõ ñòðàíèö. äîáàâëåíî â P4/Xeon
  557.  
  558. ;ïîïûòêà çàïèñè â çàùèù¸ííóþ ñòðàíèöó ÿäðà
  559.  
  560.            cmp ebx, tss._io_map_0
  561.            jb .fail
  562.  
  563.            cmp ebx, tss._io_map_0+8192
  564.            jae .fail
  565.  
  566. ; io permission map
  567. ; copy-on-write protection
  568.  
  569.            call alloc_page
  570.            test eax, eax
  571.            jz .fail
  572.  
  573.            push eax
  574.            stdcall map_page,[ebp-4],eax,dword PG_SW
  575.            pop eax
  576.            mov edi, [.err_addr]
  577.            and edi, -4096
  578.            lea esi, [edi+(not tss._io_map_0)+1]; -tss._io_map_0
  579.  
  580.            mov ebx, esi
  581.            shr ebx, 12
  582.            mov edx, [current_slot]
  583.            or eax, PG_SW
  584.            mov [edx+APPDATA.io_map+ebx*4], eax
  585.  
  586.            add esi, [default_io_map]
  587.            mov ecx, 4096/4
  588.            cld
  589.            rep movsd
  590.            jmp .exit
  591.  
  592.  
  593. ;íå îáðàáàòûâàåì. Îøèáêà
  594.  
  595. .fail:
  596.            mov esp, ebp
  597.            popad
  598.            add esp, 4
  599.  
  600. ;           iretd
  601.  
  602.            save_ring3_context     ;debugger support
  603.  
  604.            mov bl, 14
  605.            jmp exc_c
  606.            iretd
  607. endp
  608.  
  609. align 4
  610. proc map_mem stdcall, lin_addr:dword,pdir:dword,\
  611.                       ofs:dword,buf_size:dword
  612.            mov eax, [buf_size]
  613.            test eax, eax
  614.            jz .exit
  615.  
  616.            mov eax, [pdir]
  617.            and eax, 0xFFFFF000
  618.  
  619.            stdcall map_page,[ipc_pdir],eax,PG_UW
  620.            mov ebx, [ofs]
  621.            shr ebx, 22
  622.            mov esi, [ipc_pdir]
  623.            mov edi, [ipc_ptab]
  624.            mov eax, [esi+ebx*4]
  625.            and eax, 0xFFFFF000
  626.            jz .exit
  627.            stdcall map_page,edi,eax,PG_UW
  628. ;           inc ebx
  629. ;           add edi, 0x1000
  630. ;           mov eax, [esi+ebx*4]
  631. ;           test eax, eax
  632. ;           jz @f
  633. ;          and eax, 0xFFFFF000
  634. ;           stdcall map_page, edi, eax
  635.  
  636. @@:        mov edi, [lin_addr]
  637.            and edi, 0xFFFFF000
  638.            mov ecx, [buf_size]
  639.            add ecx, 4095
  640.            shr ecx, 12
  641.            inc ecx
  642.  
  643.            mov edx, [ofs]
  644.            shr edx, 12
  645.            and edx, 0x3FF
  646.            mov esi, [ipc_ptab]
  647.  
  648. .map:      mov eax, [esi+edx*4]
  649.            and eax, 0xFFFFF000
  650.            jz  .exit
  651.            stdcall map_page,edi,eax,PG_UW
  652.            dec ecx
  653.            jz  .exit
  654.            add edi, 0x1000
  655.            inc edx
  656.            cmp edx, 0x400
  657.            jnz .map
  658.            inc ebx
  659.            mov eax, [ipc_pdir]
  660.            mov eax, [eax+ebx*4]
  661.            and eax, 0xFFFFF000
  662.            jz  .exit
  663.            stdcall map_page,esi,eax,PG_UW
  664.            xor edx, edx
  665.            jmp .map
  666.  
  667. .exit:
  668.            ret
  669. endp
  670.  
  671. align 4
  672. proc map_memEx stdcall, lin_addr:dword,pdir:dword,\
  673.                         ofs:dword,buf_size:dword
  674.            mov eax, [buf_size]
  675.            test eax, eax
  676.            jz .exit
  677.  
  678.            mov eax, [pdir]
  679.            and eax, 0xFFFFF000
  680.  
  681.            stdcall map_page,[proc_mem_pdir],eax,dword PG_UW
  682.            mov ebx, [ofs]
  683.            shr ebx, 22
  684.            mov esi, [proc_mem_pdir]
  685.            mov edi, [proc_mem_tab]
  686.            mov eax, [esi+ebx*4]
  687.            and eax, 0xFFFFF000
  688.            test eax, eax
  689.            jz .exit
  690.            stdcall map_page,edi,eax,dword PG_UW
  691.  
  692. @@:        mov edi, [lin_addr]
  693.            and edi, 0xFFFFF000
  694.            mov ecx, [buf_size]
  695.            add ecx, 4095
  696.            shr ecx, 12
  697.            inc ecx
  698.  
  699.            mov edx, [ofs]
  700.            shr edx, 12
  701.            and edx, 0x3FF
  702.            mov esi, [proc_mem_tab]
  703.  
  704. .map:      mov eax, [esi+edx*4]
  705. ;           and eax, 0xFFFFF000
  706. ;           test eax, eax
  707. ;           jz .exit
  708.            stdcall map_page,edi,eax,dword PG_UW
  709.            add edi, 0x1000
  710.            inc edx
  711.            dec ecx
  712.            jnz .map
  713. .exit:
  714.            ret
  715. endp
  716.  
  717.  
  718.  
  719.  
  720. sys_IPC:
  721. ;input:
  722. ;  eax=1 - set ipc buffer area
  723. ;    ebx=address of buffer
  724. ;    ecx=size of buffer
  725. ;  eax=2 - send message
  726. ;    ebx=PID
  727. ;    ecx=address of message
  728. ;    edx=size of message
  729.  
  730.            cmp  eax,1
  731.            jne @f
  732.            call set_ipc_buff
  733.            mov [esp+36], eax
  734.            ret
  735. @@:
  736.            cmp eax, 2
  737.            jne @f
  738.            stdcall sys_ipc_send, ebx, ecx, edx
  739.            mov [esp+36], eax
  740.            ret
  741. @@:
  742.            xor eax, eax
  743.            not eax
  744.            mov [esp+36], eax
  745.            ret
  746.  
  747. align 4
  748. proc set_ipc_buff
  749.  
  750.            mov  eax,[current_slot]
  751.            pushf
  752.            cli
  753.            mov  [eax+APPDATA.ipc_start],ebx     ;set fields in extended information area
  754.            mov  [eax+APPDATA.ipc_size],ecx
  755.  
  756.            add ecx, ebx
  757.            add ecx, 4095
  758.            and ecx, not 4095
  759.  
  760. .touch:    mov eax, [ebx]
  761.            add ebx, 0x1000
  762.            cmp ebx, ecx
  763.            jb  .touch
  764.  
  765.            popf
  766.            xor eax, eax
  767.            ret
  768. endp
  769.  
  770. proc sys_ipc_send stdcall, PID:dword, msg_addr:dword, msg_size:dword
  771.            locals
  772.              dst_slot   dd ?
  773.              dst_offset dd ?
  774.              buf_size   dd ?
  775.              used_buf   dd ?
  776.            endl
  777.  
  778.            pushf
  779.            cli
  780.  
  781.            mov  eax, [PID]
  782.            call pid_to_slot
  783.            test eax,eax
  784.            jz   .no_pid
  785.  
  786.            mov [dst_slot], eax
  787.            shl  eax,8
  788.            mov  edi,[eax+SLOT_BASE+0xa0]  ;is ipc area defined?
  789.            test edi,edi
  790.            jz   .no_ipc_area
  791.  
  792.            mov ebx, edi
  793.            and ebx, 0xFFF
  794.            mov [dst_offset], ebx
  795.  
  796.            mov esi, [eax+SLOT_BASE+0xa4]
  797.            mov [buf_size], esi
  798.  
  799.            mov ecx, [ipc_tmp]
  800.            cmp esi, 0x40000-0x1000 ; size of [ipc_tmp] minus one page
  801.            jbe @f
  802.            push eax esi edi
  803.            add esi,0x1000
  804.            stdcall alloc_kernel_space,esi
  805.            mov ecx, eax
  806.            pop edi esi eax
  807. @@:
  808.            mov [used_buf], ecx
  809.            stdcall map_mem, ecx, [SLOT_BASE+eax+0xB8],\
  810.                              edi, esi
  811.  
  812.            mov edi, [dst_offset]
  813.            add edi, [used_buf]
  814.            cmp dword [edi], 0
  815.            jnz  .ipc_blocked          ;if dword [buffer]<>0 - ipc blocked now
  816.  
  817.            mov edx, dword [edi+4]
  818.            lea ebx, [edx+8]
  819.            add ebx, [msg_size]
  820.            cmp ebx, [buf_size]
  821.            ja .buffer_overflow         ;esi<0 - not enough memory in buffer
  822.  
  823.            mov dword [edi+4], ebx
  824.            mov eax,[TASK_BASE]
  825.            mov eax, [eax+0x04]         ;eax - our PID
  826.            add edi, edx
  827.            mov [edi], eax
  828.            mov ecx, [msg_size]
  829.  
  830.            mov [edi+4], ecx
  831.            add edi, 8
  832.            mov esi, [msg_addr]
  833.        ;    add esi, new_app_base
  834.            cld
  835.            rep movsb
  836.  
  837.            mov ebx, [ipc_tmp]
  838.            mov edx, ebx
  839.            shr ebx, 12
  840.            xor eax, eax
  841.            mov [page_tabs+ebx*4], eax
  842.            invlpg [edx]
  843.  
  844.            mov ebx, [ipc_pdir]
  845.            mov edx, ebx
  846.            shr ebx, 12
  847.            xor eax, eax
  848.            mov [page_tabs+ebx*4], eax
  849.            invlpg [edx]
  850.  
  851.            mov ebx, [ipc_ptab]
  852.            mov edx, ebx
  853.            shr ebx, 12
  854.            xor eax, eax
  855.            mov [page_tabs+ebx*4], eax
  856.            invlpg [edx]
  857.  
  858.            mov  eax, [dst_slot]
  859.            shl eax, 8
  860.            or   [eax+SLOT_BASE+0xA8],dword 0x40
  861.            cmp  dword [check_idle_semaphore],20
  862.            jge  .ipc_no_cis
  863.  
  864.            mov  dword [check_idle_semaphore],5
  865. .ipc_no_cis:
  866.            push 0
  867.            jmp .ret
  868. .no_pid:
  869.            popf
  870.            mov eax, 4
  871.            ret
  872. .no_ipc_area:
  873.            popf
  874.            xor eax, eax
  875.            inc eax
  876.            ret
  877. .ipc_blocked:
  878.            push 2
  879.            jmp .ret
  880. .buffer_overflow:
  881.            push 3
  882. .ret:
  883.            mov eax, [used_buf]
  884.            cmp eax, [ipc_tmp]
  885.            jz @f
  886.            stdcall free_kernel_space,eax
  887. @@:
  888.            pop eax
  889.            popf
  890.            ret
  891. endp
  892.  
  893. align 4
  894. sysfn_meminfo:
  895.  
  896.         ;   add ebx, new_app_base
  897.            cmp ebx, OS_BASE
  898.            jae .fail
  899.  
  900.            mov eax, [pg_data.pages_count]
  901.            mov [ebx], eax
  902.            shl eax, 12
  903.            mov [esp+36], eax
  904.            mov ecx, [pg_data.pages_free]
  905.            mov [ebx+4], ecx
  906.            mov edx, [pg_data.pages_faults]
  907.            mov [ebx+8], edx
  908.            mov esi, [heap_size]
  909.            mov [ebx+12], esi
  910.            mov edi, [heap_free]
  911.            mov [ebx+16], edi
  912.            mov eax, [heap_blocks]
  913.            mov [ebx+20], eax
  914.            mov ecx, [free_blocks]
  915.            mov [ebx+24], ecx
  916.            ret
  917. .fail:
  918.            mov dword [esp+36], -1
  919.            ret
  920.  
  921. align 4
  922. new_services:
  923.  
  924.            cmp  eax,4
  925.            jle  sys_sheduler
  926.  
  927.            cmp eax, 11
  928.            jb .fail
  929.            ja @f
  930.  
  931.            call init_heap
  932.            mov [esp+36], eax
  933.            ret
  934. @@:
  935.            cmp eax, 12
  936.            ja @f
  937.  
  938.            stdcall user_alloc, ebx
  939.            mov [esp+36], eax
  940.            ret
  941. @@:
  942.            cmp eax, 13
  943.            ja @f
  944.            stdcall user_free, ebx
  945.            mov [esp+36], eax
  946.            ret
  947. @@:
  948.            cmp eax, 14
  949.            ja @f
  950.            cmp ebx, OS_BASE
  951.            jae .fail
  952.            stdcall get_event_ex, ebx, ecx
  953.            mov [esp+36], eax
  954.            ret
  955. @@:
  956.            cmp eax, 15
  957.            ja @f
  958.            mov ecx, [current_slot]
  959.            mov eax, [ecx+APPDATA.fpu_handler]
  960.            mov [ecx+APPDATA.fpu_handler], ebx
  961.            mov [esp+36], eax
  962.            ret
  963. @@:
  964.            cmp eax, 16
  965.            ja @f
  966.  
  967.            test ebx, ebx
  968.            jz .fail
  969.            cmp ebx, OS_BASE
  970.            jae .fail
  971.            stdcall get_service, ebx
  972.            mov [esp+36], eax
  973.            ret
  974. @@:
  975.            cmp eax, 17
  976.            ja @f
  977.            call srv_handlerEx   ;ebx
  978.            mov [esp+36], eax
  979.            ret
  980. @@:
  981.            cmp eax, 18
  982.            ja @f
  983.            mov ecx, [current_slot]
  984.            mov eax, [ecx+APPDATA.sse_handler]
  985.            mov [ecx+APPDATA.sse_handler], ebx
  986.            mov [esp+36], eax
  987.            ret
  988. @@:
  989.            cmp eax, 19
  990.            ja @f
  991.            cmp ebx, OS_BASE
  992.            jae .fail
  993.            stdcall load_library, ebx
  994.            mov [esp+36], eax
  995.            ret
  996. @@:
  997.            cmp     eax, 20
  998.            ja      @F
  999.            mov     eax, ecx
  1000.            call    user_realloc
  1001.            mov     [esp+36], eax
  1002.            ret
  1003. @@:
  1004.            cmp eax, 21                     ;for test purposes only
  1005.            ja @f                           ;will be removed soon
  1006.            cmp ebx, OS_BASE
  1007.            jae .fail
  1008.  
  1009.            stdcall load_PE, ebx
  1010.  
  1011.            test eax, eax
  1012.            jz @F
  1013.  
  1014.            mov esi, eax
  1015.            stdcall eax, DRV_ENTRY
  1016.  
  1017.            test eax, eax
  1018.            jz @F
  1019.  
  1020.            mov [eax+SRV.entry], esi
  1021.  
  1022. @@:
  1023.            mov [esp+36], eax
  1024.            ret
  1025.  
  1026.  
  1027. .fail:
  1028.            xor eax, eax
  1029.            mov [esp+36], eax
  1030.            ret
  1031.  
  1032. align 4
  1033. proc load_pe_driver stdcall, file:dword
  1034.  
  1035.            stdcall load_PE, [file]
  1036.            test eax, eax
  1037.            jz .fail
  1038.  
  1039.            mov esi, eax
  1040.            stdcall eax, DRV_ENTRY
  1041.            test eax, eax
  1042.            jz .fail
  1043.  
  1044.            mov [eax+SRV.entry], esi
  1045.            ret
  1046.  
  1047. .fail:
  1048.            xor eax, eax
  1049.            ret
  1050. endp
  1051.  
  1052.  
  1053. align 4
  1054. proc init_mtrr
  1055.  
  1056.            cmp [BOOT_VAR+0x901c],byte 2
  1057.            je  .exit
  1058.  
  1059.            bt [cpu_caps], CAPS_MTRR
  1060.            jnc .exit
  1061.  
  1062.            mov eax, cr0
  1063.            or eax, 0x60000000   ;disable caching
  1064.            mov cr0, eax
  1065.            wbinvd               ;invalidate cache
  1066.  
  1067.            mov ecx, 0x2FF
  1068.            rdmsr                ;
  1069.            push eax
  1070.  
  1071.            xor edx, edx
  1072.            xor eax, eax
  1073.            mov ecx, 0x2FF
  1074.            wrmsr                ;disable all MTRR
  1075.  
  1076.            mov eax, [_mem_amount]
  1077. ; round eax up to next power of 2
  1078.            dec eax
  1079.            bsr ecx, eax
  1080.            mov eax, 2
  1081.            shl eax, cl
  1082.            stdcall set_mtrr, edx,edx,eax,MEM_WB
  1083.            stdcall set_mtrr, 1,[LFBAddress],[LFBSize],MEM_WC
  1084.            xor edx, edx
  1085.            xor eax, eax
  1086.            mov ecx, 0x204
  1087.            mov ebx, 6
  1088. @@:
  1089.            wrmsr                ;disable unused MTRR
  1090.            inc ecx
  1091.            wrmsr
  1092.            inc ecx
  1093.            dec ebx
  1094.            jnz @b
  1095.  
  1096.            wbinvd               ;again invalidate
  1097.  
  1098.            pop eax
  1099.            or eax, 0x800        ;set default memtype to UC
  1100.            and al, 0xF0
  1101.            mov ecx, 0x2FF
  1102.            wrmsr                ;and enable MTRR
  1103.  
  1104.            mov eax, cr0
  1105.            and eax, not 0x60000000
  1106.            mov cr0, eax         ; enable caching
  1107. .exit:
  1108.            ret
  1109. endp
  1110.  
  1111. align 4
  1112. proc set_mtrr stdcall, reg:dword,base:dword,size:dword,mem_type:dword
  1113.  
  1114.            xor edx, edx
  1115.            mov eax, [base]
  1116.            or eax, [mem_type]
  1117.            mov ecx, [reg]
  1118.            lea ecx, [0x200+ecx*2]
  1119.            wrmsr
  1120.  
  1121.            mov ebx, [size]
  1122.            dec ebx
  1123.            mov eax, 0xFFFFFFFF
  1124.            mov edx, 0x0000000F
  1125.            sub eax, ebx
  1126.            sbb edx, 0
  1127.            or eax, 0x800
  1128.            inc ecx
  1129.            wrmsr
  1130.            ret
  1131. endp
  1132.  
  1133. align 4
  1134. proc stall stdcall, delay:dword
  1135.            push ecx
  1136.            push edx
  1137.            push ebx
  1138.            push eax
  1139.  
  1140.            mov eax, [delay]
  1141.            mul [stall_mcs]
  1142.            mov ebx, eax       ;low
  1143.            mov ecx, edx       ;high
  1144.            rdtsc
  1145.            add ebx, eax
  1146.            adc ecx,edx
  1147. @@:
  1148.            rdtsc
  1149.            sub eax, ebx
  1150.            sbb edx, ecx
  1151.            jb @B
  1152.  
  1153.            pop eax
  1154.            pop ebx
  1155.            pop edx
  1156.            pop ecx
  1157.            ret
  1158. endp
  1159.  
  1160. align 4
  1161. proc create_ring_buffer stdcall, size:dword, flags:dword
  1162.            locals
  1163.              buf_ptr  dd ?
  1164.            endl
  1165.  
  1166.            mov eax, [size]
  1167.            test eax, eax
  1168.            jz .fail
  1169.  
  1170.            add eax, eax
  1171.            stdcall alloc_kernel_space, eax
  1172.            test eax, eax
  1173.            jz .fail
  1174.  
  1175.            push ebx
  1176.  
  1177.            mov [buf_ptr], eax
  1178.  
  1179.            mov ebx, [size]
  1180.            shr ebx, 12
  1181.            push ebx
  1182.  
  1183.            stdcall alloc_pages, ebx
  1184.            pop ecx
  1185.  
  1186.            test eax, eax
  1187.            jz .mm_fail
  1188.  
  1189.            push edi
  1190.  
  1191.            or eax, [flags]
  1192.            mov edi, [buf_ptr]
  1193.            mov ebx, [buf_ptr]
  1194.            mov edx, ecx
  1195.            shl edx, 2
  1196.            shr edi, 10
  1197. @@:
  1198.            mov [page_tabs+edi], eax
  1199.            mov [page_tabs+edi+edx], eax
  1200.            add eax, 0x1000
  1201.            add ebx, 0x1000
  1202.            add edi, 4
  1203.            dec ecx
  1204.            jnz @B
  1205.  
  1206.            mov eax, [buf_ptr]
  1207.            pop edi
  1208.            pop ebx
  1209.            ret
  1210. .mm_fail:
  1211.            stdcall free_kernel_space, [buf_ptr]
  1212.            xor eax, eax
  1213.            pop ebx
  1214. .fail:
  1215.            ret
  1216. endp
  1217.  
  1218.  
  1219. align 4
  1220. _balloc:   ; gcc fastcall
  1221. @balloc@4:
  1222.  
  1223.  
  1224.            mov eax, [_pg_balloc]
  1225.            add ecx, 4095
  1226.            and ecx, -4096
  1227.            add ecx, eax
  1228.            mov [_pg_balloc], ecx
  1229.            add eax, OS_BASE
  1230.            ret
  1231.  
  1232.