Subversion Repositories Kolibri OS

Rev

Rev 4423 | Rev 5565 | 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: 5201 $
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
5201 serge 126
;proc map_page stdcall,lin_addr:dword,phis_addr:dword,flags:dword
127
map_page:
2434 Serge 128
        push    ebx
5201 serge 129
        mov     eax, [esp+12]               ; phis_addr
2434 Serge 130
        and     eax, not 0xFFF
5201 serge 131
        or      eax, [esp+16]              ; flags
132
        mov     ebx, [esp+8]               ; lin_addr
2434 Serge 133
        shr     ebx, 12
134
        mov     [page_tabs+ebx*4], eax
5201 serge 135
        mov     eax, [esp+8]               ; lin_addr
136
        pop     ebx
2434 Serge 137
        invlpg  [eax]
5201 serge 138
        ret     12
164 serge 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
 
5201 serge 353
uglobal
354
sb16_buffer_allocated db 0
355
endg
356
 
357
; Allocates [.size] bytes so that the target memory block
358
; is inside one 64K page for 24-bit DMA controller,
359
; that is, somewhere between 00xx0000h and 00xxFFFFh.
360
proc alloc_dma24
361
; Implementation note.
362
; The only user of that function is SB16 driver,
363
; so just return a statically allocated buffer.
364
virtual at esp
365
                dd      ? ; return address
366
.size           dd      ?
367
end virtual
368
        cmp     [sb16_buffer_allocated], 0
369
        jnz     .fail
370
        inc     [sb16_buffer_allocated]
371
        mov     eax, SB16Buffer
372
        ret     4
373
.fail:
374
        xor     eax, eax
375
        ret     4
376
endp
377
 
378
; Allocates a physical page for master page table
379
; that duplicates first Mb of OS_BASE at address 0;
380
; used for starting APs and for shutting down,
381
; where it is important to execute code in trivial-mapped pages.
382
; Returns eax = allocated physical page.
383
proc create_trampoline_pgmap
384
; The only non-trivial moment:
385
; we need a linear address to fill information,
386
; but we don't need it outside of this function,
387
; so we're returning physical address.
388
; Therefore, allocate memory with kernel_alloc,
389
; this will allocate physical page and a linear address somewhere,
390
; and deallocate only linear address with free_kernel_space.
391
        stdcall kernel_alloc, 0x1000
392
        mov     edi, eax
393
        mov     esi, master_tab
394
        mov     ecx, 1024
395
        rep movsd
396
        mov     ecx, [master_tab+(OS_BASE shr 20)]
397
        mov     [eax], ecx
398
        mov     edi, eax
399
        call    get_pg_addr
400
        push    eax
401
        stdcall free_kernel_space, edi
402
        pop     eax
403
        ret
404
endp
405
 
164 serge 406
align 4
5201 serge 407
proc init_LFB
408
           locals
409
             pg_count dd ?
410
           endl
378 serge 411
 
2434 Serge 412
        cmp     dword [LFBAddress], -1
413
        jne     @f
3908 Serge 414
        mov     [BOOT_VARS+BOOT_MTRR], byte 2
2434 Serge 415
; max VGA=640*480*4=1228800 bytes
416
; + 32*640*4=81920 bytes for mouse pointer
417
        stdcall alloc_pages, ((1228800+81920)/4096)
1300 serge 418
 
2434 Serge 419
        push    eax
420
        call    alloc_page
421
        stdcall map_page_table, LFB_BASE, eax
422
        pop     eax
423
        or      eax, PG_UW
424
        mov     ebx, LFB_BASE
425
; max VGA=640*480*4=1228800 bytes
426
; + 32*640*4=81920 bytes for mouse pointer
427
        mov     ecx, (1228800+81920)/4096
428
        call    commit_pages
429
        mov     [LFBAddress], dword LFB_BASE
430
        ret
164 serge 431
@@:
2434 Serge 432
        test    [SCR_MODE], word 0100000000000000b
433
        jnz     @f
3908 Serge 434
        mov     [BOOT_VARS+BOOT_MTRR], byte 2
2434 Serge 435
        ret
211 serge 436
@@:
2434 Serge 437
        call    init_mtrr
490 serge 438
 
5201 serge 439
        mov     edx, LFB_BASE
440
        mov     esi, [LFBAddress]
441
        mov     edi, 0x00C00000
442
        mov     dword [exp_lfb+4], edx
443
 
444
        shr     edi, 12
445
        mov     [pg_count], edi
446
        shr     edi, 10
447
 
448
        bt      [cpu_caps], CAPS_PSE
449
        jnc     .map_page_tables
450
        or      esi, PG_LARGE+PG_UW
451
        mov     edx, sys_proc+PROC.pdt_0+(LFB_BASE shr 20)
452
@@:
453
        mov     [edx], esi
454
        add     edx, 4
455
        add     esi, 0x00400000
456
        dec     edi
457
        jnz     @B
458
 
2434 Serge 459
        bt      [cpu_caps], CAPS_PGE
5201 serge 460
        jnc     @F
461
        or      dword [sys_proc+PROC.pdt_0+(LFB_BASE shr 20)], PG_GLOBAL
462
@@:
463
        mov     dword [LFBAddress], LFB_BASE
464
        mov     eax, cr3      ;flush TLB
465
        mov     cr3, eax
466
        ret
164 serge 467
 
5201 serge 468
.map_page_tables:
164 serge 469
 
5201 serge 470
@@:
471
        call    alloc_page
472
        stdcall map_page_table, edx, eax
473
        add     edx, 0x00400000
474
        dec     edi
475
        jnz     @B
