Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
1159 hidnplayr 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
3
;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;;
4
;; Distributed under terms of the GNU General Public License    ;;
5
;;                                                              ;;
6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7
 
1206 hidnplayr 8
$Revision: 1206 $
1159 hidnplayr 9
 
10
 
11
align 4
12
proc alloc_page
13
 
1206 hidnplayr 14
	   pushfd
15
	   cli
16
	   push ebx
17
	   mov ebx, [page_start]
18
	   mov ecx, [page_end]
1159 hidnplayr 19
.l1:
1206 hidnplayr 20
	   bsf eax,[ebx];
21
	   jnz .found
22
	   add ebx,4
23
	   cmp ebx, ecx
24
	   jb .l1
25
	   pop ebx
26
	   popfd
27
	   xor eax,eax
28
	   ret
1159 hidnplayr 29
.found:
1206 hidnplayr 30
	   btr [ebx], eax
31
	   mov [page_start],ebx
32
	   sub ebx, sys_pgmap
33
	   lea eax, [eax+ebx*8]
34
	   shl eax, 12
35
	   dec [pg_data.pages_free]
36
	   pop ebx
37
	   popfd
38
	   ret
1159 hidnplayr 39
endp
40
 
41
align 4
42
proc alloc_pages stdcall, count:dword
1206 hidnplayr 43
	   pushfd
44
	   push ebx
45
	   push edi
46
	   cli
47
	   mov eax, [count]
48
	   add eax, 7
49
	   shr eax, 3
50
	   mov [count], eax
51
	   cmp eax, [pg_data.pages_free]
52
	   ja .fail
1159 hidnplayr 53
 
1206 hidnplayr 54
	   mov ecx, [page_start]
55
	   mov ebx, [page_end]
1159 hidnplayr 56
.find:
1206 hidnplayr 57
	   mov edx, [count]
58
	   mov edi, ecx
1159 hidnplayr 59
.match:
1206 hidnplayr 60
	   cmp byte [ecx], 0xFF
61
	   jne .next
62
	   dec edx
63
	   jz .ok
64
	   inc ecx
65
	   cmp ecx,ebx
66
	   jb .match
1159 hidnplayr 67
.fail:
1206 hidnplayr 68
	   xor eax, eax
69
	   pop edi
70
	   pop ebx
71
	   popfd
72
	   ret
1159 hidnplayr 73
.next:
1206 hidnplayr 74
	   inc ecx
75
	   cmp ecx, ebx
76
	   jb .find
77
	   pop edi
78
	   pop ebx
79
	   popfd
80
	   xor eax, eax
81
	   ret
1159 hidnplayr 82
.ok:
1206 hidnplayr 83
	   sub ecx, edi
84
	   inc ecx
85
	   push esi
86
	   mov esi, edi
87
	   xor eax, eax
88
	   rep stosb
89
	   sub esi, sys_pgmap
90
	   shl esi, 3+12
91
	   mov eax, esi
92
	   mov ebx, [count]
93
	   shl ebx, 3
94
	   sub [pg_data.pages_free], ebx
95
	   pop esi
96
	   pop edi
97
	   pop ebx
98
	   popfd
99
	   ret
1159 hidnplayr 100
endp
101
 
102
align 4
103
proc map_page stdcall,lin_addr:dword,phis_addr:dword,flags:dword
1206 hidnplayr 104
	   push ebx
105
	   mov eax, [phis_addr]
106
	   and eax, not 0xFFF
107
	   or eax, [flags]
108
	   mov ebx, [lin_addr]
109
	   shr ebx, 12
110
	   mov [page_tabs+ebx*4], eax
111
	   mov eax, [lin_addr]
112
	   invlpg [eax]
113
	   pop ebx
114
	   ret
1159 hidnplayr 115
endp
116
 
117
align 4
118
map_space:    ;not implemented
119
 
120
 
1206 hidnplayr 121
	   ret
1159 hidnplayr 122
 
123
 
124
align 4
125
proc free_page
126
;arg:  eax  page address
1206 hidnplayr 127
	   pushfd
128
	   cli
129
	   shr eax, 12			      ;page index
130
	   bts dword [sys_pgmap], eax	      ;that's all!
131
	   cmc
132
	   adc [pg_data.pages_free], 0
133
	   shr eax, 3
134
	   and eax, not 3		      ;dword offset from page_map
135
	   add eax, sys_pgmap
136
	   cmp [page_start], eax
137
	   ja @f
138
	   popfd
139
	   ret
1159 hidnplayr 140
@@:
1206 hidnplayr 141
	   mov [page_start], eax
142
	   popfd
143
	   ret
1159 hidnplayr 144
endp
145
 
146
proc map_io_mem stdcall, base:dword, size:dword, flags:dword
147
 
1206 hidnplayr 148
	   push ebx
149
	   push edi
150
	   mov eax, [size]
151
	   add eax, 4095
152
	   and eax, -4096
153
	   mov [size], eax
154
	   stdcall alloc_kernel_space, eax
155
	   test eax, eax
156
	   jz .fail
157
	   push eax
1159 hidnplayr 158
 
1206 hidnplayr 159
	   mov edi, 0x1000
160
	   mov ebx, eax
161
	   mov ecx,[size]
162
	   mov edx, [base]
163
	   shr eax, 12
164
	   shr ecx, 12
165
	   and edx, -4096
166
	   or edx, [flags]
1159 hidnplayr 167
@@:
1206 hidnplayr 168
	   mov [page_tabs+eax*4], edx
169
	  ; push eax
170
	  ; invlpg [ebx]
171
	  ; pop eax
172
	   inc eax
173
	   add ebx, edi
174
	   add edx, edi
175
	   loop @B
1159 hidnplayr 176
 
1206 hidnplayr 177
	   pop eax
178
	   mov edx, [base]
179
	   and edx, 4095
180
	   add eax, edx
1159 hidnplayr 181
.fail:
1206 hidnplayr 182
	   pop edi
183
	   pop ebx
184
	   ret
1159 hidnplayr 185
endp
186
 
187
; param
188
;  eax= page base + page flags
189
;  ebx= linear address
190
;  ecx= count
191
 
192
align 4
193
commit_pages:
1206 hidnplayr 194
	   push edi
195
	   test ecx, ecx
196
	   jz .fail
1159 hidnplayr 197
 
1206 hidnplayr 198
	   mov edi, ebx
199
	   mov ebx, pg_data.pg_mutex
200
	   call wait_mutex	;ebx
1159 hidnplayr 201
 
1206 hidnplayr 202
	   mov edx, 0x1000
