Subversion Repositories Kolibri OS

Rev

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

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