Subversion Repositories Kolibri OS

Rev

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