Subversion Repositories Kolibri OS

Rev

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