Subversion Repositories Kolibri OS

Rev

Rev 1629 | Rev 2129 | 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: 1739 $
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:
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:
1496 Lrz 952
;  ebx=1 - set ipc buffer area
953
;    ecx=address of buffer
954
;    edx=size of buffer
164 serge 955
;  eax=2 - send message
956
;    ebx=PID
957
;    ecx=address of message
958
;    edx=size of message
959
 
1496 Lrz 960
	dec	ebx
961
	jnz	@f
164 serge 962
 
1496 Lrz 963
	mov  	eax,[current_slot]
964
        pushf
965
        cli
966
        mov  	[eax+APPDATA.ipc_start],ecx     ;set fields in extended information area
967
        mov  	[eax+APPDATA.ipc_size],edx
164 serge 968
 
1496 Lrz 969
        add edx, ecx
970
        add edx, 4095
971
        and edx, not 4095
164 serge 972
 
1496 Lrz 973
.touch: mov eax, [ecx]
974
        add ecx, 0x1000
975
        cmp ecx, edx
976
        jb  .touch
164 serge 977
 
1496 Lrz 978
        popf
979
        mov [esp+32], ebx	;ebx=0
980
        ret
164 serge 981
 
1496 Lrz 982
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
983
;2
984
@@:
985
	dec	ebx
986
	jnz	@f
164 serge 987
 
1496 Lrz 988
        stdcall sys_ipc_send, ecx, edx, esi
989
        mov 	[esp+32], eax
990
        ret
991
@@:
992
	or	eax,-1
993
        mov 	[esp+32], eax
994
        ret
995
 
996
;align 4
997
;proc set_ipc_buff
998
 
999
;           mov  eax,[current_slot]
1000
;           pushf
1001
;           cli
1002
;           mov  [eax+APPDATA.ipc_start],ebx     ;set fields in extended information area
1003
;           mov  [eax+APPDATA.ipc_size],ecx
1004
;
1005
;           add ecx, ebx
1006
;           add ecx, 4095
1007
;           and ecx, not 4095
1008
;
1009
;.touch:    mov eax, [ebx]
1010
;           add ebx, 0x1000
1011
;           cmp ebx, ecx
1012
;           jb  .touch
1013
;
1014
;           popf
1015
;           xor eax, eax
1016
;           ret
1017
;endp
1018
 
164 serge 1019
proc sys_ipc_send stdcall, PID:dword, msg_addr:dword, msg_size:dword
1020
           locals
1021
             dst_slot   dd ?
1022
             dst_offset dd ?
1023
             buf_size   dd ?
536 diamond 1024
             used_buf   dd ?
164 serge 1025
           endl
1026
 
1027
           pushf
1028
           cli
1029
 
1030
           mov  eax, [PID]
1031
           call pid_to_slot
1032
           test eax,eax
1033
           jz   .no_pid
1034
 
1035
           mov [dst_slot], eax
1036
           shl  eax,8
380 serge 1037
           mov  edi,[eax+SLOT_BASE+0xa0]  ;is ipc area defined?
164 serge 1038
           test edi,edi
1039
           jz   .no_ipc_area
1040
 
1041
           mov ebx, edi
1042
           and ebx, 0xFFF
1043
           mov [dst_offset], ebx
1044
 
380 serge 1045
           mov esi, [eax+SLOT_BASE+0xa4]
164 serge 1046
           mov [buf_size], esi
1047
 
536 diamond 1048
           mov ecx, [ipc_tmp]
1049
           cmp esi, 0x40000-0x1000 ; size of [ipc_tmp] minus one page
1050
           jbe @f
1314 diamond 1051
           push esi edi
536 diamond 1052
           add esi,0x1000
1053
           stdcall alloc_kernel_space,esi
1054
           mov ecx, eax
1314 diamond 1055
           pop edi esi
536 diamond 1056
@@:
1057
           mov [used_buf], ecx
1314 diamond 1058
           stdcall map_mem, ecx, [dst_slot],\
1059
                             edi, esi, PG_SW
164 serge 1060
 
1061
           mov edi, [dst_offset]
536 diamond 1062
           add edi, [used_buf]
164 serge 1063
           cmp dword [edi], 0
