Subversion Repositories Kolibri OS

Rev

Rev 1081 | Rev 1103 | 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: 1089 $
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
1089 diamond 588
        push    14                ;#PF
589
        pop     ebx
1056 Galkov 590
        ret
378 serge 591
 
164 serge 592
.user_space:
1056 Galkov 593
        test    eax, PG_MAP
594
        jnz     .err_access       ;Ñòðàíèöà ïðèñóòñòâóåò
595
                                  ;Îøèáêà äîñòóïà ?
465 serge 596
 
1056 Galkov 597
        shr     ebx, 12
598
        mov     ecx, ebx
599
        shr     ecx, 10
600
        mov     edx, [master_tab+ecx*4]
601
        test    edx, PG_MAP
602
        jz      .fail             ;òàáëèöà ñòðàíèö íå ñîçäàíà
603
                                  ;íåâåðíûé àäðåñ â ïðîãðàììå
172 serge 604
 
1056 Galkov 605
        mov     eax, [page_tabs+ebx*4]
606
        test    eax, 2
607
        jz      .fail             ;àäðåñ íå çàðåçåðâèðîâàí äëÿ ;
608
                                  ;èñïîëüçîâàíèÿ. Îøèáêà
188 serge 609
.alloc:
1056 Galkov 610
        call    alloc_page
611
        test    eax, eax
612
        jz      .fail
164 serge 613
 
1056 Galkov 614
        stdcall map_page,[.err_addr],eax,dword PG_UW
164 serge 615
 
1056 Galkov 616
        mov     edi, [.err_addr]
617
        and     edi, 0xFFFFF000
618
        mov     ecx, 1024
619
        xor     eax, eax
620
       ;cld     ;caller is duty for this
621
        rep     stosd
622
.exit:  ;iret with repeat fault instruction
623
        add     esp,8 ; clear in stack: locals(.err_addr) + ret_to_caller
624
        restore_ring3_context
625
        iretd
465 serge 626
 
1056 Galkov 627
.err_access  =  .fail
465 serge 628
;íèêîãäà íå ïðîèñõîäèò
1056 Galkov 629
       ;jmp     .fail
465 serge 630
 
631
.kernel_space:
1056 Galkov 632
        test    eax, PG_MAP
633
        jz      .fail   ;ñòðàíèöà íå ïðèñóòñòâóåò
465 serge 634
 
1056 Galkov 635
        test    eax,12  ;U/S (+below)
636
        jnz     .fail   ;ïðèëîæåíèå îáðàòèëîñü ê ïàìÿòè
637
                        ;ÿäðà
638
       ;test    eax, 8
639
       ;jnz     .fail   ;óñòàíîâëåí çàðåçåðâèðîâàííûé áèò
640
                        ;â òàáëèöàõ ñòðàíèö. äîáàâëåíî â P4/Xeon
465 serge 641
 
642
;ïîïûòêà çàïèñè â çàùèù¸ííóþ ñòðàíèöó ÿäðà
643
 
1056 Galkov 644
        cmp     ebx, tss._io_map_0
645
        jb      .fail
465 serge 646
 
1056 Galkov 647
        cmp     ebx, tss._io_map_0+8192
648
        jae     .fail
465 serge 649
 
650
; io permission map
651
; copy-on-write protection
652
 
1056 Galkov 653
        call    alloc_page
654
        test    eax, eax
655
        jz      .fail
465 serge 656
 
1056 Galkov 657
        push    eax
658
        stdcall map_page,[.err_addr],eax,dword PG_SW
659
        pop     eax
660
        mov     edi, [.err_addr]
661
        and     edi, -4096
662
        lea     esi, [edi+(not tss._io_map_0)+1]; -tss._io_map_0
465 serge 663
 
1056 Galkov 664
        mov     ebx, esi
665
        shr     ebx, 12
666
        mov     edx, [current_slot]
667
        or      eax, PG_SW
668
        mov     [edx+APPDATA.io_map+ebx*4], eax
465 serge 669
 
1056 Galkov 670
        add     esi, [default_io_map]
671
        mov     ecx, 4096/4
672
       ;cld     ;caller is duty for this
673
        rep     movsd
674
        jmp     .exit
164 serge 675
endp
676
 
677
align 4
678
proc map_mem stdcall, lin_addr:dword,pdir:dword,\
679
                      ofs:dword,buf_size:dword
680
           mov eax, [buf_size]
681
           test eax, eax
