Subversion Repositories Kolibri OS

Rev

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

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