Subversion Repositories Kolibri OS

Rev

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

  1. if ~defined memmanager_inc
  2. memmanager_inc_fix:
  3. memmanager_inc fix memmanager_inc_fix
  4. ;for testing in applications
  5. if defined B32
  6.   iskernel=1
  7. else
  8.   iskernel=0
  9. end if
  10. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  11. ;; Memory allocator for MenuetOS kernel
  12. ;; Andrey Halyavin, halyavin@land.ru 2005
  13. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  14.  
  15. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  16. ;; heap block structure -
  17. ;; you can handle several ranges of
  18. ;; pages simultaneosly.
  19. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  20. .heap_linear_address   equ 0
  21. .heap_block_size       equ 4
  22. .heap_physical_address equ 8
  23. .heap_reserved         equ 12
  24. .heap_block_info       equ 16
  25. max_heaps equ 8
  26. .range_info            equ 36
  27. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  28. ;; memory manager data
  29. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  30. MEM_heap_block_    rd .heap_block_info*max_heaps/4
  31. MEM_heap_block=MEM_heap_block_+second_base_address
  32. MEM_heap_count_    rd 1
  33. MEM_heap_count=MEM_heap_count_+second_base_address
  34. if iskernel = 0
  35. MEM_general_mutex rd 1
  36. MEM_call_count    rd 1
  37. MEM_mutex_pid     rd 1
  38. MEM_mutex_count   rd 1
  39. else
  40. MEM_cli_count_    rd 1
  41. MEM_cli_count=MEM_cli_count_+second_base_address
  42. MEM_cli_prev_     rd 1
  43. MEM_cli_prev=MEM_cli_prev_+second_base_address
  44. end if
  45. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  46. ;;MEM_Init
  47. ;;Initialize memory manager structures.
  48. ;;Must be called first.
  49. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  50. MEM_Init:
  51.     push  eax
  52.     xor   eax,eax
  53. if iskernel = 0
  54.     mov   [MEM_heap_count],eax
  55.     mov   [MEM_general_mutex],eax
  56.     mov   [MEM_call_count],eax
  57.     mov   [MEM_mutex_pid],eax
  58.     mov   [MEM_mutex_count],eax
  59. else
  60.     mov   [MEM_cli_prev],eax     ;init value = 0
  61.     dec   eax
  62.     mov   [MEM_cli_count],eax    ;init value = -1
  63. end if
  64.     pop   eax
  65.     ret
  66. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  67. ;;change_task
  68. ;;procedure for changing tasks.
  69. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;    
  70. if iskernel = 0
  71. change_task:
  72.     push  eax
  73.     push  ebx
  74.     mov   eax,5
  75.     xor   ebx,ebx
  76.     inc   ebx
  77.     int   0x40
  78.     pop   ebx
  79.     pop   eax
  80.     ret
  81. end if
  82. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  83. ;;MEM_get_pid
  84. ;;determine current pid
  85. ;;result:
  86. ;; eax - pid
  87. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  88. if iskernel = 0
  89. MEM_get_pid:
  90.     push  ebx
  91.     push  ecx
  92.     sub   esp,1024
  93.     mov   eax,9
  94.     mov   ebx,esp
  95.     mov   ecx,-1
  96.     int   0x40
  97.     mov   eax,[esp+30]
  98.     add   esp,1024
  99.     pop   ecx
  100.     pop   ebx
  101.     ret
  102. else
  103. ;    pid_address dd 0x3000
  104. ;MEM_get_pid:
  105. ;    mov   eax,[pid_address]
  106. ;    mov   eax,[eax]
  107. ;    ret
  108. end if
  109. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  110. ;;MEM_Heap_Lock
  111. ;;Wait until all operations with heap will be finished.
  112. ;;Between MEM_Heap_Lock and MEM_Heap_UnLock operations
  113. ;;with heap are forbidden.
  114. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  115. MEM_Heap_Lock:
  116. if iskernel = 0
  117.     push  eax
  118.     inc   dword [MEM_call_count]
  119. MEM_Heap_Lock_wait:
  120.     mov   eax,1
  121.     xchg  [MEM_general_mutex],eax
  122.     test  eax,eax
  123.     jz    MEM_Heap_Lock_end
  124.     call  MEM_get_pid
  125.     cmp   [MEM_mutex_pid],eax
  126.     jz    MEM_Heap_Lock_end1
  127.     call  change_task        
  128.     jmp   MEM_Heap_Lock_wait
  129. MEM_Heap_Lock_end1:
  130.     inc   dword [MEM_mutex_count]
  131.     pop   eax
  132.     ret
  133. MEM_Heap_Lock_end:
  134.     call  MEM_get_pid
  135.     mov   [MEM_mutex_pid],eax
  136.     mov   dword [MEM_mutex_count],1
  137.     pop   eax
  138.     ret
  139. else
  140.     pushfd
  141.     cli
  142.     inc   dword [MEM_cli_count]  
  143.     jz    MEM_Heap_First_Lock
  144.     add   esp,4
  145.     ret
  146. MEM_Heap_First_Lock:             ;save interrupt flag
  147.     shr  dword [esp],9
  148.     and  dword [esp],1
  149.     pop  dword [MEM_cli_prev]
  150.     ret
  151. end if
  152. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  153. ;;MEM_Heap_UnLock
  154. ;;After this routine operations with heap are allowed.
  155. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  156. MEM_Heap_UnLock:
  157. if iskernel = 0
  158.     push  eax
  159.     xor   eax,eax
  160.     dec   dword [MEM_mutex_count]
  161.     jnz   MEM_Heap_UnLock_No_Wait1
  162.     dec   dword [MEM_call_count]
  163.     mov   [MEM_mutex_pid],eax
  164.     mov   [MEM_general_mutex],eax;release mutex BEFORE task switching
  165.     jz    MEM_Heap_UnLock_No_Wait
  166.     call  change_task            ;someone want to use heap - switch tasks            
  167. MEM_Heap_UnLock_No_Wait:
  168.     pop   eax
  169.     ret
  170. MEM_Heap_UnLock_No_Wait1:
  171.     dec   dword [MEM_call_count]
  172.     jz    MEM_Heap_UnLock_No_Wait2
  173.     call  change_task
  174. MEM_Heap_UnLock_No_Wait2:
  175.     pop   eax
  176.     ret
  177. else
  178.     dec   dword [MEM_cli_count]
  179.     js    MEM_Heap_UnLock_last
  180.     ret
  181. MEM_Heap_UnLock_last:
  182.     cmp   dword [MEM_cli_prev],0 ;restore saved interrupt flag
  183.     jz    MEM_Heap_UnLock_No_sti
  184.     sti
  185. MEM_Heap_UnLock_No_sti:
  186.     ret
  187. end if
  188. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  189. ;;MEM_Add_Heap
  190. ;;Add new range to memory manager.
  191. ;;eax - linear address
  192. ;;ebx - size in pages
  193. ;;ecx - physical address
  194. ;;Result:
  195. ;; eax=1 - success
  196. ;; eax=0 - failed
  197. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  198. MEM_Add_Heap:
  199.     push  edx
  200.     call  MEM_Heap_Lock
  201.     mov   edx,[MEM_heap_count]
  202.     cmp   edx,max_heaps
  203.     jz    MEM_Add_Heap_Error
  204.     inc   dword [MEM_heap_count]
  205.     shl   edx,4
  206.     mov   [MEM_heap_block+edx+.heap_linear_address],eax
  207.     mov   [MEM_heap_block+edx+.heap_block_size],ebx
  208.     shl   dword [MEM_heap_block+edx+.heap_block_size],12
  209.     mov   [MEM_heap_block+edx+.heap_physical_address],ecx
  210.     lea   edx,[4*ebx+.range_info+4095]   ;calculate space for page info table
  211.     and   edx,0xFFFFF000
  212.     mov   [eax],eax
  213.     add   [eax],edx              ;first 4 bytes - pointer to first free page
  214. ;clean page info area    
  215.     push  edi
  216.     lea   edi,[eax+4]
  217.     mov   ecx,edx
  218.     shr   ecx,2
  219.     push  eax
  220.     xor   eax,eax
  221.     rep   stosd                          
  222.     pop   eax
  223.     pop   edi
  224. ;create free pages list.    
  225.     mov   ecx,[eax]
  226.     shl   ebx,12
  227.     add   eax,ebx                ;eax - address after block
  228. MEM_Add_Heap_loop:
  229.     add   ecx,4096
  230.     mov   [ecx-4096],ecx         ;set forward pointer
  231.     cmp   ecx,eax
  232.     jnz   MEM_Add_Heap_loop
  233.     mov   dword [ecx-4096],0     ;set end of list
  234. MEM_Add_Heap_ret:
  235.     call  MEM_Heap_UnLock
  236.     pop   edx    
  237.     ret
  238. MEM_Add_Heap_Error:
  239.     xor   eax,eax
  240.     jmp   MEM_Add_Heap_ret
  241. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  242. ;;MEM_Get_Physical_Address
  243. ;;Translate linear address to physical address
  244. ;;Parameters:
  245. ;; eax - linear address
  246. ;;Result:
  247. ;; eax - physical address
  248. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  249. if used MEM_Get_Physical_Address
  250. MEM_Get_Physical_Address:
  251.     push   ecx
  252.     call   MEM_Heap_Lock
  253.     mov    ecx,[MEM_heap_count]
  254.     dec    ecx
  255.     shl    ecx,4
  256. MEM_Get_Physical_Address_loop:
  257.     sub    eax,[MEM_heap_block+ecx+.heap_linear_address]
  258.     jl     MEM_Get_Physical_Address_next
  259.     cmp    eax,[MEM_heap_block+ecx+.heap_block_size]
  260.     jge    MEM_Get_Physical_Address_next
  261.     add    eax,[MEM_heap_block+ecx+.heap_physical_address]
  262.     jmp    MEM_Get_Physical_Address_loopend
  263. MEM_Get_Physical_Address_next:
  264.     add    eax,[MEM_heap_block+ecx+.heap_linear_address]
  265.     sub    ecx,16
  266.     jns    MEM_Get_Physical_Address_loop
  267.     xor    eax,eax               ;address not found
  268. MEM_Get_Physical_Address_loopend:
  269.     call   MEM_Heap_UnLock
  270.     pop    ecx
  271.     ret
  272. end if
  273. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  274. ;;MEM_Get_Linear_Address
  275. ;;Translate physical address to linear address.
  276. ;;Parameters:
  277. ;; eax - physical address
  278. ;;Result:
  279. ;; eax - linear address
  280. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  281. if used MEM_Get_Linear_Address
  282. MEM_Get_Linear_Address:
  283.     push   ecx
  284.     call   MEM_Heap_Lock
  285.     mov    ecx,[MEM_heap_count]
  286.     dec    ecx
  287.     shl    ecx,4
  288. MEM_Get_Linear_Address_loop:
  289.     sub    eax,[MEM_heap_block+ecx+.heap_physical_address]
  290.     jl     MEM_Get_Linear_Address_Next
  291.     cmp    eax,[MEM_heap_block+ecx+.heap_block_size]
  292.     jge    MEM_Get_Linear_Address_Next
  293.     add    eax,[MEM_heap_block+ecx+.heap_linear_address]
  294.     call   MEM_Heap_UnLock
  295.     pop    ecx
  296.     ret
  297. MEM_Get_Linear_Address_Next:
  298.     add    eax,[MEM_heap_block+ecx+.heap_physical_address]
  299.     sub    ecx,16
  300.     jns    MEM_Get_Linear_Address_loop
  301.     call   MEM_Heap_UnLock
  302.     pop    ecx
  303.     xor    eax,eax               ;address not found
  304.     ret
  305. end if
  306. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  307. ;;MEM_Alloc_Page
  308. ;;Allocate and add reference to page
  309. ;;Result:
  310. ;; eax<>0 - physical address of page
  311. ;; eax=0  - not enough memory
  312. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  313. if used MEM_Alloc_Page
  314. MEM_Alloc_Page:
  315.     push   ecx
  316.     call   MEM_Heap_Lock
  317.     mov    ecx,[MEM_heap_count]
  318.     dec    ecx
  319.     shl    ecx,4
  320. MEM_Alloc_Page_loop:
  321.     push   ecx
  322.     mov    ecx,[MEM_heap_block+ecx+.heap_linear_address]
  323.     cmp    dword [ecx],0
  324.     jz     MEM_Alloc_Page_loopend
  325.     mov    eax,[ecx]
  326.     push   dword [eax]
  327.     pop    dword [ecx]
  328.     sub    eax,ecx
  329.     push   eax
  330.     shr    eax,10
  331.     mov    word [ecx+.range_info+eax],1
  332.     pop    eax
  333.     pop    ecx
  334.     add    eax,[MEM_heap_block+ecx+.heap_physical_address]
  335.     jmp    MEM_Alloc_Page_ret
  336. MEM_Alloc_Page_loopend:
  337.     pop    ecx
  338.     sub    ecx,16
  339.     jns    MEM_Alloc_Page_loop
  340.     xor    eax,eax
  341. MEM_Alloc_Page_ret:
  342.     call   MEM_Heap_UnLock
  343.     pop    ecx
  344.     ret
  345. end if
  346. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  347. ;;MEM_Alloc_Page_Linear
  348. ;;Allocate and add reference to page
  349. ;;Result:
  350. ;; eax<>0 - linear address of page
  351. ;; eax=0  - not enough memory
  352. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  353. if used MEM_Alloc_Page_Linear
  354. MEM_Alloc_Page_Linear:
  355.     push  ecx
  356.     call  MEM_Heap_Lock
  357.     mov   ecx,[MEM_heap_count]
  358.     dec   ecx
  359.     shl   ecx,4
  360. MEM_Alloc_Page_Linear_loop:
  361.     push  ecx
  362.     mov   ecx,[MEM_heap_block+ecx+.heap_linear_address]
  363.     cmp   dword [ecx],0
  364.     jz    MEM_Alloc_Page_Linear_loopend
  365.     mov   eax,[ecx]
  366.     push  dword [eax]
  367.     pop   dword [ecx]
  368.     push  eax
  369.     sub   eax,ecx
  370.     shr   eax,10
  371.     mov   word [ecx+.range_info+eax],1
  372.     pop   eax
  373.     pop   ecx
  374.     jmp   MEM_Alloc_Page_Linear_ret
  375. MEM_Alloc_Page_Linear_loopend:
  376.     pop   ecx
  377.     sub   ecx,16
  378.     jns   MEM_Alloc_Page_Linear_loop
  379.     xor   eax,eax
  380. MEM_Alloc_Page_Linear_ret:
  381.     call  MEM_Heap_UnLock
  382.     pop   ecx
  383.     ret
  384. end if
  385. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  386. ;;MEM_Free_Page
  387. ;;Remove reference and free page if number of
  388. ;;references is equal to 0
  389. ;;Parameters:
  390. ;;  eax - physical address of page
  391. ;;Result:
  392. ;;  eax - 1 success
  393. ;;  eax - 0 failed
  394. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  395. if used MEM_Free_Page
  396. MEM_Free_Page:
  397.     test  eax,eax
  398.     jz    MEM_Free_Page_Zero
  399.     test  eax,0xFFF
  400.     jnz   MEM_Free_Page_Not_Aligned
  401.     push  ebx
  402.     push  ecx
  403.     push  edx
  404.     call  MEM_Heap_Lock
  405.     mov   ecx,[MEM_heap_count]
  406.     dec   ecx
  407.     shl   ecx,4
  408. MEM_Free_Page_Heap_loop:
  409.     sub   eax,[MEM_heap_block+ecx+.heap_physical_address]
  410.     js    MEM_Free_Page_Heap_loopnext
  411.     cmp   eax,[MEM_heap_block+ecx+.heap_block_size]
  412.     jl    MEM_Free_Page_Heap_loopend
  413. MEM_Free_Page_Heap_loopnext:
  414.     add   eax,[MEM_heap_block+ecx+.heap_physical_address]
  415.     sub   ecx,16
  416.     jns   MEM_Free_Page_Heap_loop
  417.     xor   eax,eax
  418.     inc   eax
  419.     jmp   MEM_Free_Page_ret
  420. MEM_Free_Page_Heap_loopend:
  421.     mov   ecx,[MEM_heap_block+ecx+.heap_linear_address]
  422.     mov   ebx,eax
  423.     add   eax,ecx
  424.     shr   ebx,10
  425.     mov   edx,[ecx+.range_info+ebx]
  426.     test  edx,0x80000000
  427.     jnz   MEM_Free_Page_Bucket
  428.     test  dx,dx
  429.     jz    MEM_Free_Page_Error
  430.     dec   word [ecx+.range_info+ebx]
  431.     jnz   MEM_Free_Page_OK
  432. MEM_Free_Page_Bucket:
  433.     push  dword [ecx]
  434.     mov   [ecx],eax
  435.     pop   dword [eax]
  436.     mov   dword [ecx+.range_info+ebx],0
  437. MEM_Free_Page_OK:
  438.     mov   eax,1
  439. MEM_Free_Page_ret:    
  440.     call  MEM_Heap_UnLock
  441.     pop   edx
  442.     pop   ecx
  443.     pop   ebx
  444.     ret
  445. MEM_Free_Page_Error:
  446.     xor   eax,eax
  447.     jmp   MEM_Free_Page_ret
  448. MEM_Free_Page_Zero:
  449.     inc   eax
  450.     ret
  451. MEM_Free_Page_Not_Aligned:
  452.     xor   eax,eax
  453.     ret
  454. end if
  455. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  456. ;;MEM_Free_Page_Linear
  457. ;;Remove reference and free page if number of
  458. ;;references is equal to 0
  459. ;;Parameters:
  460. ;;  eax - linear address of page
  461. ;;Result:
  462. ;;  eax - 1 success
  463. ;;  eax - 0 failed
  464. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  465. if used MEM_Free_Page_Linear
  466. MEM_Free_Page_Linear:
  467.     test  eax,eax
  468.     jz    MEM_Free_Page_Linear_Zero
  469.     test  eax,0xFFF
  470.     jnz   MEM_Free_Page_Linear_Not_Aligned
  471.     push  ebx
  472.     push  ecx
  473.     push  edx
  474.     call  MEM_Heap_Lock
  475.     mov   ecx,[MEM_heap_count]
  476.     dec   ecx
  477.     shl   ecx,4
  478.    
  479. MEM_Free_Page_Linear_Heap_loop:
  480.     sub   eax,[MEM_heap_block+ecx+.heap_linear_address]
  481.     js    MEM_Free_Page_Linear_Heap_loopnext
  482.     cmp   eax,[MEM_heap_block+ecx+.heap_block_size]
  483.     jl    MEM_Free_Page_Linear_Heap_loopend
  484. MEM_Free_Page_Linear_Heap_loopnext:
  485.     add   eax,[MEM_heap_block+ecx+.heap_linear_address]
  486.     sub   ecx,16
  487.     jns   MEM_Free_Page_Linear_Heap_loop
  488.     xor   eax,eax
  489.     inc   eax
  490.     jmp   MEM_Free_Page_Linear_ret
  491.    
  492. MEM_Free_Page_Linear_Heap_loopend:
  493.     mov   ecx,[MEM_heap_block+ecx+.heap_linear_address]
  494.     mov   ebx,eax
  495.     add   eax,ecx  
  496.     shr   ebx,10
  497.     mov   edx,[ecx+.range_info+ebx]
  498.     test  edx,0x80000000
  499.     jnz   MEM_Free_Page_Linear_Bucket
  500.     test  dx,dx
  501.     jz    MEM_Free_Page_Linear_Error
  502.     dec   word [ecx+.range_info+ebx]
  503.     jnz   MEM_Free_Page_Linear_OK
  504. MEM_Free_Page_Linear_Bucket:
  505.     mov   edx,[ecx]
  506.     mov   [eax],edx
  507.     mov   dword [eax+4],0
  508.     mov   [ecx],eax
  509.     test  edx,edx
  510.     jz    MEM_Free_Page_No_Next
  511.     mov   [edx+4],eax
  512. MEM_Free_Page_No_Next:
  513.     mov   dword [ecx+.range_info+ebx],0
  514. MEM_Free_Page_Linear_OK:
  515.     xor   eax, eax
  516.     inc   eax
  517. MEM_Free_Page_Linear_ret:    
  518.     call  MEM_Heap_UnLock
  519.     pop   edx
  520.     pop   ecx
  521.     pop   ebx
  522.     ret
  523.    
  524. MEM_Free_Page_Linear_Error:
  525.     xor   eax,eax
  526.     jmp   MEM_Free_Page_Linear_ret
  527.    
  528. MEM_Free_Page_Linear_Zero:
  529.     inc   eax
  530.     ret
  531.    
  532. MEM_Free_Page_Linear_Not_Aligned:
  533.     xor   eax,eax
  534.     ret
  535. end if
  536. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  537. ;;MEM_Alloc_Pages
  538. ;;Allocates set of pages.
  539. ;;Parameters:
  540. ;; eax - number of pages
  541. ;; ebx - buffer for physical addresses
  542. ;;Result:
  543. ;; eax - number of allocated pages
  544. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  545. if used MEM_Alloc_Pages
  546. MEM_Alloc_Pages:
  547.     push  eax
  548.     push  ebx
  549.     push  ecx
  550.     mov   ecx,eax
  551.     test  ecx,ecx
  552.     jz    MEM_Alloc_Pages_ret
  553. MEM_Alloc_Pages_loop:
  554.     call  MEM_Alloc_Page
  555.     test  eax,eax
  556.     jz    MEM_Alloc_Pages_ret
  557.     mov   [ebx],eax
  558.     add   ebx,4
  559.     dec   ecx
  560.     jnz   MEM_Alloc_Pages_loop
  561. MEM_Alloc_Pages_ret:
  562.     sub   [esp+8],ecx
  563.     pop   ecx
  564.     pop   ebx
  565.     pop   eax
  566.     ret
  567. end if
  568. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  569. ;;MEM_Alloc_Pages_Linear
  570. ;;Allocates set of pages.
  571. ;;Parameters:
  572. ;; eax - number of pages
  573. ;; ebx - buffer for linear addresses
  574. ;;Result:
  575. ;; eax - number of allocated pages
  576. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  577. if used MEM_Alloc_Pages_Linear
  578. MEM_Alloc_Pages_Linear:
  579.     push  eax
  580.     push  ebx
  581.     push  ecx
  582.     mov   ecx,eax
  583.     test  ecx,ecx
  584.     jz    MEM_Alloc_Pages_Linear_ret
  585. MEM_Alloc_Pages_Linear_loop:
  586.     call  MEM_Alloc_Page_Linear
  587.     test  eax,eax
  588.     jz    MEM_Alloc_Pages_Linear_ret
  589.     mov   [ebx],eax
  590.     add   ebx,4
  591.     dec   ecx
  592.     jnz   MEM_Alloc_Pages_Linear_loop
  593. MEM_Alloc_Pages_Linear_ret:
  594.     sub   [esp+8],ecx
  595.     pop   ecx
  596.     pop   ebx
  597.     pop   eax
  598.     ret
  599. end if
  600. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  601. ;;MEM_Free_Pages
  602. ;;Parameters:
  603. ;; eax - number of pages
  604. ;; ebx - array of addresses
  605. ;;Result:
  606. ;; eax=1 - succcess
  607. ;; eax=0 - failed
  608. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  609. if used MEM_Free_Pages
  610. MEM_Free_Pages:
  611.     push  ebx
  612.     push  ecx
  613.     mov   ecx,eax
  614.     test  ecx,ecx
  615.     jz    MEM_Free_Pages_ret
  616. MEM_Free_Pages_loop:
  617.     mov   eax,[ebx]
  618.     call  MEM_Free_Page
  619.     add   ebx,4
  620.     test  eax,eax
  621.     jz    MEM_Free_Pages_ret
  622.     dec   ecx
  623.     jnz   MEM_Free_Pages_loop
  624. MEM_Free_Pages_ret:
  625.     pop   ecx
  626.     pop   ebx
  627.     ret
  628. end if
  629. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  630. ;;MEM_Free_Pages_Linear
  631. ;;Parameters:
  632. ;; eax - number of pages
  633. ;; ebx - array of addresses
  634. ;;Result:
  635. ;; eax=1 - succcess
  636. ;; eax=0 - failed
  637. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  638. if used MEM_Free_Pages_Linear
  639. MEM_Free_Pages_Linear:
  640.     push  ebx
  641.     push  ecx
  642.     mov   ecx,eax
  643.     test  ecx,ecx
  644.     jz    MEM_Free_Pages_Linear_ret
  645. MEM_Free_Pages_Linear_loop:
  646.     mov   eax,[ebx]
  647.     call  MEM_Free_Page_Linear
  648.     add   ebx,4
  649.     test  eax,eax
  650.     jz    MEM_Free_Pages_Linear_ret
  651.     dec   ecx
  652.     jnz   MEM_Free_Pages_Linear_loop
  653. MEM_Free_Pages_Linear_ret:
  654.     pop   ecx
  655.     pop   ebx
  656.     ret
  657. end if
  658. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  659. ;;MEM_Get_Heap_Number
  660. ;;Calculate number of heap which pointer belongs to.
  661. ;;Parameter:
  662. ;; eax - address
  663. ;;Result:
  664. ;; ecx - number of heap*16.
  665. ;; eax=0 if address not found.
  666. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  667. if used MEM_Get_Heap_Number
  668. MEM_Get_Heap_Number:
  669.     call  MEM_Heap_Lock
  670.     mov   ecx,[MEM_heap_count]
  671.     dec   ecx
  672.     shl   ecx,4
  673. MEM_Get_Heap_loop:
  674.     sub   eax,[MEM_heap_block+ecx+.heap_physical_address]
  675.     jl    MEM_Get_Heap_loopnext
  676.     cmp   eax,[MEM_heap_block+ecx+.heap_block_size]
  677.     jl    MEM_Get_Heap_loopend
  678. MEM_Get_Heap_loopnext:
  679.     add   eax,[MEM_heap_block+ecx+.heap_physical_address]
  680.     sub   ecx,16
  681.     jns   MEM_Get_Heap_loop
  682.     call  MEM_Heap_UnLock
  683.     xor   eax,eax
  684.     ret
  685. MEM_Get_Heap_loopend:
  686.     add   eax,[MEM_heap_block+ecx+.heap_physical_address]
  687.     call  MEM_Heap_UnLock
  688.     ret
  689. end if
  690. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  691. ;;MEM_Get_Heap_Number_Linear
  692. ;;Calculate number of heap which pointer belongs to.
  693. ;;Parameter:
  694. ;; eax - address
  695. ;;Result:
  696. ;; ecx - number of heap*16.
  697. ;; eax=0 if address not found.
  698. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  699. if used MEM_Get_Heap_Number_Linear
  700. MEM_Get_Heap_Number_Linear:
  701.     call  MEM_Heap_Lock
  702.     mov   ecx,[MEM_heap_count]
  703.     dec   ecx
  704.     shl   ecx,4
  705. MEM_Get_Heap_Linear_loop:
  706.     sub   eax,[MEM_heap_block+ecx+.heap_linear_address]
  707.     jl    MEM_Get_Heap_Linear_loopnext
  708.     cmp   eax,[MEM_heap_block+ecx+.heap_block_size]
  709.     jl    MEM_Get_Heap_Linear_loopend
  710. MEM_Get_Heap_Linear_loopnext:
  711.     add   eax,[MEM_heap_block+ecx+.heap_linear_address]
  712.     sub   ecx,16
  713.     jns   MEM_Get_Heap_Linear_loop
  714.     call  MEM_Heap_UnLock
  715.     xor   eax,eax
  716.     ret
  717. MEM_Get_Heap_Linear_loopend:
  718.     add   eax,[MEM_heap_block+ecx+.heap_linear_address]
  719.     call  MEM_Heap_UnLock
  720.     ret
  721. end if
  722. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  723. ;;MEM_Alloc
  724. ;;Allocate small region.
  725. ;;Parameters:
  726. ;; eax - size (0<eax<=4096)
  727. ;;Result:
  728. ;; eax - linear address
  729. ;; eax=0 - not enough memory
  730. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  731. if used MEM_Alloc
  732. MEM_Alloc:
  733. ;find chain
  734.     test  eax,eax
  735.     jng   MEM_Alloc_Wrong_Size
  736.     cmp   eax,4096
  737.     jg    MEM_Alloc_Wrong_Size
  738.     push  ebx
  739.     push  ecx
  740.     push  edx
  741.     push  esi
  742.     dec   eax
  743.     shr   eax,4
  744.     xor   edx,edx
  745. MEM_Alloc_Find_Size:
  746.     add   edx,4
  747.     shr   eax,1
  748.     jnz   MEM_Alloc_Find_Size
  749. MEM_Alloc_Size_Found:
  750.     mov   ecx,edx
  751.     shr   ecx,2
  752.     add   ecx,4
  753.     mov   eax,1
  754.     shl   eax,cl
  755.     mov   esi,eax
  756. ;esi - block size
  757. ;edx - offset
  758.     call  MEM_Heap_Lock
  759.     mov   ecx,[MEM_heap_count]
  760.     dec   ecx
  761.     shl   ecx,4
  762. MEM_Alloc_Find_Heap:
  763.     mov   eax,[MEM_heap_block+ecx+.heap_linear_address]
  764.     cmp   dword [eax+edx],0
  765.     jnz   MEM_Alloc_Use_Existing
  766.     sub   ecx,16
  767.     jns   MEM_Alloc_Find_Heap
  768. ;create new bucket page
  769.     call  MEM_Alloc_Page_Linear
  770.     call  MEM_Get_Heap_Number_Linear
  771.     mov   ecx,[MEM_heap_block+ecx+.heap_linear_address]
  772.     mov   [ecx+edx],eax
  773.     lea   ebx,[eax+4096]
  774. MEM_Alloc_List_loop:
  775.     mov   [eax],eax
  776.     mov   [eax+4],eax
  777.     add   [eax],esi
  778.     sub   [eax+4],esi
  779.     add   eax,esi
  780.     cmp   eax,ebx
  781.     jnz   MEM_Alloc_List_loop
  782.     sub   ebx,esi
  783.     mov   dword [ebx],0
  784.     sub   eax,4096
  785.     mov   dword [eax+4],0
  786.     mov   eax,ecx
  787.        
  788. MEM_Alloc_Use_Existing:
  789.     mov   ebx,eax
  790.     mov   eax,[eax+edx]
  791.     mov   ecx,[eax]
  792.     mov   [ebx+edx],ecx
  793.     test  ecx,ecx
  794.     jz    MEM_Alloc_Became_Empty
  795.     mov   dword [ecx+4],0
  796. MEM_Alloc_Became_Empty:
  797.     mov   ecx,eax
  798.     sub   ecx,ebx
  799.     shr   ecx,10
  800.     and   ecx,0xFFFFFFFC
  801.     inc   byte [ebx+.range_info+ecx+2]
  802.     shr   edx,2
  803.     add   edx,128
  804.     dec   edx
  805.     mov   [ebx+.range_info+ecx+3],dl
  806.    
  807. MEM_Alloc_ret:
  808.     call  MEM_Heap_UnLock
  809.     pop   esi
  810.     pop   edx
  811.     pop   ecx
  812.     pop   ebx
  813.     ret
  814. MEM_Alloc_Wrong_Size:
  815.     xor   eax,eax
  816.     ret
  817. end if
  818. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  819. ;;MEM_Free
  820. ;;Parameters:
  821. ;; eax - linear address
  822. ;;Result:
  823. ;; eax=1 - success
  824. ;; eax=0 - failed
  825. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  826. if used MEM_Free
  827. MEM_Free:
  828.     test  eax,eax
  829.     jz    MEM_Free_Zero
  830.     push  ebx
  831.     push  ecx
  832.     push  edx
  833.     push  esi
  834.     push  edi
  835.     push  ebp
  836.     call  MEM_Heap_Lock
  837.     call  MEM_Get_Heap_Number_Linear
  838.     test  eax,eax
  839.     jz    MEM_Free_ret
  840.     mov   edx,eax
  841.     mov   ecx,[MEM_heap_block+ecx+.heap_linear_address]
  842.     sub   edx,ecx
  843.     shr   edx,10
  844.     and   edx,0xFFFFFFFC
  845.     mov   ebx,[ecx+.range_info+edx]
  846.     mov   esi,ebx
  847.     shr   esi,24
  848.     sub   esi,128
  849.     mov   edi,[ecx+4+4*esi]
  850.     mov   [eax],edi
  851.     mov   dword [eax+4],0
  852.     test  edi,edi
  853.     jz    MEM_Free_Empty_List
  854.     mov   [edi+4],eax
  855. MEM_Free_Empty_List:
  856.     mov   [ecx+4+4*esi],eax
  857.     sub   ebx,0x10000
  858.     mov   [ecx+.range_info+edx],ebx
  859.     test  ebx,0xFF0000
  860.     jnz   MEM_Free_ret
  861. ;delete empty blocks on the page
  862.     lea   edx,[esi+5]
  863.     and   eax,0xFFFFF000
  864.     mov   edi,eax
  865.     mov   eax,1
  866.     xchg  ecx,edx
  867.     shl   eax,cl
  868.     mov   ecx,edx
  869.     mov   edx,eax
  870. ;edx - size of block
  871. ;edi - start of page
  872.     mov   eax,edi
  873.     lea   ebx,[eax+4096]
  874. MEM_Free_Block_loop:
  875.     cmp   dword [eax+4],0
  876.     jnz   MEM_Free_Block_Not_First
  877.     mov   ebp,dword [eax]
  878.     mov   [ecx+4+4*esi],ebp
  879.     test  ebp,ebp
  880.     jz    MEM_Free_Block_Last
  881.     mov   dword [ebp+4],0
  882. MEM_Free_Block_Last:
  883.     jmp   MEM_Free_Block_loop_end
  884. MEM_Free_Block_Not_First:
  885.     mov   ebp,dword [eax]
  886.     push  ebp
  887.     mov   ebp,dword [eax+4]
  888.     pop   dword [ebp]
  889.     mov   ebp,dword [eax]
  890.     test  ebp,ebp
  891.     jz    MEM_Free_Block_loop_end
  892.     push  dword [eax+4]
  893.     pop   dword [ebp+4]
  894. ;    jmp   MEM_Free_Block_loop_end
  895. MEM_Free_Block_loop_end:
  896.     add   eax,edx
  897.     cmp   eax,ebx
  898.     jnz   MEM_Free_Block_loop
  899.     mov   eax,edi
  900.     call  MEM_Free_Page_Linear    
  901. MEM_Free_ret:
  902.     call  MEM_Heap_UnLock
  903.     pop   ebp
  904.     pop   edi
  905.     pop   esi
  906.     pop   edx
  907.     pop   ecx
  908.     pop   ebx
  909.     ret
  910. MEM_Free_Zero:
  911.     inc   eax
  912.     ret
  913. end if
  914. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  915. ;;MEM_Add_Reference
  916. ;; eax - physical address of page
  917. ;;Result:
  918. ;; eax=1 - success
  919. ;; eax=0 - failed
  920. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  921. if used MEM_Add_Reference
  922. MEM_Add_Reference:
  923.     push  ebx
  924.     push  ecx
  925.     call  MEM_Heap_Lock
  926.     call  MEM_Get_Heap_Number
  927.     test  eax,eax
  928.     jz    MEM_Add_Reference_ret
  929.     sub   eax,[MEM_heap_block+ecx+.heap_physical_address]
  930.     mov   ecx,[MEM_heap_block+ecx+.heap_linear_address]
  931.     shr   eax,10
  932.     and   eax,0xFFFFFFFC
  933.     test  dword [ecx+eax+.range_info],0x80000000
  934.     jnz   MEM_Add_Reference_failed
  935.     inc   dword [ecx+eax+.range_info]
  936. MEM_Add_Reference_ret:  
  937.     call  MEM_Heap_UnLock
  938.     pop   ecx
  939.     pop   ebx
  940.     ret
  941. MEM_Add_Reference_failed:
  942.     xor   eax,eax
  943.     jmp   MEM_Add_Reference_ret
  944. end if
  945. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  946. ;;MEM_Add_Reference_Linear
  947. ;; eax - linear address of page
  948. ;;Result:
  949. ;; eax=1 - success
  950. ;; eax=0 - failed
  951. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  952. if used MEM_Add_Reference_Linear
  953. MEM_Add_Reference_Linear:
  954.     push  ebx
  955.     push  ecx
  956.     call  MEM_Heap_Lock
  957.     call  MEM_Get_Heap_Number_Linear
  958.     test  eax,eax
  959.     jz    MEM_Add_Reference_Linear_ret
  960.     mov   ecx,[MEM_heap_block+ecx+.heap_linear_address]
  961.     sub   eax,ecx
  962.     shr   eax,10
  963.     and   eax,0xFFFFFFFC
  964.     test  dword [ecx+eax+.range_info],0x80000000
  965.     jnz   MEM_Add_Reference_Linear_failed
  966.     inc   dword [ecx+eax+.range_info]
  967.     mov   eax,1
  968. MEM_Add_Reference_Linear_ret:  
  969.     call  MEM_Heap_UnLock
  970.     pop   ecx
  971.     pop   ebx
  972.     ret
  973. MEM_Add_Reference_Linear_failed:
  974.     xor   eax,eax
  975.     jmp   MEM_Add_Reference_Linear_ret
  976. end if
  977. end if ;memmanager.inc
  978.