682
           jz .exit
683
 
684
           mov eax, [pdir]
685
           and eax, 0xFFFFF000
686
 
536 diamond 687
           stdcall map_page,[ipc_pdir],eax,PG_UW
164 serge 688
           mov ebx, [ofs]
689
           shr ebx, 22
690
           mov esi, [ipc_pdir]
691
           mov edi, [ipc_ptab]
692
           mov eax, [esi+ebx*4]
693
           and eax, 0xFFFFF000
694
           jz .exit
536 diamond 695
           stdcall map_page,edi,eax,PG_UW
164 serge 696
;           inc ebx
697
;           add edi, 0x1000
698
;           mov eax, [esi+ebx*4]
699
;           test eax, eax
700
;           jz @f
701
;          and eax, 0xFFFFF000
702
;           stdcall map_page, edi, eax
703
 
704
@@:        mov edi, [lin_addr]
705
           and edi, 0xFFFFF000
706
           mov ecx, [buf_size]
707
           add ecx, 4095
708
           shr ecx, 12
709
           inc ecx
710
 
711
           mov edx, [ofs]
712
           shr edx, 12
713
           and edx, 0x3FF
714
           mov esi, [ipc_ptab]
715
 
716
.map:      mov eax, [esi+edx*4]
717
           and eax, 0xFFFFF000
536 diamond 718
           jz  .exit
719
           stdcall map_page,edi,eax,PG_UW
720
           dec ecx
721
           jz  .exit
164 serge 722
           add edi, 0x1000
723
           inc edx
536 diamond 724
           cmp edx, 0x400
164 serge 725
           jnz .map
536 diamond 726
           inc ebx
727
           mov eax, [ipc_pdir]
728
           mov eax, [eax+ebx*4]
729
           and eax, 0xFFFFF000
730
           jz  .exit
731
           stdcall map_page,esi,eax,PG_UW
732
           xor edx, edx
733
           jmp .map
164 serge 734
 
735
.exit:
736
           ret
737
endp
738
 
739
align 4
740
proc map_memEx stdcall, lin_addr:dword,pdir:dword,\
741
                        ofs:dword,buf_size:dword
742
           mov eax, [buf_size]
743
           test eax, eax
744
           jz .exit
745
 
746
           mov eax, [pdir]
747
           and eax, 0xFFFFF000
748
 
749
           stdcall map_page,[proc_mem_pdir],eax,dword PG_UW
750
           mov ebx, [ofs]
751
           shr ebx, 22
752
           mov esi, [proc_mem_pdir]
753
           mov edi, [proc_mem_tab]
754
           mov eax, [esi+ebx*4]
755
           and eax, 0xFFFFF000
756
           test eax, eax
757
           jz .exit
758
           stdcall map_page,edi,eax,dword PG_UW
759
 
760
@@:        mov edi, [lin_addr]
761
           and edi, 0xFFFFF000
762
           mov ecx, [buf_size]
763
           add ecx, 4095
764
           shr ecx, 12
765
           inc ecx
766
 
767
           mov edx, [ofs]
768
           shr edx, 12
769
           and edx, 0x3FF
770
           mov esi, [proc_mem_tab]
771
 
772
.map:      mov eax, [esi+edx*4]
773
;           and eax, 0xFFFFF000
774
;           test eax, eax
775
;           jz .exit
776
           stdcall map_page,edi,eax,dword PG_UW
777
           add edi, 0x1000
778
           inc edx
779
           dec ecx
780
           jnz .map
781
.exit:
782
           ret
783
endp
784
 
785
 
786
 
787
 
788
sys_IPC:
789
;input:
790
;  eax=1 - set ipc buffer area
791
;    ebx=address of buffer
792
;    ecx=size of buffer
793
;  eax=2 - send message
794
;    ebx=PID
795
;    ecx=address of message
796
;    edx=size of message
797
 
798
           cmp  eax,1
799
           jne @f
800
           call set_ipc_buff
801
           mov [esp+36], eax
802
           ret
803
@@:
804
           cmp eax, 2
805
           jne @f
806
           stdcall sys_ipc_send, ebx, ecx, edx
807
           mov [esp+36], eax
808
           ret
809
@@:
810
           xor eax, eax
811
           not eax
812
           mov [esp+36], eax
813
           ret
814
 
815
align 4
816
proc set_ipc_buff
817
 
465 serge 818
           mov  eax,[current_slot]
