Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
431 serge 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
983 diamond 3
;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;;
431 serge 4
;; Distributed under terms of the GNU General Public License    ;;
5
;;                                                              ;;
6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
164 serge 7
 
593 mikedld 8
$Revision: 1081 $
9
 
10
 
164 serge 11
align 4
12
proc alloc_page
13
 
14
           pushfd
15
           cli
660 serge 16
           push ebx
164 serge 17
           mov ebx, [page_start]
18
           mov ecx, [page_end]
19
.l1:
20
           bsf eax,[ebx];
21
           jnz .found
22
           add ebx,4
23
           cmp ebx, ecx
24
           jb .l1
660 serge 25
           pop ebx
164 serge 26
           popfd
27
           xor eax,eax
28
           ret
29
.found:
30
           btr [ebx], eax
31
           mov [page_start],ebx
32
           sub ebx, sys_pgmap
254 serge 33
           lea eax, [eax+ebx*8]
164 serge 34
           shl eax, 12
35
           dec [pg_data.pages_free]
660 serge 36
           pop ebx
164 serge 37
           popfd
38
           ret
39
endp
40
 
41
align 4
42
proc alloc_pages stdcall, count:dword
43
           pushfd
660 serge 44
           push ebx
45
           push edi
164 serge 46
           cli
47
           mov eax, [count]
48
           add eax, 7
49
           shr eax, 3
50
           mov [count], eax
51
           cmp eax, [pg_data.pages_free]
52
           ja .fail
53
 
54
           mov ecx, [page_start]
55
           mov ebx, [page_end]
56
.find:
57
           mov edx, [count]
58
           mov edi, ecx
59
.match:
60
           cmp byte [ecx], 0xFF
61
           jne .next
62
           dec edx
63
           jz .ok
64
           inc ecx
65
           cmp ecx,ebx
66
           jb .match
660 serge 67
.fail:
68
           xor eax, eax
69
           pop edi
70
           pop ebx
164 serge 71
           popfd
72
           ret
73
.next:
74
           inc ecx
75
           cmp ecx, ebx
76
           jb .find
660 serge 77
           pop edi
78
           pop ebx
164 serge 79
           popfd
80
           xor eax, eax
81
           ret
82
.ok:
83
           sub ecx, edi
84
           inc ecx
663 serge 85
           push esi
164 serge 86
           mov esi, edi
87
           xor eax, eax
88
           rep stosb
89
           sub esi, sys_pgmap
90
           shl esi, 3+12
91
           mov eax, esi
92
           mov ebx, [count]
93
           shl ebx, 3
94
           sub [pg_data.pages_free], ebx
663 serge 95
           pop esi
660 serge 96
           pop edi
97
           pop ebx
164 serge 98
           popfd
99
           ret
100
endp
101
 
102
align 4
103
proc map_page stdcall,lin_addr:dword,phis_addr:dword,flags:dword
321 diamond 104
           push ebx
164 serge 105
           mov eax, [phis_addr]
106
           and eax, not 0xFFF
107
           or eax, [flags]
108
           mov ebx, [lin_addr]
109
           shr ebx, 12
365 serge 110
           mov [page_tabs+ebx*4], eax
164 serge 111
           mov eax, [lin_addr]
112
           invlpg [eax]
321 diamond 113
           pop ebx
164 serge 114
           ret
115
endp
116
 
117
align 4
281 serge 118
map_space:    ;not implemented
119
 
120
 
121
           ret
122
 
123
 
124
align 4
164 serge 125
proc free_page
126
;arg:  eax  page address
127
           pushfd
128
           cli
819 serge 129
           shr eax, 12                        ;page index
130
           bts dword [sys_pgmap], eax         ;that's all!
291 serge 131
           cmc
328 serge 132
           adc [pg_data.pages_free], 0
164 serge 133
           shr eax, 3
819 serge 134
           and eax, not 3                     ;dword offset from page_map
448 diamond 135
           add eax, sys_pgmap
164 serge 136
           cmp [page_start], eax
137
           ja @f
138
           popfd
139
           ret
140
@@:
141
           mov [page_start], eax
142
           popfd
143
           ret
144
endp
145
 
741 serge 146
proc map_io_mem stdcall, base:dword, size:dword, flags:dword
147
 
148
           push ebx
149
           push edi
150
           mov eax, [size]
151
           add eax, 4095
152
           and eax, -4096
153
           mov [size], eax
154
           stdcall alloc_kernel_space, eax
155
           test eax, eax
156
           jz .fail
157
           push eax
158
 
159
           mov edi, 0x1000
160
           mov ebx, eax
161
           mov ecx,[size]
162
           mov edx, [base]
163
           shr eax, 12
164
           shr ecx, 12
165
           and edx, -4096
166
           or edx, [flags]
167
@@:
168
           mov [page_tabs+eax*4], edx
819 serge 169
          ; push eax
170
          ; invlpg [ebx]
171
          ; pop eax
741 serge 172
           inc eax
173
           add ebx, edi
174
           add edx, edi
175
           loop @B
176
 
177
           pop eax
178
           mov edx, [base]
179
           and edx, 4095
180
           add eax, edx
181
.fail:
182
           pop edi
183
           pop ebx
184
           ret
185
endp
186
 
279 serge 187
; param
328 serge 188
;  eax= page base + page flags
819 serge 189
;  ebx= linear address
281 serge 190
;  ecx= count
191
 
192
align 4
328 serge 193
commit_pages:
741 serge 194
           push edi
328 serge 195
           test ecx, ecx
196
           jz .fail
281 serge 197
 
328 serge 198
           mov edi, ebx
