Subversion Repositories Kolibri OS

Rev

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