Subversion Repositories Kolibri OS

Rev

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