Subversion Repositories Kolibri OS

Rev

Rev 170 | Rev 188 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
164 serge 1
 
2
;HEAP_SIZE equ 0x01000000
3
4
 
5
{  .next_block  dd ?
6
   .prev_block  dd ? ;+4
7
   .list_next   dd ? ;+8
8
   .list_prev   dd ? ;+12
9
   .base        dd ? ;+16
10
   .size        dd ? ;+20
11
   .flags       dd ? ;+24
12
   .handle      dd ? ;+28
13
}
14
15
 
16
USED_BLOCK      equ  8
17
18
 
19
  MEM_BLOCK MEM_BLOCK
20
end virtual
21
22
 
23
24
 
25
block_prev   equ MEM_BLOCK.prev_block
26
list_next    equ MEM_BLOCK.list_next
27
list_prev    equ MEM_BLOCK.list_prev
28
block_base   equ MEM_BLOCK.base
29
block_size   equ MEM_BLOCK.size
30
block_flags  equ MEM_BLOCK.flags
31
32
 
33
{          shr op, 12
34
           dec op
35
           cmp op, 63
36
           jna @f
37
           mov op, 63
38
@@:
39
}
40
41
 
42
{          mov edx, [op+list_next]
43
           mov ecx, [op+list_prev]
44
           test edx, edx
45
           jz @f
46
           mov [edx+list_prev], ecx
47
@@:
48
           test ecx, ecx
49
           jz @f
50
           mov [ecx+list_next], edx
51
@@:
52
           mov [op+list_next],0
53
           mov [op+list_prev],0
54
}
55
56
 
57
{
58
           remove_from_list op
59
60
 
61
           calc_index eax
62
           cmp [mem_block_list+eax*4], op
63
           jne @f
64
           mov [mem_block_list+eax*4], edx
65
@@:
66
           cmp [mem_block_list+eax*4], 0
67
           jne @f
68
           btr [mem_block_mask], eax
69
@@:
70
}
71
72
 
73
{
74
           remove_from_list op
75
           cmp [mem_used_list], op
76
           jne @f
77
           mov [mem_used_list], edx
78
@@:
79
}
80
81
 
82
proc init_kernel_heap
83
84
 
85
           mov edi, mem_block_list
86
           xor eax, eax
87
           cld
88
           rep stosd
89
90
 
91
           mov edi, mem_block_map
92
           not eax
93
           rep stosd
94
95
 
96
           mov [mem_block_end], mem_block_map+512
97
           mov [mem_block_arr], HEAP_BASE
98
99
 
100
           mov ecx, 32
101
           mov edx, eax
102
           mov edi, HEAP_BASE
103
104
 
105
           stdcall map_page,edi,edx,PG_SW
106
           add edi, 0x1000
107
           add edx, 0x1000
108
           dec ecx
109
           jnz .l1
110
111
 
112
           mov ebx, edi
113
           add ebx, MEM_BLOCK_SIZE
114
           xor eax, eax
115
           mov [edi+block_next], ebx
116
           mov [edi+block_prev], eax
117
           mov [edi+list_next], eax
118
           mov [edi+list_prev], eax
119
           mov [edi+block_base], HEAP_BASE
120
           mov [edi+block_size], 4096*MEM_BLOCK_SIZE
121
           mov [edi+block_flags], USED_BLOCK
122
123
 
124
           mov [ebx+block_prev], eax
125
           mov [ebx+list_next], eax
126
           mov [ebx+block_base], HEAP_BASE+4096*MEM_BLOCK_SIZE
127
128
 
129
           sub ecx, 0x01000000 + 4096*MEM_BLOCK_SIZE
170 serge 130
           mov [heap_size], ecx
131
           mov [heap_free], ecx
132
           mov [ebx+block_size], ecx
164 serge 133
           mov [ebx+block_flags], FREE_BLOCK
134
135
 
136
           mov [mem_block_mask+4],0x80000000
137
138
 
139
           mov [mem_block_list+63*4], ebx
140
           mov byte [mem_block_map], 0xFC
141
           mov [heap_blocks], 4095
170 serge 142
           mov [free_blocks], 4095
143
           ret
164 serge 144
endp
145
146
 
147
proc get_block stdcall, index:dword
148
149
 
150
           mov ecx, [index]
151
           cmp ecx, eax
152
           jna @f
153
           ;cmova ecx, eax
154
           mov ecx, eax
155
@@:
156
           xor esi, esi
