Subversion Repositories Kolibri OS

Rev

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