Subversion Repositories Kolibri OS

Rev

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