203
	   mov ebx, edi
204
	   shr ebx, 12
1159 hidnplayr 205
@@:
1206 hidnplayr 206
	   mov [page_tabs+ebx*4], eax
207
	  ; push eax
208
	  ; invlpg [edi]
209
	  ; pop eax
210
	   add edi, edx
211
	   add eax, edx
212
	   inc ebx
213
	   dec ecx
214
	   jnz @B
215
	   mov [pg_data.pg_mutex],ecx
1159 hidnplayr 216
.fail:
1206 hidnplayr 217
	   pop edi
218
	   ret
1159 hidnplayr 219
 
220
 
221
; param
222
;  eax= base
223
;  ecx= count
224
 
225
align 4
226
release_pages:
227
 
1206 hidnplayr 228
	   pushad
229
	   mov ebx, pg_data.pg_mutex
230
	   call wait_mutex	;ebx
1159 hidnplayr 231
 
1206 hidnplayr 232
	   mov esi, eax
233
	   mov edi, eax
1159 hidnplayr 234
 
1206 hidnplayr 235
	   shr esi, 10
236
	   add esi, page_tabs
1159 hidnplayr 237
 
1206 hidnplayr 238
	   mov ebp, [pg_data.pages_free]
239
	   mov ebx, [page_start]
240
	   mov edx, sys_pgmap
1159 hidnplayr 241
@@:
1206 hidnplayr 242
	   xor eax, eax
243
	   xchg eax, [esi]
244
	   push eax
245
	   invlpg [edi]
246
	   pop eax
1159 hidnplayr 247
 
1206 hidnplayr 248
	   test eax, 1
249
	   jz .next
1159 hidnplayr 250
 
1206 hidnplayr 251
	   shr eax, 12
252
	   bts [edx], eax
253
	   cmc
254
	   adc ebp, 0
255
	   shr eax, 3
256
	   and eax, -4
257
	   add eax, edx
258
	   cmp eax, ebx
259
	   jae .next
1159 hidnplayr 260
 
1206 hidnplayr 261
	   mov ebx, eax
1159 hidnplayr 262
.next:
1206 hidnplayr 263
	   add edi, 0x1000
264
	   add esi, 4
265
	   dec ecx
266
	   jnz @B
267
	   mov [pg_data.pages_free], ebp
268
	   and [pg_data.pg_mutex],0
269
	   popad
270
	   ret
1159 hidnplayr 271
 
272
; param
273
;  eax= base
274
;  ecx= count
275
 
276
align 4
277
unmap_pages:
278
 
1206 hidnplayr 279
	   push edi
1159 hidnplayr 280
 
1206 hidnplayr 281
	   mov edi, eax
282
	   mov edx, eax
1159 hidnplayr 283
 
1206 hidnplayr 284
	   shr edi, 10
285
	   add edi, page_tabs
1159 hidnplayr 286
 
1206 hidnplayr 287
	   xor eax, eax
1159 hidnplayr 288
@@:
1206 hidnplayr 289
	   stosd
290
	   invlpg [edx]
291
	   add edx, 0x1000
292
	   loop @b
1159 hidnplayr 293
 
1206 hidnplayr 294
	   pop edi
295
	   ret
1159 hidnplayr 296
 
297
 
298
align 4
299
proc map_page_table stdcall, lin_addr:dword, phis_addr:dword
1206 hidnplayr 300
	   push ebx
301
	   mov ebx, [lin_addr]
302
	   shr ebx, 22
303
	   mov eax, [phis_addr]
304
	   and eax, not 0xFFF
305
	   or eax, PG_UW	  ;+PG_NOCACHE
306
	   mov dword [master_tab+ebx*4], eax
307
	   mov eax, [lin_addr]
308
	   shr eax, 10
309
	   add eax, page_tabs
310
	   invlpg [eax]
311
	   pop ebx
312
	   ret
1159 hidnplayr 313
endp
314
 
315
align 4
316
proc init_LFB
1206 hidnplayr 317
	   locals
318
	     pg_count dd ?
319
	   endl
1159 hidnplayr 320
 
1206 hidnplayr 321
	   cmp dword [LFBAddress], -1
322
	   jne @f
323
	   mov [BOOT_VAR+0x901c],byte 2
324
	   stdcall kernel_alloc, 0x280000
325
	   mov [LFBAddress], eax
326
	   ret
1159 hidnplayr 327
@@:
1206 hidnplayr 328
	   test [SCR_MODE],word 0100000000000000b
329
	   jnz @f
330
	   mov [BOOT_VAR+0x901c],byte 2
331
	   ret
1159 hidnplayr 332
@@:
1206 hidnplayr 333
	   call init_mtrr
1159 hidnplayr 334
 
1206 hidnplayr 335
	   mov edx, LFB_BASE
336
	   mov esi, [LFBAddress]
337
	   mov edi, 0x00800000
338
	   mov dword [exp_lfb+4], edx
1159 hidnplayr 339
 
1206 hidnplayr 340
	   shr edi, 12
341
	   mov [pg_count], edi
342
	   shr edi, 10
1159 hidnplayr 343
 
1206 hidnplayr 344
	   bt [cpu_caps], CAPS_PSE
345
	   jnc .map_page_tables
346
	   or esi, PG_LARGE+PG_UW
347
	   mov edx, sys_pgdir+(LFB_BASE shr 20)
1159 hidnplayr 348
@@:
1206 hidnplayr 349
	   mov [edx], esi
350
	   add edx, 4
351
	   add esi, 0x00400000
352
	   dec edi
353
	   jnz @B
1159 hidnplayr 354
 
1206 hidnplayr 355
	   bt [cpu_caps], CAPS_PGE
356
	   jnc @F
357
	   or dword [sys_pgdir+(LFB_BASE shr 20)], PG_GLOBAL
1159 hidnplayr 358
@@:
1206 hidnplayr 359
	   mov dword [LFBAddress], LFB_BASE
360
	   mov eax, cr3       ;flush TLB
361
	   mov cr3, eax
362
	   ret
1159 hidnplayr 363
 
364
.map_page_tables:
365
 
366
@@:
1206 hidnplayr 367
	   call alloc_page
368
	   stdcall map_page_table, edx, eax
369
	   add edx, 0x00400000
370
	   dec edi
371
	   jnz @B
1159 hidnplayr 372
 
1206 hidnplayr 373
	   mov eax, [LFBAddress]
374
	   mov edi, page_tabs + (LFB_BASE shr 10)
375
	   or eax, PG_UW
376
	   mov ecx, [pg_count]