1064
           jnz  .ipc_blocked          ;if dword [buffer]<>0 - ipc blocked now
227 serge 1065
 
566 serge 1066
           mov edx, dword [edi+4]
1067
           lea ebx, [edx+8]
164 serge 1068
           add ebx, [msg_size]
1069
           cmp ebx, [buf_size]
1070
           ja .buffer_overflow         ;esi<0 - not enough memory in buffer
227 serge 1071
 
164 serge 1072
           mov dword [edi+4], ebx
1073
           mov eax,[TASK_BASE]
1074
           mov eax, [eax+0x04]         ;eax - our PID
1075
           add edi, edx
1076
           mov [edi], eax
1077
           mov ecx, [msg_size]
1078
 
1079
           mov [edi+4], ecx
1080
           add edi, 8
1081
           mov esi, [msg_addr]
465 serge 1082
       ;    add esi, new_app_base
164 serge 1083
           cld
1084
           rep movsb
1085
 
1086
           mov ebx, [ipc_tmp]
1087
           mov edx, ebx
1088
           shr ebx, 12
1089
           xor eax, eax
365 serge 1090
           mov [page_tabs+ebx*4], eax
164 serge 1091
           invlpg [edx]
1092
 
1093
           mov ebx, [ipc_pdir]
1094
           mov edx, ebx
1095
           shr ebx, 12
1096
           xor eax, eax
365 serge 1097
           mov [page_tabs+ebx*4], eax
164 serge 1098
           invlpg [edx]
1099
 
1100
           mov ebx, [ipc_ptab]
1101
           mov edx, ebx
1102
           shr ebx, 12
1103
           xor eax, eax
365 serge 1104
           mov [page_tabs+ebx*4], eax
164 serge 1105
           invlpg [edx]
1106
 
1107
           mov  eax, [dst_slot]
1108
           shl eax, 8
380 serge 1109
           or   [eax+SLOT_BASE+0xA8],dword 0x40
164 serge 1110
           cmp  dword [check_idle_semaphore],20
1111
           jge  .ipc_no_cis
1112
 
1113
           mov  dword [check_idle_semaphore],5
1114
.ipc_no_cis:
536 diamond 1115
           push 0
1116
           jmp .ret
164 serge 1117
.no_pid:
1118
           popf
536 diamond 1119
           mov eax, 4
164 serge 1120
           ret
1121
.no_ipc_area:
1122
           popf
1123
           xor eax, eax
1124
           inc eax
1125
           ret
1126
.ipc_blocked:
536 diamond 1127
           push 2
1128
           jmp .ret
164 serge 1129
.buffer_overflow:
536 diamond 1130
           push 3
1131
.ret:
1132
           mov eax, [used_buf]
1133
           cmp eax, [ipc_tmp]
1134
           jz @f
1135
           stdcall free_kernel_space,eax
1136
@@:
1137
           pop eax
164 serge 1138
           popf
1139
           ret
1140
endp
1141
 
1142
align 4
170 serge 1143
sysfn_meminfo:
164 serge 1144
 
1072 diamond 1145
        ;   add ecx, new_app_base
1146
           cmp ecx, OS_BASE
465 serge 1147
           jae .fail
172 serge 1148
 
164 serge 1149
           mov eax, [pg_data.pages_count]
1072 diamond 1150
           mov [ecx], eax
172 serge 1151
           shl eax, 12
1072 diamond 1152
           mov [esp+32], eax
1153
           mov eax, [pg_data.pages_free]
1154
           mov [ecx+4], eax
1155
           mov eax, [pg_data.pages_faults]
1156
           mov [ecx+8], eax
1157
           mov eax, [heap_size]
1158
           mov [ecx+12], eax
1159
           mov eax, [heap_free]
1160
           mov [ecx+16], eax
170 serge 1161
           mov eax, [heap_blocks]
1072 diamond 1162
           mov [ecx+20], eax
1163
           mov eax, [free_blocks]
1164
           mov [ecx+24], eax
164 serge 1165
           ret
172 serge 1166
.fail:
1276 Lrz 1167
           or dword [esp+32], -1
172 serge 1168
           ret
1629 serge 1169
 
164 serge 1170
align 4
940 serge 1171
f68:
1345 Lrz 1172
           cmp  ebx,4
