Subversion Repositories Kolibri OS

Rev

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