157
           xor ebx, ebx
158
           xor edx, edx
159
           not edx
160
161
 
162
           jb .bit_test
163
164
 
165
           add ebx, 32
166
           add esi, 4
167
168
 
169
           shl edx, cl
170
           and edx, [mem_block_mask+esi]
171
           jz .high_mask
172
           bsf eax, edx
173
           add ebx, eax
174
           mov eax, [mem_block_list+ebx*4]
175
           ret
176
177
 
178
179
 
180
           add ebx, 32
181
           test esi, 0xFFFFFFF8
182
           jnz .big_error
183
           mov edx, [mem_block_mask+esi]
184
           and edx, edx
185
           jz .high_mask
186
           bsf eax, edx
187
           add ebx, eax
188
           mov eax, [mem_block_list+ebx*4]
189
           ret
190
191
 
192
           xor eax, eax
193
           ret
194
endp
195
196
 
197
proc alloc_mem_block
198
199
 
200
           cli
201
           mov ebx, [mem_block_start]
202
           mov ecx, [mem_block_end]
203
.l1:
204
           bsf eax,[ebx];
205
           jnz found
206
           add ebx,4
207
           cmp ebx, ecx
208
           jb .l1
209
           popfd
210
           xor eax,eax
211
           ret
212
213
 
214
           btr [ebx], eax
215
           mov [mem_block_start],ebx
216
           sub ebx, mem_block_map
217
           shl ebx, 3
218
           add eax,ebx
219
           shl eax, 5
220
           add eax, [mem_block_arr]
221
           dec [free_blocks]
170 serge 222
           popfd
164 serge 223
           ret
224
endp
225
226
 
227
           pushfd
228
           cli
229
           sub eax, [mem_block_arr]
230
           shr eax, 5
231
232
 
233
           bts [ebx], eax
234
           inc [free_blocks]
170 serge 235
           shr eax, 3
164 serge 236
           and eax, not 3
237
           add eax, ebx
238
           cmp [mem_block_start], eax
239
           ja @f
240
           popfd
241
           ret
242
@@:
243
           mov [mem_block_start], eax
244
           popfd
245
	   ret
246
.err:
247
           xor eax, eax
248
           popfd
249
	   ret
250
endp
251
252
 
253
proc alloc_kernel_space stdcall, size:dword
254
           local block_ind:DWORD
255
256
 
257
           cli
258
259
 
260
           add eax, 0xFFF
261
           and eax, 0xFFFFF000;
262
           mov [size], eax
263
           cmp eax, [heap_free]
170 serge 264
           ja .error
265
164 serge 266
 
267
           sub eax, 1
268
269
 
270
271
 
272
           and eax, eax
273
           jz .error
274
275
 
276
277
 
278
           jne .error
279
280
 
281
282
 
283
           cmp eax, [size]
284
           je .m_eq_size
285
286
 
287
           and eax, eax
288
           jz .error
289
290
 
291
292
 
293
           mov eax, [edi+block_prev]
294
           mov [esi+block_prev], eax
295
           mov [edi+block_prev], esi
296
           mov [esi+list_next], 0
297
           mov [esi+list_prev], 0
298
           and eax, eax
299
           jz @f
300
           mov [eax+block_next], esi
301
@@:
302
           mov ebx, [edi+block_base]
303
           mov [esi+block_base], ebx
304
           mov edx, [size]
305
           mov [esi+block_size], edx
306
           add [edi+block_base], edx
307
           sub [edi+block_size], edx
308
309
 
310
           shr eax, 12
311
           sub eax, 1
312
           cmp eax, 63
313
           jna @f
314
           mov eax, 63
315
@@:
316
           cmp eax, [block_ind]
317
           je .m_eq_ind
318
319
 
320
           test ebx, ebx
321
           jz @f
322
323
 
324
@@:
325
           mov ecx, [block_ind]
326
           mov [mem_block_list+ecx*4], ebx
327
328
 
329
           jnz @f
330
           btr [mem_block_mask], ecx
331
@@:
332
           mov edx, [mem_block_list+eax*4]
333
           mov [edi+list_next], edx
334
           test edx, edx
335
           jz @f
336
           mov [edx+list_prev], edi
337
@@:
338
           mov [mem_block_list+eax*4], edi
339
           bts [mem_block_mask], eax
340
.m_eq_ind:
341
           mov ebx, [mem_used_list]
342
           mov [esi+list_next], ebx
