Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
4429 Serge 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
3
;; Copyright (C) KolibriOS team 2004-2012. All rights reserved. ;;
4
;; Distributed under terms of the GNU General Public License    ;;
5
;;                                                              ;;
6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7
 
8
$Revision: 4424 $
9
 
10
 
11
align 4
12
proc alloc_page
13
 
14
        pushfd
15
        cli
16
        push    ebx
17
;//-
18
        cmp     [pg_data.pages_free], 1
19
        jle     .out_of_memory
20
;//-
21
 
22
        mov     ebx, [page_start]
23
        mov     ecx, [page_end]
24
.l1:
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
34
.found:
35
;//-
36
        dec     [pg_data.pages_free]
37
        jz      .out_of_memory
38
;//-
39
        btr     [ebx], eax
40
        mov     [page_start], ebx
41
        sub     ebx, sys_pgmap
42
        lea     eax, [eax+ebx*8]
43
        shl     eax, 12
44
;//-       dec [pg_data.pages_free]
45
        pop     ebx
46
        popfd
47
        ret
48
;//-
49
.out_of_memory:
50
        mov     [pg_data.pages_free], 1
51
        xor     eax, eax
52
        pop     ebx
53
        popfd
54
        ret
55
;//-
56
endp
57
 
58
align 4
59
proc alloc_pages stdcall, count:dword
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
68
;//-
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
75
;//-
76
        mov     ecx, [page_start]
77
        mov     ebx, [page_end]
78
.find:
79
        mov     edx, [count]
80
        mov     edi, ecx
81
.match:
82
        cmp     byte [ecx], 0xFF
83
        jne     .next
84
        dec     edx
85
        jz      .ok
86
        inc     ecx
87
        cmp     ecx, ebx
88
        jb      .match
89
.out_of_memory:
90
.fail:
91
        xor     eax, eax
92
        pop     edi
93
        pop     ebx
94
        popfd
95
        ret
96
.next:
97
        inc     ecx
98
        cmp     ecx, ebx
99
        jb      .find
100
        pop     edi
101
        pop     ebx
102
        popfd
103
        xor     eax, eax
104
        ret
105
.ok:
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
123
endp
124
 
125
align 4
126
;proc map_page stdcall,lin_addr:dword,phis_addr:dword,flags:dword
127
map_page:
128
        push    ebx
129
        mov     eax, [esp+12]               ; phis_addr
130
        and     eax, not 0xFFF
131
        or      eax, [esp+16]              ; flags
132
        mov     ebx, [esp+8]               ; lin_addr
133
        shr     ebx, 12
134
        mov     [page_tabs+ebx*4], eax
135
        mov     eax, [esp+8]               ; lin_addr
136
        pop     ebx
137
        invlpg  [eax]
138
        ret     12
139
 
140
align 4
141
map_space:    ;not implemented
142
 
143
 
144
        ret
145
 
146
 
147
align 4
148
proc free_page
149
;arg:  eax  page address
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
163
@@:
164
        mov     [page_start], eax
165
        popfd
166
        ret
167
endp
168
 
169
align 4
170
proc map_io_mem stdcall, base:dword, size:dword, flags:dword
171
 
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
182
 
183
        stdcall alloc_kernel_space, eax
184
        test    eax, eax
185
        jz      .fail
186
        push    eax
187
 
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]
196
@@:
197
        mov     [page_tabs+eax*4], edx
198
        invlpg  [ebx]
199
        inc     eax
200
        add     ebx, edi
201
        add     edx, edi
202
        loop    @B
203
 
204
        pop     eax
205
        mov     edx, [base]
206
        and     edx, 4095
207
        add     eax, edx
208
.fail:
209
        pop     edi
210
        pop     ebx
211
        ret
212
endp
213
 
214
; param
215
;  eax= page base + page flags
216
;  ebx= linear address
217
;  ecx= count
218
 
219
align 4
220
commit_pages:
221
        test    ecx, ecx
222
        jz      .fail
223
 
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
231
 
232
        mov     edi, ebx
233
        shr     edi, 12
234
        lea     edi, [page_tabs+edi*4]
4587 Serge 235
 
236
if USE_FIX_FOR_INVALID_MS_VIRTUAL_PC_2007
237
        mov     edx, eax
4429 Serge 238
@@:
4587 Serge 239
        mov     eax, edx
4429 Serge 240
        stosd
241
        invlpg  [ebx]
4587 Serge 242
        add     edx, 0x1000
243
        add     ebx, 0x1000
244
        loop    @B
245
else
246
@@:
247
        stosd
248
        invlpg  [ebx]
4429 Serge 249
        add     eax, 0x1000
250
        add     ebx, 0x1000
251
        loop    @B
4587 Serge 252
end if
4429 Serge 253
 
254
        pop     edi
255
 
256
        mov     ecx, pg_data.mutex
257
        call    mutex_unlock
258
.fail:
259
        ret
260
 
261
 
262
; param
263
;  eax= base
264
;  ecx= count
265
 
266
align 4
267
release_pages:
268
 
269
        push    ebp
270
        push    esi
271
        push    edi
272
        push    ebx
273
 
274
        mov     esi, eax
275
        mov     edi, eax
276
 
277
        shr     esi, 12
278
        lea     esi, [page_tabs+esi*4]
279
 
