Subversion Repositories Kolibri OS

Rev

Rev 430 | Blame | Last modification | View Log | Download | RSS feed

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