199
           mov ebx, pg_data.pg_mutex
200
           call wait_mutex      ;ebx
201
 
202
           mov edx, 0x1000
203
           mov ebx, edi
204
           shr ebx, 12
205
@@:
365 serge 206
           mov [page_tabs+ebx*4], eax
819 serge 207
          ; push eax
208
          ; invlpg [edi]
209
          ; pop eax
328 serge 210
           add edi, edx
211
           add eax, edx
212
           inc ebx
213
           dec ecx
214
           jnz @B
215
           mov [pg_data.pg_mutex],ecx
216
.fail:
741 serge 217
           pop edi
281 serge 218
           ret
219
 
328 serge 220
 
281 serge 221
; param
279 serge 222
;  eax= base
281 serge 223
;  ecx= count
279 serge 224
 
164 serge 225
align 4
279 serge 226
release_pages:
321 diamond 227
 
228
           pushad
279 serge 229
           mov ebx, pg_data.pg_mutex
230
           call wait_mutex      ;ebx
231
 
232
           mov esi, eax
233
           mov edi, eax
234
 
235
           shr esi, 10
365 serge 236
           add esi, page_tabs
328 serge 237
 
238
           mov ebp, [pg_data.pages_free]
279 serge 239
           mov ebx, [page_start]
240
           mov edx, sys_pgmap
241
@@:
242
           xor eax, eax
243
           xchg eax, [esi]
924 serge 244
           push eax
279 serge 245
           invlpg [edi]
924 serge 246
           pop eax
279 serge 247
 
248
           test eax, 1
249
           jz .next
250
 
251
           shr eax, 12
252
           bts [edx], eax
291 serge 253
           cmc
328 serge 254
           adc ebp, 0
279 serge 255
           shr eax, 3
256
           and eax, -4
257
           add eax, edx
258
           cmp eax, ebx
259
           jae .next
260
 
261
           mov ebx, eax
262
.next:
263
           add edi, 0x1000
264
           add esi, 4
265
           dec ecx
266
           jnz @B
328 serge 267
           mov [pg_data.pages_free], ebp
279 serge 268
           and [pg_data.pg_mutex],0
321 diamond 269
           popad
279 serge 270
           ret
271
 
819 serge 272
; param
273
;  eax= base
274
;  ecx= count
275
 
279 serge 276
align 4
819 serge 277
unmap_pages:
278
 
279
           push edi
280
 
281
           mov edi, eax
282
           mov edx, eax
283
 
284
           shr edi, 10
285
           add edi, page_tabs
286
 
287
           xor eax, eax
288
@@:
289
           stosd
290
           invlpg [edx]
291
           add edx, 0x1000
292
           loop @b
293
 
294
           pop edi
295
           ret
296
 
297
 
298
align 4
188 serge 299
proc map_page_table stdcall, lin_addr:dword, phis_addr:dword
321 diamond 300
           push ebx
164 serge 301
           mov ebx, [lin_addr]
302
           shr ebx, 22
303
           mov eax, [phis_addr]
304
           and eax, not 0xFFF
305
           or eax, PG_UW          ;+PG_NOCACHE
378 serge 306
           mov dword [master_tab+ebx*4], eax
164 serge 307
           mov eax, [lin_addr]
308
           shr eax, 10
365 serge 309
           add eax, page_tabs
164 serge 310
           invlpg [eax]
321 diamond 311
           pop ebx
164 serge 312
           ret
313
endp
314
 
315
align 4
316
proc init_LFB
378 serge 317
           locals
318
             pg_count dd ?
319
           endl
320
 
164 serge 321
           cmp dword [LFBAddress], -1
322
           jne @f
412 serge 323
           mov [BOOT_VAR+0x901c],byte 2
164 serge 324
           stdcall kernel_alloc, 0x280000
325
           mov [LFBAddress], eax
326
           ret
327
@@:
328
           test [SCR_MODE],word 0100000000000000b
211 serge 329
           jnz @f
412 serge 330
           mov [BOOT_VAR+0x901c],byte 2
211 serge 331
           ret
332
@@:
490 serge 333
           call init_mtrr
334
 
378 serge 335
           mov edx, LFB_BASE
336
           mov esi, [LFBAddress]
465 serge 337
           mov edi, 0x00800000
379 serge 338
           mov dword [exp_lfb+4], edx
214 serge 339
 
164 serge 340
           shr edi, 12
341
           mov [pg_count], edi
342
           shr edi, 10
343
 
344
           bt [cpu_caps], CAPS_PSE
345
           jnc .map_page_tables
346
           or esi, PG_LARGE+PG_UW
465 serge 347
           mov edx, sys_pgdir+(LFB_BASE shr 20)
164 serge 348
@@:
465 serge 349
           mov [edx], esi
378 serge 350
           add edx, 4
164 serge 351
           add esi, 0x00400000
352
           dec edi
353
           jnz @B
354
 
207 serge 355
           bt [cpu_caps], CAPS_PGE
356
           jnc @F
465 serge 357
           or dword [sys_pgdir+(LFB_BASE shr 20)], PG_GLOBAL
207 serge 358
@@:
378 serge 359
           mov dword [LFBAddress], LFB_BASE
164 serge 360
           mov eax, cr3       ;flush TLB
361
           mov cr3, eax
362
           ret
363
 
364
.map_page_tables:
365
 
465 serge 366
@@:
164 serge 367
           call alloc_page
378 serge 368
           stdcall map_page_table, edx, eax
389 serge 369
           add edx, 0x00400000
164 serge 370
           dec edi
465 serge 371
           jnz @B
164 serge 372
 
