Subversion Repositories Kolibri OS

Rev

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