Subversion Repositories Kolibri OS

Rev

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