373
           mov eax, [LFBAddress]
378 serge 374
           mov edi, page_tabs + (LFB_BASE shr 10)
164 serge 375
           or eax, PG_UW
376
           mov ecx, [pg_count]
378 serge 377
           cld
389 serge 378
@@:
379
           stosd
380
           add eax, 0x1000
381
           dec ecx
382
           jnz @B
164 serge 383
 
378 serge 384
           mov dword [LFBAddress], LFB_BASE
164 serge 385
           mov eax, cr3       ;flush TLB
386
           mov cr3, eax
387
 
388
           ret
389
endp
390
 
391
align 4
392
proc new_mem_resize stdcall, new_size:dword
393
 
276 serge 394
           mov ebx, pg_data.pg_mutex
395
           call wait_mutex    ;ebx
164 serge 396
 
397
           mov edi, [new_size]
398
           add edi,4095
399
           and edi,not 4095
400
           mov [new_size], edi
401
 
465 serge 402
           mov edx,[current_slot]
403
           cmp [edx+APPDATA.heap_base],0
172 serge 404
           jne .exit
405
 
465 serge 406
           mov esi, [edx+APPDATA.mem_size]
164 serge 407
           add esi, 4095
408
           and esi, not 4095
409
 
410
           cmp edi, esi
411
           jae .expand
412
 
413
           shr edi, 12
414
           shr esi, 12
415
@@:
378 serge 416
           mov eax, [app_page_tabs+edi*4]
164 serge 417
           test eax, 1
418
           jz .next
378 serge 419
           mov dword [app_page_tabs+edi*4], 2
164 serge 420
           mov ebx, edi
421
           shl ebx, 12
924 serge 422
           push eax
659 serge 423
           invlpg [ebx]
924 serge 424
           pop eax
164 serge 425
           call free_page
426
 
427
.next:     add edi, 1
428
           cmp edi, esi
429
           jb @B
430
 
431
.update_size:
465 serge 432
           mov     ebx, [new_size]
433
           call    update_mem_size
164 serge 434
 
435
           xor eax, eax
436
           dec [pg_data.pg_mutex]
437
           ret
438
.expand:
439
 
440
           push esi
441
           push edi
442
 
443
           add edi, 0x3FFFFF
444
           and edi, not(0x3FFFFF)
445
           add esi, 0x3FFFFF
446
           and esi, not(0x3FFFFF)
447
 
448
           cmp esi, edi
449
           jae .grow
450
 
451
           xchg esi, edi
452
 
453
@@:
454
           call alloc_page
455
           test eax, eax
456
           jz .exit
457
 
188 serge 458
           stdcall map_page_table, edi, eax
164 serge 459
 
460
           push edi
461
           shr edi, 10
365 serge 462
           add edi, page_tabs
164 serge 463
           mov ecx, 1024
464
           xor eax, eax
465
           cld
466
           rep stosd
467
           pop edi
468
 
469
           add edi, 0x00400000
470
           cmp edi, esi
471
           jb @B
472
.grow:
473
           pop edi
474
           pop esi
475
@@:
476
           call alloc_page
477
           test eax, eax
478
           jz .exit
479
           stdcall map_page,esi,eax,dword PG_UW
480
 
481
           push edi
482
           mov edi, esi
483
           xor eax, eax
484
           mov ecx, 1024
485
           cld
486
           rep stosd
487
           pop edi
488
 
489
           add esi, 0x1000
490
           cmp esi, edi
294 diamond 491
           jb  @B
164 serge 492
 
493
           jmp .update_size
494
.exit:
495
           xor eax, eax
496
           inc eax
497
           dec [pg_data.pg_mutex]
498
           ret
499
endp
500
 
294 diamond 501
update_mem_size:
465 serge 502
; in: edx = slot base
294 diamond 503
;     ebx = new memory size
504
; destroys eax,ecx,edx
505
 
465 serge 506
           mov    [APPDATA.mem_size+edx],ebx
294 diamond 507
;search threads and update
508
;application memory size infomation
465 serge 509
           mov    ecx,[APPDATA.dir_table+edx]
294 diamond 510
           mov    eax,2
511
 
512
.search_threads:
513
;eax = current slot
514
;ebx = new memory size
515
;ecx = page directory
516
           cmp    eax,[TASK_COUNT]
517
           jg     .search_threads_end
518
           mov    edx,eax
519
           shl    edx,5
520
           cmp    word [CURRENT_TASK+edx+TASKDATA.state],9 ;if slot empty?
521
           jz     .search_threads_next
522
           shl    edx,3
380 serge 523
           cmp    [SLOT_BASE+edx+APPDATA.dir_table],ecx     ;if it is our thread?
294 diamond 524
           jnz    .search_threads_next
380 serge 525
           mov    [SLOT_BASE+edx+APPDATA.mem_size],ebx     ;update memory size
294 diamond 526
.search_threads_next:
527
           inc    eax
528
           jmp    .search_threads
529
.search_threads_end:
530
           ret
531
 
285 serge 532
; param
533
;  eax= linear address
534
;
535
; retval
536
;  eax= phisical page address
537
 
164 serge 538
align 4
285 serge 539
get_pg_addr:
540
           shr eax, 12
365 serge 541
           mov eax, [page_tabs+eax*4]
164 serge 542
           and eax, 0xFFFFF000
543
           ret
544
 
465 serge 545
 
188 serge 546
align 4
1056 Galkov 547
; Now it is called from sys32::exc_c (see stack frame there)
164 serge 548
proc page_fault_handler
465 serge 549
 
1056 Galkov 550
    .err_addr   equ ebp-4
