Subversion Repositories Kolibri OS

Rev

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