164 serge 819
           pushf
820
           cli
465 serge 821
           mov  [eax+APPDATA.ipc_start],ebx     ;set fields in extended information area
822
           mov  [eax+APPDATA.ipc_size],ecx
164 serge 823
 
824
           add ecx, ebx
825
           add ecx, 4095
826
           and ecx, not 4095
827
 
828
.touch:    mov eax, [ebx]
829
           add ebx, 0x1000
830
           cmp ebx, ecx
536 diamond 831
           jb  .touch
164 serge 832
 
833
           popf
834
           xor eax, eax
835
           ret
836
endp
837
 
838
proc sys_ipc_send stdcall, PID:dword, msg_addr:dword, msg_size:dword
839
           locals
840
             dst_slot   dd ?
841
             dst_offset dd ?
842
             buf_size   dd ?
536 diamond 843
             used_buf   dd ?
164 serge 844
           endl
845
 
846
           pushf
847
           cli
848
 
849
           mov  eax, [PID]
850
           call pid_to_slot
851
           test eax,eax
852
           jz   .no_pid
853
 
854
           mov [dst_slot], eax
855
           shl  eax,8
380 serge 856
           mov  edi,[eax+SLOT_BASE+0xa0]  ;is ipc area defined?
164 serge 857
           test edi,edi
858
           jz   .no_ipc_area
859
 
860
           mov ebx, edi
861
           and ebx, 0xFFF
862
           mov [dst_offset], ebx
863
 
380 serge 864
           mov esi, [eax+SLOT_BASE+0xa4]
164 serge 865
           mov [buf_size], esi
866
 
536 diamond 867
           mov ecx, [ipc_tmp]
868
           cmp esi, 0x40000-0x1000 ; size of [ipc_tmp] minus one page
869
           jbe @f
870
           push eax esi edi
871
           add esi,0x1000
872
           stdcall alloc_kernel_space,esi
873
           mov ecx, eax
874
           pop edi esi eax
875
@@:
876
           mov [used_buf], ecx
877
           stdcall map_mem, ecx, [SLOT_BASE+eax+0xB8],\
164 serge 878
                             edi, esi
879
 
880
           mov edi, [dst_offset]
536 diamond 881
           add edi, [used_buf]
164 serge 882
           cmp dword [edi], 0
883
           jnz  .ipc_blocked          ;if dword [buffer]<>0 - ipc blocked now
227 serge 884
 
566 serge 885
           mov edx, dword [edi+4]
886
           lea ebx, [edx+8]
164 serge 887
           add ebx, [msg_size]
888
           cmp ebx, [buf_size]
889
           ja .buffer_overflow         ;esi<0 - not enough memory in buffer
227 serge 890
 
164 serge 891
           mov dword [edi+4], ebx
892
           mov eax,[TASK_BASE]
893
           mov eax, [eax+0x04]         ;eax - our PID
894
           add edi, edx
895
           mov [edi], eax
896
           mov ecx, [msg_size]
897
 
898
           mov [edi+4], ecx
899
           add edi, 8
900
           mov esi, [msg_addr]
465 serge 901
       ;    add esi, new_app_base
164 serge 902
           cld
903
           rep movsb
904
 
905
           mov ebx, [ipc_tmp]
906
           mov edx, ebx
907
           shr ebx, 12
908
           xor eax, eax
365 serge 909
           mov [page_tabs+ebx*4], eax
164 serge 910
           invlpg [edx]
911
 
912
           mov ebx, [ipc_pdir]
913
           mov edx, ebx
914
           shr ebx, 12
915
           xor eax, eax
365 serge 916
           mov [page_tabs+ebx*4], eax
164 serge 917
           invlpg [edx]
918
 
919
           mov ebx, [ipc_ptab]
920
           mov edx, ebx
921
           shr ebx, 12
922
           xor eax, eax
365 serge 923
           mov [page_tabs+ebx*4], eax
164 serge 924
           invlpg [edx]
925
 
926
           mov  eax, [dst_slot]
927
           shl eax, 8
380 serge 928
           or   [eax+SLOT_BASE+0xA8],dword 0x40
164 serge 929
           cmp  dword [check_idle_semaphore],20
930
           jge  .ipc_no_cis
931
 
932
           mov  dword [check_idle_semaphore],5
933
.ipc_no_cis:
536 diamond 934
           push 0
935
           jmp .ret
164 serge 936
.no_pid:
937
           popf
