Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
2288 clevermous 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
2455 mario79 3
;; Copyright (C) KolibriOS team 2004-2012. All rights reserved. ;;
2288 clevermous 4
;; Distributed under terms of the GNU General Public License    ;;
5
;;                                                              ;;
6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7
 
8
$Revision: 5057 $
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
4424 Serge 126
;proc map_page stdcall,lin_addr:dword,phis_addr:dword,flags:dword
127
map_page:
2288 clevermous 128
        push    ebx
4424 Serge 129
        mov     eax, [esp+12]               ; phis_addr
2288 clevermous 130
        and     eax, not 0xFFF
4424 Serge 131
        or      eax, [esp+16]              ; flags
132
        mov     ebx, [esp+8]               ; lin_addr
2288 clevermous 133
        shr     ebx, 12
134
        mov     [page_tabs+ebx*4], eax
4424 Serge 135
        mov     eax, [esp+8]               ; lin_addr
136
        pop     ebx
2288 clevermous 137
        invlpg  [eax]
4424 Serge 138
        ret     12
2288 clevermous 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
 
2414 Serge 169
align 4
2288 clevermous 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]
235
@@:
236
        stosd
237
        invlpg  [ebx]
238
        add     eax, 0x1000
239
        add     ebx, 0x1000
240
        loop    @B
241
 
242
        pop     edi
243
 
244
        mov     ecx, pg_data.mutex
245
        call    mutex_unlock
246
.fail:
247
        ret
248
 
249
 
250
; param
251
;  eax= base
252
;  ecx= count
253
 
254
align 4
255
release_pages:
256
 
257
        push    ebp
258
        push    esi
259
        push    edi
260
        push    ebx
261
 
262
        mov     esi, eax
263
        mov     edi, eax
264
 
265
        shr     esi, 12
266
        lea     esi, [page_tabs+esi*4]
267
 
268
        push    ecx
269
        mov     ecx, pg_data.mutex
270
        call    mutex_lock
271
        pop     ecx
272
 
273
        mov     ebp, [pg_data.pages_free]
274
        mov     ebx, [page_start]
275
        mov     edx, sys_pgmap
276
@@:
277
        xor     eax, eax
278
        xchg    eax, [esi]
279
        invlpg  [edi]
280
 
281
        test    eax, 1
282
        jz      .next
283
 
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
293
 
294
        mov     ebx, eax
295
.next:
296
        add     edi, 0x1000
297
        add     esi, 4
298
        loop    @B
299
 
300
        mov     [pg_data.pages_free], ebp
301
        mov     ecx, pg_data.mutex
302
        call    mutex_unlock
303
 
304
        pop     ebx
305
        pop     edi
306
        pop     esi
307
        pop     ebp
308
        ret
309
 
310
; param
311
;  eax= base
312
;  ecx= count
313
 
314
align 4
315
unmap_pages:
316
 
317
        push    edi
318
 
319
        mov     edi, eax
320
        mov     edx, eax
321
 
322
        shr     edi, 10
323
        add     edi, page_tabs
324
 
325
        xor     eax, eax
326
@@:
327
        stosd
328
        invlpg  [edx]
329
        add     edx, 0x1000
330
        loop    @b
331
 
332
        pop     edi
333
        ret
334
 
335
 
336
align 4
337
proc map_page_table stdcall, lin_addr:dword, phis_addr:dword
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
351
endp
352
 
5057 clevermous 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
 
5032 clevermous 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
 
2288 clevermous 406
align 4
407
proc init_LFB
408
           locals
409
             pg_count dd ?
410
           endl
411
 
412
        cmp     dword [LFBAddress], -1
413
        jne     @f
3732 Serge 414
        mov     [BOOT_VARS+BOOT_MTRR], byte 2
2398 mario79 415
; max VGA=640*480*4=1228800 bytes
416
; + 32*640*4=81920 bytes for mouse pointer
417
        stdcall alloc_pages, ((1228800+81920)/4096)
2288 clevermous 418
 
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
2398 mario79 425
; max VGA=640*480*4=1228800 bytes
426
; + 32*640*4=81920 bytes for mouse pointer
427
        mov     ecx, (1228800+81920)/4096
2288 clevermous 428
        call    commit_pages
429
        mov     [LFBAddress], dword LFB_BASE
430
        ret
431
@@:
432
        test    [SCR_MODE], word 0100000000000000b
433
        jnz     @f
3732 Serge 434
        mov     [BOOT_VARS+BOOT_MTRR], byte 2
2288 clevermous 435
        ret
436
@@:
437
        call    init_mtrr
438
 
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_pgdir+(LFB_BASE shr 20)
452
@@:
453
        mov     [edx], esi
454
        add     edx, 4
455
        add     esi, 0x00400000
456
        dec     edi
457
        jnz     @B
458
 
459
        bt      [cpu_caps], CAPS_PGE
460
        jnc     @F
