Subversion Repositories Kolibri OS

Rev

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

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