Subversion Repositories Kolibri OS

Rev

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