343
           test ebx, ebx
344
           jz @f
345
           mov [ebx+list_prev], esi
346
@@:
347
           mov [esi+block_flags], USED_BLOCK
348
           mov [mem_used_list], esi
349
           mov eax, [esi+block_base]
350
           mov ebx, [size]
170 serge 351
           sub [heap_free], ebx
352
           popfd
164 serge 353
           ret
354
355
 
356
           remove_from_list edi
357
           mov [mem_block_list+ecx*4], edx
358
           and edx, edx
359
           jnz @f
360
           mov ecx, [block_ind]
361
           btr [mem_block_mask], ecx
362
@@:
363
           mov ebx, [mem_used_list]
364
           mov [edi+list_next], ebx
365
           test ebx, ebx
366
           jnz @f
367
           mov [ebx+list_prev], edi
368
@@:
369
           mov [mem_used_list], edi
370
           mov [edi+block_flags], USED_BLOCK
371
           mov eax, [edi+block_base]
372
           mov ebx, [size]
170 serge 373
           sub [heap_free], ebx
374
           popfd
164 serge 375
           ret
376
.error:
377
           xor eax, eax
378
           popfd
379
           ret
380
endp
381
382
 
383
proc free_kernel_space stdcall, base:dword
384
385
 
386
           mov esi, [mem_used_list]
387
@@:
388
           test esi, esi
389
           jz .fail
390
391
 
392
           je .found
393
           mov esi, [esi+list_next]
394
           jmp @b
395
.found:
396
           cmp [esi+block_flags], USED_BLOCK
397
           jne .fail
398
399
 
170 serge 400
           add [heap_free], eax
401
402
 
164 serge 403
           test edi, edi
404
           jz .prev
405
406
 
407
           jne .prev
408
409
 
410
411
 
412
           mov [esi+block_next], edx
413
           test edx, edx
414
           jz @f
415
416
 
417
@@:
418
           mov ecx, [edi+block_size]
419
           add [esi+block_size], ecx
420
421
 
422
           call free_mem_block
423
.prev:
424
           mov edi, [esi+block_prev]
425
           test edi, edi
426
           jz .insert
427
428
 
429
           jne .insert
430
431
 
432
433
 
434
           mov [edi+block_next], edx
435
           test edx, edx
436
           jz @f
437
           mov [edx+block_prev], edi
438
@@:
439
           mov eax, esi
440
           call free_mem_block
441
442
 
443
           mov eax, [esi+block_size]
444
           add eax, ecx
445
           mov [edi+block_size], eax
446
447
 
448
           calc_index ecx
449
           cmp eax, ecx
450
           je .m_eq
451
452
 
453
           remove_from_list edi
454
           pop ecx
455
456
 
457
           jne @f
458
           mov [mem_block_list+ecx*4], edx
459
@@:
460
           cmp [mem_block_list+ecx*4], 0
461
           jne @f
462
           btr [mem_block_mask], ecx
463
@@:
464
           mov esi, [mem_block_list+eax*4]
465
           mov [mem_block_list+eax*4], edi
466
           mov [edi+list_next], esi
467
           test esi, esi
468
           jz @f
469
           mov [esi+list_prev], edi
470
@@:
471
           bts [mem_block_mask], eax
472
.m_eq:
473
           xor eax, eax
474
           not eax
475
           ret
476
.insert:
477
           remove_from_used esi
478
479
 
480
           calc_index eax
481
482
 
483
           mov [mem_block_list+eax*4], esi
484
           mov [esi+list_next], edi
485
           test edi, edi
486
           jz @f
487
           mov [edi+list_prev], esi
488
@@:
489
           bts [mem_block_mask], eax
490
           mov [esi+block_flags],FREE_BLOCK
491
           xor eax, eax
492
           not eax
493
           ret
494
.fail:
495
           xor eax, eax
496
           ret
497
endp
498
499
 
500
proc kernel_alloc stdcall, size:dword
501
           locals
502
             lin_addr    dd ?
503
             pages_count dd ?
504
           endl
505
506
 
507
           add eax, 0xFFF
508
           and eax, 0xFFFFF000;
509
           mov [size], eax
510
           and eax, eax
511
           jz .error
512
           mov ebx, eax
513
           shr ebx, 12
514
           mov [pages_count], ebx
515
516
 
517
           and eax, eax
518
           jz .error
519
           mov [lin_addr], eax
520
521
 
522
           mov edx, eax