377
	   cld
1159 hidnplayr 378
@@:
1206 hidnplayr 379
	   stosd
380
	   add eax, 0x1000
381
	   dec ecx
382
	   jnz @B
1159 hidnplayr 383
 
1206 hidnplayr 384
	   mov dword [LFBAddress], LFB_BASE
385
	   mov eax, cr3       ;flush TLB
386
	   mov cr3, eax
1159 hidnplayr 387
 
1206 hidnplayr 388
	   ret
1159 hidnplayr 389
endp
390
 
391
align 4
392
proc new_mem_resize stdcall, new_size:dword
393
 
1206 hidnplayr 394
	   mov ebx, pg_data.pg_mutex
395
	   call wait_mutex    ;ebx
1159 hidnplayr 396
 
1206 hidnplayr 397
	   mov edi, [new_size]
398
	   add edi,4095
399
	   and edi,not 4095
400
	   mov [new_size], edi
1159 hidnplayr 401
 
1206 hidnplayr 402
	   mov edx,[current_slot]
403
	   cmp [edx+APPDATA.heap_base],0
404
	   jne .exit
1159 hidnplayr 405
 
1206 hidnplayr 406
	   mov esi, [edx+APPDATA.mem_size]
407
	   add esi, 4095
408
	   and esi, not 4095
1159 hidnplayr 409
 
1206 hidnplayr 410
	   cmp edi, esi
411
	   jae .expand
1159 hidnplayr 412
 
1206 hidnplayr 413
	   shr edi, 12
414
	   shr esi, 12
1159 hidnplayr 415
@@:
1206 hidnplayr 416
	   mov eax, [app_page_tabs+edi*4]
417
	   test eax, 1
418
	   jz .next
419
	   mov dword [app_page_tabs+edi*4], 2
420
	   mov ebx, edi
421
	   shl ebx, 12
422
	   push eax
423
	   invlpg [ebx]
424
	   pop eax
425
	   call free_page
1159 hidnplayr 426
 
1206 hidnplayr 427
.next:	   add edi, 1
428
	   cmp edi, esi
429
	   jb @B
1159 hidnplayr 430
 
431
.update_size:
1206 hidnplayr 432
	   mov	   ebx, [new_size]
433
	   call    update_mem_size
1159 hidnplayr 434
 
1206 hidnplayr 435
	   xor eax, eax
436
	   dec [pg_data.pg_mutex]
437
	   ret
1159 hidnplayr 438
.expand:
439
 
1206 hidnplayr 440
	   push esi
441
	   push edi
1159 hidnplayr 442
 
1206 hidnplayr 443
	   add edi, 0x3FFFFF
444
	   and edi, not(0x3FFFFF)
445
	   add esi, 0x3FFFFF
446
	   and esi, not(0x3FFFFF)
1159 hidnplayr 447
 
1206 hidnplayr 448
	   cmp esi, edi
449
	   jae .grow
1159 hidnplayr 450
 
1206 hidnplayr 451
	   xchg esi, edi
1159 hidnplayr 452
 
453
@@:
1206 hidnplayr 454
	   call alloc_page
455
	   test eax, eax
456
	   jz .exit_pop
1159 hidnplayr 457
 
1206 hidnplayr 458
	   stdcall map_page_table, edi, eax
1159 hidnplayr 459
 
1206 hidnplayr 460
	   push edi
461
	   shr edi, 10
462
	   add edi, page_tabs
463
	   mov ecx, 1024
464
	   xor eax, eax
465
	   cld
466
	   rep stosd
467
	   pop edi
1159 hidnplayr 468
 
1206 hidnplayr 469
	   add edi, 0x00400000
470
	   cmp edi, esi
471
	   jb @B
1159 hidnplayr 472
.grow:
1206 hidnplayr 473
	   pop edi
474
	   pop esi
1159 hidnplayr 475
@@:
1206 hidnplayr 476
	   call alloc_page
477
	   test eax, eax
478
	   jz .exit
479
	   stdcall map_page,esi,eax,dword PG_UW
1159 hidnplayr 480
 
1206 hidnplayr 481
	   push edi
482
	   mov edi, esi
483
	   xor eax, eax
484
	   mov ecx, 1024
485
	   cld
486
	   rep stosd
487
	   pop edi
1159 hidnplayr 488
 
1206 hidnplayr 489
	   add esi, 0x1000
490
	   cmp esi, edi
491
	   jb  @B
1159 hidnplayr 492
 
1206 hidnplayr 493
	   jmp .update_size
1198 clevermous 494
.exit_pop:
1206 hidnplayr 495
	   pop edi
496
	   pop esi
1159 hidnplayr 497
.exit:
1206 hidnplayr 498
	   xor eax, eax
499
	   inc eax
500
	   dec [pg_data.pg_mutex]
501
	   ret
1159 hidnplayr 502
endp
503
 
504
update_mem_size:
505
; in: edx = slot base
506
;     ebx = new memory size
507
; destroys eax,ecx,edx
508
 
1206 hidnplayr 509
	   mov	  [APPDATA.mem_size+edx],ebx
1159 hidnplayr 510
;search threads and update
511
;application memory size infomation
1206 hidnplayr 512
	   mov	  ecx,[APPDATA.dir_table+edx]
513
	   mov	  eax,2
1159 hidnplayr 514
 
515
.search_threads:
516
;eax = current slot
517
;ebx = new memory size
518
;ecx = page directory
1206 hidnplayr 519
	   cmp	  eax,[TASK_COUNT]
520
	   jg	  .search_threads_end
521
	   mov	  edx,eax
522
	   shl	  edx,5
523
	   cmp	  word [CURRENT_TASK+edx+TASKDATA.state],9 ;if slot empty?
524
	   jz	  .search_threads_next
525
	   shl	  edx,3
526
	   cmp	  [SLOT_BASE+edx+APPDATA.dir_table],ecx     ;if it is our thread?
527
	   jnz	  .search_threads_next
528
	   mov	  [SLOT_BASE+edx+APPDATA.mem_size],ebx	   ;update memory size
1159 hidnplayr 529
.search_threads_next:
1206 hidnplayr 530
	   inc	  eax
531
	   jmp	  .search_threads
1159 hidnplayr 532
.search_threads_end:
1206 hidnplayr 533
	   ret
1159 hidnplayr 534
 
535
; param
536
;  eax= linear address
537
;
538
; retval
539
;  eax= phisical page address
540
 
541
align 4
542
get_pg_addr:
1206 hidnplayr 543
	   shr eax, 12
544
	   mov eax, [page_tabs+eax*4]