536 diamond 938
           mov eax, 4
164 serge 939
           ret
940
.no_ipc_area:
941
           popf
942
           xor eax, eax
943
           inc eax
944
           ret
945
.ipc_blocked:
536 diamond 946
           push 2
947
           jmp .ret
164 serge 948
.buffer_overflow:
536 diamond 949
           push 3
950
.ret:
951
           mov eax, [used_buf]
952
           cmp eax, [ipc_tmp]
953
           jz @f
954
           stdcall free_kernel_space,eax
955
@@:
956
           pop eax
164 serge 957
           popf
958
           ret
959
endp
960
 
961
align 4
170 serge 962
sysfn_meminfo:
164 serge 963
 
1072 diamond 964
        ;   add ecx, new_app_base
965
           cmp ecx, OS_BASE
465 serge 966
           jae .fail
172 serge 967
 
164 serge 968
           mov eax, [pg_data.pages_count]
1072 diamond 969
           mov [ecx], eax
172 serge 970
           shl eax, 12
1072 diamond 971
           mov [esp+32], eax
972
           mov eax, [pg_data.pages_free]
973
           mov [ecx+4], eax
974
           mov eax, [pg_data.pages_faults]
975
           mov [ecx+8], eax
976
           mov eax, [heap_size]
977
           mov [ecx+12], eax
978
           mov eax, [heap_free]
979
           mov [ecx+16], eax
170 serge 980
           mov eax, [heap_blocks]
1072 diamond 981
           mov [ecx+20], eax
982
           mov eax, [free_blocks]
983
           mov [ecx+24], eax
164 serge 984
           ret
172 serge 985
.fail:
1072 diamond 986
           mov dword [esp+32], -1
172 serge 987
           ret
164 serge 988
 
989
align 4
940 serge 990
f68call:
991
           dd f68.11
992
           dd f68.12
993
           dd f68.13
994
           dd f68.14
1077 Galkov 995
           dd f68.fail ;moved to f68.24
940 serge 996
           dd f68.16
997
           dd f68.17
1077 Galkov 998
           dd f68.fail ;moved to f68.25
940 serge 999
           dd f68.19
1000
           dd f68.20
1001
           dd f68.21
1002
           dd f68.22
943 serge 1003
           dd f68.23
1077 Galkov 1004
           dd f68.24
1005
           dd f68.25
164 serge 1006
 
940 serge 1007
align 4
1008
f68:
164 serge 1009
           cmp  eax,4
1010
           jle  sys_sheduler
1011
 
170 serge 1012
           cmp eax, 11
164 serge 1013
           jb .fail
1014
 
1077 Galkov 1015
           cmp eax, 25
940 serge 1016
           ja .fail
1017
 
1018
           jmp dword [f68call+eax*4-11*4]
1019
.11:
188 serge 1020
           call init_heap
164 serge 1021
           mov [esp+36], eax
1022
           ret
940 serge 1023
.12:
164 serge 1024
           stdcall user_alloc, ebx
1025
           mov [esp+36], eax
1026
           ret
940 serge 1027
.13:
164 serge 1028
           stdcall user_free, ebx
1029
           mov [esp+36], eax
1030
           ret
940 serge 1031
.14:
465 serge 1032
           cmp ebx, OS_BASE
1033
           jae .fail
1055 Galkov 1034
           mov edi,ebx
1035
           call get_event_ex
227 serge 1036
           mov [esp+36], eax
164 serge 1037
           ret
1077 Galkov 1038
.24:
1074 Galkov 1039
           mov  eax, [current_slot]
1040
           xchg ebx, [eax+APPDATA.exc_handler]
1041
           xchg ecx, [eax+APPDATA.except_mask]
1042
           mov  [esp+36], ebx ; reg_eax+8
1043
           mov  [esp+24], ecx ; reg_ebx+8
164 serge 1044
           ret
940 serge 1045
.16:
188 serge 1046
           test ebx, ebx
1047
           jz .fail
465 serge 1048
           cmp ebx, OS_BASE
1049
           jae .fail
164 serge 1050
           stdcall get_service, ebx
1051
           mov [esp+36], eax
1052
           ret
940 serge 1053
.17:
378 serge 1054
           call srv_handlerEx   ;ebx
164 serge 1055
           mov [esp+36], eax
1056
           ret
1077 Galkov 1057
.25:
1081 diamond 1058
           cmp ebx,32
1059
           jae .fail