709 diamond 551
 
1056 Galkov 552
        mov     ebp, esp
553
        mov     ebx, cr2
554
        push    ebx               ; that is locals: .err_addr = cr2
555
        inc     [pg_data.pages_faults]
465 serge 556
 
557
;     push eax
558
;     push edx
559
;     mov edx, 0x400   ;bochs
560
;     mov al,0xff      ;bochs
561
;     out dx, al       ;bochs
562
;     pop edx
563
;     pop eax
164 serge 564
 
1056 Galkov 565
        mov     eax, [pf_err_code]
164 serge 566
 
1056 Galkov 567
        cmp     ebx, OS_BASE      ;ebx == .err_addr
568
        jb      .user_space       ;ñòðàíèöà â ïàìÿòè ïðèëîæåíèÿ ;
188 serge 569
 
1056 Galkov 570
        cmp     ebx, page_tabs
571
        jb      .kernel_space     ;ñòðàíèöà â ïàìÿòè ÿäðà
164 serge 572
 
1056 Galkov 573
        cmp     ebx, kernel_tabs
574
        jb      .alloc;.app_tabs  ;òàáëèöû ñòðàíèö ïðèëîæåíèÿ ;
575
                                  ;ïðîñòî ñîçäàäèì îäíó
576
if 0 ;ïîêà ýòî ïðîñòî ëèøíåå
577
        cmp     ebx, LFB_BASE
578
        jb      .core_tabs        ;òàáëèöû ñòðàíèö ÿäðà
579
                                  ;Îøèáêà
580
  .lfb:
581
                                  ;îáëàñòü LFB
582
                                  ;Îøèáêà
583
        jmp     .fail
584
end if
585
.core_tabs:
586
.fail:  ;simply return to caller
587
        mov     esp, ebp
588
        mov     bl, 14 ;#PF
589
        ret
378 serge 590
 
164 serge 591
.user_space:
1056 Galkov 592
        test    eax, PG_MAP
593
        jnz     .err_access       ;Ñòðàíèöà ïðèñóòñòâóåò
594
                                  ;Îøèáêà äîñòóïà ?
465 serge 595
 
1056 Galkov 596
        shr     ebx, 12
597
        mov     ecx, ebx
598
        shr     ecx, 10
599
        mov     edx, [master_tab+ecx*4]
600
        test    edx, PG_MAP
601
        jz      .fail             ;òàáëèöà ñòðàíèö íå ñîçäàíà
602
                                  ;íåâåðíûé àäðåñ â ïðîãðàììå
172 serge 603
 
1056 Galkov 604
        mov     eax, [page_tabs+ebx*4]
605
        test    eax, 2
606
        jz      .fail             ;àäðåñ íå çàðåçåðâèðîâàí äëÿ ;
607
                                  ;èñïîëüçîâàíèÿ. Îøèáêà
188 serge 608
.alloc:
1056 Galkov 609
        call    alloc_page
610
        test    eax, eax
611
        jz      .fail
164 serge 612
 
1056 Galkov 613
        stdcall map_page,[.err_addr],eax,dword PG_UW
164 serge 614
 
1056 Galkov 615
        mov     edi, [.err_addr]
616
        and     edi, 0xFFFFF000
617
        mov     ecx, 1024
618
        xor     eax, eax
619
       ;cld     ;caller is duty for this
620
        rep     stosd
621
.exit:  ;iret with repeat fault instruction
622
        add     esp,8 ; clear in stack: locals(.err_addr) + ret_to_caller
623
        restore_ring3_context
624
        iretd
465 serge 625
 
1056 Galkov 626
.err_access  =  .fail
465 serge 627
;íèêîãäà íå ïðîèñõîäèò
1056 Galkov 628
       ;jmp     .fail
465 serge 629
 
630
.kernel_space:
1056 Galkov 631
        test    eax, PG_MAP
632
        jz      .fail   ;ñòðàíèöà íå ïðèñóòñòâóåò
465 serge 633
 
1056 Galkov 634
        test    eax,12  ;U/S (+below)
635
        jnz     .fail   ;ïðèëîæåíèå îáðàòèëîñü ê ïàìÿòè
636
                        ;ÿäðà
637
       ;test    eax, 8
638
       ;jnz     .fail   ;óñòàíîâëåí çàðåçåðâèðîâàííûé áèò
639
                        ;â òàáëèöàõ ñòðàíèö. äîáàâëåíî â P4/Xeon
465 serge 640
 
641
;ïîïûòêà çàïèñè â çàùèù¸ííóþ ñòðàíèöó ÿäðà
642
 
1056 Galkov 643
        cmp     ebx, tss._io_map_0
644
        jb      .fail
465 serge 645
 
1056 Galkov 646
        cmp     ebx, tss._io_map_0+8192
647
        jae     .fail
465 serge 648
 
649
; io permission map
650
; copy-on-write protection
651
 
1056 Galkov 652
        call    alloc_page
653
        test    eax, eax
654
        jz      .fail
465 serge 655
 
1056 Galkov 656
        push    eax
657
        stdcall map_page,[.err_addr],eax,dword PG_SW
658
        pop     eax
659
        mov     edi, [.err_addr]
660
        and     edi, -4096
661
        lea     esi, [edi+(not tss._io_map_0)+1]; -tss._io_map_0
465 serge 662
 
1056 Galkov 663
        mov     ebx, esi
664
        shr     ebx, 12
665
        mov     edx, [current_slot]
666
        or      eax, PG_SW
667
        mov     [edx+APPDATA.io_map+ebx*4], eax
465 serge 668
 