164 serge 476
 
5201 serge 477
        mov     eax, [LFBAddress]
478
        mov     edi, page_tabs + (LFB_BASE shr 10)
479
        or      eax, PG_UW
480
        mov     ecx, [pg_count]
481
        cld
482
@@:
2434 Serge 483
        stosd
484
        add     eax, 0x1000
5201 serge 485
        dec     ecx
486
        jnz     @B
164 serge 487
 
2434 Serge 488
        mov     dword [LFBAddress], LFB_BASE
4269 Serge 489
        mov     eax, cr3                      ;flush TLB
2434 Serge 490
        mov     cr3, eax
5201 serge 491
 
2434 Serge 492
        ret
5201 serge 493
endp
164 serge 494
 
495
align 4
496
proc new_mem_resize stdcall, new_size:dword
497
 
2987 Serge 498
        push    ebx
499
        push    esi
500
        push    edi
164 serge 501
 
2987 Serge 502
        mov     edx, [current_slot]
5201 serge 503
        mov     ebx, [edx+APPDATA.process]
504
 
505
        cmp     [ebx+PROC.heap_base], 0
2987 Serge 506
        jne     .exit
507
 
2434 Serge 508
        mov     edi, [new_size]
509
        add     edi, 4095
510
        and     edi, not 4095
511
        mov     [new_size], edi
164 serge 512
 
5201 serge 513
        mov     esi, [ebx+PROC.mem_used]
2434 Serge 514
        add     esi, 4095
515
        and     esi, not 4095
164 serge 516
 
2434 Serge 517
        cmp     edi, esi
2987 Serge 518
        ja      .expand
519
        je      .exit
164 serge 520
 
2987 Serge 521
        mov     ebx, edi
2434 Serge 522
        shr     edi, 12
523
        shr     esi, 12
2987 Serge 524
 
525
        mov     ecx, pg_data.mutex
526
        call    mutex_lock
164 serge 527
@@:
2434 Serge 528
        mov     eax, [app_page_tabs+edi*4]
529
        test    eax, 1
530
        jz      .next
2987 Serge 531
 
532
        mov     dword [app_page_tabs+edi*4], 0
2434 Serge 533
        invlpg  [ebx]
534
        call    free_page
164 serge 535
 
2434 Serge 536
.next:
2987 Serge 537
        inc     edi
538
        add     ebx, 0x1000
2434 Serge 539
        cmp     edi, esi
540
        jb      @B
164 serge 541
 
2987 Serge 542
        mov     ecx, pg_data.mutex
543
        call    mutex_unlock
544
 
164 serge 545
.update_size:
2987 Serge 546
        mov     edx, [current_slot]
2434 Serge 547
        mov     ebx, [new_size]
5201 serge 548
        mov     edx, [edx+APPDATA.process]
549
        mov     [edx+PROC.mem_used], ebx
2987 Serge 550
.exit:
551
        pop     edi
552
        pop     esi
553
        pop     ebx
2434 Serge 554
        xor     eax, eax
555
        ret
2987 Serge 556
 
164 serge 557
.expand:
558
 
2987 Serge 559
        mov     ecx, pg_data.mutex
560
        call    mutex_lock
164 serge 561
 
2987 Serge 562
        xchg    esi, edi
563
 
564
        push    esi                   ;new size
565
        push    edi                   ;old size
566
 
2434 Serge 567
        add     edi, 0x3FFFFF
568
        and     edi, not(0x3FFFFF)
569
        add     esi, 0x3FFFFF
570
        and     esi, not(0x3FFFFF)
164 serge 571
 
2987 Serge 572
        cmp     edi, esi
2434 Serge 573
        jae     .grow
2987 Serge 574
 @@:
2434 Serge 575
        call    alloc_page
576
        test    eax, eax
2987 Serge 577
        jz      .exit_fail
164 serge 578
 
2434 Serge 579
        stdcall map_page_table, edi, eax
164 serge 580
 
2434 Serge 581
        push    edi
582
        shr     edi, 10
583
        add     edi, page_tabs
584
        mov     ecx, 1024
585
        xor     eax, eax
586
        cld
587
        rep stosd
588
        pop     edi
164 serge 589
 
2434 Serge 590
        add     edi, 0x00400000
591
        cmp     edi, esi
592
        jb      @B
164 serge 593
.grow:
2987 Serge 594
        pop     edi                   ;old size
595
        pop     ecx                   ;new size
164 serge 596
 
2987 Serge 597
        shr     edi, 10
598
        shr     ecx, 10
599
        sub     ecx, edi
600
        shr     ecx, 2                ;pages count
601
        mov     eax, 2
602
 
603
        add     edi, app_page_tabs
2434 Serge 604
        rep stosd
164 serge 605
 
2987 Serge 606
        mov     ecx, pg_data.mutex
607
        call    mutex_unlock
164 serge 608
 
2434 Serge 609
        jmp     .update_size
2987 Serge 610
 
611
.exit_fail:
2434 Serge 612
        mov     ecx, pg_data.mutex
613
        call    mutex_unlock
2130 serge 614
 
2987 Serge 615
        add     esp, 8
616
        pop     edi
617
        pop     esi
618
        pop     ebx
2434 Serge 619
        xor     eax, eax
620
        inc     eax
621
        ret
164 serge 622
endp
623
 
2987 Serge 624
 
285 serge 625
; param
626
;  eax= linear address
627
;
628
; retval
629
;  eax= phisical page address
630
 
164 serge 631
align 4
285 serge 632
get_pg_addr:
3232 Serge 633
        sub     eax, OS_BASE
634
        cmp     eax, 0x400000
