Subversion Repositories Kolibri OS

Rev

Rev 1508 | Rev 1687 | 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: 1599 $
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
;           cmp dword [LFBAddress], -1
341
;           jne @f
342
;
343
;        mov     esi, boot_framebuf
344
;        call    boot_log
345
;
346
;           mov [BOOT_VAR+0x901c],byte 2
347
;           stdcall alloc_pages, (0x280000 / 4096)
348
;
349
;           push eax
350
;           call alloc_page
351
;           stdcall map_page_table, LFB_BASE, eax
352
;           pop eax
353
;           or eax, PG_UW
354
;           mov ebx, LFB_BASE
355
;           mov ecx, 0x280000 / 4096
356
;           call commit_pages
357
;           mov [LFBAddress], dword LFB_BASE
358
;           ret
359
;@@:
360
	   call init_mtrr
378 serge 361
 
1599 art_zh 362
	   mov edx, LFB_BASE
363
	   mov esi, [LFBAddress]
364
	   mov edi, 0x00C00000		     ; 12Mb
365
	   mov dword [exp_lfb+4], edx
1300 serge 366
 
1599 art_zh 367
	   shr edi, 12			     ; C00
368
;           mov [pg_count], edi
369
	   shr edi, 10			     ; 3
490 serge 370
 
1599 art_zh 371
	   or esi,  PG_GLOBAL+PG_LARGE+PG_UW
372
	   mov edx, sys_pgdir+(LFB_BASE shr 20)
164 serge 373
@@:
1599 art_zh 374
	   mov [edx], esi
375
	   add edx, 4
376
	   add esi, 0x00400000
377
	   dec edi
378
	   jnz @B
164 serge 379
 
1599 art_zh 380
	   mov dword [LFBAddress], LFB_BASE
381
	   mov eax, cr3       ;flush TLB
382
	   mov cr3, eax
383
	   ret
1507 art_zh 384
endp
164 serge 385
 
1507 art_zh 386
align 4
1599 art_zh 387
init_userDMA:
388
	   stdcall alloc_pages, 4096	; 16M <<<<<<<<<<+++++++++++++++++++++++++++++++++
389
	   add eax, 0x007FFFF0		; terrible mess, sorry ...
1507 art_zh 390
	   and eax, 0xFF800000		; align at 8M boundary
391
	   mov [UserDMAaddr], eax
1599 art_zh 392
	   or  eax, PG_LARGE + PG_UW + PG_NOCACHE
393
	   mov ebx, sys_pgdir + (USER_DMA_BUFFER shr 20)
394
	   mov [ebx], eax
1507 art_zh 395
	   add ebx, 4
1599 art_zh 396
	   add eax, 0x00400000
397
	   mov [ebx], eax
398
	   mov eax, cr3       ;flush TLB
399
	   mov cr3, eax
400
	   ret
164 serge 401
 
402
align 4
403
proc new_mem_resize stdcall, new_size:dword
404
 
1599 art_zh 405
	   mov ebx, pg_data.pg_mutex
406
	   call wait_mutex    ;ebx
164 serge 407
 
1599 art_zh 408
	   mov edi, [new_size]
409
	   add edi,4095
410
	   and edi,not 4095
411
	   mov [new_size], edi
164 serge 412
 
1599 art_zh 413
	   mov edx,[current_slot]
414
	   cmp [edx+APPDATA.heap_base],0
415
	   jne .exit
172 serge 416
 
1599 art_zh 417
	   mov esi, [edx+APPDATA.mem_size]
418
	   add esi, 4095
419
	   and esi, not 4095
164 serge 420
 
1599 art_zh 421
	   cmp edi, esi
422
	   jae .expand
164 serge 423
 
1599 art_zh 424
	   shr edi, 12
425
	   shr esi, 12
164 serge 426
@@:
1599 art_zh 427
	   mov eax, [app_page_tabs+edi*4]
428
	   test eax, 1
429
	   jz .next
430
	   mov dword [app_page_tabs+edi*4], 2
431
	   mov ebx, edi
432
	   shl ebx, 12
433
	   push eax
434
	   invlpg [ebx]
435
	   pop eax
436
	   call free_page
164 serge 437
 
1599 art_zh 438
.next:	   add edi, 1
439
	   cmp edi, esi
440
	   jb @B
164 serge 441
 
442
.update_size:
1599 art_zh 443
	   mov	   ebx, [new_size]
444
	   call    update_mem_size
164 serge 445
 
1599 art_zh 446
	   xor eax, eax
447
	   dec [pg_data.pg_mutex]
448
	   ret
164 serge 449
.expand:
450
 
1599 art_zh 451
	   push esi
452
	   push edi
164 serge 453
 
1599 art_zh 454
	   add edi, 0x3FFFFF
455
	   and edi, not(0x3FFFFF)
456
	   add esi, 0x3FFFFF
457
	   and esi, not(0x3FFFFF)
164 serge 458
 
1599 art_zh 459
	   cmp esi, edi
460
	   jae .grow
164 serge 461
 
1599 art_zh 462
	   xchg esi, edi
164 serge 463
 
464
@@:
1599 art_zh 465
	   call alloc_page
466
	   test eax, eax
467
	   jz .exit_pop
164 serge 468
 
1599 art_zh 469
	   stdcall map_page_table, edi, eax
164 serge 470
 
1599 art_zh 471
	   push edi
472
	   shr edi, 10
473
	   add edi, page_tabs
474
	   mov ecx, 1024
475
	   xor eax, eax
476
	   cld
477
	   rep stosd
478
	   pop edi
164 serge 479
 
1599 art_zh 480
	   add edi, 0x00400000
481
	   cmp edi, esi
482
	   jb @B
164 serge 483
.grow:
1461 diamond 484
;//-
485
	   pop edi
486
	   push edi
487
	   mov esi, [pg_data.pages_free]