523
           mov ebx, ecx
524
525
 
526
           jz .next
527
528
 
529
           push ebx
530
           stdcall alloc_pages, ebx
531
           pop ecx                   ; yes ecx!!!
532
           and eax, eax
533
           jz .error
534
535
 
536
           mov edx, [lin_addr]
537
@@:
538
           stdcall map_page,edx,edi,dword PG_SW
539
           add edx, 0x1000
540
           add edi, 0x1000
541
           dec ecx
542
           jnz @B
543
.next:
544
           mov ecx, [pages_count]
545
           and ecx, 7
546
           jz .end
547
548
 
549
           call alloc_page
550
           pop ecx
551
           test eax, eax
552
           jz .error
553
554
 
555
           add edx, 0x1000
556
           dec ecx
557
           jnz @B
558
.end:
559
           mov eax, [lin_addr]
560
           ret
561
562
 
563
           xor eax, eax
564
           ret
565
endp
566
567
 
568
proc kernel_free stdcall, base:dword
569
           locals
570
             size  dd ?
571
           endl
572
573
 
574
           mov esi, [mem_used_list]
575
@@:
576
           test esi, esi
577
           jz .fail
578
579
 
580
           je .found
581
           mov esi, [esi+list_next]
582
           jmp @b
583
.found:
584
           cmp [esi+block_flags], USED_BLOCK
585
           jne .fail
586
587
 
588
           mov [size], ecx
589
590
 
591
           test eax, eax
592
           jz .fail
593
594
 
595
           mov edi, [base]
596
597
 
598
           mov esi, edi
599
           shr edi, 10
600
           add edi, pages_tab
601
           xor edx, edx
602
.release:
603
           mov eax, [edi]
604
           test eax, 1
605
           jz .next
606
607
 
608
           mov [edi],edx
609
.next:
610
           invlpg [esi]
611
           add esi, 0x1000
612
           add edi, 4
613
           dec ecx
614
           jnz .release
615
.fail:
616
           ret
617
endp
618
619
 
620
restore block_prev
621
restore block_list
622
restore block_base
623
restore block_size
624
restore block_flags
625
626
 
627
628
 
629
proc init_heap stdcall, heap_size:dword
630
           locals
631
             tab_count dd ?
632
           endl
633
634
 
172 serge 635
           shl ebx,8
636
           mov eax, [PROC_BASE+APPDATA.heap_top+ebx]
637
           test eax, eax
638
           jz @F
639
           sub eax,[PROC_BASE+APPDATA.heap_base+ebx]
640
           sub eax, 4096
641
           ret
642
@@:
643
           mov edx, [heap_size]
164 serge 644
           and edx, edx
645
           jz .exit
646
           add edx, (4095+4096)
172 serge 647
           and edx, not 4095
164 serge 648
           mov [heap_size], edx
649
           add edx, 0x003FFFFF
650
           and edx, not 0x003FFFFF
651
           shr edx, 22
652
           mov [tab_count], edx
653
654
 
172 serge 655
           add esi, 0x003FFFFF
164 serge 656
           and esi, not 0x003FFFFF
657
           mov edi, esi
658
           mov [PROC_BASE+APPDATA.heap_base+ebx], esi
172 serge 659
           add esi, [heap_size]
164 serge 660
           mov [PROC_BASE+APPDATA.heap_top+ebx], esi
172 serge 661
164 serge 662
 
663
           and eax, not 0xFFF
664
           stdcall map_page,[current_pdir],eax,dword PG_SW
665
666
 
667
@@:
668
           call alloc_page
669
           test eax, eax
670
           jz .exit
671
672
 
673
           add edi, 0x00400000
674
           dec edx
675
           jnz @B
676
677
 
678
           shl ecx, 12-2
679
           mov ebx,[CURRENT_TASK]
680
           shl ebx,8
681
           mov edi, [PROC_BASE+APPDATA.heap_base+ebx]
172 serge 682
           add edi, new_app_base
164 serge 683
           shr edi, 10
684
           mov esi, edi
685
           add edi, pages_tab
686
           xor eax, eax
687
           cld
688
           rep stosd
689
690
 
691
692
 
693
           mov eax, ebx
694
           sub eax, 4096
695
           or ebx, FREE_BLOCK
696
           mov [pages_tab+esi], ebx
697
           ret
698
.exit:
699
           xor eax, eax
700
           ret
701
endp
702
703
 
704
proc user_alloc stdcall, alloc_size:dword
705
706
 