635
        jb      @f
2434 Serge 636
        shr     eax, 12
3232 Serge 637
        mov     eax, [page_tabs+(eax+(OS_BASE shr 12))*4]
638
@@:
2434 Serge 639
        and     eax, 0xFFFFF000
640
        ret
164 serge 641
 
465 serge 642
 
188 serge 643
align 4
1105 Galkov 644
; Now it is called from core/sys32::exc_c (see stack frame there)
164 serge 645
proc page_fault_handler
465 serge 646
 
1056 Galkov 647
    .err_addr   equ ebp-4
709 diamond 648
 
1105 Galkov 649
        push    ebx               ;save exception number (#PF)
1056 Galkov 650
        mov     ebp, esp
651
        mov     ebx, cr2
1105 Galkov 652
        push    ebx               ;that is locals: .err_addr = cr2
1056 Galkov 653
        inc     [pg_data.pages_faults]
465 serge 654
 
1056 Galkov 655
        mov     eax, [pf_err_code]
164 serge 656
 
1056 Galkov 657
        cmp     ebx, OS_BASE      ;ebx == .err_addr
3555 Serge 658
        jb      .user_space       ;страница в памяти приложения ;
188 serge 659
 
1056 Galkov 660
        cmp     ebx, page_tabs
3555 Serge 661
        jb      .kernel_space     ;страница в памяти ядра
164 serge 662
 
1056 Galkov 663
        cmp     ebx, kernel_tabs
3555 Serge 664
        jb      .alloc;.app_tabs  ;таблицы страниц приложения ;
665
                                  ;просто создадим одну
666
if 0 ;пока это просто лишнее
1056 Galkov 667
        cmp     ebx, LFB_BASE
3555 Serge 668
        jb      .core_tabs        ;таблицы страниц ядра
669
                                  ;Ошибка
1056 Galkov 670
  .lfb:
3555 Serge 671
                                  ;область LFB
672
                                  ;Ошибка
1056 Galkov 673
        jmp     .fail
674
end if
675
.core_tabs:
676
.fail:  ;simply return to caller
677
        mov     esp, ebp
1105 Galkov 678
        pop     ebx               ;restore exception number (#PF)
1056 Galkov 679
        ret
378 serge 680
 
164 serge 681
.user_space:
1056 Galkov 682
        test    eax, PG_MAP
3555 Serge 683
        jnz     .err_access       ;Страница присутствует
684
                                  ;Ошибка доступа ?
465 serge 685
 
1056 Galkov 686
        shr     ebx, 12
687
        mov     ecx, ebx
688
        shr     ecx, 10
689
        mov     edx, [master_tab+ecx*4]
690
        test    edx, PG_MAP
3555 Serge 691
        jz      .fail             ;таблица страниц не создана
692
                                  ;неверный адрес в программе
172 serge 693
 
1056 Galkov 694
        mov     eax, [page_tabs+ebx*4]
695
        test    eax, 2
3555 Serge 696
        jz      .fail             ;адрес не зарезервирован для ;
697
                                  ;использования. Ошибка
188 serge 698
.alloc:
1056 Galkov 699
        call    alloc_page
700
        test    eax, eax
701
        jz      .fail
164 serge 702
 
2434 Serge 703
        stdcall map_page, [.err_addr], eax, PG_UW
164 serge 704
 
1056 Galkov 705
        mov     edi, [.err_addr]
706
        and     edi, 0xFFFFF000
707
        mov     ecx, 1024
708
        xor     eax, eax
709
       ;cld     ;caller is duty for this
2434 Serge 710
        rep stosd
1056 Galkov 711
.exit:  ;iret with repeat fault instruction
2434 Serge 712
        add     esp, 12;clear in stack: locals(.err_addr) + #PF + ret_to_caller
1056 Galkov 713
        restore_ring3_context
714
        iretd
465 serge 715
 
1289 diamond 716
.err_access:
717
; access denied? this may be a result of copy-on-write protection for DLL
718
; check list of HDLLs
719
        and     ebx, not 0xFFF
5201 serge 720
        mov     eax, [current_process]
721
        mov     eax, [eax+PROC.dlls_list_ptr]
1311 diamond 722
        test    eax, eax
723
        jz      .fail
724
        mov     esi, [eax+HDLL.fd]
1289 diamond 725
.scan_hdll:
726
        cmp     esi, eax
727
        jz      .fail
728
        mov     edx, ebx
729
        sub     edx, [esi+HDLL.base]
730
        cmp     edx, [esi+HDLL.size]
731
        jb      .fault_in_hdll
732
.scan_hdll.next:
1311 diamond 733
        mov     esi, [esi+HDLL.fd]
1289 diamond 734
        jmp     .scan_hdll
735
.fault_in_hdll:
736
; allocate new page, map it as rw and copy data
737
        call    alloc_page
738
        test    eax, eax
739
        jz      .fail
2434 Serge 740
        stdcall map_page, ebx, eax, PG_UW
1289 diamond 741
        mov     edi, ebx
742
        mov     ecx, 1024
743
        sub     ebx, [esi+HDLL.base]
744
        mov     esi, [esi+HDLL.parent]
745
        mov     esi, [esi+DLLDESCR.data]
746
        add     esi, ebx
2434 Serge 747
        rep movsd
1289 diamond 748
        jmp     .exit
465 serge 749
 
750
.kernel_space:
1056 Galkov 751
        test    eax, PG_MAP
3555 Serge 752
        jz      .fail   ;страница не присутствует
465 serge 753
 
2434 Serge 754
        test    eax, 12 ;U/S (+below)
3555 Serge 755
        jnz     .fail   ;приложение обратилось к памяти
756
                        ;ядра
1056 Galkov 757
       ;test    eax, 8
3555 Serge 758
       ;jnz     .fail   ;установлен зарезервированный бит
759
                        ;в таблицах страниц. добавлено в P4/Xeon
465 serge 760
 
3555 Serge 761
;попытка записи в защищённую страницу ядра
465 serge 762
 
1056 Galkov 763
        cmp     ebx, tss._io_map_0
764
        jb      .fail
465 serge 765
 
1056 Galkov 766
        cmp     ebx, tss._io_map_0+8192
767
        jae     .fail
465 serge 768
 
769
; io permission map
770
; copy-on-write protection
771
 
1056 Galkov 772
        call    alloc_page
773
        test    eax, eax
774
        jz      .fail
465 serge 775
 
1056 Galkov 776
        push    eax
2434 Serge 777
        stdcall map_page, [.err_addr], eax, dword PG_SW
1056 Galkov 778
        pop     eax
779
        mov     edi, [.err_addr]
780
        and     edi, -4096
781
        lea     esi, [edi+(not tss._io_map_0)+1]; -tss._io_map_0
465 serge 782
 
1056 Galkov 783
        mov     ebx, esi
784
        shr     ebx, 12
785
        mov     edx, [current_slot]
786
        or      eax, PG_SW
787
        mov     [edx+APPDATA.io_map+ebx*4], eax
465 serge 788
 
1056 Galkov 789
        add     esi, [default_io_map]
790
        mov     ecx, 4096/4
791
       ;cld     ;caller is duty for this
2434 Serge 792
        rep movsd
1056 Galkov 793
        jmp     .exit
164 serge 794
endp
795
 
1314 diamond 796
; returns number of mapped bytes
5201 serge 797
proc map_mem_ipc stdcall, lin_addr:dword,slot:dword,\
1314 diamond 798
                      ofs:dword,buf_size:dword,req_access:dword
5201 serge 799
        locals
800
             count   dd ?
801
             process dd ?
802
        endl
1314 diamond 803
 
5201 serge 804
        mov     [count], 0
2434 Serge 805
        cmp     [buf_size], 0
806
        jz      .exit
164 serge 807
 
2434 Serge 808
        mov     eax, [slot]
809
        shl     eax, 8
5201 serge 810
        mov     eax, [SLOT_BASE+eax+APPDATA.process]
811
        test    eax, eax
812
        jz      .exit
164 serge 813
 
5201 serge 814
        mov     [process], eax
2434 Serge 815
        mov     ebx, [ofs]
816
        shr     ebx, 22
5201 serge 817
        mov     eax, [eax+PROC.pdt_0+ebx*4]                 ;get page table
818
        mov     esi, [ipc_ptab]
2434 Serge 819
        and     eax, 0xFFFFF000
820
        jz      .exit
5201 serge 821
        stdcall map_page, esi, eax, PG_SW
2434 Serge 822
@@:
823
        mov     edi, [lin_addr]
824
        and     edi, 0xFFFFF000
825
        mov     ecx, [buf_size]
826
        add     ecx, 4095
827
        shr     ecx, 12
5201 serge 828
        inc     ecx                  ; ???????????
164 serge 829
 
2434 Serge 830
        mov     edx, [ofs]
831
        shr     edx, 12
832
        and     edx, 0x3FF
1314 diamond 833
.map:
2434 Serge 834
        stdcall safe_map_page, [slot], [req_access], [ofs]
835
        jnc     .exit
5201 serge 836
        add     [count], PAGE_SIZE
837
        add     [ofs], PAGE_SIZE
2434 Serge 838
        dec     ecx
839
        jz      .exit
5201 serge 840
 
841
        add     edi, PAGE_SIZE
2434 Serge 842
        inc     edx
5201 serge 843
        cmp     edx, 1024
2434 Serge 844
        jnz     .map
5201 serge 845
 
2434 Serge 846
        inc     ebx
5201 serge 847
        mov     eax, [process]
848
        mov     eax, [eax+PROC.pdt_0+ebx*4]
2434 Serge 849
        and     eax, 0xFFFFF000
850
        jz      .exit
5201 serge 851
 
852
        stdcall map_page, esi, eax, PG_SW
2434 Serge 853
        xor     edx, edx
854
        jmp     .map
164 serge 855
.exit:
5201 serge 856
        mov     eax, [count]
2434 Serge 857
        ret
164 serge 858
endp
859
 
1314 diamond 860
proc map_memEx stdcall, lin_addr:dword,slot:dword,\
861
                        ofs:dword,buf_size:dword,req_access:dword
5201 serge 862
        locals
863
             count   dd ?
864
             process dd ?
865
        endl
1314 diamond 866
 
5201 serge 867
        mov     [count], 0
2434 Serge 868
        cmp     [buf_size], 0
869
        jz      .exit
164 serge 870
 
2434 Serge 871
        mov     eax, [slot]
872
        shl     eax, 8
5201 serge 873
        mov     eax, [SLOT_BASE+eax+APPDATA.process]
874
        test    eax, eax
875
        jz      .exit
164 serge 876
 
5201 serge 877
        mov     [process], eax
2434 Serge 878
        mov     ebx, [ofs]
879
        shr     ebx, 22
5201 serge 880
        mov     eax, [eax+PROC.pdt_0+ebx*4]                 ;get page table
881
        mov     esi, [proc_mem_tab]
2434 Serge 882
        and     eax, 0xFFFFF000
883
        jz      .exit
5201 serge 884
        stdcall map_page, esi, eax, PG_SW
2434 Serge 885
@@:
886
        mov     edi, [lin_addr]
887
        and     edi, 0xFFFFF000
888
        mov     ecx, [buf_size]
889
        add     ecx, 4095
890
        shr     ecx, 12
5201 serge 891
        inc     ecx                  ; ???????????
164 serge 892
 
2434 Serge 893
        mov     edx, [ofs]
894
        shr     edx, 12
895
        and     edx, 0x3FF
1314 diamond 896
.map:
2434 Serge 897
        stdcall safe_map_page, [slot], [req_access], [ofs]
898
        jnc     .exit
5201 serge 899
        add     [count], PAGE_SIZE
900
        add     [ofs], PAGE_SIZE
901
        dec     ecx
902
        jz      .exit
903
 
904
        add     edi, PAGE_SIZE
2434 Serge 905
        inc     edx
5201 serge 906
        cmp     edx, 1024
2434 Serge 907
        jnz     .map
5201 serge 908
 
909
        inc     ebx
910
        mov     eax, [process]
911
        mov     eax, [eax+PROC.pdt_0+ebx*4]
912
        and     eax, 0xFFFFF000
913
        jz      .exit
914
 
915
        stdcall map_page, esi, eax, PG_SW
916
        xor     edx, edx
917
        jmp     .map
164 serge 918
.exit:
5201 serge 919
        mov     eax, [count]
2434 Serge 920
        ret
164 serge 921
endp
922
 
1314 diamond 923
; in: esi+edx*4 = pointer to page table entry
924
; in: [slot], [req_access], [ofs] on the stack
925
; in: edi = linear address to map
926
; out: CF cleared <=> failed
927
; destroys: only eax
928
proc safe_map_page stdcall, slot:dword, req_access:dword, ofs:dword
2434 Serge 929
        mov     eax, [esi+edx*4]
930
        test    al, PG_MAP
931
        jz      .not_present
932
        test    al, PG_WRITE
933
        jz      .resolve_readonly
1314 diamond 934
; normal case: writable page, just map with requested access
935
.map:
2434 Serge 936
        stdcall map_page, edi, eax, [req_access]
937
        stc
1314 diamond 938
.fail:
2434 Serge 939
        ret
1314 diamond 940
.not_present:
941
; check for alloc-on-demand page
2434 Serge 942
        test    al, 2
943
        jz      .fail
1314 diamond 944
; allocate new page, save it to source page table
2434 Serge 945
        push    ecx
946
        call    alloc_page
947
        pop     ecx
948
        test    eax, eax
949
        jz      .fail
950
        or      al, PG_UW
951
        mov     [esi+edx*4], eax
952
        jmp     .map
1314 diamond 953
.resolve_readonly:
954
; readonly page, probably copy-on-write
955
; check: readonly request of readonly page is ok
2434 Serge 956
        test    [req_access], PG_WRITE
957
        jz      .map
1314 diamond 958
; find control structure for this page
2434 Serge 959
        pushf
960
        cli
961
        cld
962
        push    ebx ecx
963
        mov     eax, [slot]
964
        shl     eax, 8
5201 serge 965
        mov     eax, [SLOT_BASE+eax+APPDATA.process]
966
        mov     eax, [eax+PROC.dlls_list_ptr]
2434 Serge 967
        test    eax, eax
968
        jz      .no_hdll
969
        mov     ecx, [eax+HDLL.fd]
1314 diamond 970
.scan_hdll:
2434 Serge 971
        cmp     ecx, eax
972
        jz      .no_hdll
973
        mov     ebx, [ofs]
974
        and     ebx, not 0xFFF
975
        sub     ebx, [ecx+HDLL.base]
976
        cmp     ebx, [ecx+HDLL.size]
977
        jb      .hdll_found
978
        mov     ecx, [ecx+HDLL.fd]
979
        jmp     .scan_hdll
1314 diamond 980
.no_hdll:
2434 Serge 981
        pop     ecx ebx
982
        popf
983
        clc
984
        ret
1314 diamond 985
.hdll_found:
986
; allocate page, save it in page table, map it, copy contents from base
2434 Serge 987
        mov     eax, [ecx+HDLL.parent]
988
        add     ebx, [eax+DLLDESCR.data]
989
        call    alloc_page
990
        test    eax, eax
991
        jz      .no_hdll
992
        or      al, PG_UW
993
        mov     [esi+edx*4], eax
994
        stdcall map_page, edi, eax, [req_access]
995
        push    esi edi
996
        mov     esi, ebx
997
        mov     ecx, 4096/4
998
        rep movsd
999
        pop     edi esi
1000
        pop     ecx ebx
1001
        popf
1002
        stc
1003
        ret
1314 diamond 1004
endp
164 serge 1005
 
1006
sys_IPC:
1007
;input:
1496 Lrz 1008
;  ebx=1 - set ipc buffer area
1009
;    ecx=address of buffer
1010
;    edx=size of buffer
164 serge 1011
;  eax=2 - send message
1012
;    ebx=PID
1013
;    ecx=address of message
1014
;    edx=size of message
1015
 
2434 Serge 1016
        dec     ebx
1017
        jnz     @f
164 serge 1018
 
2434 Serge 1019
        mov     eax, [current_slot]
1496 Lrz 1020
        pushf
1021
        cli
2434 Serge 1022
        mov     [eax+APPDATA.ipc_start], ecx    ;set fields in extended information area
1023
        mov     [eax+APPDATA.ipc_size], edx
164 serge 1024
 
2434 Serge 1025
        add     edx, ecx
1026
        add     edx, 4095
1027
        and     edx, not 4095
164 serge 1028
 
2434 Serge 1029
.touch:
1030
        mov     eax, [ecx]
1031
        add     ecx, 0x1000
1032
        cmp     ecx, edx
1033
        jb      .touch
164 serge 1034
 
1496 Lrz 1035
        popf
2434 Serge 1036
        mov     [esp+32], ebx   ;ebx=0
1496 Lrz 1037
        ret
164 serge 1038
 
1496 Lrz 1039
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1040
;2
1041
@@:
2434 Serge 1042
        dec     ebx
1043
        jnz     @f
164 serge 1044
 
1496 Lrz 1045
        stdcall sys_ipc_send, ecx, edx, esi
2434 Serge 1046
        mov     [esp+32], eax
1496 Lrz 1047
        ret
1048
@@:
2434 Serge 1049
        or      eax, -1
1050
        mov     [esp+32], eax
1496 Lrz 1051
        ret
1052
 
164 serge 1053
proc sys_ipc_send stdcall, PID:dword, msg_addr:dword, msg_size:dword
1054
           locals
1055
             dst_slot   dd ?
1056
             dst_offset dd ?
1057
             buf_size   dd ?
536 diamond 1058
             used_buf   dd ?
164 serge 1059
           endl
1060
 
2434 Serge 1061
        pushf
1062
        cli
164 serge 1063
 
2434 Serge 1064
        mov     eax, [PID]
1065
        call    pid_to_slot
1066
        test    eax, eax
1067
        jz      .no_pid
164 serge 1068
 
2434 Serge 1069
        mov     [dst_slot], eax
1070
        shl     eax, 8
5201 serge 1071
        mov     edi, [eax+SLOT_BASE+APPDATA.ipc_start] ;is ipc area defined?
2434 Serge 1072
        test    edi, edi
1073
        jz      .no_ipc_area
164 serge 1074
 
2434 Serge 1075
        mov     ebx, edi
1076
        and     ebx, 0xFFF
1077
        mov     [dst_offset], ebx
164 serge 1078
 
5201 serge 1079
        mov     esi, [eax+SLOT_BASE+APPDATA.ipc_size]
2434 Serge 1080
        mov     [buf_size], esi
164 serge 1081
 
2434 Serge 1082
        mov     ecx, [ipc_tmp]
1083
        cmp     esi, 0x40000-0x1000; size of [ipc_tmp] minus one page
1084
        jbe     @f
1085
        push    esi edi
1086
        add     esi, 0x1000
1087
        stdcall alloc_kernel_space, esi
1088
        mov     ecx, eax
1089
        pop     edi esi
536 diamond 1090
@@:
2434 Serge 1091
        mov     [used_buf], ecx
5201 serge 1092
        stdcall map_mem_ipc, ecx, [dst_slot], \
2434 Serge 1093
                edi, esi, PG_SW
164 serge 1094
 
2434 Serge 1095
        mov     edi, [dst_offset]
1096
        add     edi, [used_buf]
1097
        cmp     dword [edi], 0
1098
        jnz     .ipc_blocked          ;if dword [buffer]<>0 - ipc blocked now
227 serge 1099
 
2434 Serge 1100
        mov     edx, dword [edi+4]
1101
        lea     ebx, [edx+8]
1102
        add     ebx, [msg_size]
1103
        cmp     ebx, [buf_size]
1104
        ja      .buffer_overflow       ;esi<0 - not enough memory in buffer
227 serge 1105
 
2434 Serge 1106
        mov     dword [edi+4], ebx
1107
        mov     eax, [TASK_BASE]
1108
        mov     eax, [eax+0x04]        ;eax - our PID
1109
        add     edi, edx
1110
        mov     [edi], eax
1111
        mov     ecx, [msg_size]
164 serge 1112
 
2434 Serge 1113
        mov     [edi+4], ecx
1114
        add     edi, 8
1115
        mov     esi, [msg_addr]
465 serge 1116
       ;    add esi, new_app_base
2434 Serge 1117
        cld
1118
        rep movsb
164 serge 1119
 
2434 Serge 1120
        mov     ebx, [ipc_tmp]
1121
        mov     edx, ebx
1122
        shr     ebx, 12
1123
        xor     eax, eax
1124
        mov     [page_tabs+ebx*4], eax
1125
        invlpg  [edx]
164 serge 1126
 
2434 Serge 1127
        mov     ebx, [ipc_pdir]
1128
        mov     edx, ebx
1129
        shr     ebx, 12
1130
        xor     eax, eax
1131
        mov     [page_tabs+ebx*4], eax
1132
        invlpg  [edx]
164 serge 1133
 
2434 Serge 1134
        mov     ebx, [ipc_ptab]
1135
        mov     edx, ebx
1136
        shr     ebx, 12
1137
        xor     eax, eax
1138
        mov     [page_tabs+ebx*4], eax
1139
        invlpg  [edx]
164 serge 1140
 
2434 Serge 1141
        mov     eax, [dst_slot]
1142
        shl     eax, 8
1143
        or      [eax+SLOT_BASE+0xA8], dword 0x40
1144
        push    0
1145
        jmp     .ret
164 serge 1146
.no_pid:
2434 Serge 1147
        popf
1148
        mov     eax, 4
1149
        ret
164 serge 1150
.no_ipc_area:
2434 Serge 1151
        popf
1152
        xor     eax, eax
1153
        inc     eax
1154
        ret
164 serge 1155
.ipc_blocked:
2434 Serge 1156
        push    2
1157
        jmp     .ret
164 serge 1158
.buffer_overflow:
2434 Serge 1159
        push    3
536 diamond 1160
.ret:
2434 Serge 1161
        mov     eax, [used_buf]
1162
        cmp     eax, [ipc_tmp]
5201 serge 1163
        je      @f
2434 Serge 1164
        stdcall free_kernel_space, eax
536 diamond 1165
@@:
2434 Serge 1166
        pop     eax
1167
        popf
1168
        ret
164 serge 1169
endp
1170
 
1171
align 4
170 serge 1172
sysfn_meminfo:
164 serge 1173
 
1072 diamond 1174
        ;   add ecx, new_app_base
2434 Serge 1175
        cmp     ecx, OS_BASE
1176
        jae     .fail
172 serge 1177
 
2434 Serge 1178
        mov     eax, [pg_data.pages_count]
1179
        mov     [ecx], eax
1180
        shl     eax, 12
1181
        mov     [esp+32], eax
1182
        mov     eax, [pg_data.pages_free]
1183
        mov     [ecx+4], eax
1184
        mov     eax, [pg_data.pages_faults]
1185
        mov     [ecx+8], eax
1186
        mov     eax, [heap_size]
1187
        mov     [ecx+12], eax
1188
        mov     eax, [heap_free]
1189
        mov     [ecx+16], eax
1190
        mov     eax, [heap_blocks]
1191
        mov     [ecx+20], eax
1192
        mov     eax, [free_blocks]
1193
        mov     [ecx+24], eax
1194
        ret
172 serge 1195
.fail:
2434 Serge 1196
        or      dword [esp+32], -1
1197
        ret
1629 serge 1198
 
164 serge 1199
align 4
940 serge 1200
f68:
2434 Serge 1201
        cmp     ebx, 4
1202
        jbe     sys_sheduler
164 serge 1203
 
2434 Serge 1204
        cmp     ebx, 11
1205
        jb      .fail
164 serge 1206
 
3908 Serge 1207
        cmp     ebx, 27
2434 Serge 1208
        ja      .fail
940 serge 1209
 
2434 Serge 1210
        jmp     dword [f68call+ebx*4-11*4]
940 serge 1211
.11:
2434 Serge 1212
        call    init_heap
1213
        mov     [esp+32], eax
1214
        ret
940 serge 1215
.12:
2434 Serge 1216
        stdcall user_alloc, ecx
1217
        mov     [esp+32], eax
1218
        ret
940 serge 1219
.13:
2434 Serge 1220
        stdcall user_free, ecx
1221
        mov     [esp+32], eax
1222
        ret
940 serge 1223
.14:
2434 Serge 1224
        cmp     ecx, OS_BASE
1225
        jae     .fail
1226
        mov     edi, ecx
1227
        call    get_event_ex
1228
        mov     [esp+32], eax
1229
        ret
940 serge 1230
.16:
2434 Serge 1231
        test    ecx, ecx
1232
        jz      .fail
1233
        cmp     ecx, OS_BASE
1234
        jae     .fail
1235
        stdcall get_service, ecx
1236
        mov     [esp+32], eax
1237
        ret
940 serge 1238
.17:
2434 Serge 1239
        call    srv_handlerEx   ;ecx
1240
        mov     [esp+32], eax
1241
        ret
940 serge 1242
.19:
2434 Serge 1243
        cmp     ecx, OS_BASE
1244
        jae     .fail
1245
        stdcall load_library, ecx
1246
        mov     [esp+32], eax
1247
        ret
940 serge 1248
.20:
2434 Serge 1249
        mov     eax, edx
1250
        mov     ebx, ecx
1251
        call    user_realloc            ;in: eax = pointer, ebx = new size
1252
        mov     [esp+32], eax
1253
        ret
940 serge 1254
.21:
2434 Serge 1255
        cmp     ecx, OS_BASE
1256
        jae     .fail
740 serge 1257
 
2987 Serge 1258
        cmp     edx, OS_BASE
2434 Serge 1259
        jae     .fail
1316 serge 1260
 
4423 Serge 1261
        stdcall load_pe_driver, ecx, edx
2434 Serge 1262
        mov     [esp+32], eax
1263
        ret
940 serge 1264
.22:
2434 Serge 1265
        cmp     ecx, OS_BASE
1266
        jae     .fail
740 serge 1267
 
2434 Serge 1268
        stdcall shmem_open, ecx, edx, esi
1269
        mov     [esp+24], edx
1270
        mov     [esp+32], eax
1271
        ret
740 serge 1272
 
943 serge 1273
.23:
2434 Serge 1274
        cmp     ecx, OS_BASE
1275
        jae     .fail
943 serge 1276
 
2434 Serge 1277
        stdcall shmem_close, ecx
1278
        mov     [esp+32], eax
1279
        ret
1275 serge 1280
.24:
2434 Serge 1281
        mov     eax, [current_slot]
1282
        xchg    ecx, [eax+APPDATA.exc_handler]
1283
        xchg    edx, [eax+APPDATA.except_mask]
1284
        mov     [esp+32], ecx ; reg_eax+8
1285
        mov     [esp+20], edx ; reg_ebx+8
1286
        ret
1275 serge 1287
.25:
2434 Serge 1288
        cmp     ecx, 32
1289
        jae     .fail
1290
        mov     eax, [current_slot]
1291
        btr     [eax+APPDATA.except_mask], ecx
1292
        setc    byte[esp+32]
1293
        jecxz   @f
1294
        bts     [eax+APPDATA.except_mask], ecx
1275 serge 1295
@@:
2434 Serge 1296
        ret
943 serge 1297
 
2434 Serge 1298
.26:
1299
        stdcall user_unmap, ecx, edx, esi
1300
        mov     [esp+32], eax
1301
        ret
1302
 
3908 Serge 1303
.27:
1304
        cmp     ecx, OS_BASE
1305
        jae     .fail
1306
 
1307
        stdcall load_file_umode, ecx
1308
        mov     [esp+24], edx
1309
        mov     [esp+32], eax
1310
        ret
1311
 
164 serge 1312
.fail:
2434 Serge 1313
        xor     eax, eax
1314
        mov     [esp+32], eax
1315
        ret
164 serge 1316
 
1629 serge 1317
 
164 serge 1318
align 4
1629 serge 1319
f68call:   ; keep this table closer to main code
1320
 
1321
           dd f68.11   ; init_heap
1322
           dd f68.12   ; user_alloc
1323
           dd f68.13   ; user_free
1324
           dd f68.14   ; get_event_ex
1325
           dd f68.fail ; moved to f68.24
1326
           dd f68.16   ; get_service
1327
           dd f68.17   ; call_service
1328
           dd f68.fail ; moved to f68.25
1329
           dd f68.19   ; load_dll
1330
           dd f68.20   ; user_realloc
1331
           dd f68.21   ; load_driver
1332
           dd f68.22   ; shmem_open
1333
           dd f68.23   ; shmem_close
2434 Serge 1334
           dd f68.24   ; set exception handler
1335
           dd f68.25   ; unmask exception
1336
           dd f68.26   ; user_unmap
3908 Serge 1337
           dd f68.27   ; load_file_umode
1629 serge 1338
 
1339
 
1340
align 4
4423 Serge 1341
proc load_pe_driver stdcall, file:dword, cmdline:dword
1342
        push    esi
819 serge 1343
 
2434 Serge 1344
        stdcall load_PE, [file]
1345
        test    eax, eax
1346
        jz      .fail
819 serge 1347
 
2434 Serge 1348
        mov     esi, eax
4423 Serge 1349
        push    [cmdline]
1350
        push    DRV_ENTRY
1351
        call    eax
1352
        pop     ecx
1353
        pop     ecx
2434 Serge 1354
        test    eax, eax
1355
        jz      .fail
819 serge 1356
 
2434 Serge 1357
        mov     [eax+SRV.entry], esi
4423 Serge 1358
        pop     esi
2434 Serge 1359
        ret
819 serge 1360
 
1361
.fail:
2434 Serge 1362
        xor     eax, eax
4423 Serge 1363
        pop     esi
2434 Serge 1364
        ret
819 serge 1365
endp
1366
 
1367
align 4
520 serge 1368
proc create_ring_buffer stdcall, size:dword, flags:dword
1369
           locals
1370
             buf_ptr  dd ?
1371
           endl
237 serge 1372
 
2434 Serge 1373
        mov     eax, [size]
1374
        test    eax, eax
1375
        jz      .fail
520 serge 1376
 
2434 Serge 1377
        add     eax, eax
1378
        stdcall alloc_kernel_space, eax
1379
        test    eax, eax
1380
        jz      .fail
520 serge 1381
 
2434 Serge 1382
        push    ebx
662 serge 1383
 
2434 Serge 1384
        mov     [buf_ptr], eax
520 serge 1385
 
2434 Serge 1386
        mov     ebx, [size]
1387
        shr     ebx, 12
1388
        push    ebx
520 serge 1389
 
2434 Serge 1390
        stdcall alloc_pages, ebx
1391
        pop     ecx
520 serge 1392
 
2434 Serge 1393
        test    eax, eax
1394
        jz      .mm_fail
520 serge 1395
 
2434 Serge 1396
        push    edi
662 serge 1397
 
2434 Serge 1398
        or      eax, [flags]
1399
        mov     edi, [buf_ptr]
1400
        mov     ebx, [buf_ptr]
1401
        mov     edx, ecx
1402
        shl     edx, 2
1403
        shr     edi, 10
520 serge 1404
@@:
2434 Serge 1405
        mov     [page_tabs+edi], eax
1406
        mov     [page_tabs+edi+edx], eax
1407
        invlpg  [ebx]
1408
        invlpg  [ebx+0x10000]
1409
        add     eax, 0x1000
1410
        add     ebx, 0x1000
1411
        add     edi, 4
1412
        dec     ecx
1413
        jnz     @B
520 serge 1414
 
2434 Serge 1415
        mov     eax, [buf_ptr]
1416
        pop     edi
1417
        pop     ebx
1418
        ret
520 serge 1419
.mm_fail:
2434 Serge 1420
        stdcall free_kernel_space, [buf_ptr]
1421
        xor     eax, eax
1422
        pop     ebx
520 serge 1423
.fail:
2434 Serge 1424
        ret
520 serge 1425
endp
2442 Serge 1426
 
1427
 
1428
align 4
2467 Serge 1429
proc print_mem
2442 Serge 1430
        mov     edi, BOOT_VAR + 0x9104
1431
        mov     ecx, [edi-4]
1432
        test    ecx, ecx
3908 Serge 1433
        jz      .done
2442 Serge 1434
 
1435
@@:
3908 Serge 1436
        mov     eax, [edi]
1437
        mov     edx, [edi+4]
1438
        add     eax, [edi+8]
1439
        adc     edx, [edi+12]
2442 Serge 1440
 
1441
        DEBUGF  1, "K : E820 %x%x - %x%x type %d\n", \
1442
                    [edi+4], [edi],\
1443
                    edx, eax, [edi+16]
1444
        add     edi, 20
1445
        dec     ecx
1446
        jnz     @b
1447
.done:
1448
        ret
2467 Serge 1449
endp