1366 Lrz 1173
           jbe  sys_sheduler
164 serge 1174
 
1345 Lrz 1175
           cmp ebx, 11
164 serge 1176
           jb .fail
1177
 
1345 Lrz 1178
           cmp ebx, 25
940 serge 1179
           ja .fail
1180
 
1345 Lrz 1181
           jmp dword [f68call+ebx*4-11*4]
940 serge 1182
.11:
188 serge 1183
           call init_heap
1345 Lrz 1184
           mov [esp+32], eax
164 serge 1185
           ret
940 serge 1186
.12:
1345 Lrz 1187
           stdcall user_alloc, ecx
1188
           mov [esp+32], eax
164 serge 1189
           ret
940 serge 1190
.13:
1345 Lrz 1191
           stdcall user_free, ecx
1192
           mov [esp+32], eax
164 serge 1193
           ret
940 serge 1194
.14:
1345 Lrz 1195
           cmp ecx, OS_BASE
465 serge 1196
           jae .fail
1345 Lrz 1197
           mov edi,ecx
1055 Galkov 1198
           call get_event_ex
1345 Lrz 1199
           mov [esp+32], eax
164 serge 1200
           ret
940 serge 1201
.16:
1345 Lrz 1202
           test ecx, ecx
188 serge 1203
           jz .fail
1345 Lrz 1204
           cmp ecx, OS_BASE
465 serge 1205
           jae .fail
1345 Lrz 1206
           stdcall get_service, ecx
1207
           mov [esp+32], eax
164 serge 1208
           ret
940 serge 1209
.17:
1345 Lrz 1210
           call srv_handlerEx   ;ecx
1211
           mov [esp+32], eax
164 serge 1212
           ret
940 serge 1213
.19:
1345 Lrz 1214
           cmp ecx, OS_BASE
465 serge 1215
           jae .fail
1345 Lrz 1216
           stdcall load_library, ecx
1217
           mov [esp+32], eax
198 serge 1218
           ret
940 serge 1219
.20:
1345 Lrz 1220
           mov     eax, edx
1629 serge 1221
           mov     ebx, ecx
1345 Lrz 1222
           call    user_realloc		;in: eax = pointer, ebx = new size
1223
           mov     [esp+32], eax
490 serge 1224
           ret
940 serge 1225
.21:
1345 Lrz 1226
           cmp ecx, OS_BASE
740 serge 1227
           jae .fail
1228
 
1345 Lrz 1229
           cmp ebx, OS_BASE
1316 serge 1230
           jae .fail
1231
 
1345 Lrz 1232
           mov edi, edx
1233
           stdcall load_PE, ecx
1316 serge 1234
           mov esi, eax
740 serge 1235
           test eax, eax
1236
           jz @F
1237
 
1316 serge 1238
           push edi
1239
           push DRV_ENTRY
1240
           call eax
1241
           add esp, 8
740 serge 1242
           test eax, eax
1243
           jz @F
1244
 
1245
           mov [eax+SRV.entry], esi
1246
 
1247
@@:
1345 Lrz 1248
           mov [esp+32], eax
740 serge 1249
           ret
940 serge 1250
.22:
1345 Lrz 1251
           cmp ecx, OS_BASE
940 serge 1252
           jae .fail
740 serge 1253
 
1345 Lrz 1254
           stdcall shmem_open, ecx, edx, esi
1255
           mov [esp+24], edx
1256
           mov [esp+32], eax
940 serge 1257
           ret
740 serge 1258
 
943 serge 1259
.23:
1345 Lrz 1260
           cmp ecx, OS_BASE
943 serge 1261
           jae .fail
1262
 
1345 Lrz 1263
           stdcall shmem_close, ecx
1264
           mov [esp+32], eax
943 serge 1265
           ret
1275 serge 1266
.24:
1267
           mov  eax, [current_slot]
1345 Lrz 1268
           xchg ecx, [eax+APPDATA.exc_handler]
1269
           xchg edx, [eax+APPDATA.except_mask]
1270
           mov  [esp+32], ecx ; reg_eax+8
1271
           mov  [esp+20], edx ; reg_ebx+8
1275 serge 1272
           ret