1056 Galkov 669
        add     esi, [default_io_map]
670
        mov     ecx, 4096/4
671
       ;cld     ;caller is duty for this
672
        rep     movsd
673
        jmp     .exit
164 serge 674
endp
675
 
676
align 4
677
proc map_mem stdcall, lin_addr:dword,pdir:dword,\
678
                      ofs:dword,buf_size:dword
679
           mov eax, [buf_size]
680
           test eax, eax
681
           jz .exit
682
 
683
           mov eax, [pdir]
684
           and eax, 0xFFFFF000
685
 
536 diamond 686
           stdcall map_page,[ipc_pdir],eax,PG_UW
164 serge 687
           mov ebx, [ofs]
688
           shr ebx, 22
689
           mov esi, [ipc_pdir]
690
           mov edi, [ipc_ptab]
691
           mov eax, [esi+ebx*4]
692
           and eax, 0xFFFFF000
693
           jz .exit
536 diamond 694
           stdcall map_page,edi,eax,PG_UW
164 serge 695
;           inc ebx
696
;           add edi, 0x1000
697
;           mov eax, [esi+ebx*4]
698
;           test eax, eax
699
;           jz @f
700
;          and eax, 0xFFFFF000
701
;           stdcall map_page, edi, eax
702
 
703
@@:        mov edi, [lin_addr]
704
           and edi, 0xFFFFF000
705
           mov ecx, [buf_size]
706
           add ecx, 4095
707
           shr ecx, 12
708
           inc ecx
709
 
710
           mov edx, [ofs]
711
           shr edx, 12
712
           and edx, 0x3FF
713
           mov esi, [ipc_ptab]
714
 
715
.map:      mov eax, [esi+edx*4]
716
           and eax, 0xFFFFF000
536 diamond 717
           jz  .exit
718
           stdcall map_page,edi,eax,PG_UW
719
           dec ecx
720
           jz  .exit
164 serge 721
           add edi, 0x1000
722
           inc edx
536 diamond 723
           cmp edx, 0x400
164 serge 724
           jnz .map
536 diamond 725
           inc ebx
726
           mov eax, [ipc_pdir]
727
           mov eax, [eax+ebx*4]
728
           and eax, 0xFFFFF000
729
           jz  .exit
730
           stdcall map_page,esi,eax,PG_UW
731
           xor edx, edx
732
           jmp .map
164 serge 733
 
734
.exit:
735
           ret
736
endp
737
 
738
align 4
739
proc map_memEx stdcall, lin_addr:dword,pdir:dword,\
740
                        ofs:dword,buf_size:dword
741
           mov eax, [buf_size]
742
           test eax, eax
743
           jz .exit
744
 
745
           mov eax, [pdir]
746
           and eax, 0xFFFFF000
747
 
748
           stdcall map_page,[proc_mem_pdir],eax,dword PG_UW
749
           mov ebx, [ofs]
750
           shr ebx, 22
751
           mov esi, [proc_mem_pdir]
752
           mov edi, [proc_mem_tab]
753
           mov eax, [esi+ebx*4]
754
           and eax, 0xFFFFF000
755
           test eax, eax
756
           jz .exit
757
           stdcall map_page,edi,eax,dword PG_UW
758
 
759
@@:        mov edi, [lin_addr]
760
           and edi, 0xFFFFF000
761
           mov ecx, [buf_size]
762
           add ecx, 4095
763
           shr ecx, 12
764
           inc ecx
765
 
766
           mov edx, [ofs]
767
           shr edx, 12
768
           and edx, 0x3FF
769
           mov esi, [proc_mem_tab]
770
 
771
.map:      mov eax, [esi+edx*4]
772
;           and eax, 0xFFFFF000
773
;           test eax, eax
774
;           jz .exit
775
           stdcall map_page,edi,eax,dword PG_UW
776
           add edi, 0x1000
777
           inc edx
778
           dec ecx
779
           jnz .map
780
.exit:
781
           ret
782
endp
783
 
784
 
785
 
786
 
787
sys_IPC:
788
;input:
789
;  eax=1 - set ipc buffer area
790
;    ebx=address of buffer
791
;    ecx=size of buffer
792
;  eax=2 - send message
793
;    ebx=PID
794
;    ecx=address of message
795
;    edx=size of message
796
 
797
           cmp  eax,1
798
           jne @f
799
           call set_ipc_buff
800
           mov [esp+36], eax
801
           ret
802
@@:
803
           cmp eax, 2
804
           jne @f
805
           stdcall sys_ipc_send, ebx, ecx, edx
806
           mov [esp+36], eax
807
           ret
808
@@:
809
           xor eax, eax
810
           not eax
811
           mov [esp+36], eax
812
           ret
813
 
814
align 4
815
proc set_ipc_buff
816
 
465 serge 817
           mov  eax,[current_slot]
164 serge 818
           pushf
819
           cli
465 serge 820
           mov  [eax+APPDATA.ipc_start],ebx     ;set fields in extended information area
821
           mov  [eax+APPDATA.ipc_size],ecx
164 serge 822
 
823
           add ecx, ebx
824
           add ecx, 4095
825
           and ecx, not 4095
826
 
827
.touch:    mov eax, [ebx]
828
           add ebx, 0x1000
829
           cmp ebx, ecx
536 diamond 830
           jb  .touch
164 serge 831
 
832
           popf
833
           xor eax, eax
834
           ret
835
endp
836
 
837
proc sys_ipc_send stdcall, PID:dword, msg_addr:dword, msg_size:dword
838
           locals
839
             dst_slot   dd ?
840
             dst_offset dd ?
841
             buf_size   dd ?
