Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1 ha 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
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