1273
.25:
1345 Lrz 1274
           cmp ecx,32
1275 serge 1275
           jae .fail
1276
           mov  eax, [current_slot]
1345 Lrz 1277
           btr  [eax+APPDATA.except_mask],ecx
1278
           setc byte[esp+32]
1275 serge 1279
           jecxz @f
1345 Lrz 1280
           bts  [eax+APPDATA.except_mask],ecx
1275 serge 1281
@@:
1282
           ret
943 serge 1283
 
164 serge 1284
.fail:
1285
           xor eax, eax
1345 Lrz 1286
           mov [esp+32], eax
164 serge 1287
           ret
1288
 
1629 serge 1289
 
164 serge 1290
align 4
1629 serge 1291
f68call:   ; keep this table closer to main code
1292
 
1293
           dd f68.11   ; init_heap
1294
           dd f68.12   ; user_alloc
1295
           dd f68.13   ; user_free
1296
           dd f68.14   ; get_event_ex
1297
           dd f68.fail ; moved to f68.24
1298
           dd f68.16   ; get_service
1299
           dd f68.17   ; call_service
1300
           dd f68.fail ; moved to f68.25
1301
           dd f68.19   ; load_dll
1302
           dd f68.20   ; user_realloc
1303
           dd f68.21   ; load_driver
1304
           dd f68.22   ; shmem_open
1305
           dd f68.23   ; shmem_close
1306
           dd f68.24
1307
           dd f68.25
1308
 
1309
 
1310
align 4
819 serge 1311
proc load_pe_driver stdcall, file:dword
1312
 
1313
           stdcall load_PE, [file]
1314
           test eax, eax
1315
           jz .fail
1316
 
1317
           mov esi, eax
1318
           stdcall eax, DRV_ENTRY
1319
           test eax, eax
1320
           jz .fail
1321
 
1322
           mov [eax+SRV.entry], esi
1323
           ret
1324
 
1325
.fail:
1326
           xor eax, eax
1327
           ret
1328
endp
1329
 
1330
 
1331
align 4
164 serge 1332
proc init_mtrr
1333
 
412 serge 1334
           cmp [BOOT_VAR+0x901c],byte 2
164 serge 1335
           je  .exit
1336
 
211 serge 1337
           bt [cpu_caps], CAPS_MTRR
1338
           jnc .exit
1339
 
164 serge 1340
           mov eax, cr0
1341
           or eax, 0x60000000   ;disable caching
1342
           mov cr0, eax
1343
           wbinvd               ;invalidate cache
1344
 
1345
           mov ecx, 0x2FF
1346
           rdmsr                ;
1030 diamond 1347
; has BIOS already initialized MTRRs?
1348
           test ah, 8
1349
           jnz .skip_init
1350
; rarely needed, so mainly placeholder
1351
; main memory - cached
164 serge 1352
           push eax
1353
 
821 diamond 1354
           mov eax, [MEM_AMOUNT]
1355
; round eax up to next power of 2
1356
           dec eax
1357
           bsr ecx, eax
1030 diamond 1358
           mov ebx, 2
1359
           shl ebx, cl
1360
           dec ebx
1361
; base of memory range = 0, type of memory range = MEM_WB
164 serge 1362
           xor edx, edx
1030 diamond 1363
           mov eax, MEM_WB
1364
           mov ecx, 0x200
1365
           wrmsr
1366
; mask of memory range = 0xFFFFFFFFF - (size - 1), ebx = size - 1
1367
           mov eax, 0xFFFFFFFF
1368
           mov edx, 0x0000000F
1369
           sub eax, ebx
1370
           sbb edx, 0
1371
           or eax, 0x800
1372
           inc ecx
1373
           wrmsr
1374
; clear unused MTRRs
164 serge 1375
           xor eax, eax
1030 diamond 1376
           xor edx, edx
164 serge 1377
@@:
1030 diamond 1378
           wrmsr
164 serge 1379
           inc ecx
1030 diamond 1380
           cmp ecx, 0x210
1381
           jb @b
1382
; enable MTRRs
1383
           pop eax
1384
           or ah, 8
1385
           and al, 0xF0 ; default memtype = UC
1386
           mov ecx, 0x2FF
164 serge 1387
           wrmsr