536 diamond 842
             used_buf   dd ?
164 serge 843
           endl
844
 
845
           pushf
846
           cli
847
 
848
           mov  eax, [PID]
849
           call pid_to_slot
850
           test eax,eax
851
           jz   .no_pid
852
 
853
           mov [dst_slot], eax
854
           shl  eax,8
380 serge 855
           mov  edi,[eax+SLOT_BASE+0xa0]  ;is ipc area defined?
164 serge 856
           test edi,edi
857
           jz   .no_ipc_area
858
 
859
           mov ebx, edi
860
           and ebx, 0xFFF
861
           mov [dst_offset], ebx
862
 
380 serge 863
           mov esi, [eax+SLOT_BASE+0xa4]
164 serge 864
           mov [buf_size], esi
865
 
536 diamond 866
           mov ecx, [ipc_tmp]
867
           cmp esi, 0x40000-0x1000 ; size of [ipc_tmp] minus one page
868
           jbe @f
869
           push eax esi edi
870
           add esi,0x1000
871
           stdcall alloc_kernel_space,esi
872
           mov ecx, eax
873
           pop edi esi eax
874
@@:
875
           mov [used_buf], ecx
876
           stdcall map_mem, ecx, [SLOT_BASE+eax+0xB8],\
164 serge 877
                             edi, esi
878
 
879
           mov edi, [dst_offset]
536 diamond 880
           add edi, [used_buf]
164 serge 881
           cmp dword [edi], 0
882
           jnz  .ipc_blocked          ;if dword [buffer]<>0 - ipc blocked now
227 serge 883
 
566 serge 884
           mov edx, dword [edi+4]
885
           lea ebx, [edx+8]
164 serge 886
           add ebx, [msg_size]
887
           cmp ebx, [buf_size]
888
           ja .buffer_overflow         ;esi<0 - not enough memory in buffer
227 serge 889
 
164 serge 890
           mov dword [edi+4], ebx
891
           mov eax,[TASK_BASE]
892
           mov eax, [eax+0x04]         ;eax - our PID
893
           add edi, edx
894
           mov [edi], eax
895
           mov ecx, [msg_size]
896
 
897
           mov [edi+4], ecx
898
           add edi, 8
899
           mov esi, [msg_addr]
465 serge 900
       ;    add esi, new_app_base
164 serge 901
           cld
902
           rep movsb
903
 
904
           mov ebx, [ipc_tmp]
905
           mov edx, ebx
906
           shr ebx, 12
907
           xor eax, eax
365 serge 908
           mov [page_tabs+ebx*4], eax
164 serge 909
           invlpg [edx]
910
 
911
           mov ebx, [ipc_pdir]
912
           mov edx, ebx
913
           shr ebx, 12
914
           xor eax, eax
365 serge 915
           mov [page_tabs+ebx*4], eax
164 serge 916
           invlpg [edx]
917
 
918
           mov ebx, [ipc_ptab]
919
           mov edx, ebx
920
           shr ebx, 12
921
           xor eax, eax
365 serge 922
           mov [page_tabs+ebx*4], eax
164 serge 923
           invlpg [edx]
924
 
925
           mov  eax, [dst_slot]
926
           shl eax, 8
380 serge 927
           or   [eax+SLOT_BASE+0xA8],dword 0x40
164 serge 928
           cmp  dword [check_idle_semaphore],20
929
           jge  .ipc_no_cis
930
 
931
           mov  dword [check_idle_semaphore],5
932
.ipc_no_cis:
536 diamond 933
           push 0
934
           jmp .ret
164 serge 935
.no_pid:
936
           popf
536 diamond 937
           mov eax, 4
164 serge 938
           ret
939
.no_ipc_area:
940
           popf
941
           xor eax, eax
942
           inc eax
943
           ret
944
.ipc_blocked:
536 diamond 945
           push 2
946
           jmp .ret
164 serge 947
.buffer_overflow:
536 diamond 948
           push 3
949
.ret:
950
           mov eax, [used_buf]
951
           cmp eax, [ipc_tmp]
952
           jz @f
953
           stdcall free_kernel_space,eax
954
@@:
955
           pop eax
164 serge 956
           popf
957
           ret
958
endp
959
 
960
align 4
170 serge 961
sysfn_meminfo:
164 serge 962
 
1072 diamond 963
        ;   add ecx, new_app_base
964
           cmp ecx, OS_BASE
465 serge 965
           jae .fail
172 serge 966
 
164 serge 967
           mov eax, [pg_data.pages_count]
1072 diamond 968
           mov [ecx], eax
172 serge 969
           shl eax, 12
1072 diamond 970
           mov [esp+32], eax
971
           mov eax, [pg_data.pages_free]
972
           mov [ecx+4], eax
973
           mov eax, [pg_data.pages_faults]
974
           mov [ecx+8], eax
975
           mov eax, [heap_size]
976
           mov [ecx+12], eax
977
           mov eax, [heap_free]
978
           mov [ecx+16], eax
170 serge 979
           mov eax, [heap_blocks]
1072 diamond 980
           mov [ecx+20], eax
981
           mov eax, [free_blocks]
982
           mov [ecx+24], eax
164 serge 983
           ret
172 serge 984
.fail:
1072 diamond 985
           mov dword [esp+32], -1
172 serge 986
           ret
164 serge 987
 
988
align 4
940 serge 989
f68call:
990
           dd f68.11
991
           dd f68.12
992
           dd f68.13
993
           dd f68.14
1077 Galkov 994
           dd f68.fail ;moved to f68.24
940 serge 995
           dd f68.16
