Subversion Repositories Kolibri OS

Rev

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