707
           add ecx, (4095+4096)
708
           and ecx, not 4095
709
710
 
711
           shl ebx, 8
712
           mov esi, dword [ebx+PROC_BASE+APPDATA.heap_base]; heap_base
172 serge 713
           mov edi, dword [ebx+PROC_BASE+APPDATA.heap_top]; heap_top
714
           add esi, new_app_base
164 serge 715
           add edi, new_app_base
716
717
 
718
           cmp esi, edi
719
           jae m_exit
720
721
 
722
           shr ebx, 12
723
           mov eax, [pages_tab+ebx*4]
724
           test eax, FREE_BLOCK
725
           jz test_used
726
           and eax, 0xFFFFF000
727
           cmp eax, ecx    ;alloc_size
728
           jb  m_next
729
730
 
731
           add edx, ecx
732
           sub eax, ecx;
733
           or eax, FREE_BLOCK
734
           shr edx, 12
735
           mov [pages_tab+edx*4], eax
736
737
 
738
           mov [pages_tab+ebx*4], ecx
739
           shr ecx, 12
740
           dec ecx
741
           inc ebx
742
@@:
743
           mov dword [pages_tab+ebx*4], 2
744
           inc ebx
745
           dec ecx
746
           jnz @B
747
748
 
749
           add eax, 4096
750
           sub eax, new_app_base
751
           ret
752
m_next:
753
           add esi, eax
754
           jmp l_0
755
test_used:
756
           test eax, USED_BLOCK
757
           jz m_exit
758
759
 
760
           add esi, eax
761
           jmp l_0
762
m_exit:
763
           xor eax, eax
764
           ret
765
endp
766
767
 
768
proc user_free stdcall, base:dword
769
770
 
771
           test esi, esi
772
           jz .exit
773
774
 
775
           shr esi, 12
776
           mov eax, [pages_tab+esi*4]
777
           test eax, USED_BLOCK
778
           jz @f
779
780
 
781
           mov ecx, eax
782
           or eax, FREE_BLOCK
783
           mov [pages_tab+esi*4], eax
784
           inc esi
785
           sub ecx, 4096
786
           shr ecx, 12
787
.release:
788
           mov eax, [pages_tab+esi*4]
789
           call free_page
790
           inc esi
791
           dec ecx
792
           jnz .release
793
@@:
794
           mov ebx, [CURRENT_TASK]
795
           shl ebx, 8
796
           mov esi, dword [ebx+PROC_BASE+APPDATA.heap_base]; heap_base
172 serge 797
           mov edi, dword [ebx+PROC_BASE+APPDATA.heap_top]; heap_top
798
           shr esi, 12
164 serge 799
           shr edi, 12
800
@@:
801
           mov eax, [pages_tab+esi*4]
802
           test eax, USED_BLOCK
803
           jz .test_free
804
           shr eax, 12
805
           add esi, eax
806
           jmp @B
807
.test_free:
808
           test eax, FREE_BLOCK
809
           jz .err
810
           mov edx, eax
811
           shr edx, 12
812
           add edx, esi
813
           cmp edx, edi
814
           jae .exit
815
816
 
817
           test ebx, USED_BLOCK
818
           jz .next_free
819
820
 
821
           add edx, ebx
822
           mov esi, edx
823
           jmp @B
824
.next_free:
825
           test ebx, FREE_BLOCK
826
           jz .err
827
           and dword [pages_tab+edx*4], 0
828
           add eax, ebx
829
           and eax, not 4095
830
           or eax, FREE_BLOCK
831
           mov [pages_tab+esi*4], eax
832
           jmp @B
833
.exit:
834
           xor eax, eax
835
           inc eax
836
           ret
837
.err:
838
           xor eax, eax
839
           ret
840
endp
841
842
 
843
proc alloc_dll
844
           pushf
845
           cli
846
           bsf eax, [dll_map]
847
           jnz .find
848
           popf
849
           xor eax, eax
850
           ret
851
.find:
852
           btr [dll_map], eax
853
           popf
854
           shl eax, 5
855
           add eax, dll_tab
856
           ret
857
endp
858
859
 
860
proc alloc_service
861
           pushf
862
           cli
863
           bsf eax, [srv_map]
864
           jnz .find
865
           popf
866
           xor eax, eax
867
           ret
868
869
 
870
           popf
871
           shl eax,5
872
           add eax, srv_tab
873
           ret
874
endp
875