Subversion Repositories Kolibri OS

Rev

Rev 2467 | Rev 3232 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

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