Rev 444 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 444 | Rev 453 | ||
---|---|---|---|
1 | $Revision: 431 $ |
1 | $Revision: 448 $ |
2 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
2 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
3 | ;; ;; |
3 | ;; ;; |
4 | ;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
4 | ;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
5 | ;; Distributed under terms of the GNU General Public License ;; |
5 | ;; Distributed under terms of the GNU General Public License ;; |
6 | ;; ;; |
6 | ;; ;; |
7 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
7 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
8 | 8 | ||
9 | struc MEM_BLOCK |
9 | struc MEM_BLOCK |
10 | { .next_block dd ? |
10 | { .next_block dd ? |
11 | .prev_block dd ? ;+4 |
11 | .prev_block dd ? ;+4 |
12 | .list_fd dd ? ;+8 |
12 | .list_fd dd ? ;+8 |
13 | .list_bk dd ? ;+12 |
13 | .list_bk dd ? ;+12 |
14 | .base dd ? ;+16 |
14 | .base dd ? ;+16 |
15 | .size dd ? ;+20 |
15 | .size dd ? ;+20 |
16 | .flags dd ? ;+24 |
16 | .flags dd ? ;+24 |
17 | .handle dd ? ;+28 |
17 | .handle dd ? ;+28 |
18 | } |
18 | } |
19 | 19 | ||
20 | MEM_LIST_OFFSET equ 8 |
20 | MEM_LIST_OFFSET equ 8 |
21 | FREE_BLOCK equ 4 |
21 | FREE_BLOCK equ 4 |
22 | USED_BLOCK equ 8 |
22 | USED_BLOCK equ 8 |
23 | 23 | ||
24 | virtual at 0 |
24 | virtual at 0 |
25 | MEM_BLOCK MEM_BLOCK |
25 | MEM_BLOCK MEM_BLOCK |
26 | end virtual |
26 | end virtual |
27 | 27 | ||
28 | MEM_BLOCK_SIZE equ 8*4 |
28 | MEM_BLOCK_SIZE equ 8*4 |
29 | 29 | ||
30 | block_next equ MEM_BLOCK.next_block |
30 | block_next equ MEM_BLOCK.next_block |
31 | block_prev equ MEM_BLOCK.prev_block |
31 | block_prev equ MEM_BLOCK.prev_block |
32 | list_fd equ MEM_BLOCK.list_fd |
32 | list_fd equ MEM_BLOCK.list_fd |
33 | list_bk equ MEM_BLOCK.list_bk |
33 | list_bk equ MEM_BLOCK.list_bk |
34 | block_base equ MEM_BLOCK.base |
34 | block_base equ MEM_BLOCK.base |
35 | block_size equ MEM_BLOCK.size |
35 | block_size equ MEM_BLOCK.size |
36 | block_flags equ MEM_BLOCK.flags |
36 | block_flags equ MEM_BLOCK.flags |
37 | 37 | ||
38 | macro calc_index op |
38 | macro calc_index op |
39 | { shr op, 12 |
39 | { shr op, 12 |
40 | dec op |
40 | dec op |
41 | cmp op, 63 |
41 | cmp op, 63 |
42 | jna @f |
42 | jna @f |
43 | mov op, 63 |
43 | mov op, 63 |
44 | @@: |
44 | @@: |
45 | } |
45 | } |
46 | 46 | ||
47 | macro remove_from_list op |
47 | macro remove_from_list op |
48 | { mov edx, [op+list_fd] |
48 | { mov edx, [op+list_fd] |
49 | mov ecx, [op+list_bk] |
49 | mov ecx, [op+list_bk] |
50 | test edx, edx |
50 | test edx, edx |
51 | jz @f |
51 | jz @f |
52 | mov [edx+list_bk], ecx |
52 | mov [edx+list_bk], ecx |
53 | @@: |
53 | @@: |
54 | test ecx, ecx |
54 | test ecx, ecx |
55 | jz @f |
55 | jz @f |
56 | mov [ecx+list_fd], edx |
56 | mov [ecx+list_fd], edx |
57 | @@: |
57 | @@: |
58 | mov [op+list_fd],0 |
58 | mov [op+list_fd],0 |
59 | mov [op+list_bk],0 |
59 | mov [op+list_bk],0 |
60 | } |
60 | } |
61 | 61 | ||
62 | macro remove_from_free op |
62 | macro remove_from_free op |
63 | { |
63 | { |
64 | remove_from_list op |
64 | remove_from_list op |
65 | 65 | ||
66 | mov eax, [op+block_size] |
66 | mov eax, [op+block_size] |
67 | calc_index eax |
67 | calc_index eax |
68 | cmp [mem_block_list+eax*4], op |
68 | cmp [mem_block_list+eax*4], op |
69 | jne @f |
69 | jne @f |
70 | mov [mem_block_list+eax*4], edx |
70 | mov [mem_block_list+eax*4], edx |
71 | @@: |
71 | @@: |
72 | cmp [mem_block_list+eax*4], 0 |
72 | cmp [mem_block_list+eax*4], 0 |
73 | jne @f |
73 | jne @f |
74 | btr [mem_block_mask], eax |
74 | btr [mem_block_mask], eax |
75 | @@: |
75 | @@: |
76 | } |
76 | } |
77 | 77 | ||
78 | macro remove_from_used op |
78 | macro remove_from_used op |
79 | { |
79 | { |
80 | mov edx, [op+list_fd] |
80 | mov edx, [op+list_fd] |
81 | mov ecx, [op+list_bk] |
81 | mov ecx, [op+list_bk] |
82 | mov [edx+list_bk], ecx |
82 | mov [edx+list_bk], ecx |
83 | mov [ecx+list_fd], edx |
83 | mov [ecx+list_fd], edx |
84 | mov [op+list_fd], 0 |
84 | mov [op+list_fd], 0 |
85 | mov [op+list_bk], 0 |
85 | mov [op+list_bk], 0 |
86 | } |
86 | } |
87 | 87 | ||
88 | align 4 |
88 | align 4 |
89 | proc init_kernel_heap |
89 | proc init_kernel_heap |
90 | 90 | ||
91 | mov ecx, 64/4 |
91 | mov ecx, 64/4 |
92 | mov edi, mem_block_list |
92 | mov edi, mem_block_list |
93 | xor eax, eax |
93 | xor eax, eax |
94 | cld |
94 | cld |
95 | rep stosd |
95 | rep stosd |
96 | 96 | ||
97 | mov ecx, 512/4 |
97 | mov ecx, 512/4 |
98 | mov edi, mem_block_map |
98 | mov edi, mem_block_map |
99 | not eax |
99 | not eax |
100 | rep stosd |
100 | rep stosd |
101 | 101 | ||
102 | mov [mem_block_start], mem_block_map |
102 | mov [mem_block_start], mem_block_map |
103 | mov [mem_block_end], mem_block_map+512 |
103 | mov [mem_block_end], mem_block_map+512 |
104 | mov [mem_block_arr], HEAP_BASE |
104 | mov [mem_block_arr], HEAP_BASE |
105 | 105 | ||
106 | mov eax, mem_used.fd-MEM_LIST_OFFSET |
106 | mov eax, mem_used.fd-MEM_LIST_OFFSET |
107 | mov [mem_used.fd], eax |
107 | mov [mem_used.fd], eax |
108 | mov [mem_used.bk], eax |
108 | mov [mem_used.bk], eax |
109 | 109 | ||
110 | stdcall alloc_pages, dword 32 |
110 | stdcall alloc_pages, dword 32 |
111 | mov ecx, 32 |
111 | mov ecx, 32 |
112 | mov edx, eax |
112 | mov edx, eax |
113 | mov edi, HEAP_BASE |
113 | mov edi, HEAP_BASE |
114 | .l1: |
114 | .l1: |
115 | stdcall map_page,edi,edx,PG_SW |
115 | stdcall map_page,edi,edx,PG_SW |
116 | add edi, 0x1000 |
116 | add edi, 0x1000 |
117 | add edx, 0x1000 |
117 | add edx, 0x1000 |
118 | dec ecx |
118 | dec ecx |
119 | jnz .l1 |
119 | jnz .l1 |
120 | 120 | ||
121 | mov edi, HEAP_BASE |
121 | mov edi, HEAP_BASE |
122 | mov ebx, HEAP_BASE+MEM_BLOCK_SIZE |
122 | mov ebx, HEAP_BASE+MEM_BLOCK_SIZE |
123 | xor eax, eax |
123 | xor eax, eax |
124 | mov [edi+block_next], ebx |
124 | mov [edi+block_next], ebx |
125 | mov [edi+block_prev], eax |
125 | mov [edi+block_prev], eax |
126 | mov [edi+list_fd], eax |
126 | mov [edi+list_fd], eax |
127 | mov [edi+list_bk], eax |
127 | mov [edi+list_bk], eax |
128 | mov [edi+block_base], HEAP_BASE |
128 | mov [edi+block_base], HEAP_BASE |
129 | mov [edi+block_size], 4096*MEM_BLOCK_SIZE |
129 | mov [edi+block_size], 4096*MEM_BLOCK_SIZE |
130 | mov [edi+block_flags], USED_BLOCK |
130 | mov [edi+block_flags], USED_BLOCK |
131 | 131 | ||
132 | mov [ebx+block_next], eax |
132 | mov [ebx+block_next], eax |
133 | mov [ebx+block_prev], eax |
133 | mov [ebx+block_prev], eax |
134 | mov [ebx+list_fd], eax |
134 | mov [ebx+list_fd], eax |
135 | mov [ebx+list_bk], eax |
135 | mov [ebx+list_bk], eax |
136 | mov [ebx+block_base], HEAP_BASE+4096*MEM_BLOCK_SIZE |
136 | mov [ebx+block_base], HEAP_BASE+4096*MEM_BLOCK_SIZE |
137 | 137 | ||
138 | mov ecx, [MEM_AMOUNT] |
138 | mov ecx, [MEM_AMOUNT] |
139 | sub ecx, HEAP_BASE + 4096*MEM_BLOCK_SIZE |
139 | sub ecx, HEAP_BASE + 4096*MEM_BLOCK_SIZE |
140 | mov [heap_size], ecx |
140 | mov [heap_size], ecx |
141 | mov [heap_free], ecx |
141 | mov [heap_free], ecx |
142 | mov [ebx+block_size], ecx |
142 | mov [ebx+block_size], ecx |
143 | mov [ebx+block_flags], FREE_BLOCK |
143 | mov [ebx+block_flags], FREE_BLOCK |
144 | 144 | ||
145 | mov [mem_block_mask], eax |
145 | mov [mem_block_mask], eax |
146 | mov [mem_block_mask+4],0x80000000 |
146 | mov [mem_block_mask+4],0x80000000 |
147 | 147 | ||
148 | mov [mem_block_list+63*4], ebx |
148 | mov [mem_block_list+63*4], ebx |
149 | mov byte [mem_block_map], 0xFC |
149 | mov byte [mem_block_map], 0xFC |
150 | and [heap_mutex], 0 |
150 | and [heap_mutex], 0 |
151 | mov [heap_blocks], 4095 |
151 | mov [heap_blocks], 4095 |
152 | mov [free_blocks], 4095 |
152 | mov [free_blocks], 4095 |
153 | ret |
153 | ret |
154 | endp |
154 | endp |
155 | 155 | ||
156 | ; param |
156 | ; param |
157 | ; eax= required size |
157 | ; eax= required size |
158 | ; |
158 | ; |
159 | ; retval |
159 | ; retval |
160 | ; edi= memory block descriptor |
160 | ; edi= memory block descriptor |
161 | ; ebx= descriptor index |
161 | ; ebx= descriptor index |
162 | 162 | ||
163 | align 4 |
163 | align 4 |
164 | get_block: |
164 | get_block: |
165 | mov ecx, eax |
165 | mov ecx, eax |
166 | shr ecx, 12 |
166 | shr ecx, 12 |
167 | dec ecx |
167 | dec ecx |
168 | cmp ecx, 63 |
168 | cmp ecx, 63 |
169 | jle .get_index |
169 | jle .get_index |
170 | mov ecx, 63 |
170 | mov ecx, 63 |
171 | .get_index: |
171 | .get_index: |
172 | lea esi, [mem_block_mask] |
172 | lea esi, [mem_block_mask] |
173 | xor ebx, ebx |
173 | xor ebx, ebx |
174 | or edx, -1 |
174 | or edx, -1 |
175 | 175 | ||
176 | cmp ecx, 32 |
176 | cmp ecx, 32 |
177 | jb .bit_test |
177 | jb .bit_test |
178 | 178 | ||
179 | sub ecx, 32 |
179 | sub ecx, 32 |
180 | add ebx, 32 |
180 | add ebx, 32 |
181 | add esi, 4 |
181 | add esi, 4 |
182 | .bit_test: |
182 | .bit_test: |
183 | shl edx, cl |
183 | shl edx, cl |
184 | and edx, [esi] |
184 | and edx, [esi] |
185 | .find: |
185 | .find: |
186 | bsf edi, edx |
186 | bsf edi, edx |
187 | jz .high_mask |
187 | jz .high_mask |
188 | add ebx, edi |
188 | add ebx, edi |
189 | mov edi, [mem_block_list+ebx*4] |
189 | mov edi, [mem_block_list+ebx*4] |
190 | .check_size: |
190 | .check_size: |
191 | cmp eax, [edi+block_size] |
191 | cmp eax, [edi+block_size] |
192 | ja .next |
192 | ja .next |
193 | ret |
193 | ret |
194 | 194 | ||
195 | .high_mask: |
195 | .high_mask: |
196 | add esi, 4 |
196 | add esi, 4 |
197 | cmp esi, mem_block_mask+8 |
197 | cmp esi, mem_block_mask+8 |
198 | jae .err |
198 | jae .err |
199 | add ebx, 32 |
199 | add ebx, 32 |
200 | mov edx, [esi] |
200 | mov edx, [esi] |
201 | jmp .find |
201 | jmp .find |
202 | .next: |
202 | .next: |
203 | mov edi, [edi+list_fd] |
203 | mov edi, [edi+list_fd] |
204 | test edi, edi |
204 | test edi, edi |
205 | jnz .check_size |
205 | jnz .check_size |
206 | .err: |
206 | .err: |
207 | xor edi, edi |
207 | xor edi, edi |
208 | ret |
208 | ret |
209 | 209 | ||
210 | align 4 |
210 | align 4 |
211 | proc alloc_mem_block |
211 | proc alloc_mem_block |
212 | 212 | ||
213 | mov ebx, [mem_block_start] |
213 | mov ebx, [mem_block_start] |
214 | mov ecx, [mem_block_end] |
214 | mov ecx, [mem_block_end] |
215 | .l1: |
215 | .l1: |
216 | bsf eax,[ebx]; |
216 | bsf eax,[ebx]; |
217 | jnz found |
217 | jnz found |
218 | add ebx,4 |
218 | add ebx,4 |
219 | cmp ebx, ecx |
219 | cmp ebx, ecx |
220 | jb .l1 |
220 | jb .l1 |
221 | xor eax,eax |
221 | xor eax,eax |
222 | ret |
222 | ret |
223 | 223 | ||
224 | found: |
224 | found: |
225 | btr [ebx], eax |
225 | btr [ebx], eax |
226 | mov [mem_block_start],ebx |
226 | mov [mem_block_start],ebx |
227 | sub ebx, mem_block_map |
227 | sub ebx, mem_block_map |
228 | lea eax,[eax+ebx*8] |
228 | lea eax,[eax+ebx*8] |
229 | shl eax, 5 |
229 | shl eax, 5 |
230 | add eax, [mem_block_arr] |
230 | add eax, [mem_block_arr] |
231 | dec [free_blocks] |
231 | dec [free_blocks] |
232 | ret |
232 | ret |
233 | endp |
233 | endp |
234 | 234 | ||
235 | proc free_mem_block |
235 | proc free_mem_block |
236 | mov dword [eax], 0 |
236 | mov dword [eax], 0 |
237 | mov dword [eax+4], 0 |
237 | mov dword [eax+4], 0 |
238 | mov dword [eax+8], 0 |
238 | mov dword [eax+8], 0 |
239 | mov dword [eax+12], 0 |
239 | mov dword [eax+12], 0 |
240 | mov dword [eax+16], 0 |
240 | mov dword [eax+16], 0 |
241 | ; mov dword [eax+20], 0 |
241 | ; mov dword [eax+20], 0 |
242 | mov dword [eax+24], 0 |
242 | mov dword [eax+24], 0 |
243 | mov dword [eax+28], 0 |
243 | mov dword [eax+28], 0 |
244 | 244 | ||
245 | sub eax, [mem_block_arr] |
245 | sub eax, [mem_block_arr] |
246 | shr eax, 5 |
246 | shr eax, 5 |
247 | 247 | ||
248 | mov ebx, mem_block_map |
248 | mov ebx, mem_block_map |
249 | bts [ebx], eax |
249 | bts [ebx], eax |
250 | inc [free_blocks] |
250 | inc [free_blocks] |
251 | shr eax, 3 |
251 | shr eax, 3 |
252 | and eax, not 3 |
252 | and eax, not 3 |
253 | add eax, ebx |
253 | add eax, ebx |
254 | cmp [mem_block_start], eax |
254 | cmp [mem_block_start], eax |
255 | ja @f |
255 | ja @f |
256 | ret |
256 | ret |
257 | @@: |
257 | @@: |
258 | mov [mem_block_start], eax |
258 | mov [mem_block_start], eax |
259 | ret |
259 | ret |
260 | .err: |
260 | .err: |
261 | xor eax, eax |
261 | xor eax, eax |
262 | ret |
262 | ret |
263 | endp |
263 | endp |
264 | 264 | ||
265 | align 4 |
265 | align 4 |
266 | proc alloc_kernel_space stdcall, size:dword |
266 | proc alloc_kernel_space stdcall, size:dword |
267 | local block_ind:DWORD |
267 | local block_ind:DWORD |
268 | 268 | ||
269 | mov eax, [size] |
269 | mov eax, [size] |
270 | add eax, 4095 |
270 | add eax, 4095 |
271 | and eax, not 4095 |
271 | and eax, not 4095 |
272 | mov [size], eax |
272 | mov [size], eax |
273 | 273 | ||
274 | mov ebx, heap_mutex |
274 | mov ebx, heap_mutex |
275 | call wait_mutex ;ebx |
275 | call wait_mutex ;ebx |
276 | 276 | ||
277 | cmp eax, [heap_free] |
277 | cmp eax, [heap_free] |
278 | ja .error |
278 | ja .error |
279 | 279 | ||
280 | call get_block ; eax |
280 | call get_block ; eax |
281 | test edi, edi |
281 | test edi, edi |
282 | jz .error |
282 | jz .error |
283 | 283 | ||
284 | cmp [edi+block_flags], FREE_BLOCK |
284 | cmp [edi+block_flags], FREE_BLOCK |
285 | jne .error |
285 | jne .error |
286 | 286 | ||
287 | mov [block_ind], ebx ;index of allocated block |
287 | mov [block_ind], ebx ;index of allocated block |
288 | 288 | ||
289 | mov eax, [edi+block_size] |
289 | mov eax, [edi+block_size] |
290 | cmp eax, [size] |
290 | cmp eax, [size] |
291 | je .m_eq_size |
291 | je .m_eq_size |
292 | 292 | ||
293 | call alloc_mem_block |
293 | call alloc_mem_block |
294 | and eax, eax |
294 | and eax, eax |
295 | jz .error |
295 | jz .error |
296 | 296 | ||
297 | mov esi, eax ;esi - splitted block |
297 | mov esi, eax ;esi - splitted block |
298 | 298 | ||
299 | mov [esi+block_next], edi |
299 | mov [esi+block_next], edi |
300 | mov eax, [edi+block_prev] |
300 | mov eax, [edi+block_prev] |
301 | mov [esi+block_prev], eax |
301 | mov [esi+block_prev], eax |
302 | mov [edi+block_prev], esi |
302 | mov [edi+block_prev], esi |
303 | mov [esi+list_fd], 0 |
303 | mov [esi+list_fd], 0 |
304 | mov [esi+list_bk], 0 |
304 | mov [esi+list_bk], 0 |
305 | and eax, eax |
305 | and eax, eax |
306 | jz @f |
306 | jz @f |
307 | mov [eax+block_next], esi |
307 | mov [eax+block_next], esi |
308 | @@: |
308 | @@: |
309 | mov ebx, [edi+block_base] |
309 | mov ebx, [edi+block_base] |
310 | mov [esi+block_base], ebx |
310 | mov [esi+block_base], ebx |
311 | mov edx, [size] |
311 | mov edx, [size] |
312 | mov [esi+block_size], edx |
312 | mov [esi+block_size], edx |
313 | add [edi+block_base], edx |
313 | add [edi+block_base], edx |
314 | sub [edi+block_size], edx |
314 | sub [edi+block_size], edx |
315 | 315 | ||
316 | mov eax, [edi+block_size] |
316 | mov eax, [edi+block_size] |
317 | shr eax, 12 |
317 | shr eax, 12 |
318 | sub eax, 1 |
318 | sub eax, 1 |
319 | cmp eax, 63 |
319 | cmp eax, 63 |
320 | jna @f |
320 | jna @f |
321 | mov eax, 63 |
321 | mov eax, 63 |
322 | @@: |
322 | @@: |
323 | cmp eax, [block_ind] |
323 | cmp eax, [block_ind] |
324 | je .m_eq_ind |
324 | je .m_eq_ind |
325 | 325 | ||
326 | remove_from_list edi |
326 | remove_from_list edi |
327 | 327 | ||
328 | mov ecx, [block_ind] |
328 | mov ecx, [block_ind] |
329 | mov [mem_block_list+ecx*4], edx |
329 | mov [mem_block_list+ecx*4], edx |
330 | 330 | ||
331 | test edx, edx |
331 | test edx, edx |
332 | jnz @f |
332 | jnz @f |
333 | btr [mem_block_mask], ecx |
333 | btr [mem_block_mask], ecx |
334 | @@: |
334 | @@: |
335 | mov edx, [mem_block_list+eax*4] |
335 | mov edx, [mem_block_list+eax*4] |
336 | mov [edi+list_fd], edx |
336 | mov [edi+list_fd], edx |
337 | test edx, edx |
337 | test edx, edx |
338 | jz @f |
338 | jz @f |
339 | mov [edx+list_bk], edi |
339 | mov [edx+list_bk], edi |
340 | @@: |
340 | @@: |
341 | mov [mem_block_list+eax*4], edi |
341 | mov [mem_block_list+eax*4], edi |
342 | bts [mem_block_mask], eax |
342 | bts [mem_block_mask], eax |
343 | .m_eq_ind: |
343 | .m_eq_ind: |
344 | mov ecx, mem_used.fd-MEM_LIST_OFFSET |
344 | mov ecx, mem_used.fd-MEM_LIST_OFFSET |
345 | mov edx, [ecx+list_fd] |
345 | mov edx, [ecx+list_fd] |
346 | mov [esi+list_fd], edx |
346 | mov [esi+list_fd], edx |
347 | mov [esi+list_bk], ecx |
347 | mov [esi+list_bk], ecx |
348 | mov [ecx+list_fd], esi |
348 | mov [ecx+list_fd], esi |
349 | mov [edx+list_bk], esi |
349 | mov [edx+list_bk], esi |
350 | 350 | ||
351 | mov [esi+block_flags], USED_BLOCK |
351 | mov [esi+block_flags], USED_BLOCK |
352 | mov eax, [esi+block_base] |
352 | mov eax, [esi+block_base] |
353 | mov ebx, [size] |
353 | mov ebx, [size] |
354 | sub [heap_free], ebx |
354 | sub [heap_free], ebx |
355 | and [heap_mutex], 0 |
355 | and [heap_mutex], 0 |
356 | ret |
356 | ret |
357 | .m_eq_size: |
357 | .m_eq_size: |
358 | remove_from_list edi |
358 | remove_from_list edi |
359 | mov [mem_block_list+ebx*4], edx |
359 | mov [mem_block_list+ebx*4], edx |
360 | and edx, edx |
360 | and edx, edx |
361 | jnz @f |
361 | jnz @f |
362 | btr [mem_block_mask], ebx |
362 | btr [mem_block_mask], ebx |
363 | @@: |
363 | @@: |
364 | mov ecx, mem_used.fd-MEM_LIST_OFFSET |
364 | mov ecx, mem_used.fd-MEM_LIST_OFFSET |
365 | mov edx, [ecx+list_fd] |
365 | mov edx, [ecx+list_fd] |
366 | mov [edi+list_fd], edx |
366 | mov [edi+list_fd], edx |
367 | mov [edi+list_bk], ecx |
367 | mov [edi+list_bk], ecx |
368 | mov [ecx+list_fd], edi |
368 | mov [ecx+list_fd], edi |
369 | mov [edx+list_bk], edi |
369 | mov [edx+list_bk], edi |
370 | 370 | ||
371 | mov [edi+block_flags], USED_BLOCK |
371 | mov [edi+block_flags], USED_BLOCK |
372 | mov eax, [edi+block_base] |
372 | mov eax, [edi+block_base] |
373 | mov ebx, [size] |
373 | mov ebx, [size] |
374 | sub [heap_free], ebx |
374 | sub [heap_free], ebx |
375 | and [heap_mutex], 0 |
375 | and [heap_mutex], 0 |
376 | ret |
376 | ret |
377 | .error: |
377 | .error: |
378 | xor eax, eax |
378 | xor eax, eax |
379 | mov [heap_mutex], eax |
379 | mov [heap_mutex], eax |
380 | ret |
380 | ret |
381 | endp |
381 | endp |
382 | 382 | ||
383 | align 4 |
383 | align 4 |
384 | proc free_kernel_space stdcall uses ebx ecx edx esi edi, base:dword |
384 | proc free_kernel_space stdcall uses ebx ecx edx esi edi, base:dword |
385 | 385 | ||
386 | mov ebx, heap_mutex |
386 | mov ebx, heap_mutex |
387 | call wait_mutex ;ebx |
387 | call wait_mutex ;ebx |
388 | 388 | ||
389 | mov eax, [base] |
389 | mov eax, [base] |
390 | mov esi, [mem_used.fd] |
390 | mov esi, [mem_used.fd] |
391 | @@: |
391 | @@: |
392 | cmp esi, mem_used.fd-MEM_LIST_OFFSET |
392 | cmp esi, mem_used.fd-MEM_LIST_OFFSET |
393 | je .fail |
393 | je .fail |
394 | 394 | ||
395 | cmp [esi+block_base], eax |
395 | cmp [esi+block_base], eax |
396 | je .found |
396 | je .found |
397 | mov esi, [esi+list_fd] |
397 | mov esi, [esi+list_fd] |
398 | jmp @b |
398 | jmp @b |
399 | .found: |
399 | .found: |
400 | cmp [esi+block_flags], USED_BLOCK |
400 | cmp [esi+block_flags], USED_BLOCK |
401 | jne .fail |
401 | jne .fail |
402 | 402 | ||
403 | mov eax, [esi+block_size] |
403 | mov eax, [esi+block_size] |
404 | add [heap_free], eax |
404 | add [heap_free], eax |
405 | 405 | ||
406 | mov edi, [esi+block_next] |
406 | mov edi, [esi+block_next] |
407 | test edi, edi |
407 | test edi, edi |
408 | jz .prev |
408 | jz .prev |
409 | 409 | ||
410 | cmp [edi+block_flags], FREE_BLOCK |
410 | cmp [edi+block_flags], FREE_BLOCK |
411 | jne .prev |
411 | jne .prev |
412 | 412 | ||
413 | remove_from_free edi |
413 | remove_from_free edi |
414 | 414 | ||
415 | mov edx, [edi+block_next] |
415 | mov edx, [edi+block_next] |
416 | mov [esi+block_next], edx |
416 | mov [esi+block_next], edx |
417 | test edx, edx |
417 | test edx, edx |
418 | jz @f |
418 | jz @f |
419 | 419 | ||
420 | mov [edx+block_prev], esi |
420 | mov [edx+block_prev], esi |
421 | @@: |
421 | @@: |
422 | mov ecx, [edi+block_size] |
422 | mov ecx, [edi+block_size] |
423 | add [esi+block_size], ecx |
423 | add [esi+block_size], ecx |
424 | 424 | ||
425 | mov eax, edi |
425 | mov eax, edi |
426 | call free_mem_block |
426 | call free_mem_block |
427 | .prev: |
427 | .prev: |
428 | mov edi, [esi+block_prev] |
428 | mov edi, [esi+block_prev] |
429 | test edi, edi |
429 | test edi, edi |
430 | jz .insert |
430 | jz .insert |
431 | 431 | ||
432 | cmp [edi+block_flags], FREE_BLOCK |
432 | cmp [edi+block_flags], FREE_BLOCK |
433 | jne .insert |
433 | jne .insert |
434 | 434 | ||
435 | remove_from_used esi |
435 | remove_from_used esi |
436 | 436 | ||
437 | mov edx, [esi+block_next] |
437 | mov edx, [esi+block_next] |
438 | mov [edi+block_next], edx |
438 | mov [edi+block_next], edx |
439 | test edx, edx |
439 | test edx, edx |
440 | jz @f |
440 | jz @f |
441 | mov [edx+block_prev], edi |
441 | mov [edx+block_prev], edi |
442 | @@: |
442 | @@: |
443 | mov eax, esi |
443 | mov eax, esi |
444 | call free_mem_block |
444 | call free_mem_block |
445 | 445 | ||
446 | mov ecx, [edi+block_size] |
446 | mov ecx, [edi+block_size] |
447 | mov eax, [esi+block_size] |
447 | mov eax, [esi+block_size] |
448 | add eax, ecx |
448 | add eax, ecx |
449 | mov [edi+block_size], eax |
449 | mov [edi+block_size], eax |
450 | 450 | ||
451 | calc_index eax |
451 | calc_index eax |
452 | calc_index ecx |
452 | calc_index ecx |
453 | cmp eax, ecx |
453 | cmp eax, ecx |
454 | je .m_eq |
454 | je .m_eq |
455 | 455 | ||
456 | push ecx |
456 | push ecx |
457 | remove_from_list edi |
457 | remove_from_list edi |
458 | pop ecx |
458 | pop ecx |
459 | 459 | ||
460 | cmp [mem_block_list+ecx*4], edi |
460 | cmp [mem_block_list+ecx*4], edi |
461 | jne @f |
461 | jne @f |
462 | mov [mem_block_list+ecx*4], edx |
462 | mov [mem_block_list+ecx*4], edx |
463 | @@: |
463 | @@: |
464 | cmp [mem_block_list+ecx*4], 0 |
464 | cmp [mem_block_list+ecx*4], 0 |
465 | jne @f |
465 | jne @f |
466 | btr [mem_block_mask], ecx |
466 | btr [mem_block_mask], ecx |
467 | @@: |
467 | @@: |
468 | mov esi, [mem_block_list+eax*4] |
468 | mov esi, [mem_block_list+eax*4] |
469 | mov [mem_block_list+eax*4], edi |
469 | mov [mem_block_list+eax*4], edi |
470 | mov [edi+list_fd], esi |
470 | mov [edi+list_fd], esi |
471 | test esi, esi |
471 | test esi, esi |
472 | jz @f |
472 | jz @f |
473 | mov [esi+list_bk], edi |
473 | mov [esi+list_bk], edi |
474 | @@: |
474 | @@: |
475 | bts [mem_block_mask], eax |
475 | bts [mem_block_mask], eax |
476 | .m_eq: |
476 | .m_eq: |
477 | xor eax, eax |
477 | xor eax, eax |
478 | mov [heap_mutex], eax |
478 | mov [heap_mutex], eax |
479 | dec eax |
479 | dec eax |
480 | ret |
480 | ret |
481 | .insert: |
481 | .insert: |
482 | remove_from_used esi |
482 | remove_from_used esi |
483 | 483 | ||
484 | mov eax, [esi+block_size] |
484 | mov eax, [esi+block_size] |
485 | calc_index eax |
485 | calc_index eax |
486 | 486 | ||
487 | mov edi, [mem_block_list+eax*4] |
487 | mov edi, [mem_block_list+eax*4] |
488 | mov [mem_block_list+eax*4], esi |
488 | mov [mem_block_list+eax*4], esi |
489 | mov [esi+list_fd], edi |
489 | mov [esi+list_fd], edi |
490 | test edi, edi |
490 | test edi, edi |
491 | jz @f |
491 | jz @f |
492 | mov [edi+list_bk], esi |
492 | mov [edi+list_bk], esi |
493 | @@: |
493 | @@: |
494 | bts [mem_block_mask], eax |
494 | bts [mem_block_mask], eax |
495 | mov [esi+block_flags],FREE_BLOCK |
495 | mov [esi+block_flags],FREE_BLOCK |
496 | xor eax, eax |
496 | xor eax, eax |
497 | mov [heap_mutex], eax |
497 | mov [heap_mutex], eax |
498 | dec eax |
498 | dec eax |
499 | ret |
499 | ret |
500 | .fail: |
500 | .fail: |
501 | xor eax, eax |
501 | xor eax, eax |
502 | mov [heap_mutex], eax |
502 | mov [heap_mutex], eax |
503 | ret |
503 | ret |
504 | endp |
504 | endp |
505 | 505 | ||
506 | align 4 |
506 | align 4 |
507 | proc kernel_alloc stdcall, size:dword |
507 | proc kernel_alloc stdcall, size:dword |
508 | locals |
508 | locals |
509 | lin_addr dd ? |
509 | lin_addr dd ? |
510 | pages_count dd ? |
510 | pages_count dd ? |
511 | endl |
511 | endl |
512 | 512 | ||
513 | mov eax, [size] |
513 | mov eax, [size] |
514 | add eax, 4095 |
514 | add eax, 4095 |
515 | and eax, not 4095; |
515 | and eax, not 4095; |
516 | mov [size], eax |
516 | mov [size], eax |
517 | and eax, eax |
517 | and eax, eax |
518 | jz .err |
518 | jz .err |
519 | mov ebx, eax |
519 | mov ebx, eax |
520 | shr ebx, 12 |
520 | shr ebx, 12 |
521 | mov [pages_count], ebx |
521 | mov [pages_count], ebx |
522 | 522 | ||
523 | stdcall alloc_kernel_space, eax |
523 | stdcall alloc_kernel_space, eax |
524 | test eax, eax |
524 | test eax, eax |
525 | jz .err |
525 | jz .err |
526 | mov [lin_addr], eax |
526 | mov [lin_addr], eax |
527 | 527 | ||
528 | mov ecx, [pages_count] |
528 | mov ecx, [pages_count] |
529 | mov edx, eax |
529 | mov edx, eax |
530 | mov ebx, ecx |
530 | mov ebx, ecx |
531 | 531 | ||
532 | shr ecx, 3 |
532 | shr ecx, 3 |
533 | jz .next |
533 | jz .next |
534 | 534 | ||
535 | and ebx, not 7 |
535 | and ebx, not 7 |
536 | push ebx |
536 | push ebx |
537 | stdcall alloc_pages, ebx |
537 | stdcall alloc_pages, ebx |
538 | pop ecx ; yes ecx!!! |
538 | pop ecx ; yes ecx!!! |
539 | and eax, eax |
539 | and eax, eax |
540 | jz .err |
540 | jz .err |
541 | 541 | ||
542 | mov edi, eax |
542 | mov edi, eax |
543 | mov edx, [lin_addr] |
543 | mov edx, [lin_addr] |
544 | @@: |
544 | @@: |
545 | stdcall map_page,edx,edi,dword PG_SW |
545 | stdcall map_page,edx,edi,dword PG_SW |
546 | add edx, 0x1000 |
546 | add edx, 0x1000 |
547 | add edi, 0x1000 |
547 | add edi, 0x1000 |
548 | dec ecx |
548 | dec ecx |
549 | jnz @B |
549 | jnz @B |
550 | .next: |
550 | .next: |
551 | mov ecx, [pages_count] |
551 | mov ecx, [pages_count] |
552 | and ecx, 7 |
552 | and ecx, 7 |
553 | jz .end |
553 | jz .end |
554 | @@: |
554 | @@: |
555 | push ecx |
555 | push ecx |
556 | call alloc_page |
556 | call alloc_page |
557 | pop ecx |
557 | pop ecx |
558 | test eax, eax |
558 | test eax, eax |
559 | jz .err |
559 | jz .err |
560 | 560 | ||
561 | stdcall map_page,edx,eax,dword PG_SW |
561 | stdcall map_page,edx,eax,dword PG_SW |
562 | add edx, 0x1000 |
562 | add edx, 0x1000 |
563 | dec ecx |
563 | dec ecx |
564 | jnz @B |
564 | jnz @B |
565 | .end: |
565 | .end: |
566 | mov eax, [lin_addr] |
566 | mov eax, [lin_addr] |
567 | ret |
567 | ret |
568 | .err: |
568 | .err: |
569 | xor eax, eax |
569 | xor eax, eax |
570 | ret |
570 | ret |
571 | endp |
571 | endp |
572 | 572 | ||
573 | align 4 |
573 | align 4 |
574 | proc kernel_free stdcall, base:dword |
574 | proc kernel_free stdcall, base:dword |
575 | push ebx esi |
575 | push ebx esi |
576 | 576 | ||
577 | mov ebx, heap_mutex |
577 | mov ebx, heap_mutex |
578 | call wait_mutex ;ebx |
578 | call wait_mutex ;ebx |
579 | 579 | ||
580 | mov eax, [base] |
580 | mov eax, [base] |
581 | mov esi, [mem_used.fd] |
581 | mov esi, [mem_used.fd] |
582 | @@: |
582 | @@: |
583 | cmp esi, mem_used.fd-MEM_LIST_OFFSET |
583 | cmp esi, mem_used.fd-MEM_LIST_OFFSET |
584 | je .fail |
584 | je .fail |
585 | 585 | ||
586 | cmp [esi+block_base], eax |
586 | cmp [esi+block_base], eax |
587 | je .found |
587 | je .found |
588 | mov esi, [esi+list_fd] |
588 | mov esi, [esi+list_fd] |
589 | jmp @b |
589 | jmp @b |
590 | .found: |
590 | .found: |
591 | cmp [esi+block_flags], USED_BLOCK |
591 | cmp [esi+block_flags], USED_BLOCK |
592 | jne .fail |
592 | jne .fail |
593 | 593 | ||
594 | and [heap_mutex], 0 |
594 | and [heap_mutex], 0 |
595 | 595 | ||
596 | push ecx |
596 | push ecx |
597 | mov ecx, [esi+block_size]; |
597 | mov ecx, [esi+block_size]; |
598 | shr ecx, 12 |
598 | shr ecx, 12 |
599 | call release_pages ;eax, ecx |
599 | call release_pages ;eax, ecx |
600 | pop ecx |
600 | pop ecx |
601 | stdcall free_kernel_space, [base] |
601 | stdcall free_kernel_space, [base] |
602 | pop esi ebx |
602 | pop esi ebx |
603 | ret |
603 | ret |
604 | .fail: |
604 | .fail: |
605 | and [heap_mutex], 0 |
605 | and [heap_mutex], 0 |
606 | pop esi ebx |
606 | pop esi ebx |
607 | ret |
607 | ret |
608 | endp |
608 | endp |
609 | 609 | ||
610 | restore block_next |
610 | restore block_next |
611 | restore block_prev |
611 | restore block_prev |
612 | restore block_list |
612 | restore block_list |
613 | restore block_base |
613 | restore block_base |
614 | restore block_size |
614 | restore block_size |
615 | restore block_flags |
615 | restore block_flags |
616 | 616 | ||
617 | ;;;;;;;;;;;;;; USER ;;;;;;;;;;;;;;;;; |
617 | ;;;;;;;;;;;;;; USER ;;;;;;;;;;;;;;;;; |
618 | 618 | ||
619 | HEAP_TOP equ 0x5FC00000 |
619 | HEAP_TOP equ 0x5FC00000 |
620 | 620 | ||
621 | align 4 |
621 | align 4 |
622 | proc init_heap |
622 | proc init_heap |
623 | 623 | ||
624 | mov ebx,[current_slot] |
624 | mov ebx,[current_slot] |
625 | mov eax, [ebx+APPDATA.heap_top] |
625 | mov eax, [ebx+APPDATA.heap_top] |
626 | test eax, eax |
626 | test eax, eax |
627 | jz @F |
627 | jz @F |
628 | sub eax,[ebx+APPDATA.heap_base] |
628 | sub eax,[ebx+APPDATA.heap_base] |
629 | sub eax, 4096 |
629 | sub eax, 4096 |
630 | ret |
630 | ret |
631 | @@: |
631 | @@: |
632 | mov esi, [ebx+APPDATA.mem_size] |
632 | mov esi, [ebx+APPDATA.mem_size] |
633 | add esi, 4095 |
633 | add esi, 4095 |
634 | and esi, not 4095 |
634 | and esi, not 4095 |
635 | mov [ebx+APPDATA.mem_size], esi |
635 | mov [ebx+APPDATA.mem_size], esi |
636 | mov eax, HEAP_TOP |
636 | mov eax, HEAP_TOP |
637 | mov [ebx+APPDATA.heap_base], esi |
637 | mov [ebx+APPDATA.heap_base], esi |
638 | mov [ebx+APPDATA.heap_top], eax |
638 | mov [ebx+APPDATA.heap_top], eax |
639 | 639 | ||
640 | sub eax, esi |
640 | sub eax, esi |
641 | ; add esi, new_app_base |
641 | ; add esi, new_app_base |
642 | shr esi, 10 |
642 | shr esi, 10 |
643 | mov ecx, eax |
643 | mov ecx, eax |
644 | sub eax, 4096 |
644 | sub eax, 4096 |
645 | or ecx, FREE_BLOCK |
645 | or ecx, FREE_BLOCK |
646 | mov [page_tabs+esi], ecx |
646 | mov [page_tabs+esi], ecx |
647 | ret |
647 | ret |
648 | .exit: |
648 | .exit: |
649 | xor eax, eax |
649 | xor eax, eax |
650 | ret |
650 | ret |
651 | endp |
651 | endp |
652 | 652 | ||
653 | align 4 |
653 | align 4 |
654 | proc user_alloc stdcall, alloc_size:dword |
654 | proc user_alloc stdcall, alloc_size:dword |
655 | 655 | ||
656 | mov ecx, [alloc_size] |
656 | mov ecx, [alloc_size] |
657 | add ecx, (4095+4096) |
657 | add ecx, (4095+4096) |
658 | and ecx, not 4095 |
658 | and ecx, not 4095 |
659 | 659 | ||
660 | mov ebx, [current_slot] |
660 | mov ebx, [current_slot] |
661 | mov esi, dword [ebx+APPDATA.heap_base] ; heap_base |
661 | mov esi, dword [ebx+APPDATA.heap_base] ; heap_base |
662 | mov edi, dword [ebx+APPDATA.heap_top] ; heap_top |
662 | mov edi, dword [ebx+APPDATA.heap_top] ; heap_top |
663 | l_0: |
663 | l_0: |
664 | cmp esi, edi |
664 | cmp esi, edi |
665 | jae m_exit |
665 | jae m_exit |
666 | 666 | ||
667 | mov ebx, esi |
667 | mov ebx, esi |
668 | shr ebx, 12 |
668 | shr ebx, 12 |
669 | mov eax, [page_tabs+ebx*4] |
669 | mov eax, [page_tabs+ebx*4] |
670 | test eax, FREE_BLOCK |
670 | test eax, FREE_BLOCK |
671 | jz test_used |
671 | jz test_used |
672 | and eax, 0xFFFFF000 |
672 | and eax, 0xFFFFF000 |
673 | cmp eax, ecx ;alloc_size |
673 | cmp eax, ecx ;alloc_size |
674 | jb m_next |
674 | jb m_next |
675 | jz @f |
675 | jz @f |
676 | 676 | ||
677 | mov edx, esi |
677 | mov edx, esi |
678 | add edx, ecx |
678 | add edx, ecx |
679 | sub eax, ecx; |
679 | sub eax, ecx; |
680 | or eax, FREE_BLOCK |
680 | or eax, FREE_BLOCK |
681 | shr edx, 12 |
681 | shr edx, 12 |
682 | mov [page_tabs+edx*4], eax |
682 | mov [page_tabs+edx*4], eax |
683 | @@: |
683 | @@: |
684 | or ecx, USED_BLOCK |
684 | or ecx, USED_BLOCK |
685 | mov [page_tabs+ebx*4], ecx |
685 | mov [page_tabs+ebx*4], ecx |
686 | shr ecx, 12 |
686 | shr ecx, 12 |
687 | dec ecx |
687 | dec ecx |
688 | inc ebx |
688 | inc ebx |
689 | @@: |
689 | @@: |
690 | mov dword [page_tabs+ebx*4], 2 |
690 | mov dword [page_tabs+ebx*4], 2 |
691 | inc ebx |
691 | inc ebx |
692 | dec ecx |
692 | dec ecx |
693 | jnz @B |
693 | jnz @B |
694 | 694 | ||
695 | mov edx, [current_slot] |
695 | mov edx, [current_slot] |
696 | mov ebx, [alloc_size] |
696 | mov ebx, [alloc_size] |
697 | add ebx, 0xFFF |
697 | add ebx, 0xFFF |
698 | and ebx, not 0xFFF |
698 | and ebx, not 0xFFF |
699 | add ebx, [edx+APPDATA.mem_size] |
699 | add ebx, [edx+APPDATA.mem_size] |
700 | call update_mem_size |
700 | call update_mem_size |
701 | 701 | ||
702 | mov eax, esi |
702 | mov eax, esi |
703 | add eax, 4096 |
703 | add eax, 4096 |
704 | ret |
704 | ret |
705 | m_next: |
705 | m_next: |
706 | add esi, eax |
706 | add esi, eax |
707 | jmp l_0 |
707 | jmp l_0 |
708 | test_used: |
708 | test_used: |
709 | test eax, USED_BLOCK |
709 | test eax, USED_BLOCK |
710 | jz m_exit |
710 | jz m_exit |
711 | 711 | ||
712 | and eax, 0xFFFFF000 |
712 | and eax, 0xFFFFF000 |
713 | add esi, eax |
713 | add esi, eax |
714 | jmp l_0 |
714 | jmp l_0 |
715 | m_exit: |
715 | m_exit: |
716 | xor eax, eax |
716 | xor eax, eax |
717 | ret |
717 | ret |
718 | endp |
718 | endp |
719 | 719 | ||
720 | align 4 |
720 | align 4 |
721 | proc user_free stdcall, base:dword |
721 | proc user_free stdcall, base:dword |
722 | 722 | ||
723 | mov esi, [base] |
723 | mov esi, [base] |
724 | test esi, esi |
724 | test esi, esi |
725 | jz .exit |
725 | jz .exit |
726 | 726 | ||
727 | xor ebx, ebx |
727 | xor ebx, ebx |
728 | sub esi, 4096 |
728 | sub esi, 4096 |
729 | shr esi, 12 |
729 | shr esi, 12 |
730 | mov eax, [page_tabs+esi*4] |
730 | mov eax, [page_tabs+esi*4] |
731 | test eax, USED_BLOCK |
731 | test eax, USED_BLOCK |
732 | jz .not_used |
732 | jz .not_used |
733 | 733 | ||
734 | and eax, not 4095 |
734 | and eax, not 4095 |
735 | mov ecx, eax |
735 | mov ecx, eax |
736 | or eax, FREE_BLOCK |
736 | or eax, FREE_BLOCK |
737 | mov [page_tabs+esi*4], eax |
737 | mov [page_tabs+esi*4], eax |
738 | inc esi |
738 | inc esi |
739 | sub ecx, 4096 |
739 | sub ecx, 4096 |
740 | shr ecx, 12 |
740 | shr ecx, 12 |
741 | mov ebx, ecx |
741 | mov ebx, ecx |
742 | .release: |
742 | .release: |
743 | xor eax, eax |
743 | xor eax, eax |
744 | xchg eax, [page_tabs+esi*4] |
744 | xchg eax, [page_tabs+esi*4] |
745 | test eax, 1 |
745 | test eax, 1 |
746 | jz @F |
746 | jz @F |
747 | call free_page |
747 | call free_page |
- | 748 | mov eax, esi |
|
- | 749 | shl eax, 12 |
|
- | 750 | invlpg [eax] |
|
748 | @@: |
751 | @@: |
749 | inc esi |
752 | inc esi |
750 | dec ecx |
753 | dec ecx |
751 | jnz .release |
754 | jnz .release |
752 | .not_used: |
755 | .not_used: |
753 | mov edx, [current_slot] |
756 | mov edx, [current_slot] |
754 | mov esi, dword [edx+APPDATA.heap_base] |
757 | mov esi, dword [edx+APPDATA.heap_base] |
755 | mov edi, dword [edx+APPDATA.heap_top] |
758 | mov edi, dword [edx+APPDATA.heap_top] |
756 | sub ebx, [edx+APPDATA.mem_size] |
759 | sub ebx, [edx+APPDATA.mem_size] |
757 | neg ebx |
760 | neg ebx |
758 | call update_mem_size |
761 | call update_mem_size |
- | 762 | call user_normalize |
|
- | 763 | ret |
|
- | 764 | .exit: |
|
- | 765 | xor eax, eax |
|
- | 766 | inc eax |
|
- | 767 | ret |
|
- | 768 | endp |
|
- | 769 | ||
- | 770 | user_normalize: |
|
- | 771 | ; in: esi=heap_base, edi=heap_top |
|
- | 772 | ; out: eax=0 <=> OK |
|
- | 773 | ; destroys: ebx,edx,esi,edi |
|
759 | shr esi, 12 |
774 | shr esi, 12 |
760 | shr edi, 12 |
775 | shr edi, 12 |
761 | @@: |
776 | @@: |
762 | mov eax, [page_tabs+esi*4] |
777 | mov eax, [page_tabs+esi*4] |
763 | test eax, USED_BLOCK |
778 | test eax, USED_BLOCK |
764 | jz .test_free |
779 | jz .test_free |
765 | shr eax, 12 |
780 | shr eax, 12 |
766 | add esi, eax |
781 | add esi, eax |
767 | jmp @B |
782 | jmp @B |
768 | .test_free: |
783 | .test_free: |
769 | test eax, FREE_BLOCK |
784 | test eax, FREE_BLOCK |
770 | jz .err |
785 | jz .err |
771 | mov edx, eax |
786 | mov edx, eax |
772 | shr edx, 12 |
787 | shr edx, 12 |
773 | add edx, esi |
788 | add edx, esi |
774 | cmp edx, edi |
789 | cmp edx, edi |
775 | jae .exit |
790 | jae .exit |
776 | 791 | ||
777 | mov ebx, [page_tabs+edx*4] |
792 | mov ebx, [page_tabs+edx*4] |
778 | test ebx, USED_BLOCK |
793 | test ebx, USED_BLOCK |
779 | jz .next_free |
794 | jz .next_free |
780 | 795 | ||
781 | shr ebx, 12 |
796 | shr ebx, 12 |
782 | add edx, ebx |
797 | add edx, ebx |
783 | mov esi, edx |
798 | mov esi, edx |
784 | jmp @B |
799 | jmp @B |
785 | .next_free: |
800 | .next_free: |
786 | test ebx, FREE_BLOCK |
801 | test ebx, FREE_BLOCK |
787 | jz .err |
802 | jz .err |
788 | and dword [page_tabs+edx*4], 0 |
803 | and dword [page_tabs+edx*4], 0 |
789 | add eax, ebx |
804 | add eax, ebx |
790 | and eax, not 4095 |
805 | and eax, not 4095 |
791 | or eax, FREE_BLOCK |
806 | or eax, FREE_BLOCK |
792 | mov [page_tabs+esi*4], eax |
807 | mov [page_tabs+esi*4], eax |
793 | jmp @B |
808 | jmp @B |
794 | .exit: |
809 | .exit: |
795 | xor eax, eax |
810 | xor eax, eax |
796 | inc eax |
811 | inc eax |
797 | ret |
812 | ret |
798 | .err: |
813 | .err: |
799 | xor eax, eax |
814 | xor eax, eax |
800 | ret |
815 | ret |
- | 816 | ||
- | 817 | user_realloc: |
|
- | 818 | ; in: eax = pointer, ebx = new size |
|
- | 819 | ; out: eax = new pointer or NULL |
|
- | 820 | test eax, eax |
|
- | 821 | jnz @f |
|
- | 822 | ; realloc(NULL,sz) - same as malloc(sz) |
|
- | 823 | push ebx |
|
- | 824 | call user_alloc |
|
- | 825 | ret |
|
- | 826 | @@: |
|
- | 827 | push ecx edx |
|
- | 828 | lea ecx, [eax - 0x1000] |
|
- | 829 | shr ecx, 12 |
|
- | 830 | mov edx, [page_tabs+ecx*4] |
|
- | 831 | test edx, USED_BLOCK |
|
- | 832 | jnz @f |
|
- | 833 | ; attempt to realloc invalid pointer |
|
801 | endp |
834 | .ret0: |
- | 835 | pop edx ecx |
|
- | 836 | xor eax, eax |
|
- | 837 | ret |
|
- | 838 | @@: |
|
- | 839 | add ebx, 0x1FFF |
|
- | 840 | shr edx, 12 |
|
- | 841 | shr ebx, 12 |
|
- | 842 | ; edx = allocated size, ebx = new size |
|
- | 843 | add edx, ecx |
|
- | 844 | add ebx, ecx |
|
- | 845 | cmp edx, ebx |
|
- | 846 | jb .realloc_add |
|
- | 847 | ; release part of allocated memory |
|
- | 848 | .loop: |
|
- | 849 | cmp edx, ebx |
|
- | 850 | jz .release_done |
|
- | 851 | dec edx |
|
- | 852 | xor eax, eax |
|
- | 853 | xchg eax, [page_tabs+edx*4] |
|
- | 854 | test al, 1 |
|
- | 855 | jz .loop |
|
- | 856 | call free_page |
|
- | 857 | mov eax, edx |
|
- | 858 | shl eax, 12 |
|
- | 859 | invlpg [eax] |
|
- | 860 | jmp .loop |
|
- | 861 | .release_done: |
|
- | 862 | sub ebx, ecx |
|
- | 863 | cmp ebx, 1 |
|
- | 864 | jnz .nofreeall |
|
- | 865 | mov eax, [page_tabs+ecx*4] |
|
- | 866 | and eax, not 0xFFF |
|
- | 867 | mov edx, [CURRENT_TASK] |
|
- | 868 | shl edx, 8 |
|
- | 869 | mov ebx, [SLOT_BASE+APPDATA.mem_size+edx] |
|
- | 870 | sub ebx, eax |
|
- | 871 | add ebx, 0x1000 |
|
- | 872 | or al, FREE_BLOCK |
|
- | 873 | mov [page_tabs+ecx*4], eax |
|
- | 874 | push esi edi |
|
- | 875 | mov esi, [SLOT_BASE+APPDATA.heap_base+edx] |
|
- | 876 | mov edi, [SLOT_BASE+APPDATA.heap_top+edx] |
|
- | 877 | call update_mem_size |
|
- | 878 | call user_normalize |
|
- | 879 | pop edi esi |
|
- | 880 | jmp .ret0 ; all freed |
|
- | 881 | .nofreeall: |
|
- | 882 | sub edx, ecx |
|
- | 883 | shl ebx, 12 |
|
- | 884 | or ebx, USED_BLOCK |
|
- | 885 | xchg [page_tabs+ecx*4], ebx |
|
- | 886 | shr ebx, 12 |
|
- | 887 | sub ebx, edx |
|
- | 888 | push ebx ecx edx |
|
- | 889 | mov edx, [CURRENT_TASK] |
|
- | 890 | shl edx, 8 |
|
- | 891 | shl ebx, 12 |
|
- | 892 | sub ebx, [SLOT_BASE+APPDATA.mem_size+edx] |
|
- | 893 | neg ebx |
|
- | 894 | call update_mem_size |
|
- | 895 | pop edx ecx ebx |
|
- | 896 | lea eax, [ecx+1] |
|
- | 897 | shl eax, 12 |
|
- | 898 | push eax |
|
- | 899 | add ecx, ebx |
|
- | 900 | add edx, ecx |
|
- | 901 | shl ebx, 12 |
|
- | 902 | jz .ret |
|
- | 903 | push esi |
|
- | 904 | mov esi, [CURRENT_TASK] |
|
- | 905 | shl esi, 8 |
|
- | 906 | mov esi, [SLOT_BASE+APPDATA.heap_top+esi] |
|
- | 907 | shr esi, 12 |
|
- | 908 | @@: |
|
- | 909 | cmp edx, esi |
|
- | 910 | jae .merge_done |
|
- | 911 | mov eax, [page_tabs+edx*4] |
|
- | 912 | test al, USED_BLOCK |
|
- | 913 | jz .merge_done |
|
- | 914 | and dword [page_tabs+edx*4], 0 |
|
- | 915 | and eax, not 0xFFF |
|
- | 916 | add ebx, eax |
|
- | 917 | add edx, eax |
|
- | 918 | jmp @b |
|
- | 919 | .merge_done: |
|
- | 920 | pop esi |
|
- | 921 | or ebx, FREE_BLOCK |
|
- | 922 | mov [page_tabs+ecx*4], ebx |
|
- | 923 | .ret: |
|
- | 924 | pop eax edx ecx |
|
- | 925 | ret |
|
- | 926 | .realloc_add: |
|
- | 927 | ; get some additional memory |
|
- | 928 | mov eax, [CURRENT_TASK] |
|
- | 929 | shl eax, 8 |
|
- | 930 | mov eax, [SLOT_BASE+APPDATA.heap_top+eax] |
|
- | 931 | shr eax, 12 |
|
- | 932 | cmp edx, eax |
|
- | 933 | jae .cant_inplace |
|
- | 934 | mov eax, [page_tabs+edx*4] |
|
- | 935 | shr eax, 12 |
|
- | 936 | add eax, edx |
|
- | 937 | cmp eax, ebx |
|
- | 938 | jb .cant_inplace |
|
- | 939 | sub eax, ebx |
|
- | 940 | jz @f |
|
- | 941 | shl eax, 12 |
|
- | 942 | or al, FREE_BLOCK |
|
- | 943 | mov [page_tabs+ebx*4], eax |
|
- | 944 | @@: |
|
- | 945 | mov eax, ebx |
|
- | 946 | sub eax, ecx |
|
- | 947 | shl eax, 12 |
|
- | 948 | or al, USED_BLOCK |
|
- | 949 | mov [page_tabs+ecx*4], eax |
|
- | 950 | lea eax, [ecx+1] |
|
- | 951 | shl eax, 12 |
|
- | 952 | push eax |
|
- | 953 | push edi |
|
- | 954 | lea edi, [page_tabs+edx*4] |
|
- | 955 | mov eax, 2 |
|
- | 956 | sub ebx, edx |
|
- | 957 | mov ecx, ebx |
|
- | 958 | cld |
|
- | 959 | rep stosd |
|
- | 960 | pop edi |
|
- | 961 | mov edx, [CURRENT_TASK] |
|
- | 962 | shl edx, 8 |
|
- | 963 | shl ebx, 12 |
|
- | 964 | add ebx, [SLOT_BASE+APPDATA.mem_size+edx] |
|
- | 965 | call update_mem_size |
|
- | 966 | pop eax edx ecx |
|
- | 967 | ret |
|
- | 968 | .cant_inplace: |
|
- | 969 | push esi edi |
|
- | 970 | mov eax, [CURRENT_TASK] |
|
- | 971 | shl eax, 8 |
|
- | 972 | mov esi, [SLOT_BASE+APPDATA.heap_base+eax] |
|
- | 973 | mov edi, [SLOT_BASE+APPDATA.heap_top+eax] |
|
- | 974 | shr esi, 12 |
|
- | 975 | shr edi, 12 |
|
- | 976 | sub ebx, ecx |
|
- | 977 | .find_place: |
|
- | 978 | cmp esi, edi |
|
- | 979 | jae .place_not_found |
|
- | 980 | mov eax, [page_tabs+esi*4] |
|
- | 981 | test al, FREE_BLOCK |
|
- | 982 | jz .next_place |
|
- | 983 | shr eax, 12 |
|
- | 984 | cmp eax, ebx |
|
- | 985 | jae .place_found |
|
- | 986 | add esi, eax |
|
- | 987 | jmp .find_place |
|
- | 988 | .next_place: |
|
- | 989 | shr eax, 12 |
|
- | 990 | add esi, eax |
|
- | 991 | jmp .find_place |
|
- | 992 | .place_not_found: |
|
- | 993 | pop edi esi |
|
- | 994 | jmp .ret0 |
|
- | 995 | .place_found: |
|
- | 996 | sub eax, ebx |
|
- | 997 | jz @f |
|
- | 998 | push esi |
|
- | 999 | add esi, eax |
|
- | 1000 | shl eax, 12 |
|
- | 1001 | or al, FREE_BLOCK |
|
- | 1002 | mov [page_tabs+esi*4], eax |
|
- | 1003 | pop esi |
|
- | 1004 | @@: |
|
- | 1005 | mov eax, ebx |
|
- | 1006 | shl eax, 12 |
|
- | 1007 | or al, USED_BLOCK |
|
- | 1008 | mov [page_tabs+esi*4], eax |
|
- | 1009 | inc esi |
|
- | 1010 | mov eax, esi |
|
- | 1011 | shl eax, 12 |
|
- | 1012 | sub eax, new_app_base |
|
- | 1013 | push eax |
|
- | 1014 | mov eax, [page_tabs+ecx*4] |
|
- | 1015 | and eax, not 0xFFF |
|
- | 1016 | or al, FREE_BLOCK |
|
- | 1017 | sub edx, ecx |
|
- | 1018 | mov [page_tabs+ecx*4], eax |
|
- | 1019 | inc ecx |
|
- | 1020 | @@: |
|
- | 1021 | xor eax, eax |
|
- | 1022 | xchg eax, [page_tabs+ecx*4] |
|
- | 1023 | mov [page_tabs+esi*4], eax |
|
- | 1024 | mov eax, ecx |
|
- | 1025 | shl eax, 12 |
|
- | 1026 | invlpg [eax] |
|
- | 1027 | inc ecx |
|
- | 1028 | inc esi |
|
- | 1029 | dec ebx |
|
- | 1030 | dec edx |
|
- | 1031 | jnz @b |
|
- | 1032 | push ebx |
|
- | 1033 | mov edx, [CURRENT_TASK] |
|
- | 1034 | shl edx, 8 |
|
- | 1035 | shl ebx, 12 |
|
- | 1036 | add ebx, [SLOT_BASE+APPDATA.mem_size+edx] |
|
- | 1037 | call update_mem_size |
|
- | 1038 | pop ebx |
|
- | 1039 | @@: |
|
- | 1040 | mov dword [page_tabs+esi*4], 2 |
|
- | 1041 | inc esi |
|
- | 1042 | dec ebx |
|
- | 1043 | jnz @b |
|
- | 1044 | pop eax edi esi edx ecx |
|
- | 1045 | ret |
|
802 | 1046 | ||
803 | if 0 |
1047 | if 0 |
804 | align 4 |
1048 | align 4 |
805 | proc alloc_dll |
1049 | proc alloc_dll |
806 | pushf |
1050 | pushf |
807 | cli |
1051 | cli |
808 | bsf eax, [dll_map] |
1052 | bsf eax, [dll_map] |
809 | jnz .find |
1053 | jnz .find |
810 | popf |
1054 | popf |
811 | xor eax, eax |
1055 | xor eax, eax |
812 | ret |
1056 | ret |
813 | .find: |
1057 | .find: |
814 | btr [dll_map], eax |
1058 | btr [dll_map], eax |
815 | popf |
1059 | popf |
816 | shl eax, 5 |
1060 | shl eax, 5 |
817 | add eax, dll_tab |
1061 | add eax, dll_tab |
818 | ret |
1062 | ret |
819 | endp |
1063 | endp |
820 | 1064 | ||
821 | align 4 |
1065 | align 4 |
822 | proc alloc_service |
1066 | proc alloc_service |
823 | pushf |
1067 | pushf |
824 | cli |
1068 | cli |
825 | bsf eax, [srv_map] |
1069 | bsf eax, [srv_map] |
826 | jnz .find |
1070 | jnz .find |
827 | popf |
1071 | popf |
828 | xor eax, eax |
1072 | xor eax, eax |
829 | ret |
1073 | ret |
830 | .find: |
1074 | .find: |
831 | btr [srv_map], eax |
1075 | btr [srv_map], eax |
832 | popf |
1076 | popf |
833 | shl eax,0x02 |
1077 | shl eax,0x02 |
834 | lea eax,[srv_tab+eax+eax*8] ;srv_tab+eax*36 |
1078 | lea eax,[srv_tab+eax+eax*8] ;srv_tab+eax*36 |
835 | ret |
1079 | ret |
836 | endp |
1080 | endp |
837 | 1081 | ||
838 | end if |
1082 | end if=> |