996
           dd f68.17
1077 Galkov 997
           dd f68.fail ;moved to f68.25
940 serge 998
           dd f68.19
999
           dd f68.20
1000
           dd f68.21
1001
           dd f68.22
943 serge 1002
           dd f68.23
1077 Galkov 1003
           dd f68.24
1004
           dd f68.25
164 serge 1005
 
940 serge 1006
align 4
1007
f68:
164 serge 1008
           cmp  eax,4
1009
           jle  sys_sheduler
1010
 
170 serge 1011
           cmp eax, 11
164 serge 1012
           jb .fail
1013
 
1077 Galkov 1014
           cmp eax, 25
940 serge 1015
           ja .fail
1016
 
1017
           jmp dword [f68call+eax*4-11*4]
1018
.11:
188 serge 1019
           call init_heap
164 serge 1020
           mov [esp+36], eax
1021
           ret
940 serge 1022
.12:
164 serge 1023
           stdcall user_alloc, ebx
1024
           mov [esp+36], eax
1025
           ret
940 serge 1026
.13:
164 serge 1027
           stdcall user_free, ebx
1028
           mov [esp+36], eax
1029
           ret
940 serge 1030
.14:
465 serge 1031
           cmp ebx, OS_BASE
1032
           jae .fail
1055 Galkov 1033
           mov edi,ebx
1034
           call get_event_ex
227 serge 1035
           mov [esp+36], eax
164 serge 1036
           ret
1077 Galkov 1037
.24:
1074 Galkov 1038
           mov  eax, [current_slot]
1039
           xchg ebx, [eax+APPDATA.exc_handler]
1040
           xchg ecx, [eax+APPDATA.except_mask]
1041
           mov  [esp+36], ebx ; reg_eax+8
1042
           mov  [esp+24], ecx ; reg_ebx+8
164 serge 1043
           ret
940 serge 1044
.16:
188 serge 1045
           test ebx, ebx
1046
           jz .fail
465 serge 1047
           cmp ebx, OS_BASE
1048
           jae .fail
164 serge 1049
           stdcall get_service, ebx
1050
           mov [esp+36], eax
1051
           ret
940 serge 1052
.17:
378 serge 1053
           call srv_handlerEx   ;ebx
164 serge 1054
           mov [esp+36], eax
1055
           ret
1077 Galkov 1056
.25:
1081 diamond 1057
           cmp ebx,32
1058
           jae .fail
1074 Galkov 1059
           mov  eax, [current_slot]
1060
           btr  [eax+APPDATA.except_mask],ebx
1061
           setc byte[esp+36]
1062
           jecxz @f
1063
           bts  [eax+APPDATA.except_mask],ebx
1064
     @@:   ret
940 serge 1065
.19:
465 serge 1066
           cmp ebx, OS_BASE
1067
           jae .fail
198 serge 1068
           stdcall load_library, ebx
1069
           mov [esp+36], eax
1070
           ret
940 serge 1071
.20:
490 serge 1072
           mov     eax, ecx
1073
           call    user_realloc
1074
           mov     [esp+36], eax
1075
           ret
940 serge 1076
.21:
740 serge 1077
           cmp ebx, OS_BASE
1078
           jae .fail
1079
 
1080
           stdcall load_PE, ebx
1081
 
1082
           test eax, eax
1083
           jz @F
1084
 
1085
           mov esi, eax
1086
           stdcall eax, DRV_ENTRY
1087
 
1088
           test eax, eax
1089
           jz @F
1090
 
1091
           mov [eax+SRV.entry], esi
1092
 
1093
@@:
1094
           mov [esp+36], eax
1095
           ret
940 serge 1096
.22:
1097
           cmp ebx, OS_BASE
1098
           jae .fail
740 serge 1099
 
940 serge 1100
           stdcall shmem_open, ebx, ecx, edx
1101
           mov [esp+28], edx
1102
           mov [esp+36], eax
1103
           ret
740 serge 1104
 
943 serge 1105
.23:
1106
           cmp ebx, OS_BASE
1107
           jae .fail
1108
 
1109
           stdcall shmem_close, ebx
1110
           mov [esp+36], eax
1111
           ret
1112
 
164 serge 1113
.fail:
1114
           xor eax, eax
1115
           mov [esp+36], eax
1116
           ret
1117
 
1118
align 4
819 serge 1119
proc load_pe_driver stdcall, file:dword
1120
 
1121
           stdcall load_PE, [file]
1122
           test eax, eax
1123
           jz .fail
1124
 
1125
           mov esi, eax
1126
           stdcall eax, DRV_ENTRY
1127
           test eax, eax
1128
           jz .fail
1129
 
1130
           mov [eax+SRV.entry], esi
1131
           ret
1132
 
1133
.fail:
1134
           xor eax, eax
1135
           ret
1136
endp
1137
 
1138
 
1139
align 4
164 serge 1140
proc init_mtrr
1141
 
412 serge 1142
           cmp [BOOT_VAR+0x901c],byte 2
164 serge 1143
           je  .exit
1144
 
211 serge 1145
           bt [cpu_caps], CAPS_MTRR
1146
           jnc .exit
1147
 
164 serge 1148
           mov eax, cr0
1149
           or eax, 0x60000000   ;disable caching
1150
           mov cr0, eax
1151
           wbinvd               ;invalidate cache
1152
 
1153
           mov ecx, 0x2FF
1154
           rdmsr                ;
1030 diamond 1155
; has BIOS already initialized MTRRs?
1156
           test ah, 8
1157
           jnz .skip_init
1158
; rarely needed, so mainly placeholder
1159
; main memory - cached
164 serge 1160
           push eax
