Subversion Repositories Kolibri OS

Rev

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