Subversion Repositories Kolibri OS

Rev

Rev 1074 | Rev 1081 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                              ;;
  3. ;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;;
  4. ;; Distributed under terms of the GNU General Public License    ;;
  5. ;;                                                              ;;
  6. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  7.  
  8. $Revision: 1077 $
  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. ; Now it is called from sys32::exc_c (see stack frame there)
  548. proc page_fault_handler
  549.  
  550.     .err_addr   equ ebp-4
  551.  
  552.         mov     ebp, esp
  553.         mov     ebx, cr2
  554.         push    ebx               ; that is locals: .err_addr = cr2
  555.         inc     [pg_data.pages_faults]
  556.  
  557. ;     push eax
  558. ;     push edx
  559. ;     mov edx, 0x400   ;bochs
  560. ;     mov al,0xff      ;bochs
  561. ;     out dx, al       ;bochs
  562. ;     pop edx
  563. ;     pop eax
  564.  
  565.         mov     eax, [pf_err_code]
  566.  
  567.         cmp     ebx, OS_BASE      ;ebx == .err_addr
  568.         jb      .user_space       ;ёЄЁрэшЎр т ярь Єш яЁшыюцхэш  ;
  569.  
  570.         cmp     ebx, page_tabs
  571.         jb      .kernel_space     ;ёЄЁрэшЎр т ярь Єш  фЁр
  572.  
  573.         cmp     ebx, kernel_tabs
  574.         jb      .alloc;.app_tabs  ;ЄрсышЎ√ ёЄЁрэшЎ яЁшыюцхэш  ;
  575.                                   ;яЁюёЄю ёючфрфшь юфэє
  576. if 0 ;яюър ¤Єю яЁюёЄю ыш°эхх
  577.         cmp     ebx, LFB_BASE
  578.         jb      .core_tabs        ;ЄрсышЎ√ ёЄЁрэшЎ  фЁр
  579.                                   ;╬°шсър
  580.   .lfb:
  581.                                   ;юсырёЄ№ LFB
  582.                                   ;╬°шсър
  583.         jmp     .fail
  584. end if
  585. .core_tabs:
  586. .fail:  ;simply return to caller
  587.         mov     esp, ebp
  588.         mov     bl, 14 ;#PF
  589.         ret
  590.  
  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,[.err_addr],eax,dword PG_UW
  614.  
  615.         mov     edi, [.err_addr]
  616.         and     edi, 0xFFFFF000
  617.         mov     ecx, 1024
  618.         xor     eax, eax
  619.        ;cld     ;caller is duty for this
  620.         rep     stosd
  621. .exit:  ;iret with repeat fault instruction
  622.         add     esp,8 ; clear in stack: locals(.err_addr) + ret_to_caller
  623.         restore_ring3_context
  624.         iretd
  625.  
  626. .err_access  =  .fail
  627. ;эшъюуфр эх яЁюшёїюфшЄ
  628.        ;jmp     .fail
  629.  
  630. .kernel_space:
  631.         test    eax, PG_MAP
  632.         jz      .fail   ;ёЄЁрэшЎр эх яЁшёєЄёЄтєхЄ
  633.  
  634.         test    eax,12  ;U/S (+below)
  635.         jnz     .fail   ;яЁшыюцхэшх юсЁрЄшыюё№ ъ ярь Єш
  636.                         ; фЁр
  637.        ;test    eax, 8
  638.        ;jnz     .fail   ;єёЄрэютыхэ чрЁхчхЁтшЁютрээ√щ сшЄ
  639.                         ;т ЄрсышЎрї ёЄЁрэшЎ. фюсртыхэю т P4/Xeon
  640.  
  641. ;яюя√Єър чряшёш т чр∙ш∙╕ээє■ ёЄЁрэшЎє  фЁр
  642.  
  643.         cmp     ebx, tss._io_map_0
  644.         jb      .fail
  645.  
  646.         cmp     ebx, tss._io_map_0+8192
  647.         jae     .fail
  648.  
  649. ; io permission map
  650. ; copy-on-write protection
  651.  
  652.         call    alloc_page
  653.         test    eax, eax
  654.         jz      .fail
  655.  
  656.         push    eax
  657.         stdcall map_page,[.err_addr],eax,dword PG_SW
  658.         pop     eax
  659.         mov     edi, [.err_addr]
  660.         and     edi, -4096
  661.         lea     esi, [edi+(not tss._io_map_0)+1]; -tss._io_map_0
  662.  
  663.         mov     ebx, esi
  664.         shr     ebx, 12
  665.         mov     edx, [current_slot]
  666.         or      eax, PG_SW
  667.         mov     [edx+APPDATA.io_map+ebx*4], eax
  668.  
  669.         add     esi, [default_io_map]
  670.         mov     ecx, 4096/4
  671.        ;cld     ;caller is duty for this
  672.         rep     movsd
  673.         jmp     .exit
  674. endp
  675.  
  676. align 4
  677. proc map_mem stdcall, lin_addr:dword,pdir:dword,\
  678.                       ofs:dword,buf_size:dword
  679.            mov eax, [buf_size]
  680.            test eax, eax
  681.            jz .exit
  682.  
  683.            mov eax, [pdir]
  684.            and eax, 0xFFFFF000
  685.  
  686.            stdcall map_page,[ipc_pdir],eax,PG_UW
  687.            mov ebx, [ofs]
  688.            shr ebx, 22
  689.            mov esi, [ipc_pdir]
  690.            mov edi, [ipc_ptab]
  691.            mov eax, [esi+ebx*4]
  692.            and eax, 0xFFFFF000
  693.            jz .exit
  694.            stdcall map_page,edi,eax,PG_UW
  695. ;           inc ebx
  696. ;           add edi, 0x1000
  697. ;           mov eax, [esi+ebx*4]
  698. ;           test eax, eax
  699. ;           jz @f
  700. ;          and eax, 0xFFFFF000
  701. ;           stdcall map_page, edi, eax
  702.  
  703. @@:        mov edi, [lin_addr]
  704.            and edi, 0xFFFFF000
  705.            mov ecx, [buf_size]
  706.            add ecx, 4095
  707.            shr ecx, 12
  708.            inc ecx
  709.  
  710.            mov edx, [ofs]
  711.            shr edx, 12
  712.            and edx, 0x3FF
  713.            mov esi, [ipc_ptab]
  714.  
  715. .map:      mov eax, [esi+edx*4]
  716.            and eax, 0xFFFFF000
  717.            jz  .exit
  718.            stdcall map_page,edi,eax,PG_UW
  719.            dec ecx
  720.            jz  .exit
  721.            add edi, 0x1000
  722.            inc edx
  723.            cmp edx, 0x400
  724.            jnz .map
  725.            inc ebx
  726.            mov eax, [ipc_pdir]
  727.            mov eax, [eax+ebx*4]
  728.            and eax, 0xFFFFF000
  729.            jz  .exit
  730.            stdcall map_page,esi,eax,PG_UW
  731.            xor edx, edx
  732.            jmp .map
  733.  
  734. .exit:
  735.            ret
  736. endp
  737.  
  738. align 4
  739. proc map_memEx stdcall, lin_addr:dword,pdir:dword,\
  740.                         ofs:dword,buf_size:dword
  741.            mov eax, [buf_size]
  742.            test eax, eax
  743.            jz .exit
  744.  
  745.            mov eax, [pdir]
  746.            and eax, 0xFFFFF000
  747.  
  748.            stdcall map_page,[proc_mem_pdir],eax,dword PG_UW
  749.            mov ebx, [ofs]
  750.            shr ebx, 22
  751.            mov esi, [proc_mem_pdir]
  752.            mov edi, [proc_mem_tab]
  753.            mov eax, [esi+ebx*4]
  754.            and eax, 0xFFFFF000
  755.            test eax, eax
  756.            jz .exit
  757.            stdcall map_page,edi,eax,dword PG_UW
  758.  
  759. @@:        mov edi, [lin_addr]
  760.            and edi, 0xFFFFF000
  761.            mov ecx, [buf_size]
  762.            add ecx, 4095
  763.            shr ecx, 12
  764.            inc ecx
  765.  
  766.            mov edx, [ofs]
  767.            shr edx, 12
  768.            and edx, 0x3FF
  769.            mov esi, [proc_mem_tab]
  770.  
  771. .map:      mov eax, [esi+edx*4]
  772. ;           and eax, 0xFFFFF000
  773. ;           test eax, eax
  774. ;           jz .exit
  775.            stdcall map_page,edi,eax,dword PG_UW
  776.            add edi, 0x1000
  777.            inc edx
  778.            dec ecx
  779.            jnz .map
  780. .exit:
  781.            ret
  782. endp
  783.  
  784.  
  785.  
  786.  
  787. sys_IPC:
  788. ;input:
  789. ;  eax=1 - set ipc buffer area
  790. ;    ebx=address of buffer
  791. ;    ecx=size of buffer
  792. ;  eax=2 - send message
  793. ;    ebx=PID
  794. ;    ecx=address of message
  795. ;    edx=size of message
  796.  
  797.            cmp  eax,1
  798.            jne @f
  799.            call set_ipc_buff
  800.            mov [esp+36], eax
  801.            ret
  802. @@:
  803.            cmp eax, 2
  804.            jne @f
  805.            stdcall sys_ipc_send, ebx, ecx, edx
  806.            mov [esp+36], eax
  807.            ret
  808. @@:
  809.            xor eax, eax
  810.            not eax
  811.            mov [esp+36], eax
  812.            ret
  813.  
  814. align 4
  815. proc set_ipc_buff
  816.  
  817.            mov  eax,[current_slot]
  818.            pushf
  819.            cli
  820.            mov  [eax+APPDATA.ipc_start],ebx     ;set fields in extended information area
  821.            mov  [eax+APPDATA.ipc_size],ecx
  822.  
  823.            add ecx, ebx
  824.            add ecx, 4095
  825.            and ecx, not 4095
  826.  
  827. .touch:    mov eax, [ebx]
  828.            add ebx, 0x1000
  829.            cmp ebx, ecx
  830.            jb  .touch
  831.  
  832.            popf
  833.            xor eax, eax
  834.            ret
  835. endp
  836.  
  837. proc sys_ipc_send stdcall, PID:dword, msg_addr:dword, msg_size:dword
  838.            locals
  839.              dst_slot   dd ?
  840.              dst_offset dd ?
  841.              buf_size   dd ?
  842.              used_buf   dd ?
  843.            endl
  844.  
  845.            pushf
  846.            cli
  847.  
  848.            mov  eax, [PID]
  849.            call pid_to_slot
  850.            test eax,eax
  851.            jz   .no_pid
  852.  
  853.            mov [dst_slot], eax
  854.            shl  eax,8
  855.            mov  edi,[eax+SLOT_BASE+0xa0]  ;is ipc area defined?
  856.            test edi,edi
  857.            jz   .no_ipc_area
  858.  
  859.            mov ebx, edi
  860.            and ebx, 0xFFF
  861.            mov [dst_offset], ebx
  862.  
  863.            mov esi, [eax+SLOT_BASE+0xa4]
  864.            mov [buf_size], esi
  865.  
  866.            mov ecx, [ipc_tmp]
  867.            cmp esi, 0x40000-0x1000 ; size of [ipc_tmp] minus one page
  868.            jbe @f
  869.            push eax esi edi
  870.            add esi,0x1000
  871.            stdcall alloc_kernel_space,esi
  872.            mov ecx, eax
  873.            pop edi esi eax
  874. @@:
  875.            mov [used_buf], ecx
  876.            stdcall map_mem, ecx, [SLOT_BASE+eax+0xB8],\
  877.                              edi, esi
  878.  
  879.            mov edi, [dst_offset]
  880.            add edi, [used_buf]
  881.            cmp dword [edi], 0
  882.            jnz  .ipc_blocked          ;if dword [buffer]<>0 - ipc blocked now
  883.  
  884.            mov edx, dword [edi+4]
  885.            lea ebx, [edx+8]
  886.            add ebx, [msg_size]
  887.            cmp ebx, [buf_size]
  888.            ja .buffer_overflow         ;esi<0 - not enough memory in buffer
  889.  
  890.            mov dword [edi+4], ebx
  891.            mov eax,[TASK_BASE]
  892.            mov eax, [eax+0x04]         ;eax - our PID
  893.            add edi, edx
  894.            mov [edi], eax
  895.            mov ecx, [msg_size]
  896.  
  897.            mov [edi+4], ecx
  898.            add edi, 8
  899.            mov esi, [msg_addr]
  900.        ;    add esi, new_app_base
  901.            cld
  902.            rep movsb
  903.  
  904.            mov ebx, [ipc_tmp]
  905.            mov edx, ebx
  906.            shr ebx, 12
  907.            xor eax, eax
  908.            mov [page_tabs+ebx*4], eax
  909.            invlpg [edx]
  910.  
  911.            mov ebx, [ipc_pdir]
  912.            mov edx, ebx
  913.            shr ebx, 12
  914.            xor eax, eax
  915.            mov [page_tabs+ebx*4], eax
  916.            invlpg [edx]
  917.  
  918.            mov ebx, [ipc_ptab]
  919.            mov edx, ebx
  920.            shr ebx, 12
  921.            xor eax, eax
  922.            mov [page_tabs+ebx*4], eax
  923.            invlpg [edx]
  924.  
  925.            mov  eax, [dst_slot]
  926.            shl eax, 8
  927.            or   [eax+SLOT_BASE+0xA8],dword 0x40
  928.            cmp  dword [check_idle_semaphore],20
  929.            jge  .ipc_no_cis
  930.  
  931.            mov  dword [check_idle_semaphore],5
  932. .ipc_no_cis:
  933.            push 0
  934.            jmp .ret
  935. .no_pid:
  936.            popf
  937.            mov eax, 4
  938.            ret
  939. .no_ipc_area:
  940.            popf
  941.            xor eax, eax
  942.            inc eax
  943.            ret
  944. .ipc_blocked:
  945.            push 2
  946.            jmp .ret
  947. .buffer_overflow:
  948.            push 3
  949. .ret:
  950.            mov eax, [used_buf]
  951.            cmp eax, [ipc_tmp]
  952.            jz @f
  953.            stdcall free_kernel_space,eax
  954. @@:
  955.            pop eax
  956.            popf
  957.            ret
  958. endp
  959.  
  960. align 4
  961. sysfn_meminfo:
  962.  
  963.         ;   add ecx, new_app_base
  964.            cmp ecx, OS_BASE
  965.            jae .fail
  966.  
  967.            mov eax, [pg_data.pages_count]
  968.            mov [ecx], eax
  969.            shl eax, 12
  970.            mov [esp+32], eax
  971.            mov eax, [pg_data.pages_free]
  972.            mov [ecx+4], eax
  973.            mov eax, [pg_data.pages_faults]
  974.            mov [ecx+8], eax
  975.            mov eax, [heap_size]
  976.            mov [ecx+12], eax
  977.            mov eax, [heap_free]
  978.            mov [ecx+16], eax
  979.            mov eax, [heap_blocks]
  980.            mov [ecx+20], eax
  981.            mov eax, [free_blocks]
  982.            mov [ecx+24], eax
  983.            ret
  984. .fail:
  985.            mov dword [esp+32], -1
  986.            ret
  987.  
  988. align 4
  989. f68call:
  990.            dd f68.11
  991.            dd f68.12
  992.            dd f68.13
  993.            dd f68.14
  994.            dd f68.fail ;moved to f68.24
  995.            dd f68.16
  996.            dd f68.17
  997.            dd f68.fail ;moved to f68.25
  998.            dd f68.19
  999.            dd f68.20
  1000.            dd f68.21
  1001.            dd f68.22
  1002.            dd f68.23
  1003.            dd f68.24
  1004.            dd f68.25
  1005.  
  1006. align 4
  1007. f68:
  1008.            cmp  eax,4
  1009.            jle  sys_sheduler
  1010.  
  1011.            cmp eax, 11
  1012.            jb .fail
  1013.  
  1014.            cmp eax, 25
  1015.            ja .fail
  1016.  
  1017.            jmp dword [f68call+eax*4-11*4]
  1018. .11:
  1019.            call init_heap
  1020.            mov [esp+36], eax
  1021.            ret
  1022. .12:
  1023.            stdcall user_alloc, ebx
  1024.            mov [esp+36], eax
  1025.            ret
  1026. .13:
  1027.            stdcall user_free, ebx
  1028.            mov [esp+36], eax
  1029.            ret
  1030. .14:
  1031.            cmp ebx, OS_BASE
  1032.            jae .fail
  1033.            mov edi,ebx
  1034.            call get_event_ex
  1035.            mov [esp+36], eax
  1036.            ret
  1037. .24:
  1038.            mov  eax, [current_slot]
  1039.            xchg ebx, [eax+APPDATA.exc_handler]
  1040.            xchg ecx, [eax+APPDATA.except_mask]
  1041.            mov  [esp+36], ebx ; reg_eax+8
  1042.            mov  [esp+24], ecx ; reg_ebx+8
  1043.            ret
  1044. .16:
  1045.            test ebx, ebx
  1046.            jz .fail
  1047.            cmp ebx, OS_BASE
  1048.            jae .fail
  1049.            stdcall get_service, ebx
  1050.            mov [esp+36], eax
  1051.            ret
  1052. .17:
  1053.            call srv_handlerEx   ;ebx
  1054.            mov [esp+36], eax
  1055.            ret
  1056. .25:
  1057.            mov  eax, [current_slot]
  1058.            btr  [eax+APPDATA.except_mask],ebx
  1059.            setc byte[esp+36]
  1060.            jecxz @f
  1061.            bts  [eax+APPDATA.except_mask],ebx
  1062.      @@:   ret
  1063. .19:
  1064.            cmp ebx, OS_BASE
  1065.            jae .fail
  1066.            stdcall load_library, ebx
  1067.            mov [esp+36], eax
  1068.            ret
  1069. .20:
  1070.            mov     eax, ecx
  1071.            call    user_realloc
  1072.            mov     [esp+36], eax
  1073.            ret
  1074. .21:
  1075.            cmp ebx, OS_BASE
  1076.            jae .fail
  1077.  
  1078.            stdcall load_PE, ebx
  1079.  
  1080.            test eax, eax
  1081.            jz @F
  1082.  
  1083.            mov esi, eax
  1084.            stdcall eax, DRV_ENTRY
  1085.  
  1086.            test eax, eax
  1087.            jz @F
  1088.  
  1089.            mov [eax+SRV.entry], esi
  1090.  
  1091. @@:
  1092.            mov [esp+36], eax
  1093.            ret
  1094. .22:
  1095.            cmp ebx, OS_BASE
  1096.            jae .fail
  1097.  
  1098.            stdcall shmem_open, ebx, ecx, edx
  1099.            mov [esp+28], edx
  1100.            mov [esp+36], eax
  1101.            ret
  1102.  
  1103. .23:
  1104.            cmp ebx, OS_BASE
  1105.            jae .fail
  1106.  
  1107.            stdcall shmem_close, ebx
  1108.            mov [esp+36], eax
  1109.            ret
  1110.  
  1111. .fail:
  1112.            xor eax, eax
  1113.            mov [esp+36], eax
  1114.            ret
  1115.  
  1116. align 4
  1117. proc load_pe_driver stdcall, file:dword
  1118.  
  1119.            stdcall load_PE, [file]
  1120.            test eax, eax
  1121.            jz .fail
  1122.  
  1123.            mov esi, eax
  1124.            stdcall eax, DRV_ENTRY
  1125.            test eax, eax
  1126.            jz .fail
  1127.  
  1128.            mov [eax+SRV.entry], esi
  1129.            ret
  1130.  
  1131. .fail:
  1132.            xor eax, eax
  1133.            ret
  1134. endp
  1135.  
  1136.  
  1137. align 4
  1138. proc init_mtrr
  1139.  
  1140.            cmp [BOOT_VAR+0x901c],byte 2
  1141.            je  .exit
  1142.  
  1143.            bt [cpu_caps], CAPS_MTRR
  1144.            jnc .exit
  1145.  
  1146.            mov eax, cr0
  1147.            or eax, 0x60000000   ;disable caching
  1148.            mov cr0, eax
  1149.            wbinvd               ;invalidate cache
  1150.  
  1151.            mov ecx, 0x2FF
  1152.            rdmsr                ;
  1153. ; has BIOS already initialized MTRRs?
  1154.            test ah, 8
  1155.            jnz .skip_init
  1156. ; rarely needed, so mainly placeholder
  1157. ; main memory - cached
  1158.            push eax
  1159.  
  1160.            mov eax, [MEM_AMOUNT]
  1161. ; round eax up to next power of 2
  1162.            dec eax
  1163.            bsr ecx, eax
  1164.            mov ebx, 2
  1165.            shl ebx, cl
  1166.            dec ebx
  1167. ; base of memory range = 0, type of memory range = MEM_WB
  1168.            xor edx, edx
  1169.            mov eax, MEM_WB
  1170.            mov ecx, 0x200
  1171.            wrmsr
  1172. ; mask of memory range = 0xFFFFFFFFF - (size - 1), ebx = size - 1
  1173.            mov eax, 0xFFFFFFFF
  1174.            mov edx, 0x0000000F
  1175.            sub eax, ebx
  1176.            sbb edx, 0
  1177.            or eax, 0x800
  1178.            inc ecx
  1179.            wrmsr
  1180. ; clear unused MTRRs
  1181.            xor eax, eax
  1182.            xor edx, edx
  1183. @@:
  1184.            wrmsr
  1185.            inc ecx
  1186.            cmp ecx, 0x210
  1187.            jb @b
  1188. ; enable MTRRs
  1189.            pop eax
  1190.            or ah, 8
  1191.            and al, 0xF0 ; default memtype = UC
  1192.            mov ecx, 0x2FF
  1193.            wrmsr
  1194. .skip_init:
  1195.            stdcall set_mtrr, [LFBAddress],[LFBSize],MEM_WC
  1196.  
  1197.            wbinvd               ;again invalidate
  1198.  
  1199.            mov eax, cr0
  1200.            and eax, not 0x60000000
  1201.            mov cr0, eax         ; enable caching
  1202. .exit:
  1203.            ret
  1204. endp
  1205.  
  1206. align 4
  1207. proc set_mtrr stdcall, base:dword,size:dword,mem_type:dword
  1208. ; find unused register
  1209.            mov ecx, 0x201
  1210. @@:
  1211.            rdmsr
  1212.            dec ecx
  1213.            test ah, 8
  1214.            jz .found
  1215.            rdmsr
  1216.            mov al, 0 ; clear memory type field
  1217.            cmp eax, [base]
  1218.            jz .ret
  1219.            add ecx, 3
  1220.            cmp ecx, 0x210
  1221.            jb @b
  1222. ; no free registers, ignore the call
  1223. .ret:
  1224.            ret
  1225. .found:
  1226. ; found, write values
  1227.            xor edx, edx
  1228.            mov eax, [base]
  1229.            or eax, [mem_type]
  1230.            wrmsr
  1231.  
  1232.            mov ebx, [size]
  1233.            dec ebx
  1234.            mov eax, 0xFFFFFFFF
  1235.            mov edx, 0x0000000F
  1236.            sub eax, ebx
  1237.            sbb edx, 0
  1238.            or eax, 0x800
  1239.            inc ecx
  1240.            wrmsr
  1241.            ret
  1242. endp
  1243.  
  1244. align 4
  1245. proc stall stdcall, delay:dword
  1246.            push ecx
  1247.            push edx
  1248.            push ebx
  1249.            push eax
  1250.  
  1251.            mov eax, [delay]
  1252.            mul [stall_mcs]
  1253.            mov ebx, eax       ;low
  1254.            mov ecx, edx       ;high
  1255.            rdtsc
  1256.            add ebx, eax
  1257.            adc ecx,edx
  1258. @@:
  1259.            rdtsc
  1260.            sub eax, ebx
  1261.            sbb edx, ecx
  1262.            jb @B
  1263.  
  1264.            pop eax
  1265.            pop ebx
  1266.            pop edx
  1267.            pop ecx
  1268.            ret
  1269. endp
  1270.  
  1271. align 4
  1272. proc create_ring_buffer stdcall, size:dword, flags:dword
  1273.            locals
  1274.              buf_ptr  dd ?
  1275.            endl
  1276.  
  1277.            mov eax, [size]
  1278.            test eax, eax
  1279.            jz .fail
  1280.  
  1281.            add eax, eax
  1282.            stdcall alloc_kernel_space, eax
  1283.            test eax, eax
  1284.            jz .fail
  1285.  
  1286.            push ebx
  1287.  
  1288.            mov [buf_ptr], eax
  1289.  
  1290.            mov ebx, [size]
  1291.            shr ebx, 12
  1292.            push ebx
  1293.  
  1294.            stdcall alloc_pages, ebx
  1295.            pop ecx
  1296.  
  1297.            test eax, eax
  1298.            jz .mm_fail
  1299.  
  1300.            push edi
  1301.  
  1302.            or eax, [flags]
  1303.            mov edi, [buf_ptr]
  1304.            mov ebx, [buf_ptr]
  1305.            mov edx, ecx
  1306.            shl edx, 2
  1307.            shr edi, 10
  1308. @@:
  1309.            mov [page_tabs+edi], eax
  1310.            mov [page_tabs+edi+edx], eax
  1311.            invlpg [ebx]
  1312.            invlpg [ebx+0x10000]
  1313.            add eax, 0x1000
  1314.            add ebx, 0x1000
  1315.            add edi, 4
  1316.            dec ecx
  1317.            jnz @B
  1318.  
  1319.            mov eax, [buf_ptr]
  1320.            pop edi
  1321.            pop ebx
  1322.            ret
  1323. .mm_fail:
  1324.            stdcall free_kernel_space, [buf_ptr]
  1325.            xor eax, eax
  1326.            pop ebx
  1327. .fail:
  1328.            ret
  1329. endp
  1330.