Subversion Repositories Kolibri OS

Rev

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