545
	   and eax, 0xFFFFF000
546
	   ret
1159 hidnplayr 547
 
548
 
549
align 4
1198 clevermous 550
; Now it is called from core/sys32::exc_c (see stack frame there)
1159 hidnplayr 551
proc page_fault_handler
552
 
1206 hidnplayr 553
    .err_addr	equ ebp-4
1159 hidnplayr 554
 
1206 hidnplayr 555
	push	ebx		  ;save exception number (#PF)
556
	mov	ebp, esp
557
	mov	ebx, cr2
558
	push	ebx		  ;that is locals: .err_addr = cr2
559
	inc	[pg_data.pages_faults]
1159 hidnplayr 560
 
561
;     push eax
562
;     push edx
563
;     mov edx, 0x400   ;bochs
564
;     mov al,0xff      ;bochs
565
;     out dx, al       ;bochs
566
;     pop edx
567
;     pop eax
568
 
1206 hidnplayr 569
	mov	eax, [pf_err_code]
1159 hidnplayr 570
 
1206 hidnplayr 571
	cmp	ebx, OS_BASE	  ;ebx == .err_addr
572
	jb	.user_space	  ;ñòðàíèöà â ïàìÿòè ïðèëîæåíèÿ ;
1159 hidnplayr 573
 
1206 hidnplayr 574
	cmp	ebx, page_tabs
575
	jb	.kernel_space	  ;ñòðàíèöà â ïàìÿòè ÿäðà
1159 hidnplayr 576
 
1206 hidnplayr 577
	cmp	ebx, kernel_tabs
578
	jb	.alloc;.app_tabs  ;òàáëèöû ñòðàíèö ïðèëîæåíèÿ ;
579
				  ;ïðîñòî ñîçäàäèì îäíó
1198 clevermous 580
if 0 ;ïîêà ýòî ïðîñòî ëèøíåå
1206 hidnplayr 581
	cmp	ebx, LFB_BASE
582
	jb	.core_tabs	  ;òàáëèöû ñòðàíèö ÿäðà
583
				  ;Îøèáêà
1198 clevermous 584
  .lfb:
1206 hidnplayr 585
				  ;îáëàñòü LFB
586
				  ;Îøèáêà
587
	jmp	.fail
1198 clevermous 588
end if
589
.core_tabs:
1206 hidnplayr 590
.fail:	;simply return to caller
591
	mov	esp, ebp
592
	pop	ebx		  ;restore exception number (#PF)
593
	ret
1159 hidnplayr 594
 
595
.user_space:
1206 hidnplayr 596
	test	eax, PG_MAP
597
	jnz	.err_access	  ;Ñòðàíèöà ïðèñóòñòâóåò
598
				  ;Îøèáêà äîñòóïà ?
1159 hidnplayr 599
 
1206 hidnplayr 600
	shr	ebx, 12
601
	mov	ecx, ebx
602
	shr	ecx, 10
603
	mov	edx, [master_tab+ecx*4]
604
	test	edx, PG_MAP
605
	jz	.fail		  ;òàáëèöà ñòðàíèö íå ñîçäàíà
606
				  ;íåâåðíûé àäðåñ â ïðîãðàììå
1159 hidnplayr 607
 
1206 hidnplayr 608
	mov	eax, [page_tabs+ebx*4]
609
	test	eax, 2
610
	jz	.fail		  ;àäðåñ íå çàðåçåðâèðîâàí äëÿ ;
611
				  ;èñïîëüçîâàíèÿ. Îøèáêà
1159 hidnplayr 612
.alloc:
1206 hidnplayr 613
	call	alloc_page
614
	test	eax, eax
615
	jz	.fail
1159 hidnplayr 616
 
1206 hidnplayr 617
	stdcall map_page,[.err_addr],eax,dword PG_UW
1159 hidnplayr 618
 
1206 hidnplayr 619
	mov	edi, [.err_addr]
620
	and	edi, 0xFFFFF000
621
	mov	ecx, 1024
622
	xor	eax, eax
1198 clevermous 623
       ;cld     ;caller is duty for this
1206 hidnplayr 624
	rep	stosd
625
.exit:	;iret with repeat fault instruction
626
	add	esp,12 ;clear in stack: locals(.err_addr) + #PF + ret_to_caller
627
	restore_ring3_context
628
	iretd
1159 hidnplayr 629
 
1206 hidnplayr 630
.err_access  =	.fail
1159 hidnplayr 631
;íèêîãäà íå ïðîèñõîäèò
1198 clevermous 632
       ;jmp     .fail
1159 hidnplayr 633
 
634
.kernel_space:
1206 hidnplayr 635
	test	eax, PG_MAP
636
	jz	.fail	;ñòðàíèöà íå ïðèñóòñòâóåò
1159 hidnplayr 637
 
1206 hidnplayr 638
	test	eax,12	;U/S (+below)
639
	jnz	.fail	;ïðèëîæåíèå îáðàòèëîñü ê ïàìÿòè
640
			;ÿäðà
1198 clevermous 641
       ;test    eax, 8
642
       ;jnz     .fail   ;óñòàíîâëåí çàðåçåðâèðîâàííûé áèò
1206 hidnplayr 643
			;â òàáëèöàõ ñòðàíèö. äîáàâëåíî â P4/Xeon
1159 hidnplayr 644
 
645
;ïîïûòêà çàïèñè â çàùèù¸ííóþ ñòðàíèöó ÿäðà
646
 
1206 hidnplayr 647
	cmp	ebx, tss._io_map_0
648
	jb	.fail
1159 hidnplayr 649
 
1206 hidnplayr 650
	cmp	ebx, tss._io_map_0+8192
651
	jae	.fail
1159 hidnplayr 652
 
653
; io permission map
654
; copy-on-write protection
655
 
1206 hidnplayr 656
	call	alloc_page
657
	test	eax, eax
658
	jz	.fail
1159 hidnplayr 659
 
1206 hidnplayr 660
	push	eax
661
	stdcall map_page,[.err_addr],eax,dword PG_SW
662
	pop	eax
663
	mov	edi, [.err_addr]
664
	and	edi, -4096
665
	lea	esi, [edi+(not tss._io_map_0)+1]; -tss._io_map_0
1159 hidnplayr 666
 
1206 hidnplayr 667
	mov	ebx, esi
668
	shr	ebx, 12
669
	mov	edx, [current_slot]
670
	or	eax, PG_SW
671
	mov	[edx+APPDATA.io_map+ebx*4], eax
1159 hidnplayr 672
 
1206 hidnplayr 673
	add	esi, [default_io_map]
674
	mov	ecx, 4096/4
1198 clevermous 675
       ;cld     ;caller is duty for this
1206 hidnplayr 676
	rep	movsd
677
	jmp	.exit
1159 hidnplayr 678
endp
679
 
680
align 4
681
proc map_mem stdcall, lin_addr:dword,pdir:dword,\
1206 hidnplayr 682
		      ofs:dword,buf_size:dword
683
	   mov eax, [buf_size]
684
	   test eax, eax
685
	   jz .exit
1159 hidnplayr 686
 
1206 hidnplayr 687
	   mov eax, [pdir]
688
	   and eax, 0xFFFFF000
1159 hidnplayr 689
 
1206 hidnplayr 690
	   stdcall map_page,[ipc_pdir],eax,PG_UW
691
	   mov ebx, [ofs]
692
	   shr ebx, 22
693
	   mov esi, [ipc_pdir]
694
	   mov edi, [ipc_ptab]
695
	   mov eax, [esi+ebx*4]
696
	   and eax, 0xFFFFF000
697
	   jz .exit
698
	   stdcall map_page,edi,eax,PG_UW
1159 hidnplayr 699
;           inc ebx
700
;           add edi, 0x1000
701
;           mov eax, [esi+ebx*4]
702
;           test eax, eax
703
;           jz @f
704
;          and eax, 0xFFFFF000
705
;           stdcall map_page, edi, eax
706
 
1206 hidnplayr 707
@@:	   mov edi, [lin_addr]
708
	   and edi, 0xFFFFF000
709
	   mov ecx, [buf_size]
710
	   add ecx, 4095
711
	   shr ecx, 12
712
	   inc ecx
1159 hidnplayr 713
 
1206 hidnplayr 714
	   mov edx, [ofs]
715
	   shr edx, 12
716
	   and edx, 0x3FF
717
	   mov esi, [ipc_ptab]
1159 hidnplayr 718
 
1206 hidnplayr 719
.map:	   mov eax, [esi+edx*4]
720
	   and eax, 0xFFFFF000
721
	   jz  .exit
722
	   stdcall map_page,edi,eax,PG_UW
723
	   dec ecx
724
	   jz  .exit
725
	   add edi, 0x1000
726
	   inc edx
727
	   cmp edx, 0x400
728
	   jnz .map
729
	   inc ebx
730
	   mov eax, [ipc_pdir]
731
	   mov eax, [eax+ebx*4]
732
	   and eax, 0xFFFFF000
733
	   jz  .exit
734
	   stdcall map_page,esi,eax,PG_UW
735
	   xor edx, edx
736
	   jmp .map
1159 hidnplayr 737
 
738
.exit:
1206 hidnplayr 739
	   ret
1159 hidnplayr 740
endp
741
 
742
align 4
743
proc map_memEx stdcall, lin_addr:dword,pdir:dword,\
1206 hidnplayr 744
			ofs:dword,buf_size:dword
745
	   mov eax, [buf_size]
746
	   test eax, eax
747
	   jz .exit
1159 hidnplayr 748
 
1206 hidnplayr 749
	   mov eax, [pdir]
750
	   and eax, 0xFFFFF000
1159 hidnplayr 751
 
1206 hidnplayr 752
	   stdcall map_page,[proc_mem_pdir],eax,dword PG_UW
753
	   mov ebx, [ofs]
754
	   shr ebx, 22
755
	   mov esi, [proc_mem_pdir]
756
	   mov edi, [proc_mem_tab]
757
	   mov eax, [esi+ebx*4]
758
	   and eax, 0xFFFFF000
759
	   test eax, eax
760
	   jz .exit
761
	   stdcall map_page,edi,eax,dword PG_UW
1159 hidnplayr 762
 
1206 hidnplayr 763
@@:	   mov edi, [lin_addr]
764
	   and edi, 0xFFFFF000
765
	   mov ecx, [buf_size]
766
	   add ecx, 4095
767
	   shr ecx, 12
768
	   inc ecx
1159 hidnplayr 769
 
1206 hidnplayr 770
	   mov edx, [ofs]
771
	   shr edx, 12
772
	   and edx, 0x3FF
773
	   mov esi, [proc_mem_tab]
1159 hidnplayr 774
 
1206 hidnplayr 775
.map:	   mov eax, [esi+edx*4]
1159 hidnplayr 776
;           and eax, 0xFFFFF000
777
;           test eax, eax
778
;           jz .exit
1206 hidnplayr 779
	   stdcall map_page,edi,eax,dword PG_UW
780
	   add edi, 0x1000
781
	   inc edx
782
	   dec ecx
783
	   jnz .map
1159 hidnplayr 784
.exit:
1206 hidnplayr 785
	   ret
1159 hidnplayr 786
endp
787
 
788
 
789
 
790
 
791
sys_IPC:
792
;input:
793
;  eax=1 - set ipc buffer area
794
;    ebx=address of buffer
795
;    ecx=size of buffer
796
;  eax=2 - send message
797
;    ebx=PID
798
;    ecx=address of message
799
;    edx=size of message
800
 
1206 hidnplayr 801
	   cmp	eax,1
802
	   jne @f
803
	   call set_ipc_buff
804
	   mov [esp+36], eax
805
	   ret
1159 hidnplayr 806
@@:
1206 hidnplayr 807
	   cmp eax, 2
808
	   jne @f
809
	   stdcall sys_ipc_send, ebx, ecx, edx
810
	   mov [esp+36], eax
811
	   ret
1159 hidnplayr 812
@@:
1206 hidnplayr 813
	   xor eax, eax
814
	   not eax
815
	   mov [esp+36], eax
816
	   ret
1159 hidnplayr 817
 
818
align 4
819
proc set_ipc_buff
820
 
1206 hidnplayr 821
	   mov	eax,[current_slot]
822
	   pushf
823
	   cli
824
	   mov	[eax+APPDATA.ipc_start],ebx	;set fields in extended information area
825
	   mov	[eax+APPDATA.ipc_size],ecx
1159 hidnplayr 826
 
1206 hidnplayr 827
	   add ecx, ebx
828
	   add ecx, 4095
829
	   and ecx, not 4095
1159 hidnplayr 830
 
831
.touch:    mov eax, [ebx]
1206 hidnplayr 832
	   add ebx, 0x1000
833
	   cmp ebx, ecx
834
	   jb  .touch
1159 hidnplayr 835
 
1206 hidnplayr 836
	   popf
837
	   xor eax, eax
838
	   ret
1159 hidnplayr 839
endp
840
 
841
proc sys_ipc_send stdcall, PID:dword, msg_addr:dword, msg_size:dword
1206 hidnplayr 842
	   locals
843
	     dst_slot	dd ?
844
	     dst_offset dd ?
845
	     buf_size	dd ?
846
	     used_buf	dd ?
847
	   endl
1159 hidnplayr 848
 
1206 hidnplayr 849
	   pushf
850
	   cli
1159 hidnplayr 851
 
1206 hidnplayr 852
	   mov	eax, [PID]
853
	   call pid_to_slot
854
	   test eax,eax
855
	   jz	.no_pid
1159 hidnplayr 856
 
1206 hidnplayr 857
	   mov [dst_slot], eax
858
	   shl	eax,8
859
	   mov	edi,[eax+SLOT_BASE+0xa0]  ;is ipc area defined?
860
	   test edi,edi
861
	   jz	.no_ipc_area
1159 hidnplayr 862
 
1206 hidnplayr 863
	   mov ebx, edi
864
	   and ebx, 0xFFF
865
	   mov [dst_offset], ebx
1159 hidnplayr 866
 
1206 hidnplayr 867
	   mov esi, [eax+SLOT_BASE+0xa4]
868
	   mov [buf_size], esi
1159 hidnplayr 869
 
1206 hidnplayr 870
	   mov ecx, [ipc_tmp]
871
	   cmp esi, 0x40000-0x1000 ; size of [ipc_tmp] minus one page
872
	   jbe @f
873
	   push eax esi edi
874
	   add esi,0x1000
875
	   stdcall alloc_kernel_space,esi
876
	   mov ecx, eax
877
	   pop edi esi eax
1159 hidnplayr 878
@@:
1206 hidnplayr 879
	   mov [used_buf], ecx
880
	   stdcall map_mem, ecx, [SLOT_BASE+eax+0xB8],\
881
			     edi, esi
1159 hidnplayr 882
 
1206 hidnplayr 883
	   mov edi, [dst_offset]
884
	   add edi, [used_buf]
885
	   cmp dword [edi], 0
886
	   jnz	.ipc_blocked	      ;if dword [buffer]<>0 - ipc blocked now
1159 hidnplayr 887
 
1206 hidnplayr 888
	   mov edx, dword [edi+4]
889
	   lea ebx, [edx+8]
890
	   add ebx, [msg_size]
891
	   cmp ebx, [buf_size]
892
	   ja .buffer_overflow	       ;esi<0 - not enough memory in buffer
1159 hidnplayr 893
 
1206 hidnplayr 894
	   mov dword [edi+4], ebx
895
	   mov eax,[TASK_BASE]
896
	   mov eax, [eax+0x04]	       ;eax - our PID
897
	   add edi, edx
898
	   mov [edi], eax
899
	   mov ecx, [msg_size]
1159 hidnplayr 900
 
1206 hidnplayr 901
	   mov [edi+4], ecx
902
	   add edi, 8
903
	   mov esi, [msg_addr]
1159 hidnplayr 904
       ;    add esi, new_app_base
1206 hidnplayr 905
	   cld
906
	   rep movsb
1159 hidnplayr 907
 
1206 hidnplayr 908
	   mov ebx, [ipc_tmp]
909
	   mov edx, ebx
910
	   shr ebx, 12
911
	   xor eax, eax
912
	   mov [page_tabs+ebx*4], eax
913
	   invlpg [edx]
1159 hidnplayr 914
 
1206 hidnplayr 915
	   mov ebx, [ipc_pdir]
916
	   mov edx, ebx
917
	   shr ebx, 12
918
	   xor eax, eax
919
	   mov [page_tabs+ebx*4], eax
920
	   invlpg [edx]
1159 hidnplayr 921
 
1206 hidnplayr 922
	   mov ebx, [ipc_ptab]
923
	   mov edx, ebx
924
	   shr ebx, 12
925
	   xor eax, eax
926
	   mov [page_tabs+ebx*4], eax
927
	   invlpg [edx]
1159 hidnplayr 928
 
1206 hidnplayr 929
	   mov	eax, [dst_slot]
930
	   shl eax, 8
931
	   or	[eax+SLOT_BASE+0xA8],dword 0x40
932
	   cmp	dword [check_idle_semaphore],20
933
	   jge	.ipc_no_cis
1159 hidnplayr 934
 
1206 hidnplayr 935
	   mov	dword [check_idle_semaphore],5
1159 hidnplayr 936
.ipc_no_cis:
1206 hidnplayr 937
	   push 0
938
	   jmp .ret
1159 hidnplayr 939
.no_pid:
1206 hidnplayr 940
	   popf
941
	   mov eax, 4
942
	   ret
1159 hidnplayr 943
.no_ipc_area:
1206 hidnplayr 944
	   popf
945
	   xor eax, eax
946
	   inc eax
947
	   ret
1159 hidnplayr 948
.ipc_blocked:
1206 hidnplayr 949
	   push 2
950
	   jmp .ret
1159 hidnplayr 951
.buffer_overflow:
1206 hidnplayr 952
	   push 3
1159 hidnplayr 953
.ret:
1206 hidnplayr 954
	   mov eax, [used_buf]
955
	   cmp eax, [ipc_tmp]
956
	   jz @f
957
	   stdcall free_kernel_space,eax
1159 hidnplayr 958
@@:
1206 hidnplayr 959
	   pop eax
960
	   popf
961
	   ret
1159 hidnplayr 962
endp
963
 
964
align 4
965
sysfn_meminfo:
966
 
1206 hidnplayr 967
	;   add ecx, new_app_base
968
	   cmp ecx, OS_BASE
969
	   jae .fail
1159 hidnplayr 970
 
1206 hidnplayr 971
	   mov eax, [pg_data.pages_count]
972
	   mov [ecx], eax
973
	   shl eax, 12
974
	   mov [esp+32], eax
975
	   mov eax, [pg_data.pages_free]
976
	   mov [ecx+4], eax
977
	   mov eax, [pg_data.pages_faults]
978
	   mov [ecx+8], eax
979
	   mov eax, [heap_size]
980
	   mov [ecx+12], eax
981
	   mov eax, [heap_free]
982
	   mov [ecx+16], eax
983
	   mov eax, [heap_blocks]
984
	   mov [ecx+20], eax
985
	   mov eax, [free_blocks]
986
	   mov [ecx+24], eax
987
	   ret
1159 hidnplayr 988
.fail:
1206 hidnplayr 989
	   mov dword [esp+32], -1
990
	   ret
1159 hidnplayr 991
 
992
align 4
993
f68call:
1206 hidnplayr 994
	   dd f68.11
995
	   dd f68.12
996
	   dd f68.13
997
	   dd f68.14
998
	   dd f68.fail ;moved to f68.24
999
	   dd f68.16
1000
	   dd f68.17
1001
	   dd f68.fail ;moved to f68.25
1002
	   dd f68.19
1003
	   dd f68.20
1004
	   dd f68.21
1005
	   dd f68.22
1006
	   dd f68.23
1007
	   dd f68.24
1008
	   dd f68.25
1159 hidnplayr 1009
 
1010
align 4
1011
f68:
1206 hidnplayr 1012
	   cmp	eax,4
1013
	   jle	sys_sheduler
1159 hidnplayr 1014
 
1206 hidnplayr 1015
	   cmp eax, 11
1016
	   jb .fail
1159 hidnplayr 1017
 
1206 hidnplayr 1018
	   cmp eax, 25
1019
	   ja .fail
1159 hidnplayr 1020
 
1206 hidnplayr 1021
	   jmp dword [f68call+eax*4-11*4]
1159 hidnplayr 1022
.11:
1206 hidnplayr 1023
	   call init_heap
1024
	   mov [esp+36], eax
1025
	   ret
1159 hidnplayr 1026
.12:
1206 hidnplayr 1027
	   stdcall user_alloc, ebx
1028
	   mov [esp+36], eax
1029
	   ret
1159 hidnplayr 1030
.13:
1206 hidnplayr 1031
	   stdcall user_free, ebx
1032
	   mov [esp+36], eax
1033
	   ret
1159 hidnplayr 1034
.14:
1206 hidnplayr 1035
	   cmp ebx, OS_BASE
1036
	   jae .fail
1037
	   mov edi,ebx
1038
	   call get_event_ex
1039
	   mov [esp+36], eax
1040
	   ret
1198 clevermous 1041
.24:
1206 hidnplayr 1042
	   mov	eax, [current_slot]
1043
	   xchg ebx, [eax+APPDATA.exc_handler]
1044
	   xchg ecx, [eax+APPDATA.except_mask]
1045
	   mov	[esp+36], ebx ; reg_eax+8
1046
	   mov	[esp+24], ecx ; reg_ebx+8
1047
	   ret
1159 hidnplayr 1048
.16:
1206 hidnplayr 1049
	   test ebx, ebx
1050
	   jz .fail
1051
	   cmp ebx, OS_BASE
1052
	   jae .fail
1053
	   stdcall get_service, ebx
1054
	   mov [esp+36], eax
1055
	   ret
1159 hidnplayr 1056
.17:
1206 hidnplayr 1057
	   call srv_handlerEx	;ebx
1058
	   mov [esp+36], eax
1059
	   ret
1198 clevermous 1060
.25:
1206 hidnplayr 1061
	   cmp ebx,32
1062
	   jae .fail
1063
	   mov	eax, [current_slot]
1064
	   btr	[eax+APPDATA.except_mask],ebx
1065
	   setc byte[esp+36]
1066
	   jecxz @f
1067
	   bts	[eax+APPDATA.except_mask],ebx
1198 clevermous 1068
     @@:   ret
1159 hidnplayr 1069
.19:
1206 hidnplayr 1070
	   cmp ebx, OS_BASE
1071
	   jae .fail
1072
	   stdcall load_library, ebx
1073
	   mov [esp+36], eax
1074
	   ret
1159 hidnplayr 1075
.20:
1206 hidnplayr 1076
	   mov	   eax, ecx
1077
	   call    user_realloc
1078
	   mov	   [esp+36], eax
1079
	   ret
1159 hidnplayr 1080
.21:
1206 hidnplayr 1081
	   cmp ebx, OS_BASE
1082
	   jae .fail
1159 hidnplayr 1083
 
1206 hidnplayr 1084
	   stdcall load_PE, ebx
1159 hidnplayr 1085
 
1206 hidnplayr 1086
	   test eax, eax
1087
	   jz @F
1159 hidnplayr 1088
 
1206 hidnplayr 1089
	   mov esi, eax
1090
	   stdcall eax, DRV_ENTRY
1159 hidnplayr 1091
 
1206 hidnplayr 1092
	   test eax, eax
1093
	   jz @F
1159 hidnplayr 1094
 
1206 hidnplayr 1095
	   mov [eax+SRV.entry], esi
1159 hidnplayr 1096
 
1097
@@:
1206 hidnplayr 1098
	   mov [esp+36], eax
1099
	   ret
1159 hidnplayr 1100
.22:
1206 hidnplayr 1101
	   cmp ebx, OS_BASE
1102
	   jae .fail
1159 hidnplayr 1103
 
1206 hidnplayr 1104
	   stdcall shmem_open, ebx, ecx, edx
1105
	   mov [esp+28], edx
1106
	   mov [esp+36], eax
1107
	   ret
1159 hidnplayr 1108
 
1109
.23:
1206 hidnplayr 1110
	   cmp ebx, OS_BASE
1111
	   jae .fail
1159 hidnplayr 1112
 
1206 hidnplayr 1113
	   stdcall shmem_close, ebx
1114
	   mov [esp+36], eax
1115
	   ret
1159 hidnplayr 1116
 
1117
.fail:
1206 hidnplayr 1118
	   xor eax, eax
1119
	   mov [esp+36], eax
1120
	   ret
1159 hidnplayr 1121
 
1122
align 4
1123
proc load_pe_driver stdcall, file:dword
1124
 
1206 hidnplayr 1125
	   stdcall load_PE, [file]
1126
	   test eax, eax
1127
	   jz .fail
1159 hidnplayr 1128
 
1206 hidnplayr 1129
	   mov esi, eax
1130
	   stdcall eax, DRV_ENTRY
1131
	   test eax, eax
1132
	   jz .fail
1159 hidnplayr 1133
 
1206 hidnplayr 1134
	   mov [eax+SRV.entry], esi
1135
	   ret
1159 hidnplayr 1136
 
1137
.fail:
1206 hidnplayr 1138
	   xor eax, eax
1139
	   ret
1159 hidnplayr 1140
endp
1141
 
1142
 
1143
align 4
1144
proc init_mtrr
1145
 
1206 hidnplayr 1146
	   cmp [BOOT_VAR+0x901c],byte 2
1147
	   je  .exit
1159 hidnplayr 1148
 
1206 hidnplayr 1149
	   bt [cpu_caps], CAPS_MTRR
1150
	   jnc .exit
1159 hidnplayr 1151
 
1206 hidnplayr 1152
	   mov eax, cr0
1153
	   or eax, 0x60000000	;disable caching
1154
	   mov cr0, eax
1155
	   wbinvd		;invalidate cache
1159 hidnplayr 1156
 
1206 hidnplayr 1157
	   mov ecx, 0x2FF
1158
	   rdmsr		;
1159
	   push eax
1159 hidnplayr 1160
 
1206 hidnplayr 1161
	   xor edx, edx
1162
	   xor eax, eax
1163
	   mov ecx, 0x2FF
1164
	   wrmsr		;disable all MTRR
1159 hidnplayr 1165
 
1206 hidnplayr 1166
	   mov eax, [MEM_AMOUNT]
1159 hidnplayr 1167
; round eax up to next power of 2
1206 hidnplayr 1168
	   dec eax
1169
	   bsr ecx, eax
1170
	   mov eax, 2
1171
	   shl eax, cl
1172
	   stdcall set_mtrr, edx,edx,eax,MEM_WB
1173
	   stdcall set_mtrr, 1,[LFBAddress],[LFBSize],MEM_WC
1174
	   xor edx, edx
1175
	   xor eax, eax
1176
	   mov ecx, 0x204
1177
	   mov ebx, 6
1159 hidnplayr 1178
@@:
1206 hidnplayr 1179
	   wrmsr		;disable unused MTRR
1180
	   inc ecx
1181
	   wrmsr
1182
	   inc ecx
1183
	   dec ebx
1184
	   jnz @b
1159 hidnplayr 1185
 
1206 hidnplayr 1186
	   wbinvd		;again invalidate
1159 hidnplayr 1187
 
1206 hidnplayr 1188
	   pop eax
1189
	   or eax, 0x800	;set default memtype to UC
1190
	   and al, 0xF0
1191
	   mov ecx, 0x2FF
1192
	   wrmsr		;and enable MTRR
1159 hidnplayr 1193
 
1206 hidnplayr 1194
	   mov eax, cr0
1195
	   and eax, not 0x60000000
1196
	   mov cr0, eax 	; enable caching
1159 hidnplayr 1197
.exit:
1206 hidnplayr 1198
	   ret
1159 hidnplayr 1199
endp
1200
 
1201
align 4
1202
proc set_mtrr stdcall, reg:dword,base:dword,size:dword,mem_type:dword
1203
 
1206 hidnplayr 1204
	   xor edx, edx
1205
	   mov eax, [base]
1206
	   or eax, [mem_type]
1207
	   mov ecx, [reg]
1208
	   lea ecx, [0x200+ecx*2]
1209
	   wrmsr
1159 hidnplayr 1210
 
1206 hidnplayr 1211
	   mov ebx, [size]
1212
	   dec ebx
1213
	   mov eax, 0xFFFFFFFF
1214
	   mov edx, 0x0000000F
1215
	   sub eax, ebx
1216
	   sbb edx, 0
1217
	   or eax, 0x800
1218
	   inc ecx
1219
	   wrmsr
1220
	   ret
1159 hidnplayr 1221
endp
1222
 
1223
align 4
1224
proc stall stdcall, delay:dword
1206 hidnplayr 1225
	   push ecx
1226
	   push edx
1227
	   push ebx
1228
	   push eax
1159 hidnplayr 1229
 
1206 hidnplayr 1230
	   mov eax, [delay]
1231
	   mul [stall_mcs]
1232
	   mov ebx, eax       ;low
1233
	   mov ecx, edx       ;high
1234
	   rdtsc
1235
	   add ebx, eax
1236
	   adc ecx,edx
1159 hidnplayr 1237
@@:
1206 hidnplayr 1238
	   rdtsc
1239
	   sub eax, ebx
1240
	   sbb edx, ecx
1241
	   jb @B
1159 hidnplayr 1242
 
1206 hidnplayr 1243
	   pop eax
1244
	   pop ebx
1245
	   pop edx
1246
	   pop ecx
1247
	   ret
1159 hidnplayr 1248
endp
1249
 
1250
align 4
1251
proc create_ring_buffer stdcall, size:dword, flags:dword
1206 hidnplayr 1252
	   locals
1253
	     buf_ptr  dd ?
1254
	   endl
1159 hidnplayr 1255
 
1206 hidnplayr 1256
	   mov eax, [size]
1257
	   test eax, eax
1258
	   jz .fail
1159 hidnplayr 1259
 
1206 hidnplayr 1260
	   add eax, eax
1261
	   stdcall alloc_kernel_space, eax
1262
	   test eax, eax
1263
	   jz .fail
1159 hidnplayr 1264
 
1206 hidnplayr 1265
	   push ebx
1159 hidnplayr 1266
 
1206 hidnplayr 1267
	   mov [buf_ptr], eax
1159 hidnplayr 1268
 
1206 hidnplayr 1269
	   mov ebx, [size]
1270
	   shr ebx, 12
1271
	   push ebx
1159 hidnplayr 1272
 
1206 hidnplayr 1273
	   stdcall alloc_pages, ebx
1274
	   pop ecx
1159 hidnplayr 1275
 
1206 hidnplayr 1276
	   test eax, eax
1277
	   jz .mm_fail
1159 hidnplayr 1278
 
1206 hidnplayr 1279
	   push edi
1159 hidnplayr 1280
 
1206 hidnplayr 1281
	   or eax, [flags]
1282
	   mov edi, [buf_ptr]
1283
	   mov ebx, [buf_ptr]
1284
	   mov edx, ecx
1285
	   shl edx, 2
1286
	   shr edi, 10
1159 hidnplayr 1287
@@:
1206 hidnplayr 1288
	   mov [page_tabs+edi], eax
1289
	   mov [page_tabs+edi+edx], eax
1290
	   invlpg [ebx]
1291
	   invlpg [ebx+0x10000]
1292
	   add eax, 0x1000
1293
	   add ebx, 0x1000
1294
	   add edi, 4
1295
	   dec ecx
1296
	   jnz @B
1159 hidnplayr 1297
 
1206 hidnplayr 1298
	   mov eax, [buf_ptr]
1299
	   pop edi
1300
	   pop ebx
1301
	   ret
1159 hidnplayr 1302
.mm_fail:
1206 hidnplayr 1303
	   stdcall free_kernel_space, [buf_ptr]
1304
	   xor eax, eax
1305
	   pop ebx
1159 hidnplayr 1306
.fail:
1206 hidnplayr 1307
	   ret
1159 hidnplayr 1308
endp