461
        or      dword [sys_pgdir+(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
467
 
468
.map_page_tables:
469
 
470
@@:
471
        call    alloc_page
472
        stdcall map_page_table, edx, eax
473
        add     edx, 0x00400000
474
        dec     edi
475
        jnz     @B
476
 
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
@@:
483
        stosd
484
        add     eax, 0x1000
485
        dec     ecx
486
        jnz     @B
487
 
488
        mov     dword [LFBAddress], LFB_BASE
489
        mov     eax, cr3      ;flush TLB
490
        mov     cr3, eax
491
 
492
        ret
493
endp
494
 
495
align 4
496
proc new_mem_resize stdcall, new_size:dword
497
 
2594 Serge 498
        push    ebx
499
        push    esi
500
        push    edi
2288 clevermous 501
 
2594 Serge 502
        mov     edx, [current_slot]
503
        cmp     [edx+APPDATA.heap_base], 0
504
        jne     .exit
505
 
2288 clevermous 506
        mov     edi, [new_size]
507
        add     edi, 4095
508
        and     edi, not 4095
509
        mov     [new_size], edi
510
 
511
        mov     esi, [edx+APPDATA.mem_size]
512
        add     esi, 4095
513
        and     esi, not 4095
514
 
515
        cmp     edi, esi
2594 Serge 516
        ja      .expand
517
        je      .exit
2288 clevermous 518
 
2594 Serge 519
        mov     ebx, edi
2288 clevermous 520
        shr     edi, 12
521
        shr     esi, 12
2594 Serge 522
 
523
        mov     ecx, pg_data.mutex
524
        call    mutex_lock
2288 clevermous 525
@@:
526
        mov     eax, [app_page_tabs+edi*4]
527
        test    eax, 1
528
        jz      .next
2594 Serge 529
 
530
        mov     dword [app_page_tabs+edi*4], 0
2288 clevermous 531
        invlpg  [ebx]
532
        call    free_page
533
 
534
.next:
2594 Serge 535
        inc     edi
2595 Serge 536
        add     ebx, 0x1000
2288 clevermous 537
        cmp     edi, esi
538
        jb      @B
539
 
2594 Serge 540
        mov     ecx, pg_data.mutex
541
        call    mutex_unlock
542
 
2288 clevermous 543
.update_size:
2594 Serge 544
        mov     edx, [current_slot]
2288 clevermous 545
        mov     ebx, [new_size]
546
        call    update_mem_size
2594 Serge 547
.exit:
548
        pop     edi
549
        pop     esi
550
        pop     ebx
2288 clevermous 551
        xor     eax, eax
552
        ret
2594 Serge 553
 
2288 clevermous 554
.expand:
555
 
2594 Serge 556
        mov     ecx, pg_data.mutex
557
        call    mutex_lock
2288 clevermous 558
 
2594 Serge 559
        xchg    esi, edi
560
 
561
        push    esi                   ;new size
562
        push    edi                   ;old size
563
 
2288 clevermous 564
        add     edi, 0x3FFFFF
565
        and     edi, not(0x3FFFFF)
566
        add     esi, 0x3FFFFF
567
        and     esi, not(0x3FFFFF)
568
 
2594 Serge 569
        cmp     edi, esi
2288 clevermous 570
        jae     .grow
2594 Serge 571
 @@:
2288 clevermous 572
        call    alloc_page
573
        test    eax, eax
2594 Serge 574
        jz      .exit_fail
2288 clevermous 575
 
576
        stdcall map_page_table, edi, eax
577
 
578
        push    edi
579
        shr     edi, 10
580
        add     edi, page_tabs
581
        mov     ecx, 1024
582
        xor     eax, eax
583
        cld
584
        rep stosd
585
        pop     edi
586
 
587
        add     edi, 0x00400000
588
        cmp     edi, esi
589
        jb      @B
590
.grow:
2594 Serge 591
        pop     edi                   ;old size
592
        pop     ecx                   ;new size
2288 clevermous 593
 
2594 Serge 594
        shr     edi, 10
595
        shr     ecx, 10
596
        sub     ecx, edi
597
        shr     ecx, 2                ;pages count
598
        mov     eax, 2
599
 
600
        add     edi, app_page_tabs
2288 clevermous 601
        rep stosd
602
 
2594 Serge 603
        mov     ecx, pg_data.mutex
604
        call    mutex_unlock
2288 clevermous 605
 
606
        jmp     .update_size
2594 Serge 607
 
608
.exit_fail:
2288 clevermous 609
        mov     ecx, pg_data.mutex
610
        call    mutex_unlock
611
 
2594 Serge 612
        add     esp, 8
613
        pop     edi
614
        pop     esi
615
        pop     ebx
2288 clevermous 616
        xor     eax, eax
617
        inc     eax
618
        ret
619
endp
620
 
2594 Serge 621
 
622
align 4
2288 clevermous 623
update_mem_size:
624
; in: edx = slot base
625
;     ebx = new memory size
626
; destroys eax,ecx,edx
627
 
628
        mov     [APPDATA.mem_size+edx], ebx
629
;search threads and update
630
;application memory size infomation
631
        mov     ecx, [APPDATA.dir_table+edx]
632
        mov     eax, 2
633
 
634
.search_threads:
635
;eax = current slot
636
;ebx = new memory size
637
;ecx = page directory
638
        cmp     eax, [TASK_COUNT]
639
        jg      .search_threads_end
640
        mov     edx, eax
641
        shl     edx, 5
642
        cmp     word [CURRENT_TASK+edx+TASKDATA.state], 9  ;if slot empty?
643
        jz      .search_threads_next
644
        shl     edx, 3
645
        cmp     [SLOT_BASE+edx+APPDATA.dir_table], ecx      ;if it is our thread?
646
        jnz     .search_threads_next
647
        mov     [SLOT_BASE+edx+APPDATA.mem_size], ebx      ;update memory size
648
.search_threads_next:
649
        inc     eax
650
        jmp     .search_threads
651
.search_threads_end:
652
        ret
653
 
654
; param
655
;  eax= linear address
656
;
657
; retval
658
;  eax= phisical page address
659
 
660
align 4
661
get_pg_addr:
3166 clevermous 662
        sub     eax, OS_BASE
663
        cmp     eax, 0x400000
664
        jb      @f
2288 clevermous 665
        shr     eax, 12
3166 clevermous 666
        mov     eax, [page_tabs+(eax+(OS_BASE shr 12))*4]
667
@@:
2288 clevermous 668
        and     eax, 0xFFFFF000
669
        ret
670
 
671
 
672
align 4
673
; Now it is called from core/sys32::exc_c (see stack frame there)
674
proc page_fault_handler
675
 
676
    .err_addr   equ ebp-4
677
 
678
        push    ebx               ;save exception number (#PF)
679
        mov     ebp, esp
680
        mov     ebx, cr2
681
        push    ebx               ;that is locals: .err_addr = cr2
682
        inc     [pg_data.pages_faults]
683
 
684
        mov     eax, [pf_err_code]
685
 
686
        cmp     ebx, OS_BASE      ;ebx == .err_addr
3539 clevermous 687
        jb      .user_space       ;страница в памяти приложения ;
2288 clevermous 688
 
689
        cmp     ebx, page_tabs
3539 clevermous 690
        jb      .kernel_space     ;страница в памяти ядра
2288 clevermous 691
 
692
        cmp     ebx, kernel_tabs
3539 clevermous 693
        jb      .alloc;.app_tabs  ;таблицы страниц приложения ;
694
                                  ;просто создадим одну
695
if 0 ;пока это просто лишнее
2288 clevermous 696
        cmp     ebx, LFB_BASE
3539 clevermous 697
        jb      .core_tabs        ;таблицы страниц ядра
698
                                  ;Ошибка
2288 clevermous 699
  .lfb:
3539 clevermous 700
                                  ;область LFB
701
                                  ;Ошибка
2288 clevermous 702
        jmp     .fail
703
end if
704
.core_tabs:
705
.fail:  ;simply return to caller
706
        mov     esp, ebp
707
        pop     ebx               ;restore exception number (#PF)
708
        ret
709
 
710
;        xchg bx, bx
711
;        add     esp,12 ;clear in stack: locals(.err_addr) + #PF + ret_to_caller
712
;        restore_ring3_context
713
;        iretd
714
 
715
.user_space:
716
        test    eax, PG_MAP
3539 clevermous 717
        jnz     .err_access       ;Страница присутствует
718
                                  ;Ошибка доступа ?
2288 clevermous 719
 
720
        shr     ebx, 12
721
        mov     ecx, ebx
722
        shr     ecx, 10
723
        mov     edx, [master_tab+ecx*4]
724
        test    edx, PG_MAP
3539 clevermous 725
        jz      .fail             ;таблица страниц не создана
726
                                  ;неверный адрес в программе
2288 clevermous 727
 
728
        mov     eax, [page_tabs+ebx*4]
729
        test    eax, 2
3539 clevermous 730
        jz      .fail             ;адрес не зарезервирован для ;
731
                                  ;использования. Ошибка
2288 clevermous 732
.alloc:
733
        call    alloc_page
734
        test    eax, eax
735
        jz      .fail
736
 
737
        stdcall map_page, [.err_addr], eax, PG_UW
738
 
739
        mov     edi, [.err_addr]
740
        and     edi, 0xFFFFF000
741
        mov     ecx, 1024
742
        xor     eax, eax
743
       ;cld     ;caller is duty for this
744
        rep stosd
745
.exit:  ;iret with repeat fault instruction
746
        add     esp, 12;clear in stack: locals(.err_addr) + #PF + ret_to_caller
747
        restore_ring3_context
748
        iretd
749
 
750
.err_access:
751
; access denied? this may be a result of copy-on-write protection for DLL
752
; check list of HDLLs
753
        and     ebx, not 0xFFF
754
        mov     eax, [CURRENT_TASK]
755
        shl     eax, 8
756
        mov     eax, [SLOT_BASE+eax+APPDATA.dlls_list_ptr]
757
        test    eax, eax
758
        jz      .fail
759
        mov     esi, [eax+HDLL.fd]
760
.scan_hdll:
761
        cmp     esi, eax
762
        jz      .fail
763
        mov     edx, ebx
764
        sub     edx, [esi+HDLL.base]
765
        cmp     edx, [esi+HDLL.size]
766
        jb      .fault_in_hdll
767
.scan_hdll.next:
768
        mov     esi, [esi+HDLL.fd]
769
        jmp     .scan_hdll
770
.fault_in_hdll:
771
; allocate new page, map it as rw and copy data
772
        call    alloc_page
773
        test    eax, eax
774
        jz      .fail
775
        stdcall map_page, ebx, eax, PG_UW
776
        mov     edi, ebx
777
        mov     ecx, 1024
778
        sub     ebx, [esi+HDLL.base]
779
        mov     esi, [esi+HDLL.parent]
780
        mov     esi, [esi+DLLDESCR.data]
781
        add     esi, ebx
782
        rep movsd
783
        jmp     .exit
784
 
785
.kernel_space:
786
        test    eax, PG_MAP
3539 clevermous 787
        jz      .fail   ;страница не присутствует
2288 clevermous 788
 
789
        test    eax, 12 ;U/S (+below)
3539 clevermous 790
        jnz     .fail   ;приложение обратилось к памяти
791
                        ;ядра
2288 clevermous 792
       ;test    eax, 8
3539 clevermous 793
       ;jnz     .fail   ;установлен зарезервированный бит
794
                        ;в таблицах страниц. добавлено в P4/Xeon
2288 clevermous 795
 
3539 clevermous 796
;попытка записи в защищённую страницу ядра
2288 clevermous 797
 
798
        cmp     ebx, tss._io_map_0
799
        jb      .fail
800
 
801
        cmp     ebx, tss._io_map_0+8192
802
        jae     .fail
803
 
804
; io permission map
805
; copy-on-write protection
806
 
807
        call    alloc_page
808
        test    eax, eax
809
        jz      .fail
810
 
811
        push    eax
812
        stdcall map_page, [.err_addr], eax, dword PG_SW
813
        pop     eax
814
        mov     edi, [.err_addr]
815
        and     edi, -4096
816
        lea     esi, [edi+(not tss._io_map_0)+1]; -tss._io_map_0
817
 
818
        mov     ebx, esi
819
        shr     ebx, 12
820
        mov     edx, [current_slot]
821
        or      eax, PG_SW
822
        mov     [edx+APPDATA.io_map+ebx*4], eax
823
 
824
        add     esi, [default_io_map]
825
        mov     ecx, 4096/4
826
       ;cld     ;caller is duty for this
827
        rep movsd
828
        jmp     .exit
829
endp
830
 
831
; returns number of mapped bytes
832
proc map_mem stdcall, lin_addr:dword,slot:dword,\
833
                      ofs:dword,buf_size:dword,req_access:dword
834
        push    0 ; initialize number of mapped bytes
835
 
836
        cmp     [buf_size], 0
837
        jz      .exit
838
 
839
        mov     eax, [slot]
840
        shl     eax, 8
841
        mov     eax, [SLOT_BASE+eax+APPDATA.dir_table]
842
        and     eax, 0xFFFFF000
843
 
844
        stdcall map_page, [ipc_pdir], eax, PG_UW
845
        mov     ebx, [ofs]
846
        shr     ebx, 22
847
        mov     esi, [ipc_pdir]
848
        mov     edi, [ipc_ptab]
849
        mov     eax, [esi+ebx*4]
850
        and     eax, 0xFFFFF000
851
        jz      .exit
852
        stdcall map_page, edi, eax, PG_UW
853
;           inc ebx
854
;           add edi, 0x1000
855
;           mov eax, [esi+ebx*4]
856
;           test eax, eax
857
;           jz @f
858
;          and eax, 0xFFFFF000
859
;           stdcall map_page, edi, eax
860
 
861
@@:
862
        mov     edi, [lin_addr]
863
        and     edi, 0xFFFFF000
864
        mov     ecx, [buf_size]
865
        add     ecx, 4095
866
        shr     ecx, 12
867
        inc     ecx
868
 
869
        mov     edx, [ofs]
870
        shr     edx, 12
871
        and     edx, 0x3FF
872
        mov     esi, [ipc_ptab]
873
 
874
.map:
875
        stdcall safe_map_page, [slot], [req_access], [ofs]
876
        jnc     .exit
877
        add     dword [ebp-4], 4096
878
        add     [ofs], 4096
879
        dec     ecx
880
        jz      .exit
881
        add     edi, 0x1000
882
        inc     edx
883
        cmp     edx, 0x400
884
        jnz     .map
885
        inc     ebx
886
        mov     eax, [ipc_pdir]
887
        mov     eax, [eax+ebx*4]
888
        and     eax, 0xFFFFF000
889
        jz      .exit
890
        stdcall map_page, esi, eax, PG_UW
891
        xor     edx, edx
892
        jmp     .map
893
 
894
.exit:
895
        pop     eax
896
        ret
897
endp
898
 
899
proc map_memEx stdcall, lin_addr:dword,slot:dword,\
900
                        ofs:dword,buf_size:dword,req_access:dword
901
        push    0 ; initialize number of mapped bytes
902
 
903
        cmp     [buf_size], 0
904
        jz      .exit
905
 
906
        mov     eax, [slot]
907
        shl     eax, 8
908
        mov     eax, [SLOT_BASE+eax+APPDATA.dir_table]
909
        and     eax, 0xFFFFF000
910
 
911
        stdcall map_page, [proc_mem_pdir], eax, PG_UW
912
        mov     ebx, [ofs]
913
        shr     ebx, 22
914
        mov     esi, [proc_mem_pdir]
915
        mov     edi, [proc_mem_tab]
916
        mov     eax, [esi+ebx*4]
917
        and     eax, 0xFFFFF000
918
        test    eax, eax
919
        jz      .exit
920
        stdcall map_page, edi, eax, PG_UW
921
 
922
@@:
923
        mov     edi, [lin_addr]
924
        and     edi, 0xFFFFF000
925
        mov     ecx, [buf_size]
926
        add     ecx, 4095
927
        shr     ecx, 12
928
        inc     ecx
929
 
930
        mov     edx, [ofs]
931
        shr     edx, 12
932
        and     edx, 0x3FF
933
        mov     esi, [proc_mem_tab]
934
 
935
.map:
936
        stdcall safe_map_page, [slot], [req_access], [ofs]
937
        jnc     .exit
938
        add     dword [ebp-4], 0x1000
939
        add     edi, 0x1000
940
        add     [ofs], 0x1000
941
        inc     edx
942
        dec     ecx
943
        jnz     .map
944
.exit:
945
        pop     eax
946
        ret
947
endp
948
 
949
; in: esi+edx*4 = pointer to page table entry
950
; in: [slot], [req_access], [ofs] on the stack
951
; in: edi = linear address to map
952
; out: CF cleared <=> failed
953
; destroys: only eax
954
proc safe_map_page stdcall, slot:dword, req_access:dword, ofs:dword
955
        mov     eax, [esi+edx*4]
956
        test    al, PG_MAP
957
        jz      .not_present
958
        test    al, PG_WRITE
959
        jz      .resolve_readonly
960
; normal case: writable page, just map with requested access
961
.map:
962
        stdcall map_page, edi, eax, [req_access]
963
        stc
964
.fail:
965
        ret
966
.not_present:
967
; check for alloc-on-demand page
968
        test    al, 2
969
        jz      .fail
970
; allocate new page, save it to source page table
971
        push    ecx
972
        call    alloc_page
973
        pop     ecx
974
        test    eax, eax
975
        jz      .fail
976
        or      al, PG_UW
977
        mov     [esi+edx*4], eax
978
        jmp     .map
979
.resolve_readonly:
980
; readonly page, probably copy-on-write
981
; check: readonly request of readonly page is ok
982
        test    [req_access], PG_WRITE
983
        jz      .map
984
; find control structure for this page
985
        pushf
986
        cli
987
        cld
988
        push    ebx ecx
989
        mov     eax, [slot]
990
        shl     eax, 8
991
        mov     eax, [SLOT_BASE+eax+APPDATA.dlls_list_ptr]
992
        test    eax, eax
993
        jz      .no_hdll
994
        mov     ecx, [eax+HDLL.fd]
995
.scan_hdll:
996
        cmp     ecx, eax
997
        jz      .no_hdll
998
        mov     ebx, [ofs]
999
        and     ebx, not 0xFFF
1000
        sub     ebx, [ecx+HDLL.base]
1001
        cmp     ebx, [ecx+HDLL.size]
1002
        jb      .hdll_found
1003
        mov     ecx, [ecx+HDLL.fd]
1004
        jmp     .scan_hdll
1005
.no_hdll:
1006
        pop     ecx ebx
1007
        popf
1008
        clc
1009
        ret
1010
.hdll_found:
1011
; allocate page, save it in page table, map it, copy contents from base
1012
        mov     eax, [ecx+HDLL.parent]
1013
        add     ebx, [eax+DLLDESCR.data]
1014
        call    alloc_page
1015
        test    eax, eax
1016
        jz      .no_hdll
1017
        or      al, PG_UW
1018
        mov     [esi+edx*4], eax
1019
        stdcall map_page, edi, eax, [req_access]
1020
        push    esi edi
1021
        mov     esi, ebx
1022
        mov     ecx, 4096/4
1023
        rep movsd
1024
        pop     edi esi
1025
        pop     ecx ebx
1026
        popf
1027
        stc
1028
        ret
1029
endp
1030
 
1031
sys_IPC:
1032
;input:
1033
;  ebx=1 - set ipc buffer area
1034
;    ecx=address of buffer
1035
;    edx=size of buffer
1036
;  eax=2 - send message
1037
;    ebx=PID
1038
;    ecx=address of message
1039
;    edx=size of message
1040
 
1041
        dec     ebx
1042
        jnz     @f
1043
 
1044
        mov     eax, [current_slot]
1045
        pushf
1046
        cli
1047
        mov     [eax+APPDATA.ipc_start], ecx    ;set fields in extended information area
1048
        mov     [eax+APPDATA.ipc_size], edx
1049
 
1050
        add     edx, ecx
1051
        add     edx, 4095
1052
        and     edx, not 4095
1053
 
1054
.touch:
1055
        mov     eax, [ecx]
1056
        add     ecx, 0x1000
1057
        cmp     ecx, edx
1058
        jb      .touch
1059
 
1060
        popf
1061
        mov     [esp+32], ebx   ;ebx=0
1062
        ret
1063
 
1064
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1065
;2
1066
@@:
1067
        dec     ebx
1068
        jnz     @f
1069
 
1070
        stdcall sys_ipc_send, ecx, edx, esi
1071
        mov     [esp+32], eax
1072
        ret
1073
@@:
1074
        or      eax, -1
1075
        mov     [esp+32], eax
1076
        ret
1077
 
1078
;align 4
1079
;proc set_ipc_buff
1080
 
1081
;           mov  eax,[current_slot]
1082
;           pushf
1083
;           cli
1084
;           mov  [eax+APPDATA.ipc_start],ebx     ;set fields in extended information area
1085
;           mov  [eax+APPDATA.ipc_size],ecx
1086
;
1087
;           add ecx, ebx
1088
;           add ecx, 4095
1089
;           and ecx, not 4095
1090
;
1091
;.touch:    mov eax, [ebx]
1092
;           add ebx, 0x1000
1093
;           cmp ebx, ecx
1094
;           jb  .touch
1095
;
1096
;           popf
1097
;           xor eax, eax
1098
;           ret
1099
;endp
1100
 
1101
proc sys_ipc_send stdcall, PID:dword, msg_addr:dword, msg_size:dword
1102
           locals
1103
             dst_slot   dd ?
1104
             dst_offset dd ?
1105
             buf_size   dd ?
1106
             used_buf   dd ?
1107
           endl
1108
 
1109
        pushf
1110
        cli
1111
 
1112
        mov     eax, [PID]
1113
        call    pid_to_slot
1114
        test    eax, eax
1115
        jz      .no_pid
1116
 
1117
        mov     [dst_slot], eax
1118
        shl     eax, 8
1119
        mov     edi, [eax+SLOT_BASE+0xa0] ;is ipc area defined?
1120
        test    edi, edi
1121
        jz      .no_ipc_area
1122
 
1123
        mov     ebx, edi
1124
        and     ebx, 0xFFF
1125
        mov     [dst_offset], ebx
1126
 
1127
        mov     esi, [eax+SLOT_BASE+0xa4]
1128
        mov     [buf_size], esi
1129
 
1130
        mov     ecx, [ipc_tmp]
1131
        cmp     esi, 0x40000-0x1000; size of [ipc_tmp] minus one page
1132
        jbe     @f
1133
        push    esi edi
1134
        add     esi, 0x1000
1135
        stdcall alloc_kernel_space, esi
1136
        mov     ecx, eax
1137
        pop     edi esi
1138
@@:
1139
        mov     [used_buf], ecx
1140
        stdcall map_mem, ecx, [dst_slot], \
1141
                edi, esi, PG_SW
1142
 
1143
        mov     edi, [dst_offset]
1144
        add     edi, [used_buf]
1145
        cmp     dword [edi], 0
1146
        jnz     .ipc_blocked          ;if dword [buffer]<>0 - ipc blocked now
1147
 
1148
        mov     edx, dword [edi+4]
1149
        lea     ebx, [edx+8]
1150
        add     ebx, [msg_size]
1151
        cmp     ebx, [buf_size]
1152
        ja      .buffer_overflow       ;esi<0 - not enough memory in buffer
1153
 
1154
        mov     dword [edi+4], ebx
1155
        mov     eax, [TASK_BASE]
1156
        mov     eax, [eax+0x04]        ;eax - our PID
1157
        add     edi, edx
1158
        mov     [edi], eax
1159
        mov     ecx, [msg_size]
1160
 
1161
        mov     [edi+4], ecx
1162
        add     edi, 8
1163
        mov     esi, [msg_addr]
1164
       ;    add esi, new_app_base
1165
        cld
1166
        rep movsb
1167
 
1168
        mov     ebx, [ipc_tmp]
1169
        mov     edx, ebx
1170
        shr     ebx, 12
1171
        xor     eax, eax
1172
        mov     [page_tabs+ebx*4], eax
1173
        invlpg  [edx]
1174
 
1175
        mov     ebx, [ipc_pdir]
1176
        mov     edx, ebx
1177
        shr     ebx, 12
1178
        xor     eax, eax
1179
        mov     [page_tabs+ebx*4], eax
1180
        invlpg  [edx]
1181
 
1182
        mov     ebx, [ipc_ptab]
1183
        mov     edx, ebx
1184
        shr     ebx, 12
1185
        xor     eax, eax
1186
        mov     [page_tabs+ebx*4], eax
1187
        invlpg  [edx]
1188
 
1189
        mov     eax, [dst_slot]
1190
        shl     eax, 8
1191
        or      [eax+SLOT_BASE+0xA8], dword 0x40
1192
        push    0
1193
        jmp     .ret
1194
.no_pid:
1195
        popf
1196
        mov     eax, 4
1197
        ret
1198
.no_ipc_area:
1199
        popf
1200
        xor     eax, eax
1201
        inc     eax
1202
        ret
1203
.ipc_blocked:
1204
        push    2
1205
        jmp     .ret
1206
.buffer_overflow:
1207
        push    3
1208
.ret:
1209
        mov     eax, [used_buf]
1210
        cmp     eax, [ipc_tmp]
1211
        jz      @f
1212
        stdcall free_kernel_space, eax
1213
@@:
1214
        pop     eax
1215
        popf
1216
        ret
1217
endp
1218
 
1219
align 4
1220
sysfn_meminfo:
1221
 
1222
        ;   add ecx, new_app_base
1223
        cmp     ecx, OS_BASE
1224
        jae     .fail
1225
 
1226
        mov     eax, [pg_data.pages_count]
1227
        mov     [ecx], eax
1228
        shl     eax, 12
1229
        mov     [esp+32], eax
1230
        mov     eax, [pg_data.pages_free]
1231
        mov     [ecx+4], eax
1232
        mov     eax, [pg_data.pages_faults]
1233
        mov     [ecx+8], eax
1234
        mov     eax, [heap_size]
1235
        mov     [ecx+12], eax
1236
        mov     eax, [heap_free]
1237
        mov     [ecx+16], eax
1238
        mov     eax, [heap_blocks]
1239
        mov     [ecx+20], eax
1240
        mov     eax, [free_blocks]
1241
        mov     [ecx+24], eax
1242
        ret
1243
.fail:
1244
        or      dword [esp+32], -1
1245
        ret
1246
 
1247
align 4
1248
f68:
1249
        cmp     ebx, 4
1250
        jbe     sys_sheduler
1251
 
1252
        cmp     ebx, 11
1253
        jb      .fail
1254
 
3786 Serge 1255
        cmp     ebx, 27
2288 clevermous 1256
        ja      .fail
1257
 
1258
        jmp     dword [f68call+ebx*4-11*4]
1259
.11:
1260
        call    init_heap
1261
        mov     [esp+32], eax
1262
        ret
1263
.12:
1264
        stdcall user_alloc, ecx
1265
        mov     [esp+32], eax
1266
        ret
1267
.13:
1268
        stdcall user_free, ecx
1269
        mov     [esp+32], eax
1270
        ret
1271
.14:
1272
        cmp     ecx, OS_BASE
1273
        jae     .fail
1274
        mov     edi, ecx
1275
        call    get_event_ex
1276
        mov     [esp+32], eax
1277
        ret
1278
.16:
1279
        test    ecx, ecx
1280
        jz      .fail
1281
        cmp     ecx, OS_BASE
1282
        jae     .fail
1283
        stdcall get_service, ecx
1284
        mov     [esp+32], eax
1285
        ret
1286
.17:
1287
        call    srv_handlerEx   ;ecx
1288
        mov     [esp+32], eax
1289
        ret
1290
.19:
1291
        cmp     ecx, OS_BASE
1292
        jae     .fail
1293
        stdcall load_library, ecx
1294
        mov     [esp+32], eax
1295
        ret
1296
.20:
1297
        mov     eax, edx
1298
        mov     ebx, ecx
1299
        call    user_realloc            ;in: eax = pointer, ebx = new size
1300
        mov     [esp+32], eax
1301
        ret
1302
.21:
1303
        cmp     ecx, OS_BASE
1304
        jae     .fail
1305
 
2647 mario79 1306
        cmp     edx, OS_BASE
2288 clevermous 1307
        jae     .fail
1308
 
4418 clevermous 1309
        stdcall load_pe_driver, ecx, edx
2288 clevermous 1310
        mov     [esp+32], eax
1311
        ret
1312
.22:
1313
        cmp     ecx, OS_BASE
1314
        jae     .fail
1315
 
1316
        stdcall shmem_open, ecx, edx, esi
1317
        mov     [esp+24], edx
1318
        mov     [esp+32], eax
1319
        ret
1320
 
1321
.23:
1322
        cmp     ecx, OS_BASE
1323
        jae     .fail
1324
 
1325
        stdcall shmem_close, ecx
1326
        mov     [esp+32], eax
1327
        ret
1328
.24:
1329
        mov     eax, [current_slot]
1330
        xchg    ecx, [eax+APPDATA.exc_handler]
1331
        xchg    edx, [eax+APPDATA.except_mask]
1332
        mov     [esp+32], ecx ; reg_eax+8
1333
        mov     [esp+20], edx ; reg_ebx+8
1334
        ret
1335
.25:
1336
        cmp     ecx, 32
1337
        jae     .fail
1338
        mov     eax, [current_slot]
1339
        btr     [eax+APPDATA.except_mask], ecx
1340
        setc    byte[esp+32]
1341
        jecxz   @f
1342
        bts     [eax+APPDATA.except_mask], ecx
1343
@@:
1344
        ret
1345
 
2400 Serge 1346
.26:
1347
        stdcall user_unmap, ecx, edx, esi
1348
        mov     [esp+32], eax
1349
        ret
1350
 
3786 Serge 1351
.27:
1352
        cmp     ecx, OS_BASE
1353
        jae     .fail
1354
 
1355
        stdcall load_file_umode, ecx
1356
        mov     [esp+24], edx
1357
        mov     [esp+32], eax
1358
        ret
1359
 
2288 clevermous 1360
.fail:
1361
        xor     eax, eax
1362
        mov     [esp+32], eax
1363
        ret
1364
 
1365
 
1366
align 4
1367
f68call:   ; keep this table closer to main code
1368
 
1369
           dd f68.11   ; init_heap
1370
           dd f68.12   ; user_alloc
1371
           dd f68.13   ; user_free
1372
           dd f68.14   ; get_event_ex
1373
           dd f68.fail ; moved to f68.24
1374
           dd f68.16   ; get_service
1375
           dd f68.17   ; call_service
1376
           dd f68.fail ; moved to f68.25
1377
           dd f68.19   ; load_dll
1378
           dd f68.20   ; user_realloc
1379
           dd f68.21   ; load_driver
1380
           dd f68.22   ; shmem_open
1381
           dd f68.23   ; shmem_close
2400 Serge 1382
           dd f68.24   ; set exception handler
1383
           dd f68.25   ; unmask exception
1384
           dd f68.26   ; user_unmap
3786 Serge 1385
           dd f68.27   ; load_file_umode
2288 clevermous 1386
 
1387
 
1388
align 4
4418 clevermous 1389
proc load_pe_driver stdcall, file:dword, cmdline:dword
1390
        push    esi
2288 clevermous 1391
 
1392
        stdcall load_PE, [file]
1393
        test    eax, eax
1394
        jz      .fail
1395
 
1396
        mov     esi, eax
4418 clevermous 1397
        push    [cmdline]
1398
        push    DRV_ENTRY
1399
        call    eax
1400
        pop     ecx
1401
        pop     ecx
2288 clevermous 1402
        test    eax, eax
1403
        jz      .fail
1404
 
1405
        mov     [eax+SRV.entry], esi
4418 clevermous 1406
        pop     esi
2288 clevermous 1407
        ret
1408
 
1409
.fail:
1410
        xor     eax, eax
4418 clevermous 1411
        pop     esi
2288 clevermous 1412
        ret
1413
endp
1414
 
1415
align 4
1416
proc create_ring_buffer stdcall, size:dword, flags:dword
1417
           locals
1418
             buf_ptr  dd ?
1419
           endl
1420
 
1421
        mov     eax, [size]
1422
        test    eax, eax
1423
        jz      .fail
1424
 
1425
        add     eax, eax
1426
        stdcall alloc_kernel_space, eax
1427
        test    eax, eax
1428
        jz      .fail
1429
 
1430
        push    ebx
1431
 
1432
        mov     [buf_ptr], eax
1433
 
1434
        mov     ebx, [size]
1435
        shr     ebx, 12
1436
        push    ebx
1437
 
1438
        stdcall alloc_pages, ebx
1439
        pop     ecx
1440
 
1441
        test    eax, eax
1442
        jz      .mm_fail
1443
 
1444
        push    edi
1445
 
1446
        or      eax, [flags]
1447
        mov     edi, [buf_ptr]
1448
        mov     ebx, [buf_ptr]
1449
        mov     edx, ecx
1450
        shl     edx, 2
1451
        shr     edi, 10
1452
@@:
1453
        mov     [page_tabs+edi], eax
1454
        mov     [page_tabs+edi+edx], eax
1455
        invlpg  [ebx]
1456
        invlpg  [ebx+0x10000]
1457
        add     eax, 0x1000
1458
        add     ebx, 0x1000
1459
        add     edi, 4
1460
        dec     ecx
1461
        jnz     @B
1462
 
1463
        mov     eax, [buf_ptr]
1464
        pop     edi
1465
        pop     ebx
1466
        ret
1467
.mm_fail:
1468
        stdcall free_kernel_space, [buf_ptr]
1469
        xor     eax, eax
1470
        pop     ebx
1471
.fail:
1472
        ret
1473
endp
2466 Serge 1474
 
1475
 
1476
align 4
1477
proc print_mem
1478
        mov     edi, BOOT_VAR + 0x9104
1479
        mov     ecx, [edi-4]
1480
        test    ecx, ecx
1481
        jz      .done
1482
 
1483
@@:
1484
        mov     eax, [edi]
1485
        mov     edx, [edi+4]
1486
        add     eax, [edi+8]
1487
        adc     edx, [edi+12]
1488
 
1489
        DEBUGF  1, "K : E820 %x%x - %x%x type %d\n", \
1490
                    [edi+4], [edi],\
1491
                    edx, eax, [edi+16]
1492
        add     edi, 20
1493
        dec     ecx
1494
        jnz     @b
1495
.done:
1496
        ret
1497
endp