488
	   sub esi, 1
489
	   shr edi, 12
490
	   cmp esi, edi
491
	   jle .out_of_memory
492
;//-
1599 art_zh 493
	   pop edi
494
	   pop esi
164 serge 495
@@:
1599 art_zh 496
	   call alloc_page
497
	   test eax, eax
498
	   jz .exit
499
	   stdcall map_page,esi,eax,dword PG_UW
164 serge 500
 
1599 art_zh 501
	   push edi
502
	   mov edi, esi
503
	   xor eax, eax
504
	   mov ecx, 1024
505
	   cld
506
	   rep stosd
507
	   pop edi
164 serge 508
 
1599 art_zh 509
	   add esi, 0x1000
510
	   cmp esi, edi
511
	   jb  @B
164 serge 512
 
1599 art_zh 513
	   jmp .update_size
1461 diamond 514
;//-
1103 diamond 515
.exit_pop:
1461 diamond 516
.out_of_memory:
517
;//-
1599 art_zh 518
	   pop edi
519
	   pop esi
164 serge 520
.exit:
1599 art_zh 521
	   xor eax, eax
522
	   inc eax
523
	   dec [pg_data.pg_mutex]
524
	   ret
164 serge 525
endp
526
 
294 diamond 527
update_mem_size:
465 serge 528
; in: edx = slot base
294 diamond 529
;     ebx = new memory size
530
; destroys eax,ecx,edx
531
 
1599 art_zh 532
	   mov	  [APPDATA.mem_size+edx],ebx
294 diamond 533
;search threads and update
534
;application memory size infomation
1599 art_zh 535
	   mov	  ecx,[APPDATA.dir_table+edx]
536
	   mov	  eax,2
294 diamond 537
 
538
.search_threads:
539
;eax = current slot
540
;ebx = new memory size
541
;ecx = page directory
1599 art_zh 542
	   cmp	  eax,[TASK_COUNT]
543
	   jg	  .search_threads_end
544
	   mov	  edx,eax
545
	   shl	  edx,5
546
	   cmp	  word [CURRENT_TASK+edx+TASKDATA.state],9 ;if slot empty?
547
	   jz	  .search_threads_next
548
	   shl	  edx,3
549
	   cmp	  [SLOT_BASE+edx+APPDATA.dir_table],ecx     ;if it is our thread?
550
	   jnz	  .search_threads_next
551
	   mov	  [SLOT_BASE+edx+APPDATA.mem_size],ebx	   ;update memory size
294 diamond 552
.search_threads_next:
1599 art_zh 553
	   inc	  eax
554
	   jmp	  .search_threads
294 diamond 555
.search_threads_end:
1599 art_zh 556
	   ret
294 diamond 557
 
285 serge 558
; param
559
;  eax= linear address
560
;
561
; retval
562
;  eax= phisical page address
563
 
164 serge 564
align 4
285 serge 565
get_pg_addr:
1599 art_zh 566
	   shr eax, 12
567
	   mov eax, [page_tabs+eax*4]
568
	   and eax, 0xFFFFF000
569
	   ret
164 serge 570
 
465 serge 571
 
188 serge 572
align 4
1105 Galkov 573
; Now it is called from core/sys32::exc_c (see stack frame there)
164 serge 574
proc page_fault_handler
465 serge 575
 
1599 art_zh 576
    .err_addr	equ ebp-4
709 diamond 577
 