280
        push    ecx
281
        mov     ecx, pg_data.mutex
282
        call    mutex_lock
283
        pop     ecx
284
 
285
        mov     ebp, [pg_data.pages_free]
286
        mov     ebx, [page_start]
287
        mov     edx, sys_pgmap
288
@@:
289
        xor     eax, eax
290
        xchg    eax, [esi]
291
        invlpg  [edi]
292
 
293
        test    eax, 1
294
        jz      .next
295
 
296
        shr     eax, 12
297
        bts     [edx], eax
298
        cmc
299
        adc     ebp, 0
300
        shr     eax, 3
301
        and     eax, -4
302
        add     eax, edx
303
        cmp     eax, ebx
304
        jae     .next
305
 
306
        mov     ebx, eax
307
.next:
308
        add     edi, 0x1000
309
        add     esi, 4
310
        loop    @B
311
 
312
        mov     [pg_data.pages_free], ebp
313
        mov     ecx, pg_data.mutex
314
        call    mutex_unlock
315
 
316
        pop     ebx
317
        pop     edi
318
        pop     esi
319
        pop     ebp
320
        ret
321
 
322
; param
323
;  eax= base
324
;  ecx= count
325
 
326
align 4
327
unmap_pages:
328
 
329
        push    edi
330
 
331
        mov     edi, eax
332
        mov     edx, eax
333
 
334
        shr     edi, 10
335
        add     edi, page_tabs
336
 
337
        xor     eax, eax
338
@@:
339
        stosd
340
        invlpg  [edx]
341
        add     edx, 0x1000
342
        loop    @b
343
 
344
        pop     edi
345
        ret
346
 
347
 
348
align 4
349
proc map_page_table stdcall, lin_addr:dword, phis_addr:dword
350
        push    ebx
351
        mov     ebx, [lin_addr]
352
        shr     ebx, 22
353
        mov     eax, [phis_addr]
354
        and     eax, not 0xFFF
355
        or      eax, PG_UW        ;+PG_NOCACHE
356
        mov     dword [master_tab+ebx*4], eax
357
        mov     eax, [lin_addr]
358
        shr     eax, 10
359
        add     eax, page_tabs
360
        invlpg  [eax]
361
        pop     ebx
362
        ret
363
endp
364
 
365
align 4
366
proc init_LFB
367
           locals
368
             pg_count dd ?
369
           endl
370
 
371
        cmp     dword [LFBAddress], -1
372
        jne     @f
373
        mov     [BOOT_VARS+BOOT_MTRR], byte 2
374
; max VGA=640*480*4=1228800 bytes
375
; + 32*640*4=81920 bytes for mouse pointer
376
        stdcall alloc_pages, ((1228800+81920)/4096)
377
 
378
        push    eax
379
        call    alloc_page
380
        stdcall map_page_table, LFB_BASE, eax
381
        pop     eax
382
        or      eax, PG_UW
383
        mov     ebx, LFB_BASE
384
; max VGA=640*480*4=1228800 bytes
385
; + 32*640*4=81920 bytes for mouse pointer
386
        mov     ecx, (1228800+81920)/4096
387
        call    commit_pages
388
        mov     [LFBAddress], dword LFB_BASE
389
        ret
390
@@:
391
        test    [SCR_MODE], word 0100000000000000b
392
        jnz     @f
393
        mov     [BOOT_VARS+BOOT_MTRR], byte 2
394
        ret
395
@@:
396
        call    init_mtrr
397
 
398
        mov     edx, LFB_BASE
399
        mov     esi, [LFBAddress]
400
        mov     edi, 0x00C00000
401
        mov     dword [exp_lfb+4], edx
402
 
403
        shr     edi, 12
404
        mov     [pg_count], edi
405
        shr     edi, 10
406
 
407
        bt      [cpu_caps], CAPS_PSE
408
        jnc     .map_page_tables
409
        or      esi, PG_LARGE+PG_UW
410
        mov     edx, sys_proc+PROC.pdt_0+(LFB_BASE shr 20)
411
@@:
412
        mov     [edx], esi
413
        add     edx, 4
414
        add     esi, 0x00400000
415
        dec     edi
416
        jnz     @B
417
 
418
        bt      [cpu_caps], CAPS_PGE
419
        jnc     @F
420
        or      dword [sys_proc+PROC.pdt_0+(LFB_BASE shr 20)], PG_GLOBAL
421
@@:
422
        mov     dword [LFBAddress], LFB_BASE
423
        mov     eax, cr3      ;flush TLB
424
        mov     cr3, eax
425
        ret
426
 
427
.map_page_tables:
428
 
429
@@:
430
        call    alloc_page
431
        stdcall map_page_table, edx, eax
432
        add     edx, 0x00400000
433
        dec     edi
434
        jnz     @B
435
 
436
        mov     eax, [LFBAddress]
437
        mov     edi, page_tabs + (LFB_BASE shr 10)
438
        or      eax, PG_UW
439
        mov     ecx, [pg_count]
440
        cld
441
@@:
442
        stosd
443
        add     eax, 0x1000
444
        dec     ecx
445
        jnz     @B
446
 
447
        mov     dword [LFBAddress], LFB_BASE
448
        mov     eax, cr3      ;flush TLB
449
        mov     cr3, eax
450
 
451
        ret
