Subversion Repositories Kolibri OS

Rev

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