1599 art_zh 578
	push	ebx		  ;save exception number (#PF)
579
	mov	ebp, esp
580
	mov	ebx, cr2
581
	push	ebx		  ;that is locals: .err_addr = cr2
582
	inc	[pg_data.pages_faults]
465 serge 583
 
1599 art_zh 584
	mov	eax, [pf_err_code]
164 serge 585
 
1599 art_zh 586
	cmp	ebx, OS_BASE	  ;ebx == .err_addr
587
	jb	.user_space	  ;ñòðàíèöà â ïàìÿòè ïðèëîæåíèÿ ;
188 serge 588
 
1599 art_zh 589
	cmp	ebx, page_tabs
590
	jb	.kernel_space	  ;ñòðàíèöà â ïàìÿòè ÿäðà
164 serge 591
 
1599 art_zh 592
	cmp	ebx, kernel_tabs
593
	jb	.alloc;.app_tabs  ;òàáëèöû ñòðàíèö ïðèëîæåíèÿ ;
594
				  ;ïðîñòî ñîçäàäèì îäíó
1056 Galkov 595
if 0 ;ïîêà ýòî ïðîñòî ëèøíåå
1599 art_zh 596
	cmp	ebx, LFB_BASE
597
	jb	.core_tabs	  ;òàáëèöû ñòðàíèö ÿäðà
598
				  ;Îøèáêà
1056 Galkov 599
  .lfb:
1599 art_zh 600
				  ;îáëàñòü LFB
601
				  ;Îøèáêà
602
	jmp	.fail
1056 Galkov 603
end if
604
.core_tabs:
1599 art_zh 605
.fail:	;simply return to caller
606
	mov	esp, ebp
607
	pop	ebx		  ;restore exception number (#PF)
608
	ret
378 serge 609
 
1300 serge 610
;        xchg bx, bx
611
;        add     esp,12 ;clear in stack: locals(.err_addr) + #PF + ret_to_caller
612
;        restore_ring3_context
613
;        iretd
614
 
164 serge 615
.user_space:
1599 art_zh 616
	test	eax, PG_MAP
617
	jnz	.err_access	  ;Ñòðàíèöà ïðèñóòñòâóåò
618
				  ;Îøèáêà äîñòóïà ?
465 serge 619
 
1599 art_zh 620
	shr	ebx, 12
621
	mov	ecx, ebx
622
	shr	ecx, 10
623
	mov	edx, [master_tab+ecx*4]
624
	test	edx, PG_MAP
625
	jz	.fail		  ;òàáëèöà ñòðàíèö íå ñîçäàíà
626
				  ;íåâåðíûé àäðåñ â ïðîãðàììå
172 serge 627
 
1599 art_zh 628
	mov	eax, [page_tabs+ebx*4]
629
	test	eax, 2
630
	jz	.fail		  ;àäðåñ íå çàðåçåðâèðîâàí äëÿ ;
631
				  ;èñïîëüçîâàíèÿ. Îøèáêà
188 serge 632
.alloc:
1599 art_zh 633
	call	alloc_page
634
	test	eax, eax
635
	jz	.fail
164 serge 636
 
1599 art_zh 637
	stdcall map_page,[.err_addr],eax,PG_UW
164 serge 638
 
1599 art_zh 639
	mov	edi, [.err_addr]
640
	and	edi, 0xFFFFF000
641
	mov	ecx, 1024
642
	xor	eax, eax
1056 Galkov 643
       ;cld     ;caller is duty for this
1599 art_zh 644
	rep	stosd
645
.exit:	;iret with repeat fault instruction
646
	add	esp,12 ;clear in stack: locals(.err_addr) + #PF + ret_to_caller
647
	restore_ring3_context
648
	iretd
465 serge 649
 
1289 diamond 650
.err_access:
651
; access denied? this may be a result of copy-on-write protection for DLL
652
; check list of HDLLs
1599 art_zh 653
	and	ebx, not 0xFFF
654
	mov	eax, [CURRENT_TASK]
655
	shl	eax, 8
656
	mov	eax, [SLOT_BASE+eax+APPDATA.dlls_list_ptr]
657
	test	eax, eax
658
	jz	.fail
659
	mov	esi, [eax+HDLL.fd]
1289 diamond 660
.scan_hdll:
1599 art_zh 661
	cmp	esi, eax
662
	jz	.fail
663
	mov	edx, ebx
664
	sub	edx, [esi+HDLL.base]
665
	cmp	edx, [esi+HDLL.size]
666
	jb	.fault_in_hdll
1289 diamond 667
.scan_hdll.next:
1599 art_zh 668
	mov	esi, [esi+HDLL.fd]
669
	jmp	.scan_hdll
1289 diamond 670
.fault_in_hdll:
671
; allocate new page, map it as rw and copy data
1599 art_zh 672
	call	alloc_page
673
	test	eax, eax
674
	jz	.fail
675
	stdcall map_page,ebx,eax,PG_UW
676
	mov	edi, ebx
677
	mov	ecx, 1024
678
	sub	ebx, [esi+HDLL.base]
679
	mov	esi, [esi+HDLL.parent]
680
	mov	esi, [esi+DLLDESCR.data]
681
	add	esi, ebx
682
	rep	movsd
683
	jmp	.exit
465 serge 684
 
685
.kernel_space:
1599 art_zh 686
	test	eax, PG_MAP
687
	jz	.fail	;ñòðàíèöà íå ïðèñóòñòâóåò
465 serge 688
 
1599 art_zh 689
	test	eax,12	;U/S (+below)
690
	jnz	.fail	;ïðèëîæåíèå îáðàòèëîñü ê ïàìÿòè
691
			;ÿäðà
1056 Galkov 692
       ;test    eax, 8
693
       ;jnz     .fail   ;óñòàíîâëåí çàðåçåðâèðîâàííûé áèò
1599 art_zh 694
			;â òàáëèöàõ ñòðàíèö. äîáàâëåíî â P4/Xeon
465 serge 695
 
696
;ïîïûòêà çàïèñè â çàùèù¸ííóþ ñòðàíèöó ÿäðà
697
 
1599 art_zh 698
	cmp	ebx, tss._io_map_0
699
	jb	.fail
465 serge 700
 
1599 art_zh 701
	cmp	ebx, tss._io_map_0+8192
702
	jae	.fail
465 serge 703
 
704
; io permission map
705
; copy-on-write protection
706
 
1599 art_zh 707
	call	alloc_page
708
	test	eax, eax
709
	jz	.fail
465 serge 710
 
1599 art_zh 711
	push	eax
712
	stdcall map_page,[.err_addr],eax,dword PG_SW
713
	pop	eax
714
	mov	edi, [.err_addr]
715
	and	edi, -4096
716
	lea	esi, [edi+(not tss._io_map_0)+1]; -tss._io_map_0
465 serge 717
 
1599 art_zh 718
	mov	ebx, esi
719
	shr	ebx, 12
720
	mov	edx, [current_slot]
721
	or	eax, PG_SW
722
	mov	[edx+APPDATA.io_map+ebx*4], eax
465 serge 723
 
1599 art_zh 724
	add	esi, [default_io_map]
725
	mov	ecx, 4096/4
1056 Galkov 726
       ;cld     ;caller is duty for this
1599 art_zh 727
	rep	movsd
728
	jmp	.exit
164 serge 729
endp
730
 
1314 diamond 731
; returns number of mapped bytes
732
proc map_mem stdcall, lin_addr:dword,slot:dword,\
1599 art_zh 733
		      ofs:dword,buf_size:dword,req_access:dword
734
	   push 0 ; initialize number of mapped bytes
1314 diamond 735
 
1599 art_zh 736
	   cmp [buf_size], 0
737
	   jz .exit
164 serge 738
 
1599 art_zh 739
	   mov eax, [slot]
740
	   shl eax, 8
741
	   mov eax, [SLOT_BASE+eax+APPDATA.dir_table]
742
	   and eax, 0xFFFFF000
164 serge 743
 
1599 art_zh 744
	   stdcall map_page,[ipc_pdir],eax,PG_UW
745
	   mov ebx, [ofs]
746
	   shr ebx, 22
747
	   mov esi, [ipc_pdir]
748
	   mov edi, [ipc_ptab]
749
	   mov eax, [esi+ebx*4]
750
	   and eax, 0xFFFFF000
751
	   jz .exit
752
	   stdcall map_page,edi,eax,PG_UW
164 serge 753
;           inc ebx
754
;           add edi, 0x1000
755
;           mov eax, [esi+ebx*4]
756
;           test eax, eax
757
;           jz @f
758
;          and eax, 0xFFFFF000
759
;           stdcall map_page, edi, eax
760
 
1599 art_zh 761
@@:	   mov edi, [lin_addr]
762
	   and edi, 0xFFFFF000
763
	   mov ecx, [buf_size]
764
	   add ecx, 4095
765
	   shr ecx, 12
766
	   inc ecx
164 serge 767
 
1599 art_zh 768
	   mov edx, [ofs]
769
	   shr edx, 12
770
	   and edx, 0x3FF
771
	   mov esi, [ipc_ptab]
164 serge 772
 
1314 diamond 773
.map:
1599 art_zh 774
	   stdcall safe_map_page,[slot],[req_access],[ofs]
775
	   jnc .exit
776
	   add dword [ebp-4], 4096
777
	   add [ofs], 4096
778
	   dec ecx
779
	   jz  .exit
780
	   add edi, 0x1000
781
	   inc edx
782
	   cmp edx, 0x400
783
	   jnz .map
784
	   inc ebx
785
	   mov eax, [ipc_pdir]
786
	   mov eax, [eax+ebx*4]
787
	   and eax, 0xFFFFF000
788
	   jz  .exit
789
	   stdcall map_page,esi,eax,PG_UW
790
	   xor edx, edx
791
	   jmp .map
164 serge 792
 
793
.exit:
1599 art_zh 794
	   pop eax
795
	   ret
164 serge 796
endp
797
 
1314 diamond 798
proc map_memEx stdcall, lin_addr:dword,slot:dword,\
1599 art_zh 799
			ofs:dword,buf_size:dword,req_access:dword
800
	   push 0 ; initialize number of mapped bytes
1314 diamond 801
 
1599 art_zh 802
	   cmp [buf_size], 0
803
	   jz .exit
164 serge 804
 
1599 art_zh 805
	   mov eax, [slot]
806
	   shl eax, 8
807
	   mov eax, [SLOT_BASE+eax+APPDATA.dir_table]
808
	   and eax, 0xFFFFF000
164 serge 809
 
1599 art_zh 810
	   stdcall map_page,[proc_mem_pdir],eax,PG_UW
811
	   mov ebx, [ofs]
812
	   shr ebx, 22
813
	   mov esi, [proc_mem_pdir]
814
	   mov edi, [proc_mem_tab]
815
	   mov eax, [esi+ebx*4]
816
	   and eax, 0xFFFFF000
817
	   test eax, eax
818
	   jz .exit
819
	   stdcall map_page,edi,eax,PG_UW
164 serge 820
 
1599 art_zh 821
@@:	   mov edi, [lin_addr]
822
	   and edi, 0xFFFFF000
823
	   mov ecx, [buf_size]
824
	   add ecx, 4095
825
	   shr ecx, 12
826
	   inc ecx
164 serge 827
 
1599 art_zh 828
	   mov edx, [ofs]
829
	   shr edx, 12
830
	   and edx, 0x3FF
831
	   mov esi, [proc_mem_tab]
164 serge 832
 
1314 diamond 833
.map:
1599 art_zh 834
	   stdcall safe_map_page,[slot],[req_access],[ofs]
835
	   jnc .exit
836
	   add dword [ebp-4], 0x1000
837
	   add edi, 0x1000
838
	   add [ofs], 0x1000
839
	   inc edx
840
	   dec ecx
841
	   jnz .map
164 serge 842
.exit:
1599 art_zh 843
	   pop eax
844
	   ret
164 serge 845
endp
846
 
1314 diamond 847
; in: esi+edx*4 = pointer to page table entry
848
; in: [slot], [req_access], [ofs] on the stack
849
; in: edi = linear address to map
850
; out: CF cleared <=> failed
851
; destroys: only eax
852
proc safe_map_page stdcall, slot:dword, req_access:dword, ofs:dword
853
	mov	eax, [esi+edx*4]
854
	test	al, PG_MAP
855
	jz	.not_present
856
	test	al, PG_WRITE
857
	jz	.resolve_readonly
858
; normal case: writable page, just map with requested access
859
.map:
1599 art_zh 860
	stdcall map_page, edi, eax, [req_access]
1314 diamond 861
	stc
862
.fail:
863
	ret
864
.not_present:
865
; check for alloc-on-demand page
866
	test	al, 2
867
	jz	.fail
868
; allocate new page, save it to source page table
869
	push	ecx
870
	call	alloc_page
871
	pop	ecx
872
	test	eax, eax
873
	jz	.fail
874
	or	al, PG_UW
875
	mov	[esi+edx*4], eax
876
	jmp	.map
877
.resolve_readonly:
878
; readonly page, probably copy-on-write
879
; check: readonly request of readonly page is ok
880
	test	[req_access], PG_WRITE
881
	jz	.map
882
; find control structure for this page
883
	pushf
884
	cli
885
	cld
886
	push	ebx ecx
887
	mov	eax, [slot]
888
	shl	eax, 8
889
	mov	eax, [SLOT_BASE+eax+APPDATA.dlls_list_ptr]
890
	test	eax, eax
891
	jz	.no_hdll
892
	mov	ecx, [eax+HDLL.fd]
893
.scan_hdll:
894
	cmp	ecx, eax
895
	jz	.no_hdll
896
	mov	ebx, [ofs]
897
	and	ebx, not 0xFFF
898
	sub	ebx, [ecx+HDLL.base]
899
	cmp	ebx, [ecx+HDLL.size]
900
	jb	.hdll_found
901
	mov	ecx, [ecx+HDLL.fd]
902
	jmp	.scan_hdll
903
.no_hdll:
904
	pop	ecx ebx
905
	popf
906
	clc
907
	ret
908
.hdll_found:
909
; allocate page, save it in page table, map it, copy contents from base
910
	mov	eax, [ecx+HDLL.parent]
911
	add	ebx, [eax+DLLDESCR.data]
912
	call	alloc_page
913
	test	eax, eax
914
	jz	.no_hdll
915
	or	al, PG_UW
916
	mov	[esi+edx*4], eax
1599 art_zh 917
	stdcall map_page, edi, eax, [req_access]
1314 diamond 918
	push	esi edi
919
	mov	esi, ebx
920
	mov	ecx, 4096/4
921
	rep	movsd
922
	pop	edi esi
923
	pop	ecx ebx
924
	popf
925
	stc
926
	ret
927
endp
164 serge 928
 
929
sys_IPC:
930
;input:
1496 Lrz 931
;  ebx=1 - set ipc buffer area
932
;    ecx=address of buffer
933
;    edx=size of buffer
164 serge 934
;  eax=2 - send message
935
;    ebx=PID
936
;    ecx=address of message
937
;    edx=size of message
938
 
1496 Lrz 939
	dec	ebx
940
	jnz	@f
164 serge 941
 
1599 art_zh 942
	mov	eax,[current_slot]
943
	pushf
944
	cli
945
	mov	[eax+APPDATA.ipc_start],ecx	;set fields in extended information area
946
	mov	[eax+APPDATA.ipc_size],edx
164 serge 947
 
1599 art_zh 948
	add edx, ecx
949
	add edx, 4095
950
	and edx, not 4095
164 serge 951
 
1496 Lrz 952
.touch: mov eax, [ecx]
1599 art_zh 953
	add ecx, 0x1000
954
	cmp ecx, edx
955
	jb  .touch
164 serge 956
 
1599 art_zh 957
	popf
958
	mov [esp+32], ebx	;ebx=0
959
	ret
164 serge 960
 
1496 Lrz 961
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
962
;2
963
@@:
964
	dec	ebx
965
	jnz	@f
164 serge 966
 
1599 art_zh 967
	stdcall sys_ipc_send, ecx, edx, esi
968
	mov	[esp+32], eax
969
	ret
1496 Lrz 970
@@:
971
	or	eax,-1
1599 art_zh 972
	mov	[esp+32], eax
973
	ret
1496 Lrz 974
 
975
;align 4
976
;proc set_ipc_buff
977
 
978
;           mov  eax,[current_slot]
979
;           pushf
980
;           cli
981
;           mov  [eax+APPDATA.ipc_start],ebx     ;set fields in extended information area
982
;           mov  [eax+APPDATA.ipc_size],ecx
983
;
984
;           add ecx, ebx
985
;           add ecx, 4095
986
;           and ecx, not 4095
987
;
988
;.touch:    mov eax, [ebx]
989
;           add ebx, 0x1000
990
;           cmp ebx, ecx
991
;           jb  .touch
992
;
993
;           popf
994
;           xor eax, eax
995
;           ret
996
;endp
997
 
164 serge 998
proc sys_ipc_send stdcall, PID:dword, msg_addr:dword, msg_size:dword
1599 art_zh 999
	   locals
1000
	     dst_slot	dd ?
1001
	     dst_offset dd ?
1002
	     buf_size	dd ?
1003
	     used_buf	dd ?
1004
	   endl
164 serge 1005
 
1599 art_zh 1006
	   pushf
1007
	   cli
164 serge 1008
 
1599 art_zh 1009
	   mov	eax, [PID]
1010
	   call pid_to_slot
1011
	   test eax,eax
1012
	   jz	.no_pid
164 serge 1013
 
1599 art_zh 1014
	   mov [dst_slot], eax
1015
	   shl	eax,8
1016
	   mov	edi,[eax+SLOT_BASE+0xa0]  ;is ipc area defined?
1017
	   test edi,edi
1018
	   jz	.no_ipc_area
164 serge 1019
 
1599 art_zh 1020
	   mov ebx, edi
1021
	   and ebx, 0xFFF
1022
	   mov [dst_offset], ebx
164 serge 1023
 
1599 art_zh 1024
	   mov esi, [eax+SLOT_BASE+0xa4]
1025
	   mov [buf_size], esi
164 serge 1026
 
1599 art_zh 1027
	   mov ecx, [ipc_tmp]
1028
	   cmp esi, 0x40000-0x1000 ; size of [ipc_tmp] minus one page
1029
	   jbe @f
1030
	   push esi edi
1031
	   add esi,0x1000
1032
	   stdcall alloc_kernel_space,esi
1033
	   mov ecx, eax
1034
	   pop edi esi
536 diamond 1035
@@:
1599 art_zh 1036
	   mov [used_buf], ecx
1037
	   stdcall map_mem, ecx, [dst_slot],\
1038
			     edi, esi, PG_SW
164 serge 1039
 
1599 art_zh 1040
	   mov edi, [dst_offset]
1041
	   add edi, [used_buf]
1042
	   cmp dword [edi], 0
1043
	   jnz	.ipc_blocked	      ;if dword [buffer]<>0 - ipc blocked now
227 serge 1044
 
1599 art_zh 1045
	   mov edx, dword [edi+4]
1046
	   lea ebx, [edx+8]
1047
	   add ebx, [msg_size]
1048
	   cmp ebx, [buf_size]
1049
	   ja .buffer_overflow	       ;esi<0 - not enough memory in buffer
227 serge 1050
 
1599 art_zh 1051
	   mov dword [edi+4], ebx
1052
	   mov eax,[TASK_BASE]
1053
	   mov eax, [eax+0x04]	       ;eax - our PID
1054
	   add edi, edx
1055
	   mov [edi], eax
1056
	   mov ecx, [msg_size]
164 serge 1057
 
1599 art_zh 1058
	   mov [edi+4], ecx
1059
	   add edi, 8
1060
	   mov esi, [msg_addr]
465 serge 1061
       ;    add esi, new_app_base
1599 art_zh 1062
	   cld
1063
	   rep movsb
164 serge 1064
 
1599 art_zh 1065
	   mov ebx, [ipc_tmp]
1066
	   mov edx, ebx
1067
	   shr ebx, 12
1068
	   xor eax, eax
1069
	   mov [page_tabs+ebx*4], eax
1070
	   invlpg [edx]
164 serge 1071
 
1599 art_zh 1072
	   mov ebx, [ipc_pdir]
1073
	   mov edx, ebx
1074
	   shr ebx, 12
1075
	   xor eax, eax
1076
	   mov [page_tabs+ebx*4], eax
1077
	   invlpg [edx]
164 serge 1078
 
1599 art_zh 1079
	   mov ebx, [ipc_ptab]
1080
	   mov edx, ebx
1081
	   shr ebx, 12
1082
	   xor eax, eax
1083
	   mov [page_tabs+ebx*4], eax
1084
	   invlpg [edx]
164 serge 1085
 
1599 art_zh 1086
	   mov	eax, [dst_slot]
1087
	   shl eax, 8
1088
	   or	[eax+SLOT_BASE+0xA8],dword 0x40
1089
	   cmp	dword [check_idle_semaphore],20
1090
	   jge	.ipc_no_cis
164 serge 1091
 
1599 art_zh 1092
	   mov	dword [check_idle_semaphore],5
164 serge 1093
.ipc_no_cis:
1599 art_zh 1094
	   push 0
1095
	   jmp .ret
164 serge 1096
.no_pid:
1599 art_zh 1097
	   popf
1098
	   mov eax, 4
1099
	   ret
164 serge 1100
.no_ipc_area:
1599 art_zh 1101
	   popf
1102
	   xor eax, eax
1103
	   inc eax
1104
	   ret
164 serge 1105
.ipc_blocked:
1599 art_zh 1106
	   push 2
1107
	   jmp .ret
164 serge 1108
.buffer_overflow:
1599 art_zh 1109
	   push 3
536 diamond 1110
.ret:
1599 art_zh 1111
	   mov eax, [used_buf]
1112
	   cmp eax, [ipc_tmp]
1113
	   jz @f
1114
	   stdcall free_kernel_space,eax
536 diamond 1115
@@:
1599 art_zh 1116
	   pop eax
1117
	   popf
1118
	   ret
164 serge 1119
endp
1120
 
1121
align 4
170 serge 1122
sysfn_meminfo:
164 serge 1123
 
1599 art_zh 1124
	;   add ecx, new_app_base
1125
	   cmp ecx, OS_BASE
1126
	   jae .fail
172 serge 1127
 
1599 art_zh 1128
	   mov eax, [pg_data.pages_count]
1129
	   mov [ecx], eax
1130
	   shl eax, 12
1131
	   mov [esp+32], eax
1132
	   mov eax, [pg_data.pages_free]
1133
	   mov [ecx+4], eax
1134
	   mov eax, [pg_data.pages_faults]
1135
	   mov [ecx+8], eax
1136
	   mov eax, [heap_size]
1137
	   mov [ecx+12], eax
1138
	   mov eax, [heap_free]
1139
	   mov [ecx+16], eax
1140
	   mov eax, [heap_blocks]
1141
	   mov [ecx+20], eax
1142
	   mov eax, [free_blocks]
1143
	   mov [ecx+24], eax
1144
	   ret
172 serge 1145
.fail:
1599 art_zh 1146
	   or dword [esp+32], -1
1147
	   ret
1276 Lrz 1148
iglobal
164 serge 1149
align 4
940 serge 1150
f68call:
1599 art_zh 1151
	   dd f68.11   ; init_heap
1152
	   dd f68.12   ; user_alloc
1153
	   dd f68.13   ; user_free
1154
	   dd f68.14   ; get_event_ex
1155
	   dd f68.fail ;moved to f68.24
1156
	   dd f68.16   ; get_service
1157
	   dd f68.17   ; call_service
1158
	   dd f68.fail ;moved to f68.25
1159
	   dd f68.19   ; load_dll
1160
	   dd f68.20   ; user_realloc
1161
	   dd f68.21   ; load_driver
1162
	   dd f68.22   ; shmem_open
1163
	   dd f68.23   ; shmem_close
1164
	   dd f68.24
1165
	   dd f68.25
1276 Lrz 1166
endg
940 serge 1167
align 4
1168
f68:
1599 art_zh 1169
	   cmp	ebx,4
1170
	   jbe	sys_sheduler
164 serge 1171
 
1599 art_zh 1172
	   cmp ebx, 11
1173
	   jb .fail
164 serge 1174
 
1599 art_zh 1175
	   cmp ebx, 25
1176
	   ja .fail
940 serge 1177
 
1599 art_zh 1178
	   jmp dword [f68call+ebx*4-11*4]
940 serge 1179
.11:
1599 art_zh 1180
	   call init_heap
1181
	   mov [esp+32], eax
1182
	   ret
940 serge 1183
.12:
1599 art_zh 1184
	   stdcall user_alloc, ecx
1185
	   mov [esp+32], eax
1186
	   ret
940 serge 1187
.13:
1599 art_zh 1188
	   stdcall user_free, ecx
1189
	   mov [esp+32], eax
1190
	   ret
940 serge 1191
.14:
1599 art_zh 1192
	   cmp ecx, OS_BASE
1193
	   jae .fail
1194
	   mov edi,ecx
1195
	   call get_event_ex
1196
	   mov [esp+32], eax
1197
	   ret
940 serge 1198
.16:
1599 art_zh 1199
	   test ecx, ecx
1200
	   jz .fail
1201
	   cmp ecx, OS_BASE
1202
	   jae .fail
1203
	   stdcall get_service, ecx
1204
	   mov [esp+32], eax
1205
	   ret
940 serge 1206
.17:
1599 art_zh 1207
	   call srv_handlerEx	;ecx
1208
	   mov [esp+32], eax
1209
	   ret
940 serge 1210
.19:
1599 art_zh 1211
	   cmp ecx, OS_BASE
1212
	   jae .fail
1213
	   stdcall load_library, ecx
1214
	   mov [esp+32], eax
1215
	   ret
940 serge 1216
.20:
1599 art_zh 1217
	   mov	   eax, edx
1345 Lrz 1218
	   mov	   ebx, ecx
1599 art_zh 1219
	   call    user_realloc 	;in: eax = pointer, ebx = new size
1220
	   mov	   [esp+32], eax
1221
	   ret
940 serge 1222
.21:
1599 art_zh 1223
	   cmp ecx, OS_BASE
1224
	   jae .fail
740 serge 1225
 
1599 art_zh 1226
	   cmp ebx, OS_BASE
1227
	   jae .fail
1316 serge 1228
 
1599 art_zh 1229
	   mov edi, edx
1230
	   stdcall load_PE, ecx
1231
	   mov esi, eax
1232
	   test eax, eax
1233
	   jz @F
740 serge 1234
 
1599 art_zh 1235
	   push edi
1236
	   push DRV_ENTRY
1237
	   call eax
1238
	   add esp, 8
1239
	   test eax, eax
1240
	   jz @F
740 serge 1241
 
1599 art_zh 1242
	   mov [eax+SRV.entry], esi
740 serge 1243
 
1244
@@:
1599 art_zh 1245
	   mov [esp+32], eax
1246
	   ret
940 serge 1247
.22:
1599 art_zh 1248
	   cmp ecx, OS_BASE
1249
	   jae .fail
740 serge 1250
 
1599 art_zh 1251
	   stdcall shmem_open, ecx, edx, esi
1252
	   mov [esp+24], edx
1253
	   mov [esp+32], eax
1254
	   ret
740 serge 1255
 
943 serge 1256
.23:
1599 art_zh 1257
	   cmp ecx, OS_BASE
1258
	   jae .fail
943 serge 1259
 
1599 art_zh 1260
	   stdcall shmem_close, ecx
1261
	   mov [esp+32], eax
1262
	   ret
1275 serge 1263
.24:
1599 art_zh 1264
	   mov	eax, [current_slot]
1265
	   xchg ecx, [eax+APPDATA.exc_handler]
1266
	   xchg edx, [eax+APPDATA.except_mask]
1267
	   mov	[esp+32], ecx ; reg_eax+8
1268
	   mov	[esp+20], edx ; reg_ebx+8
1269
	   ret
1275 serge 1270
.25:
1599 art_zh 1271
	   cmp ecx,32
1272
	   jae .fail
1273
	   mov	eax, [current_slot]
1274
	   btr	[eax+APPDATA.except_mask],ecx
1275
	   setc byte[esp+32]
1276
	   jecxz @f
1277
	   bts	[eax+APPDATA.except_mask],ecx
1275 serge 1278
@@:
1599 art_zh 1279
	   ret
943 serge 1280
 
164 serge 1281
.fail:
1599 art_zh 1282
	   xor eax, eax
1283
	   mov [esp+32], eax
1284
	   ret
164 serge 1285
 
1286
align 4
819 serge 1287
proc load_pe_driver stdcall, file:dword
1288
 
1599 art_zh 1289
	   stdcall load_PE, [file]
1290
	   test eax, eax
1291
	   jz .fail
819 serge 1292
 
1599 art_zh 1293
	   mov esi, eax
1294
	   stdcall eax, DRV_ENTRY
1295
	   test eax, eax
1296
	   jz .fail
819 serge 1297
 
1599 art_zh 1298
	   mov [eax+SRV.entry], esi
1299
	   ret
819 serge 1300
 
1301
.fail:
1599 art_zh 1302
	   xor eax, eax
1303
	   ret
819 serge 1304
endp
1305
 
1306
 
1307
align 4
164 serge 1308
proc init_mtrr
1309
 
1599 art_zh 1310
	   cmp [BOOT_VAR+0x901c],byte 2
1311
	   je  .exit
164 serge 1312
 
1599 art_zh 1313
	   bt [cpu_caps], CAPS_MTRR
1314
	   jnc .exit
211 serge 1315
 
1599 art_zh 1316
	   mov eax, cr0
1317
	   or eax, 0x60000000	;disable caching
1318
	   mov cr0, eax
1319
	   wbinvd		;invalidate cache
164 serge 1320
 
1599 art_zh 1321
	   mov ecx, 0x2FF
1322
	   rdmsr		;
1030 diamond 1323
; has BIOS already initialized MTRRs?
1599 art_zh 1324
	   test ah, 8
1325
	   jnz .skip_init
1030 diamond 1326
; rarely needed, so mainly placeholder
1327
; main memory - cached
1599 art_zh 1328
	   push eax
164 serge 1329
 
1599 art_zh 1330
	   mov eax, [MEM_AMOUNT]
821 diamond 1331
; round eax up to next power of 2
1599 art_zh 1332
	   dec eax
1333
	   bsr ecx, eax
1334
	   mov ebx, 2
1335
	   shl ebx, cl
1336
	   dec ebx
1030 diamond 1337
; base of memory range = 0, type of memory range = MEM_WB
1599 art_zh 1338
	   xor edx, edx
1339
	   mov eax, MEM_WB
1340
	   mov ecx, 0x200
1341
	   wrmsr
1030 diamond 1342
; mask of memory range = 0xFFFFFFFFF - (size - 1), ebx = size - 1
1599 art_zh 1343
	   mov eax, 0xFFFFFFFF
1344
	   mov edx, 0x0000000F
1345
	   sub eax, ebx
1346
	   sbb edx, 0
1347
	   or eax, 0x800
1348
	   inc ecx
1349
	   wrmsr
1030 diamond 1350
; clear unused MTRRs
1599 art_zh 1351
	   xor eax, eax
1352
	   xor edx, edx
164 serge 1353
@@:
1599 art_zh 1354
	   wrmsr
1355
	   inc ecx
1356
	   cmp ecx, 0x210
1357
	   jb @b
1030 diamond 1358
; enable MTRRs
1599 art_zh 1359
	   pop eax
1360
	   or ah, 8
1361
	   and al, 0xF0 ; default memtype = UC
1362
	   mov ecx, 0x2FF
1363
	   wrmsr
1030 diamond 1364
.skip_init:
1599 art_zh 1365
	   stdcall set_mtrr, [LFBAddress],[LFBSize],MEM_WC
164 serge 1366
 
1599 art_zh 1367
	   wbinvd		;again invalidate
164 serge 1368
 
1599 art_zh 1369
	   mov eax, cr0
1370
	   and eax, not 0x60000000
1371
	   mov cr0, eax 	; enable caching
164 serge 1372
.exit:
1599 art_zh 1373
	   ret
164 serge 1374
endp
1375
 
1376
align 4
1030 diamond 1377
proc set_mtrr stdcall, base:dword,size:dword,mem_type:dword
1378
; find unused register
1599 art_zh 1379
	   mov ecx, 0x201
1030 diamond 1380
@@:
1599 art_zh 1381
	   rdmsr
1382
	   dec ecx
1383
	   test ah, 8
1384
	   jz .found
1385
	   rdmsr
1386
	   mov al, 0 ; clear memory type field
1387
	   cmp eax, [base]
1388
	   jz .ret
1389
	   add ecx, 3
1390
	   cmp ecx, 0x210
1391
	   jb @b
1030 diamond 1392
; no free registers, ignore the call
1393
.ret:
1599 art_zh 1394
	   ret
1030 diamond 1395
.found:
1396
; found, write values
1599 art_zh 1397
	   xor edx, edx
1398
	   mov eax, [base]
1399
	   or eax, [mem_type]
1400
	   wrmsr
164 serge 1401
 
1599 art_zh 1402
	   mov ebx, [size]
1403
	   dec ebx
1404
	   mov eax, 0xFFFFFFFF
1405
	   mov edx, 0x0000000F
1406
	   sub eax, ebx
1407
	   sbb edx, 0
1408
	   or eax, 0x800
1409
	   inc ecx
1410
	   wrmsr
1411
	   ret
164 serge 1412
endp
1413
 
465 serge 1414
align 4
172 serge 1415
proc stall stdcall, delay:dword
1599 art_zh 1416
	   push ecx
1417
	   push edx
1418
	   push ebx
1419
	   push eax
172 serge 1420
 
1599 art_zh 1421
	   mov eax, [delay]
1422
	   mul [stall_mcs]
1423
	   mov ebx, eax       ;low
1424
	   mov ecx, edx       ;high
1425
	   rdtsc
1426
	   add ebx, eax
1427
	   adc ecx,edx
172 serge 1428
@@:
1599 art_zh 1429
	   rdtsc
1430
	   sub eax, ebx
1431
	   sbb edx, ecx
1432
	   jb @B
172 serge 1433
 
1599 art_zh 1434
	   pop eax
1435
	   pop ebx
1436
	   pop edx
1437
	   pop ecx
1438
	   ret
172 serge 1439
endp
1440
 
520 serge 1441
align 4
1442
proc create_ring_buffer stdcall, size:dword, flags:dword
1599 art_zh 1443
	   locals
1444
	     buf_ptr  dd ?
1445
	   endl
237 serge 1446
 
1599 art_zh 1447
	   mov eax, [size]
1448
	   test eax, eax
1449
	   jz .fail
520 serge 1450
 
1599 art_zh 1451
	   add eax, eax
1452
	   stdcall alloc_kernel_space, eax
1453
	   test eax, eax
1454
	   jz .fail
520 serge 1455
 
1599 art_zh 1456
	   push ebx
662 serge 1457
 
1599 art_zh 1458
	   mov [buf_ptr], eax
520 serge 1459
 
1599 art_zh 1460
	   mov ebx, [size]
1461
	   shr ebx, 12
1462
	   push ebx
520 serge 1463
 
1599 art_zh 1464
	   stdcall alloc_pages, ebx
1465
	   pop ecx
520 serge 1466
 
1599 art_zh 1467
	   test eax, eax
1468
	   jz .mm_fail
520 serge 1469
 
1599 art_zh 1470
	   push edi
662 serge 1471
 
1599 art_zh 1472
	   or eax, [flags]
1473
	   mov edi, [buf_ptr]
1474
	   mov ebx, [buf_ptr]
1475
	   mov edx, ecx
1476
	   shl edx, 2
1477
	   shr edi, 10
520 serge 1478
@@:
1599 art_zh 1479
	   mov [page_tabs+edi], eax
1480
	   mov [page_tabs+edi+edx], eax
1481
	   invlpg [ebx]
1482
	   invlpg [ebx+0x10000]
1483
	   add eax, 0x1000
1484
	   add ebx, 0x1000
1485
	   add edi, 4
1486
	   dec ecx
1487
	   jnz @B
520 serge 1488
 
1599 art_zh 1489
	   mov eax, [buf_ptr]
1490
	   pop edi
1491
	   pop ebx
1492
	   ret
520 serge 1493
.mm_fail:
1599 art_zh 1494
	   stdcall free_kernel_space, [buf_ptr]
1495
	   xor eax, eax
1496
	   pop ebx
520 serge 1497
.fail:
1599 art_zh 1498
	   ret
520 serge 1499
endp