452
endp
453
 
454
align 4
455
proc new_mem_resize stdcall, new_size:dword
456
 
457
        push    ebx
458
        push    esi
459
        push    edi
460
 
461
        mov     edx, [current_slot]
4430 Serge 462
        mov     ebx, [edx+APPDATA.process]
463
 
464
        cmp     [ebx+PROC.heap_base], 0
4429 Serge 465
        jne     .exit
466
 
467
        mov     edi, [new_size]
468
        add     edi, 4095
469
        and     edi, not 4095
470
        mov     [new_size], edi
471
 
4430 Serge 472
        mov     esi, [ebx+PROC.mem_used]
4429 Serge 473
        add     esi, 4095
474
        and     esi, not 4095
475
 
476
        cmp     edi, esi
477
        ja      .expand
478
        je      .exit
479
 
480
        mov     ebx, edi
481
        shr     edi, 12
482
        shr     esi, 12
483
 
484
        mov     ecx, pg_data.mutex
485
        call    mutex_lock
486
@@:
487
        mov     eax, [app_page_tabs+edi*4]
488
        test    eax, 1
489
        jz      .next
490
 
491
        mov     dword [app_page_tabs+edi*4], 0
492
        invlpg  [ebx]
493
        call    free_page
494
 
495
.next:
496
        inc     edi
497
        add     ebx, 0x1000
498
        cmp     edi, esi
499
        jb      @B
500
 
501
        mov     ecx, pg_data.mutex
502
        call    mutex_unlock
503
 
504
.update_size:
505
        mov     edx, [current_slot]
506
        mov     ebx, [new_size]
4430 Serge 507
        mov     edx, [edx+APPDATA.process]
508
        mov     [edx+PROC.mem_used], ebx
4429 Serge 509
.exit:
510
        pop     edi
511
        pop     esi
512
        pop     ebx
513
        xor     eax, eax
514
        ret
515
 
516
.expand:
517
 
518
        mov     ecx, pg_data.mutex
519
        call    mutex_lock
520
 
521
        xchg    esi, edi
522
 
523
        push    esi                   ;new size
524
        push    edi                   ;old size
525
 
526
        add     edi, 0x3FFFFF
527
        and     edi, not(0x3FFFFF)
528
        add     esi, 0x3FFFFF
529
        and     esi, not(0x3FFFFF)
530
 
531
        cmp     edi, esi
532
        jae     .grow
533
 @@:
534
        call    alloc_page
535
        test    eax, eax
536
        jz      .exit_fail
537
 
538
        stdcall map_page_table, edi, eax
539
 
540
        push    edi
541
        shr     edi, 10
542
        add     edi, page_tabs
543
        mov     ecx, 1024
544
        xor     eax, eax
545
        cld
546
        rep stosd
547
        pop     edi
548
 
549
        add     edi, 0x00400000
550
        cmp     edi, esi
551
        jb      @B
552
.grow:
553
        pop     edi                   ;old size
554
        pop     ecx                   ;new size
555
 
556
        shr     edi, 10
557
        shr     ecx, 10
558
        sub     ecx, edi
559
        shr     ecx, 2                ;pages count
560
        mov     eax, 2
561
 
562
        add     edi, app_page_tabs
563
        rep stosd
564
 
565
        mov     ecx, pg_data.mutex
566
        call    mutex_unlock
567
 
568
        jmp     .update_size
569
 
570
.exit_fail:
571
        mov     ecx, pg_data.mutex
572
        call    mutex_unlock
573
 
574
        add     esp, 8
575
        pop     edi
576
        pop     esi
577
        pop     ebx
578
        xor     eax, eax
579
        inc     eax
580
        ret
581
endp
582
 
583
 
584
; param
585
;  eax= linear address
586
;
587
; retval
588
;  eax= phisical page address
589
 
590
align 4
591
get_pg_addr:
592
        sub     eax, OS_BASE
593
        cmp     eax, 0x400000
594
        jb      @f
595
        shr     eax, 12
596
        mov     eax, [page_tabs+(eax+(OS_BASE shr 12))*4]
597
@@:
598
        and     eax, 0xFFFFF000
599
        ret
600
 
601
 
602
align 4
603
; Now it is called from core/sys32::exc_c (see stack frame there)
604
proc page_fault_handler
605
 
606
    .err_addr   equ ebp-4
607
 
