Subversion Repositories Kolibri OS

Rev

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