Subversion Repositories Kolibri OS

Rev

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

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