1074 Galkov 1060
           mov  eax, [current_slot]
1061
           btr  [eax+APPDATA.except_mask],ebx
1062
           setc byte[esp+36]
1063
           jecxz @f
1064
           bts  [eax+APPDATA.except_mask],ebx
1065
     @@:   ret
940 serge 1066
.19:
465 serge 1067
           cmp ebx, OS_BASE
1068
           jae .fail
198 serge 1069
           stdcall load_library, ebx
1070
           mov [esp+36], eax
1071
           ret
940 serge 1072
.20:
490 serge 1073
           mov     eax, ecx
1074
           call    user_realloc
1075
           mov     [esp+36], eax
1076
           ret
940 serge 1077
.21:
740 serge 1078
           cmp ebx, OS_BASE
1079
           jae .fail
1080
 
1081
           stdcall load_PE, ebx
1082
 
1083
           test eax, eax
1084
           jz @F
1085
 
1086
           mov esi, eax
1087
           stdcall eax, DRV_ENTRY
1088
 
1089
           test eax, eax
1090
           jz @F
1091
 
1092
           mov [eax+SRV.entry], esi
1093
 
1094
@@:
1095
           mov [esp+36], eax
1096
           ret
940 serge 1097
.22:
1098
           cmp ebx, OS_BASE
1099
           jae .fail
740 serge 1100
 
940 serge 1101
           stdcall shmem_open, ebx, ecx, edx
1102
           mov [esp+28], edx
1103
           mov [esp+36], eax
1104
           ret
740 serge 1105
 
943 serge 1106
.23:
1107
           cmp ebx, OS_BASE
1108
           jae .fail
1109
 
1110
           stdcall shmem_close, ebx
1111
           mov [esp+36], eax
1112
           ret
1113
 
164 serge 1114
.fail:
1115
           xor eax, eax
1116
           mov [esp+36], eax
1117
           ret
1118
 
1119
align 4
819 serge 1120
proc load_pe_driver stdcall, file:dword
1121
 
1122
           stdcall load_PE, [file]
1123
           test eax, eax
1124
           jz .fail
1125
 
1126
           mov esi, eax
1127
           stdcall eax, DRV_ENTRY
1128
           test eax, eax
1129
           jz .fail
1130
 
1131
           mov [eax+SRV.entry], esi
1132
           ret
1133
 
1134
.fail:
1135
           xor eax, eax
1136
           ret
1137
endp
1138
 
1139
 
1140
align 4
164 serge 1141
proc init_mtrr
1142
 
412 serge 1143
           cmp [BOOT_VAR+0x901c],byte 2
164 serge 1144
           je  .exit
1145
 
211 serge 1146
           bt [cpu_caps], CAPS_MTRR
1147
           jnc .exit
1148
 
164 serge 1149
           mov eax, cr0
1150
           or eax, 0x60000000   ;disable caching
1151
           mov cr0, eax
1152
           wbinvd               ;invalidate cache
1153
 
1154
           mov ecx, 0x2FF
1155
           rdmsr                ;
1030 diamond 1156
; has BIOS already initialized MTRRs?
1157
           test ah, 8
1158
           jnz .skip_init
1159
; rarely needed, so mainly placeholder
1160
; main memory - cached
164 serge 1161
           push eax
1162
 
821 diamond 1163
           mov eax, [MEM_AMOUNT]
1164
; round eax up to next power of 2
1165
           dec eax
1166
           bsr ecx, eax
1030 diamond 1167
           mov ebx, 2
1168
           shl ebx, cl
1169
           dec ebx
1170
; base of memory range = 0, type of memory range = MEM_WB
164 serge 1171
           xor edx, edx
1030 diamond 1172
           mov eax, MEM_WB
1173
           mov ecx, 0x200
1174
           wrmsr
1175
; mask of memory range = 0xFFFFFFFFF - (size - 1), ebx = size - 1
1176
           mov eax, 0xFFFFFFFF
1177
           mov edx, 0x0000000F
1178
           sub eax, ebx
1179
           sbb edx, 0
1180
           or eax, 0x800
1181
           inc ecx
1182
           wrmsr
1183
; clear unused MTRRs
164 serge 1184
           xor eax, eax
1030 diamond 1185
           xor edx, edx
164 serge 1186
@@:
1030 diamond 1187
           wrmsr
164 serge 1188
           inc ecx
1030 diamond 1189
           cmp ecx, 0x210
1190
           jb @b