608
        push    ebx               ;save exception number (#PF)
609
        mov     ebp, esp
610
        mov     ebx, cr2
611
        push    ebx               ;that is locals: .err_addr = cr2
612
        inc     [pg_data.pages_faults]
613
 
614
        mov     eax, [pf_err_code]
615
 
616
        cmp     ebx, OS_BASE      ;ebx == .err_addr
617
        jb      .user_space       ;страница в памяти приложения ;
618
 
619
        cmp     ebx, page_tabs
620
        jb      .kernel_space     ;страница в памяти ядра
621
 
622
        cmp     ebx, kernel_tabs
623
        jb      .alloc;.app_tabs  ;таблицы страниц приложения ;
624
                                  ;просто создадим одну
625
if 0 ;пока это просто лишнее
626
        cmp     ebx, LFB_BASE
627
        jb      .core_tabs        ;таблицы страниц ядра
628
                                  ;Ошибка
629
  .lfb:
630
                                  ;область LFB
631
                                  ;Ошибка
632
        jmp     .fail
633
end if
634
.core_tabs:
635
.fail:  ;simply return to caller
636
        mov     esp, ebp
637
        pop     ebx               ;restore exception number (#PF)
638
        ret
639
 
640
.user_space:
641
        test    eax, PG_MAP
642
        jnz     .err_access       ;Страница присутствует
643
                                  ;Ошибка доступа ?
644
 
645
        shr     ebx, 12
646
        mov     ecx, ebx
647
        shr     ecx, 10
648
        mov     edx, [master_tab+ecx*4]
649
        test    edx, PG_MAP
650
        jz      .fail             ;таблица страниц не создана
651
                                  ;неверный адрес в программе
652
 
653
        mov     eax, [page_tabs+ebx*4]
654
        test    eax, 2
655
        jz      .fail             ;адрес не зарезервирован для ;
656
                                  ;использования. Ошибка
657
.alloc:
658
        call    alloc_page
659
        test    eax, eax
660
        jz      .fail
661
 
662
        stdcall map_page, [.err_addr], eax, PG_UW
663
 
664
        mov     edi, [.err_addr]
665
        and     edi, 0xFFFFF000
666
        mov     ecx, 1024
667
        xor     eax, eax
668
       ;cld     ;caller is duty for this
669
        rep stosd
670
.exit:  ;iret with repeat fault instruction
671
        add     esp, 12;clear in stack: locals(.err_addr) + #PF + ret_to_caller
672
        restore_ring3_context
673
        iretd
674
 
675
.err_access:
676
; access denied? this may be a result of copy-on-write protection for DLL
677
; check list of HDLLs
678
        and     ebx, not 0xFFF
4433 Serge 679
        mov     eax, [current_process]
680
        mov     eax, [eax+PROC.dlls_list_ptr]
4429 Serge 681
        test    eax, eax
682
        jz      .fail
683
        mov     esi, [eax+HDLL.fd]
684
.scan_hdll:
685
        cmp     esi, eax
686
        jz      .fail
687
        mov     edx, ebx
688
        sub     edx, [esi+HDLL.base]
689
        cmp     edx, [esi+HDLL.size]
690
        jb      .fault_in_hdll
691
.scan_hdll.next:
692
        mov     esi, [esi+HDLL.fd]
693
        jmp     .scan_hdll
694
.fault_in_hdll:
695
; allocate new page, map it as rw and copy data
696
        call    alloc_page
697
        test    eax, eax
698
        jz      .fail
699
        stdcall map_page, ebx, eax, PG_UW
700
        mov     edi, ebx
701
        mov     ecx, 1024
702
        sub     ebx, [esi+HDLL.base]
703
        mov     esi, [esi+HDLL.parent]
704
        mov     esi, [esi+DLLDESCR.data]
705
        add     esi, ebx
706
        rep movsd
707
        jmp     .exit
708
 
709
.kernel_space:
710
        test    eax, PG_MAP
711
        jz      .fail   ;страница не присутствует
712
 
713
        test    eax, 12 ;U/S (+below)
714
        jnz     .fail   ;приложение обратилось к памяти
715
                        ;ядра
716
       ;test    eax, 8
717
       ;jnz     .fail   ;установлен зарезервированный бит
718
                        ;в таблицах страниц. добавлено в P4/Xeon
719
 
720
;попытка записи в защищённую страницу ядра
721
 
722
        cmp     ebx, tss._io_map_0
723
        jb      .fail
724
 
725
        cmp     ebx, tss._io_map_0+8192
726
        jae     .fail
727
 
728
; io permission map
729
; copy-on-write protection
730
 
731
        call    alloc_page
732
        test    eax, eax
733
        jz      .fail
734
 
735
        push    eax
736
        stdcall map_page, [.err_addr], eax, dword PG_SW
737
        pop     eax
738
        mov     edi, [.err_addr]
739
        and     edi, -4096
740
        lea     esi, [edi+(not tss._io_map_0)+1]; -tss._io_map_0
741
 
742
        mov     ebx, esi
743
        shr     ebx, 12
744
        mov     edx, [current_slot]
745
        or      eax, PG_SW
746
        mov     [edx+APPDATA.io_map+ebx*4], eax
747
 
748
        add     esi, [default_io_map]
749
        mov     ecx, 4096/4
750
       ;cld     ;caller is duty for this
751
        rep movsd
752
        jmp     .exit
753
endp
754
 
755
; returns number of mapped bytes
4430 Serge 756
proc map_mem_ipc stdcall, lin_addr:dword,slot:dword,\
4429 Serge 757
                      ofs:dword,buf_size:dword,req_access:dword
4430 Serge 758
        locals
759
             count   dd ?
760
             process dd ?
761
        endl
4429 Serge 762
 
4430 Serge 763
        mov     [count], 0
4429 Serge 764
        cmp     [buf_size], 0
765
        jz      .exit
766
 
767
        mov     eax, [slot]
768
        shl     eax, 8
769
        mov     eax, [SLOT_BASE+eax+APPDATA.process]
4430 Serge 770
        test    eax, eax
771
        jz      .exit
4429 Serge 772
 
4430 Serge 773
        mov     [process], eax
4429 Serge 774
        mov     ebx, [ofs]
775
        shr     ebx, 22
4430 Serge 776
        mov     eax, [eax+PROC.pdt_0+ebx*4]                 ;get page table
777
        mov     esi, [ipc_ptab]
4429 Serge 778
        and     eax, 0xFFFFF000
779
        jz      .exit
4430 Serge 780
        stdcall map_page, esi, eax, PG_SW
4429 Serge 781
@@:
782
        mov     edi, [lin_addr]
783
        and     edi, 0xFFFFF000
784
        mov     ecx, [buf_size]
785
        add     ecx, 4095
786
        shr     ecx, 12
4430 Serge 787
        inc     ecx                  ; ???????????
4429 Serge 788
 
789
        mov     edx, [ofs]
790
        shr     edx, 12
791
        and     edx, 0x3FF
792
.map:
793
        stdcall safe_map_page, [slot], [req_access], [ofs]
794
        jnc     .exit
4430 Serge 795
        add     dword [ebp-4], PAGE_SIZE
796
        add     [ofs], PAGE_SIZE
4429 Serge 797
        dec     ecx
798
        jz      .exit
4430 Serge 799
 
800
        add     edi, PAGE_SIZE
4429 Serge 801
        inc     edx
4430 Serge 802
        cmp     edx, 1024
4429 Serge 803
        jnz     .map
4430 Serge 804
 
4429 Serge 805
        inc     ebx
4430 Serge 806
        mov     eax, [process]
807
        mov     eax, [eax+PROC.pdt_0+ebx*4]
4429 Serge 808
        and     eax, 0xFFFFF000
809
        jz      .exit
4430 Serge 810
 
811
        stdcall map_page, esi, eax, PG_SW
4429 Serge 812
        xor     edx, edx
813
        jmp     .map
814
 
815
.exit:
816
        pop     eax
817
        ret
818
endp
819
 
820
proc map_memEx stdcall, lin_addr:dword,slot:dword,\
821
                        ofs:dword,buf_size:dword,req_access:dword
822
        push    0 ; initialize number of mapped bytes
823
 
824
        cmp     [buf_size], 0
825
        jz      .exit
826
 
827
        mov     eax, [slot]
828
        shl     eax, 8
829
        mov     eax, [SLOT_BASE+eax+APPDATA.process]
830
        mov     eax, [eax+PROC.pdt_0_phys]
831
        and     eax, 0xFFFFF000
832
 
833
        stdcall map_page, [proc_mem_pdir], eax, PG_UW
834
        mov     ebx, [ofs]
835
        shr     ebx, 22
836
        mov     esi, [proc_mem_pdir]
837
        mov     edi, [proc_mem_tab]
838
        mov     eax, [esi+ebx*4]
839
        and     eax, 0xFFFFF000
840
        test    eax, eax
841
        jz      .exit
842
        stdcall map_page, edi, eax, PG_UW
843
 
844
@@:
845
        mov     edi, [lin_addr]
846
        and     edi, 0xFFFFF000
847
        mov     ecx, [buf_size]
848
        add     ecx, 4095
849
        shr     ecx, 12
850
        inc     ecx
851
 
852
        mov     edx, [ofs]
853
        shr     edx, 12
854
        and     edx, 0x3FF
855
        mov     esi, [proc_mem_tab]
856
 
857
.map:
858
        stdcall safe_map_page, [slot], [req_access], [ofs]
859
        jnc     .exit
860
        add     dword [ebp-4], 0x1000
861
        add     edi, 0x1000
862
        add     [ofs], 0x1000
863
        inc     edx
864
        dec     ecx
865
        jnz     .map
866
.exit:
867
        pop     eax
868
        ret
869
endp
870
 
871
; in: esi+edx*4 = pointer to page table entry
872
; in: [slot], [req_access], [ofs] on the stack
873
; in: edi = linear address to map
874
; out: CF cleared <=> failed
875
; destroys: only eax
876
proc safe_map_page stdcall, slot:dword, req_access:dword, ofs:dword
877
        mov     eax, [esi+edx*4]
878
        test    al, PG_MAP
879
        jz      .not_present
880
        test    al, PG_WRITE
881
        jz      .resolve_readonly
882
; normal case: writable page, just map with requested access
883
.map:
884
        stdcall map_page, edi, eax, [req_access]
885
        stc
886
.fail:
887
        ret
888
.not_present:
889
; check for alloc-on-demand page
890
        test    al, 2
891
        jz      .fail
892
; allocate new page, save it to source page table
893
        push    ecx
894
        call    alloc_page
895
        pop     ecx
896
        test    eax, eax
897
        jz      .fail
898
        or      al, PG_UW
899
        mov     [esi+edx*4], eax
900
        jmp     .map
901
.resolve_readonly:
902
; readonly page, probably copy-on-write
903
; check: readonly request of readonly page is ok
904
        test    [req_access], PG_WRITE
905
        jz      .map
906
; find control structure for this page
907
        pushf
908
        cli
909
        cld
910
        push    ebx ecx
911
        mov     eax, [slot]
912
        shl     eax, 8
4433 Serge 913
        mov     eax, [SLOT_BASE+eax+APPDATA.process]
914
        mov     eax, [eax+PROC.dlls_list_ptr]
4429 Serge 915
        test    eax, eax
916
        jz      .no_hdll
917
        mov     ecx, [eax+HDLL.fd]
918
.scan_hdll:
919
        cmp     ecx, eax
920
        jz      .no_hdll
921
        mov     ebx, [ofs]
922
        and     ebx, not 0xFFF
923
        sub     ebx, [ecx+HDLL.base]
924
        cmp     ebx, [ecx+HDLL.size]
925
        jb      .hdll_found
926
        mov     ecx, [ecx+HDLL.fd]
927
        jmp     .scan_hdll
928
.no_hdll:
929
        pop     ecx ebx
930
        popf
931
        clc
932
        ret
933
.hdll_found:
934
; allocate page, save it in page table, map it, copy contents from base
935
        mov     eax, [ecx+HDLL.parent]
936
        add     ebx, [eax+DLLDESCR.data]
937
        call    alloc_page
938
        test    eax, eax
939
        jz      .no_hdll
940
        or      al, PG_UW
941
        mov     [esi+edx*4], eax
942
        stdcall map_page, edi, eax, [req_access]
943
        push    esi edi
944
        mov     esi, ebx
945
        mov     ecx, 4096/4
946
        rep movsd
947
        pop     edi esi
948
        pop     ecx ebx
949
        popf
950
        stc
951
        ret
952
endp
953
 
954
sys_IPC:
955
;input:
956
;  ebx=1 - set ipc buffer area
957
;    ecx=address of buffer
958
;    edx=size of buffer
959
;  eax=2 - send message
960
;    ebx=PID
961
;    ecx=address of message
962
;    edx=size of message
963
 
964
        dec     ebx
965
        jnz     @f
966
 
967
        mov     eax, [current_slot]
968
        pushf
969
        cli
970
        mov     [eax+APPDATA.ipc_start], ecx    ;set fields in extended information area
971
        mov     [eax+APPDATA.ipc_size], edx
972
 
973
        add     edx, ecx
974
        add     edx, 4095
975
        and     edx, not 4095
976
 
977
.touch:
978
        mov     eax, [ecx]
979
        add     ecx, 0x1000
980
        cmp     ecx, edx
981
        jb      .touch
982
 
983
        popf
984
        mov     [esp+32], ebx   ;ebx=0
985
        ret
986
 
987
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
988
;2
989
@@:
990
        dec     ebx
991
        jnz     @f
992
 
993
        stdcall sys_ipc_send, ecx, edx, esi
994
        mov     [esp+32], eax
995
        ret
996
@@:
997
        or      eax, -1
998
        mov     [esp+32], eax
999
        ret
1000
 
1001
proc sys_ipc_send stdcall, PID:dword, msg_addr:dword, msg_size:dword
1002
           locals
1003
             dst_slot   dd ?
1004
             dst_offset dd ?
1005
             buf_size   dd ?
1006
             used_buf   dd ?
1007
           endl
1008
 
1009
        pushf
1010
        cli
1011
 
1012
        mov     eax, [PID]
1013
        call    pid_to_slot
1014
        test    eax, eax
1015
        jz      .no_pid
1016
 
1017
        mov     [dst_slot], eax
1018
        shl     eax, 8
4430 Serge 1019
        mov     edi, [eax+SLOT_BASE+APPDATA.ipc_start] ;is ipc area defined?
4429 Serge 1020
        test    edi, edi
1021
        jz      .no_ipc_area
1022
 
1023
        mov     ebx, edi
1024
        and     ebx, 0xFFF
1025
        mov     [dst_offset], ebx
1026
 
4430 Serge 1027
        mov     esi, [eax+SLOT_BASE+APPDATA.ipc_size]
4429 Serge 1028
        mov     [buf_size], esi
1029
 
1030
        mov     ecx, [ipc_tmp]
1031
        cmp     esi, 0x40000-0x1000; size of [ipc_tmp] minus one page
1032
        jbe     @f
1033
        push    esi edi
1034
        add     esi, 0x1000
1035
        stdcall alloc_kernel_space, esi
1036
        mov     ecx, eax
1037
        pop     edi esi
1038
@@:
1039
        mov     [used_buf], ecx
4430 Serge 1040
        stdcall map_mem_ipc, ecx, [dst_slot], \
4429 Serge 1041
                edi, esi, PG_SW
1042
 
1043
        mov     edi, [dst_offset]
1044
        add     edi, [used_buf]
1045
        cmp     dword [edi], 0
1046
        jnz     .ipc_blocked          ;if dword [buffer]<>0 - ipc blocked now
1047
 
1048
        mov     edx, dword [edi+4]
1049
        lea     ebx, [edx+8]
1050
        add     ebx, [msg_size]
1051
        cmp     ebx, [buf_size]
1052
        ja      .buffer_overflow       ;esi<0 - not enough memory in buffer
1053
 
1054
        mov     dword [edi+4], ebx
1055
        mov     eax, [TASK_BASE]
1056
        mov     eax, [eax+0x04]        ;eax - our PID
1057
        add     edi, edx
1058
        mov     [edi], eax
1059
        mov     ecx, [msg_size]
1060
 
1061
        mov     [edi+4], ecx
1062
        add     edi, 8
1063
        mov     esi, [msg_addr]
1064
       ;    add esi, new_app_base
1065
        cld
1066
        rep movsb
1067
 
1068
        mov     ebx, [ipc_tmp]
1069
        mov     edx, ebx
1070
        shr     ebx, 12
1071
        xor     eax, eax
1072
        mov     [page_tabs+ebx*4], eax
1073
        invlpg  [edx]
1074
 
1075
        mov     ebx, [ipc_pdir]
1076
        mov     edx, ebx
1077
        shr     ebx, 12
1078
        xor     eax, eax
1079
        mov     [page_tabs+ebx*4], eax
1080
        invlpg  [edx]
1081
 
1082
        mov     ebx, [ipc_ptab]
1083
        mov     edx, ebx
1084
        shr     ebx, 12
1085
        xor     eax, eax
1086
        mov     [page_tabs+ebx*4], eax
1087
        invlpg  [edx]
1088
 
1089
        mov     eax, [dst_slot]
1090
        shl     eax, 8
1091
        or      [eax+SLOT_BASE+0xA8], dword 0x40
1092
        push    0
1093
        jmp     .ret
1094
.no_pid:
1095
        popf
1096
        mov     eax, 4
1097
        ret
1098
.no_ipc_area:
1099
        popf
1100
        xor     eax, eax
1101
        inc     eax
1102
        ret
1103
.ipc_blocked:
1104
        push    2
1105
        jmp     .ret
1106
.buffer_overflow:
1107
        push    3
1108
.ret:
1109
        mov     eax, [used_buf]
1110
        cmp     eax, [ipc_tmp]
4430 Serge 1111
        je      @f
4429 Serge 1112
        stdcall free_kernel_space, eax
1113
@@:
1114
        pop     eax
1115
        popf
1116
        ret
1117
endp
1118
 
1119
align 4
1120
sysfn_meminfo:
1121
 
1122
        ;   add ecx, new_app_base
1123
        cmp     ecx, OS_BASE
1124
        jae     .fail
1125
 
1126
        mov     eax, [pg_data.pages_count]
1127
        mov     [ecx], eax
1128
        shl     eax, 12
1129
        mov     [esp+32], eax
1130
        mov     eax, [pg_data.pages_free]
1131
        mov     [ecx+4], eax
1132
        mov     eax, [pg_data.pages_faults]
1133
        mov     [ecx+8], eax
1134
        mov     eax, [heap_size]
1135
        mov     [ecx+12], eax
1136
        mov     eax, [heap_free]
1137
        mov     [ecx+16], eax
1138
        mov     eax, [heap_blocks]
1139
        mov     [ecx+20], eax
1140
        mov     eax, [free_blocks]
1141
        mov     [ecx+24], eax
1142
        ret
1143
.fail:
1144
        or      dword [esp+32], -1
1145
        ret
1146
 
1147
align 4
1148
f68:
1149
        cmp     ebx, 4
1150
        jbe     sys_sheduler
1151
 
1152
        cmp     ebx, 11
1153
        jb      .fail
1154
 
1155
        cmp     ebx, 27
1156
        ja      .fail
1157
 
1158
        jmp     dword [f68call+ebx*4-11*4]
1159
.11:
1160
        call    init_heap
1161
        mov     [esp+32], eax
1162
        ret
1163
.12:
1164
        stdcall user_alloc, ecx
1165
        mov     [esp+32], eax
1166
        ret
1167
.13:
1168
        stdcall user_free, ecx
1169
        mov     [esp+32], eax
1170
        ret
1171
.14:
1172
        cmp     ecx, OS_BASE
1173
        jae     .fail
1174
        mov     edi, ecx
1175
        call    get_event_ex
1176
        mov     [esp+32], eax
1177
        ret
1178
.16:
1179
        test    ecx, ecx
1180
        jz      .fail
1181
        cmp     ecx, OS_BASE
1182
        jae     .fail
1183
        stdcall get_service, ecx
1184
        mov     [esp+32], eax
1185
        ret
1186
.17:
1187
        call    srv_handlerEx   ;ecx
1188
        mov     [esp+32], eax
1189
        ret
1190
.19:
1191
        cmp     ecx, OS_BASE
1192
        jae     .fail
1193
        stdcall load_library, ecx
1194
        mov     [esp+32], eax
1195
        ret
1196
.20:
1197
        mov     eax, edx
1198
        mov     ebx, ecx
1199
        call    user_realloc            ;in: eax = pointer, ebx = new size
1200
        mov     [esp+32], eax
1201
        ret
1202
.21:
1203
        cmp     ecx, OS_BASE
1204
        jae     .fail
1205
 
1206
        cmp     edx, OS_BASE
1207
        jae     .fail
1208
 
1209
        stdcall load_pe_driver, ecx, edx
1210
        mov     [esp+32], eax
1211
        ret
1212
.22:
1213
        cmp     ecx, OS_BASE
1214
        jae     .fail
1215
 
1216
        stdcall shmem_open, ecx, edx, esi
1217
        mov     [esp+24], edx
1218
        mov     [esp+32], eax
1219
        ret
1220
 
1221
.23:
1222
        cmp     ecx, OS_BASE
1223
        jae     .fail
1224
 
1225
        stdcall shmem_close, ecx
1226
        mov     [esp+32], eax
1227
        ret
1228
.24:
1229
        mov     eax, [current_slot]
1230
        xchg    ecx, [eax+APPDATA.exc_handler]
1231
        xchg    edx, [eax+APPDATA.except_mask]
1232
        mov     [esp+32], ecx ; reg_eax+8
1233
        mov     [esp+20], edx ; reg_ebx+8
1234
        ret
1235
.25:
1236
        cmp     ecx, 32
1237
        jae     .fail
1238
        mov     eax, [current_slot]
1239
        btr     [eax+APPDATA.except_mask], ecx
1240
        setc    byte[esp+32]
1241
        jecxz   @f
1242
        bts     [eax+APPDATA.except_mask], ecx
1243
@@:
1244
        ret
1245
 
1246
.26:
1247
        stdcall user_unmap, ecx, edx, esi
1248
        mov     [esp+32], eax
1249
        ret
1250
 
1251
.27:
1252
        cmp     ecx, OS_BASE
1253
        jae     .fail
1254
 
1255
        stdcall load_file_umode, ecx
1256
        mov     [esp+24], edx
1257
        mov     [esp+32], eax
1258
        ret
1259
 
1260
.fail:
1261
        xor     eax, eax
1262
        mov     [esp+32], eax
1263
        ret
1264
 
1265
 
1266
align 4
1267
f68call:   ; keep this table closer to main code
1268
 
1269
           dd f68.11   ; init_heap
1270
           dd f68.12   ; user_alloc
1271
           dd f68.13   ; user_free
1272
           dd f68.14   ; get_event_ex
1273
           dd f68.fail ; moved to f68.24
1274
           dd f68.16   ; get_service
1275
           dd f68.17   ; call_service
1276
           dd f68.fail ; moved to f68.25
1277
           dd f68.19   ; load_dll
1278
           dd f68.20   ; user_realloc
1279
           dd f68.21   ; load_driver
1280
           dd f68.22   ; shmem_open
1281
           dd f68.23   ; shmem_close
1282
           dd f68.24   ; set exception handler
1283
           dd f68.25   ; unmask exception
1284
           dd f68.26   ; user_unmap
1285
           dd f68.27   ; load_file_umode
1286
 
1287
 
1288
align 4
1289
proc load_pe_driver stdcall, file:dword, cmdline:dword
1290
        push    esi
1291
 
1292
        stdcall load_PE, [file]
1293
        test    eax, eax
1294
        jz      .fail
1295
 
1296
        mov     esi, eax
1297
        push    [cmdline]
1298
        push    DRV_ENTRY
1299
        call    eax
1300
        pop     ecx
1301
        pop     ecx
1302
        test    eax, eax
1303
        jz      .fail
1304
 
1305
        mov     [eax+SRV.entry], esi
1306
        pop     esi
1307
        ret
1308
 
1309
.fail:
1310
        xor     eax, eax
1311
        pop     esi
1312
        ret
1313
endp
1314
 
1315
align 4
1316
proc create_ring_buffer stdcall, size:dword, flags:dword
1317
           locals
1318
             buf_ptr  dd ?
1319
           endl
1320
 
1321
        mov     eax, [size]
1322
        test    eax, eax
1323
        jz      .fail
1324
 
1325
        add     eax, eax
1326
        stdcall alloc_kernel_space, eax
1327
        test    eax, eax
1328
        jz      .fail
1329
 
1330
        push    ebx
1331
 
1332
        mov     [buf_ptr], eax
1333
 
1334
        mov     ebx, [size]
1335
        shr     ebx, 12
1336
        push    ebx
1337
 
1338
        stdcall alloc_pages, ebx
1339
        pop     ecx
1340
 
1341
        test    eax, eax
1342
        jz      .mm_fail
1343
 
1344
        push    edi
1345
 
1346
        or      eax, [flags]
1347
        mov     edi, [buf_ptr]
1348
        mov     ebx, [buf_ptr]
1349
        mov     edx, ecx
1350
        shl     edx, 2
1351
        shr     edi, 10
1352
@@:
1353
        mov     [page_tabs+edi], eax
1354
        mov     [page_tabs+edi+edx], eax
1355
        invlpg  [ebx]
1356
        invlpg  [ebx+0x10000]
1357
        add     eax, 0x1000
1358
        add     ebx, 0x1000
1359
        add     edi, 4
1360
        dec     ecx
1361
        jnz     @B
1362
 
1363
        mov     eax, [buf_ptr]
1364
        pop     edi
1365
        pop     ebx
1366
        ret
1367
.mm_fail:
1368
        stdcall free_kernel_space, [buf_ptr]
1369
        xor     eax, eax
1370
        pop     ebx
1371
.fail:
1372
        ret
1373
endp
1374
 
1375
 
1376
align 4
1377
proc print_mem
1378
        mov     edi, BOOT_VAR + 0x9104
1379
        mov     ecx, [edi-4]
1380
        test    ecx, ecx
1381
        jz      .done
1382
 
1383
@@:
1384
        mov     eax, [edi]
1385
        mov     edx, [edi+4]
1386
        add     eax, [edi+8]
1387
        adc     edx, [edi+12]
1388
 
1389
        DEBUGF  1, "K : E820 %x%x - %x%x type %d\n", \
1390
                    [edi+4], [edi],\
1391
                    edx, eax, [edi+16]
1392
        add     edi, 20
1393
        dec     ecx
1394
        jnz     @b
1395
.done:
1396
        ret
1397
endp