Subversion Repositories Kolibri OS

Rev

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

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