Subversion Repositories Kolibri OS

Rev

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