1030 diamond 1388
.skip_init:
1389
           stdcall set_mtrr, [LFBAddress],[LFBSize],MEM_WC
164 serge 1390
 
1391
           wbinvd               ;again invalidate
1392
 
1393
           mov eax, cr0
1394
           and eax, not 0x60000000
1395
           mov cr0, eax         ; enable caching
1396
.exit:
1397
           ret
1398
endp
1399
 
1400
align 4
1030 diamond 1401
proc set_mtrr stdcall, base:dword,size:dword,mem_type:dword
1402
; find unused register
1403
           mov ecx, 0x201
1404
@@:
1405
           rdmsr
1406
           dec ecx
1407
           test ah, 8
1408
           jz .found
1409
           rdmsr
1410
           mov al, 0 ; clear memory type field
1411
           cmp eax, [base]
1412
           jz .ret
1413
           add ecx, 3
1414
           cmp ecx, 0x210
1415
           jb @b
1416
; no free registers, ignore the call
1417
.ret:
1418
           ret
1419
.found:
1420
; found, write values
164 serge 1421
           xor edx, edx
1422
           mov eax, [base]
1423
           or eax, [mem_type]
1424
           wrmsr
1425
 
1426
           mov ebx, [size]
1427
           dec ebx
1428
           mov eax, 0xFFFFFFFF
1739 clevermous 1429
           mov edx, 0x00000000
164 serge 1430
           sub eax, ebx
1431
           sbb edx, 0
1432
           or eax, 0x800
1433
           inc ecx
1434
           wrmsr
1435
           ret
1436
endp
1437
 
465 serge 1438
align 4
172 serge 1439
proc stall stdcall, delay:dword
1440
           push ecx
1441
           push edx
1442
           push ebx
1443
           push eax
1444
 
1445
           mov eax, [delay]
1446
           mul [stall_mcs]
1447
           mov ebx, eax       ;low
1448
           mov ecx, edx       ;high
1449
           rdtsc
1450
           add ebx, eax
1451
           adc ecx,edx
1452
@@:
1453
           rdtsc
1454
           sub eax, ebx
1455
           sbb edx, ecx
1456
           jb @B
1457
 
1458
           pop eax
1459
           pop ebx
1460
           pop edx
1461
           pop ecx
1462
           ret
1463
endp
1464
 
520 serge 1465
align 4
1466
proc create_ring_buffer stdcall, size:dword, flags:dword
1467
           locals
1468
             buf_ptr  dd ?
1469
           endl
237 serge 1470
 
520 serge 1471
           mov eax, [size]
1472
           test eax, eax
1473
           jz .fail
1474
 
1475
           add eax, eax
1476
           stdcall alloc_kernel_space, eax
1477
           test eax, eax
1478
           jz .fail
1479
 
662 serge 1480
           push ebx
1481
 
520 serge 1482
           mov [buf_ptr], eax
1483
 
1484
           mov ebx, [size]
1485
           shr ebx, 12
1486
           push ebx
1487
 
1488
           stdcall alloc_pages, ebx
1489
           pop ecx
1490
 
1491
           test eax, eax
1492
           jz .mm_fail
1493
 
662 serge 1494
           push edi
1495
 
520 serge 1496
           or eax, [flags]
1497
           mov edi, [buf_ptr]
1498
           mov ebx, [buf_ptr]
1499
           mov edx, ecx
566 serge 1500
           shl edx, 2
520 serge 1501
           shr edi, 10
1502
@@:
1503
           mov [page_tabs+edi], eax
1504
           mov [page_tabs+edi+edx], eax
924 serge 1505
           invlpg [ebx]
1506
           invlpg [ebx+0x10000]
520 serge 1507
           add eax, 0x1000
1508
           add ebx, 0x1000
566 serge 1509
           add edi, 4
520 serge 1510
           dec ecx
1511
           jnz @B
1512
 
1513
           mov eax, [buf_ptr]
662 serge 1514
           pop edi
1515
           pop ebx
520 serge 1516
           ret
1517
.mm_fail:
1518
           stdcall free_kernel_space, [buf_ptr]
1519
           xor eax, eax
662 serge 1520
           pop ebx
520 serge 1521
.fail:
1522
           ret
1523
endp