Subversion Repositories Kolibri OS

Rev

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

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