1191
; enable MTRRs
1192
           pop eax
1193
           or ah, 8
1194
           and al, 0xF0 ; default memtype = UC
1195
           mov ecx, 0x2FF
164 serge 1196
           wrmsr
1030 diamond 1197
.skip_init:
1198
           stdcall set_mtrr, [LFBAddress],[LFBSize],MEM_WC
164 serge 1199
 
1200
           wbinvd               ;again invalidate
1201
 
1202
           mov eax, cr0
1203
           and eax, not 0x60000000
1204
           mov cr0, eax         ; enable caching
1205
.exit:
1206
           ret
1207
endp
1208
 
1209
align 4
1030 diamond 1210
proc set_mtrr stdcall, base:dword,size:dword,mem_type:dword
1211
; find unused register
1212
           mov ecx, 0x201
1213
@@:
1214
           rdmsr
1215
           dec ecx
1216
           test ah, 8
1217
           jz .found
1218
           rdmsr
1219
           mov al, 0 ; clear memory type field
1220
           cmp eax, [base]
1221
           jz .ret
1222
           add ecx, 3
1223
           cmp ecx, 0x210
1224
           jb @b
1225
; no free registers, ignore the call
1226
.ret:
1227
           ret
1228
.found:
1229
; found, write values
164 serge 1230
           xor edx, edx
1231
           mov eax, [base]
1232
           or eax, [mem_type]
1233
           wrmsr
1234
 
1235
           mov ebx, [size]
1236
           dec ebx
1237
           mov eax, 0xFFFFFFFF
1238
           mov edx, 0x0000000F
1239
           sub eax, ebx
1240
           sbb edx, 0
1241
           or eax, 0x800
1242
           inc ecx
1243
           wrmsr
1244
           ret
1245
endp
1246
 
465 serge 1247
align 4
172 serge 1248
proc stall stdcall, delay:dword
1249
           push ecx
1250
           push edx
1251
           push ebx
1252
           push eax
1253
 
1254
           mov eax, [delay]
1255
           mul [stall_mcs]
1256
           mov ebx, eax       ;low
1257
           mov ecx, edx       ;high
1258
           rdtsc
1259
           add ebx, eax
1260
           adc ecx,edx
1261
@@:
1262
           rdtsc
1263
           sub eax, ebx
1264
           sbb edx, ecx
1265
           jb @B
1266
 
1267
           pop eax
1268
           pop ebx
1269
           pop edx
1270
           pop ecx
1271
           ret
1272
endp
1273
 
520 serge 1274
align 4
1275
proc create_ring_buffer stdcall, size:dword, flags:dword
1276
           locals
1277
             buf_ptr  dd ?
1278
           endl
237 serge 1279
 
520 serge 1280
           mov eax, [size]
1281
           test eax, eax
1282
           jz .fail
1283
 
1284
           add eax, eax
1285
           stdcall alloc_kernel_space, eax
1286
           test eax, eax
1287
           jz .fail
1288
 
662 serge 1289
           push ebx
1290
 
520 serge 1291
           mov [buf_ptr], eax
1292
 
1293
           mov ebx, [size]
1294
           shr ebx, 12
1295
           push ebx
1296
 
1297
           stdcall alloc_pages, ebx
1298
           pop ecx
1299
 
1300
           test eax, eax
1301
           jz .mm_fail
1302
 
662 serge 1303
           push edi
1304
 
520 serge 1305
           or eax, [flags]
1306
           mov edi, [buf_ptr]
1307
           mov ebx, [buf_ptr]
1308
           mov edx, ecx
566 serge 1309
           shl edx, 2
520 serge 1310
           shr edi, 10
1311
@@:
1312
           mov [page_tabs+edi], eax
1313
           mov [page_tabs+edi+edx], eax
924 serge 1314
           invlpg [ebx]
1315
           invlpg [ebx+0x10000]
520 serge 1316
           add eax, 0x1000
1317
           add ebx, 0x1000
566 serge 1318
           add edi, 4
520 serge 1319
           dec ecx
1320
           jnz @B
1321
 
1322
           mov eax, [buf_ptr]
662 serge 1323
           pop edi
1324
           pop ebx
520 serge 1325
           ret
1326
.mm_fail:
1327
           stdcall free_kernel_space, [buf_ptr]
1328
           xor eax, eax
662 serge 1329
           pop ebx
520 serge 1330
.fail:
1331
           ret
1332
endp