1161
 
821 diamond 1162
           mov eax, [MEM_AMOUNT]
1163
; round eax up to next power of 2
1164
           dec eax
1165
           bsr ecx, eax
1030 diamond 1166
           mov ebx, 2
1167
           shl ebx, cl
1168
           dec ebx
1169
; base of memory range = 0, type of memory range = MEM_WB
164 serge 1170
           xor edx, edx
1030 diamond 1171
           mov eax, MEM_WB
1172
           mov ecx, 0x200
1173
           wrmsr
1174
; mask of memory range = 0xFFFFFFFFF - (size - 1), ebx = size - 1
1175
           mov eax, 0xFFFFFFFF
1176
           mov edx, 0x0000000F
1177
           sub eax, ebx
1178
           sbb edx, 0
1179
           or eax, 0x800
1180
           inc ecx
1181
           wrmsr
1182
; clear unused MTRRs
164 serge 1183
           xor eax, eax
1030 diamond 1184
           xor edx, edx
164 serge 1185
@@:
1030 diamond 1186
           wrmsr
164 serge 1187
           inc ecx
1030 diamond 1188
           cmp ecx, 0x210
1189
           jb @b
1190
; enable MTRRs
1191
           pop eax
1192
           or ah, 8
1193
           and al, 0xF0 ; default memtype = UC
1194
           mov ecx, 0x2FF
164 serge 1195
           wrmsr
1030 diamond 1196
.skip_init:
1197
           stdcall set_mtrr, [LFBAddress],[LFBSize],MEM_WC
164 serge 1198
 
1199
           wbinvd               ;again invalidate
1200
 
1201
           mov eax, cr0
1202
           and eax, not 0x60000000
1203
           mov cr0, eax         ; enable caching
1204
.exit:
1205
           ret
1206
endp
1207
 
1208
align 4
1030 diamond 1209
proc set_mtrr stdcall, base:dword,size:dword,mem_type:dword
1210
; find unused register
1211
           mov ecx, 0x201
1212
@@:
1213
           rdmsr
1214
           dec ecx
1215
           test ah, 8
1216
           jz .found
1217
           rdmsr
1218
           mov al, 0 ; clear memory type field
1219
           cmp eax, [base]
1220
           jz .ret
1221
           add ecx, 3
1222
           cmp ecx, 0x210
1223
           jb @b
1224
; no free registers, ignore the call
1225
.ret:
1226
           ret
1227
.found:
1228
; found, write values
164 serge 1229
           xor edx, edx
1230
           mov eax, [base]
1231
           or eax, [mem_type]
1232
           wrmsr
1233
 
1234
           mov ebx, [size]
1235
           dec ebx
1236
           mov eax, 0xFFFFFFFF
1237
           mov edx, 0x0000000F
1238
           sub eax, ebx
1239
           sbb edx, 0
1240
           or eax, 0x800
1241
           inc ecx
1242
           wrmsr
1243
           ret
1244
endp
1245
 
465 serge 1246
align 4
172 serge 1247
proc stall stdcall, delay:dword
1248
           push ecx
1249
           push edx
1250
           push ebx
1251
           push eax
1252
 
1253
           mov eax, [delay]
1254
           mul [stall_mcs]
1255
           mov ebx, eax       ;low
1256
           mov ecx, edx       ;high
1257
           rdtsc
1258
           add ebx, eax
1259
           adc ecx,edx
1260
@@:
1261
           rdtsc
1262
           sub eax, ebx
1263
           sbb edx, ecx
1264
           jb @B
1265
 
1266
           pop eax
1267
           pop ebx
1268
           pop edx
1269
           pop ecx
1270
           ret
1271
endp
1272
 
520 serge 1273
align 4
1274
proc create_ring_buffer stdcall, size:dword, flags:dword
1275
           locals
1276
             buf_ptr  dd ?
1277
           endl
237 serge 1278
 
520 serge 1279
           mov eax, [size]
1280
           test eax, eax
1281
           jz .fail
1282
 
1283
           add eax, eax
1284
           stdcall alloc_kernel_space, eax
1285
           test eax, eax
1286
           jz .fail
1287
 
662 serge 1288
           push ebx
1289
 
520 serge 1290
           mov [buf_ptr], eax
1291
 
1292
           mov ebx, [size]
1293
           shr ebx, 12
1294
           push ebx
1295
 
1296
           stdcall alloc_pages, ebx
1297
           pop ecx
1298
 
1299
           test eax, eax
1300
           jz .mm_fail
1301
 
662 serge 1302
           push edi
1303
 
520 serge 1304
           or eax, [flags]
1305
           mov edi, [buf_ptr]
1306
           mov ebx, [buf_ptr]
1307
           mov edx, ecx
566 serge 1308
           shl edx, 2
520 serge 1309
           shr edi, 10
1310
@@:
1311
           mov [page_tabs+edi], eax
1312
           mov [page_tabs+edi+edx], eax
924 serge 1313
           invlpg [ebx]
1314
           invlpg [ebx+0x10000]
520 serge 1315
           add eax, 0x1000
1316
           add ebx, 0x1000
566 serge 1317
           add edi, 4
520 serge 1318
           dec ecx
1319
           jnz @B
1320
 
1321
           mov eax, [buf_ptr]
662 serge 1322
           pop edi
1323
           pop ebx
520 serge 1324
           ret
1325
.mm_fail:
1326
           stdcall free_kernel_space, [buf_ptr]
1327
           xor eax, eax
662 serge 1328
           pop ebx
520 serge 1329
.fail:
1330
           ret
1331
endp