Subversion Repositories Kolibri OS

Rev

Rev 839 | Rev 841 | 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: 840 $
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
839 serge 324
           stdcall alloc_pages, 0x280000 shr 12
325
           add eax, OS_BASE
164 serge 326
           mov [LFBAddress], eax
327
           ret
328
@@:
329
           test [SCR_MODE],word 0100000000000000b
211 serge 330
           jnz @f
412 serge 331
           mov [BOOT_VAR+0x901c],byte 2
211 serge 332
           ret
333
@@:
490 serge 334
           call init_mtrr
335
 
839 serge 336
           mov eax, [LFBAddress]
337
           or eax, PG_LARGE+PG_UW
338
           mov [sys_pgdir+(LFB_BASE shr 20)], eax
339
           add eax, 0x00400000
340
           mov [sys_pgdir+4+(LFB_BASE shr 20)], eax
164 serge 341
 
839 serge 342
           mov dword [exp_lfb+4], LFB_BASE
164 serge 343
 
207 serge 344
           bt [cpu_caps], CAPS_PGE
345
           jnc @F
465 serge 346
           or dword [sys_pgdir+(LFB_BASE shr 20)], PG_GLOBAL
207 serge 347
@@:
378 serge 348
           mov dword [LFBAddress], LFB_BASE
164 serge 349
           mov eax, cr3       ;flush TLB
350
           mov cr3, eax
351
 
352
           ret
353
endp
354
 
355
align 4
356
proc new_mem_resize stdcall, new_size:dword
357
 
276 serge 358
           mov ebx, pg_data.pg_mutex
359
           call wait_mutex    ;ebx
164 serge 360
 
361
           mov edi, [new_size]
362
           add edi,4095
363
           and edi,not 4095
364
           mov [new_size], edi
365
 
465 serge 366
           mov edx,[current_slot]
367
           cmp [edx+APPDATA.heap_base],0
172 serge 368
           jne .exit
369
 
465 serge 370
           mov esi, [edx+APPDATA.mem_size]
164 serge 371
           add esi, 4095
372
           and esi, not 4095
373
 
374
           cmp edi, esi
375
           jae .expand
376
 
377
           shr edi, 12
378
           shr esi, 12
379
@@:
378 serge 380
           mov eax, [app_page_tabs+edi*4]
164 serge 381
           test eax, 1
382
           jz .next
378 serge 383
           mov dword [app_page_tabs+edi*4], 2
164 serge 384
           mov ebx, edi
385
           shl ebx, 12
837 serge 386
           push eax
659 serge 387
           invlpg [ebx]
837 serge 388
           pop eax
164 serge 389
           call free_page
390
 
391
.next:     add edi, 1
392
           cmp edi, esi
393
           jb @B
394
 
395
.update_size:
465 serge 396
           mov     ebx, [new_size]
397
           call    update_mem_size
164 serge 398
 
399
           xor eax, eax
400
           dec [pg_data.pg_mutex]
401
           ret
402
.expand:
403
 
404
           push esi
405
           push edi
406
 
407
           add edi, 0x3FFFFF
408
           and edi, not(0x3FFFFF)
409
           add esi, 0x3FFFFF
410
           and esi, not(0x3FFFFF)
411
 
412
           cmp esi, edi
413
           jae .grow
414
 
415
           xchg esi, edi
416
 
417
@@:
418
           call alloc_page
419
           test eax, eax
420
           jz .exit
421
 
188 serge 422
           stdcall map_page_table, edi, eax
164 serge 423
 
424
           push edi
425
           shr edi, 10
365 serge 426
           add edi, page_tabs
164 serge 427
           mov ecx, 1024
428
           xor eax, eax
429
           cld
430
           rep stosd
431
           pop edi
432
 
433
           add edi, 0x00400000
434
           cmp edi, esi
435
           jb @B
436
.grow:
437
           pop edi
438
           pop esi
439
@@:
440
           call alloc_page
441
           test eax, eax
442
           jz .exit
443
           stdcall map_page,esi,eax,dword PG_UW
444
 
445
           push edi
446
           mov edi, esi
447
           xor eax, eax
448
           mov ecx, 1024
449
           cld
450
           rep stosd
451
           pop edi
452
 
453
           add esi, 0x1000
454
           cmp esi, edi
294 diamond 455
           jb  @B
164 serge 456
 
457
           jmp .update_size
458
.exit:
459
           xor eax, eax
460
           inc eax
461
           dec [pg_data.pg_mutex]
462
           ret
463
endp
464
 
294 diamond 465
update_mem_size:
465 serge 466
; in: edx = slot base
294 diamond 467
;     ebx = new memory size
468
; destroys eax,ecx,edx
469
 
465 serge 470
           mov    [APPDATA.mem_size+edx],ebx
294 diamond 471
;search threads and update
472
;application memory size infomation
465 serge 473
           mov    ecx,[APPDATA.dir_table+edx]
294 diamond 474
           mov    eax,2
475
 
476
.search_threads:
477
;eax = current slot
478
;ebx = new memory size
479
;ecx = page directory
480
           cmp    eax,[TASK_COUNT]
481
           jg     .search_threads_end
482
           mov    edx,eax
483
           shl    edx,5
484
           cmp    word [CURRENT_TASK+edx+TASKDATA.state],9 ;if slot empty?
485
           jz     .search_threads_next
486
           shl    edx,3
380 serge 487
           cmp    [SLOT_BASE+edx+APPDATA.dir_table],ecx     ;if it is our thread?
294 diamond 488
           jnz    .search_threads_next
380 serge 489
           mov    [SLOT_BASE+edx+APPDATA.mem_size],ebx     ;update memory size
294 diamond 490
.search_threads_next:
491
           inc    eax
492
           jmp    .search_threads
493
.search_threads_end:
494
           ret
495
 
285 serge 496
; param
497
;  eax= linear address
498
;
499
; retval
500
;  eax= phisical page address
501
 
164 serge 502
align 4
285 serge 503
get_pg_addr:
504
           shr eax, 12
365 serge 505
           mov eax, [page_tabs+eax*4]
164 serge 506
           and eax, 0xFFFFF000
507
           ret
508
 
465 serge 509
 
188 serge 510
align 4
164 serge 511
proc page_fault_handler
465 serge 512
 
709 diamond 513
        test    byte [esp+12+2], 2
514
        jnz     v86_page_fault
515
 
465 serge 516
        .err_code equ ebp+32
517
        .err_addr equ ebp-4
518
 
164 serge 519
           pushad
520
           mov ebp, esp
521
           mov eax, cr2
172 serge 522
           push eax
164 serge 523
 
465 serge 524
           mov ax, app_data
164 serge 525
           mov ds, ax
188 serge 526
           mov es, ax
164 serge 527
 
188 serge 528
           inc [pg_data.pages_faults]
529
 
465 serge 530
           mov ebx, [.err_addr]
531
           mov eax, [.err_code]
164 serge 532
 
839 serge 533
     ;      xchg bx, bx
534
 
535
           cmp ebx, HEAP_BASE
465 serge 536
           jb .user_space      ;ñòðàíèöà â ïàìÿòè ïðèëîæåíèÿ ;
188 serge 537
 
839 serge 538
           cmp ebx, LFB_BASE
539
           jb  .kernel_heap
540
 
378 serge 541
           cmp ebx, page_tabs
839 serge 542
           jb .lfb
164 serge 543
 
839 serge 544
           cmp ebx, OS_BASE
545
           jb .core_tabs
546
 
547
           jmp .core_tabs
548
 
549
         ;  cmp ebx, kernel_tabs
550
         ;  jb .alloc;.app_tabs ;òàáëèöû ñòðàíèö ïðèëîæåíèÿ ;
465 serge 551
                               ;ïðîñòî ñîçäàäèì îäíó
378 serge 552
 
465 serge 553
.lfb:
839 serge 554
           shr ebx, 22
555
           mov edx, [sys_pgdir + ebx*4]
556
           mov [master_tab + ebx*4], edx
557
           jmp .exit
164 serge 558
 
839 serge 559
.core_tabs:
560
 
561
           shr ebx, 12
562
           and ebx, 0x3FF
563
           mov edx, [master_tab + ebx*4]
564
           test edx, PG_MAP
565
           jz .check_ptab      ;òàáëèöà ñòðàíèö íå ñîçäàíà
566
 
465 serge 567
align 4
839 serge 568
.kernel_heap:
569
 
570
           shr ebx, 22
571
           mov edx, [master_tab + ebx*4]
572
           test edx, PG_MAP
573
           jz .check_ptab      ;òàáëèöà ñòðàíèö íå ñîçäàíà
574
 
575
.check_ptab:
576
           mov edx, [sys_pgdir + ebx*4]
577
           test edx, PG_MAP
578
           jnz @F
579
 
580
           call alloc_page
581
           test eax, eax
582
           jz .fail
583
 
584
           lea edx, [eax + PG_UW]
585
           lea edi, [eax + OS_BASE]
586
           mov ecx, 1024
587
           xor eax, eax
588
           cld
589
           rep stosd
590
 
591
           mov [sys_pgdir + ebx*4], edx
592
@@:
593
           mov [master_tab + ebx*4], edx
594
           jmp .exit
595
 
596
align 4
164 serge 597
.user_space:
465 serge 598
           test eax, PG_MAP
599
           jnz .err_access     ;Ñòðàíèöà ïðèñóòñòâóåò
600
                               ;Îøèáêà äîñòóïà ?
601
 
164 serge 602
           shr ebx, 12
172 serge 603
           mov ecx, ebx
604
           shr ecx, 10
839 serge 605
           mov edx, [master_tab + ecx*4]
465 serge 606
           test edx, PG_MAP
607
           jz .fail            ;òàáëèöà ñòðàíèö íå ñîçäàíà
608
                               ;íåâåðíûé àäðåñ â ïðîãðàììå
172 serge 609
 
365 serge 610
           mov eax, [page_tabs+ebx*4]
164 serge 611
           test eax, 2
465 serge 612
           jz .fail            ;àäðåñ íå çàðåçåðâèðîâàí äëÿ ;
613
                               ;èñïîëüçîâàíèÿ. Îøèáêà
188 serge 614
.alloc:
164 serge 615
           call alloc_page
566 serge 616
           test eax, eax
465 serge 617
           jz .fail
164 serge 618
 
619
           stdcall map_page,[ebp-4],eax,dword PG_UW
620
 
188 serge 621
           mov edi, [ebp-4]
622
           and edi, 0xFFFFF000
164 serge 623
           mov ecx, 1024
624
           xor eax, eax
188 serge 625
           cld
626
           rep stosd
164 serge 627
.exit:
628
           mov esp, ebp
629
           popad
630
           add esp, 4
631
           iretd
465 serge 632
 
633
.err_access:
634
;íèêîãäà íå ïðîèñõîäèò
635
           jmp .fail
636
 
637
.kernel_space:
638
           test eax, PG_MAP
639
           jz .fail        ;ñòðàíèöà íå ïðèñóòñòâóåò
640
 
641
           test eax, 4     ;U/S
642
           jnz .fail       ;ïðèëîæåíèå îáðàòèëîñü ê ïàìÿòè
643
                           ;ÿäðà
644
           test eax, 8
645
           jnz .fail       ;óñòàíîâëåí çàðåçåðâèðîâàííûé áèò
646
                           ;â òàáëèöàõ ñòðàíèö. äîáàâëåíî â P4/Xeon
647
 
648
;ïîïûòêà çàïèñè â çàùèù¸ííóþ ñòðàíèöó ÿäðà
649
 
650
           cmp ebx, tss._io_map_0
651
           jb .fail
652
 
653
           cmp ebx, tss._io_map_0+8192
654
           jae .fail
655
 
656
; io permission map
657
; copy-on-write protection
658
 
659
           call alloc_page
566 serge 660
           test eax, eax
465 serge 661
           jz .fail
662
 
663
           push eax
664
           stdcall map_page,[ebp-4],eax,dword PG_SW
665
           pop eax
666
           mov edi, [.err_addr]
667
           and edi, -4096
668
           lea esi, [edi+(not tss._io_map_0)+1]; -tss._io_map_0
669
 
670
           mov ebx, esi
671
           shr ebx, 12
672
           mov edx, [current_slot]
673
           or eax, PG_SW
674
           mov [edx+APPDATA.io_map+ebx*4], eax
675
 
676
           add esi, [default_io_map]
677
           mov ecx, 4096/4
678
           cld
679
           rep movsd
680
           jmp .exit
681
 
682
 
683
;íå îáðàáàòûâàåì. Îøèáêà
684
 
172 serge 685
.fail:
686
           mov esp, ebp
687
           popad
688
           add esp, 4
164 serge 689
 
465 serge 690
;           iretd
691
 
172 serge 692
           save_ring3_context     ;debugger support
693
 
694
           mov bl, 14
695
           jmp exc_c
696
           iretd
164 serge 697
endp
698
 
699
align 4
700
proc map_mem stdcall, lin_addr:dword,pdir:dword,\
701
                      ofs:dword,buf_size:dword
702
           mov eax, [buf_size]
703
           test eax, eax
704
           jz .exit
705
 
706
           mov eax, [pdir]
707
           and eax, 0xFFFFF000
708
 
536 diamond 709
           stdcall map_page,[ipc_pdir],eax,PG_UW
164 serge 710
           mov ebx, [ofs]
711
           shr ebx, 22
712
           mov esi, [ipc_pdir]
713
           mov edi, [ipc_ptab]
714
           mov eax, [esi+ebx*4]
715
           and eax, 0xFFFFF000
716
           jz .exit
536 diamond 717
           stdcall map_page,edi,eax,PG_UW
164 serge 718
;           inc ebx
719
;           add edi, 0x1000
720
;           mov eax, [esi+ebx*4]
721
;           test eax, eax
722
;           jz @f
723
;          and eax, 0xFFFFF000
724
;           stdcall map_page, edi, eax
725
 
726
@@:        mov edi, [lin_addr]
727
           and edi, 0xFFFFF000
728
           mov ecx, [buf_size]
729
           add ecx, 4095
730
           shr ecx, 12
731
           inc ecx
732
 
733
           mov edx, [ofs]
734
           shr edx, 12
735
           and edx, 0x3FF
736
           mov esi, [ipc_ptab]
737
 
738
.map:      mov eax, [esi+edx*4]
739
           and eax, 0xFFFFF000
536 diamond 740
           jz  .exit
741
           stdcall map_page,edi,eax,PG_UW
742
           dec ecx
743
           jz  .exit
164 serge 744
           add edi, 0x1000
745
           inc edx
536 diamond 746
           cmp edx, 0x400
164 serge 747
           jnz .map
536 diamond 748
           inc ebx
749
           mov eax, [ipc_pdir]
750
           mov eax, [eax+ebx*4]
751
           and eax, 0xFFFFF000
752
           jz  .exit
753
           stdcall map_page,esi,eax,PG_UW
754
           xor edx, edx
755
           jmp .map
164 serge 756
 
757
.exit:
758
           ret
759
endp
760
 
761
align 4
762
proc map_memEx stdcall, lin_addr:dword,pdir:dword,\
763
                        ofs:dword,buf_size:dword
764
           mov eax, [buf_size]
765
           test eax, eax
766
           jz .exit
767
 
768
           mov eax, [pdir]
769
           and eax, 0xFFFFF000
770
 
771
           stdcall map_page,[proc_mem_pdir],eax,dword PG_UW
772
           mov ebx, [ofs]
773
           shr ebx, 22
774
           mov esi, [proc_mem_pdir]
775
           mov edi, [proc_mem_tab]
776
           mov eax, [esi+ebx*4]
777
           and eax, 0xFFFFF000
778
           test eax, eax
779
           jz .exit
780
           stdcall map_page,edi,eax,dword PG_UW
781
 
782
@@:        mov edi, [lin_addr]
783
           and edi, 0xFFFFF000
784
           mov ecx, [buf_size]
785
           add ecx, 4095
786
           shr ecx, 12
787
           inc ecx
788
 
789
           mov edx, [ofs]
790
           shr edx, 12
791
           and edx, 0x3FF
792
           mov esi, [proc_mem_tab]
793
 
794
.map:      mov eax, [esi+edx*4]
795
;           and eax, 0xFFFFF000
796
;           test eax, eax
797
;           jz .exit
798
           stdcall map_page,edi,eax,dword PG_UW
799
           add edi, 0x1000
800
           inc edx
801
           dec ecx
802
           jnz .map
803
.exit:
804
           ret
805
endp
806
 
807
 
808
 
809
 
810
sys_IPC:
811
;input:
812
;  eax=1 - set ipc buffer area
813
;    ebx=address of buffer
814
;    ecx=size of buffer
815
;  eax=2 - send message
816
;    ebx=PID
817
;    ecx=address of message
818
;    edx=size of message
819
 
820
           cmp  eax,1
821
           jne @f
822
           call set_ipc_buff
823
           mov [esp+36], eax
824
           ret
825
@@:
826
           cmp eax, 2
827
           jne @f
828
           stdcall sys_ipc_send, ebx, ecx, edx
829
           mov [esp+36], eax
830
           ret
831
@@:
832
           xor eax, eax
833
           not eax
834
           mov [esp+36], eax
835
           ret
836
 
837
align 4
838
proc set_ipc_buff
839
 
465 serge 840
           mov  eax,[current_slot]
164 serge 841
           pushf
842
           cli
465 serge 843
           mov  [eax+APPDATA.ipc_start],ebx     ;set fields in extended information area
844
           mov  [eax+APPDATA.ipc_size],ecx
164 serge 845
 
846
           add ecx, ebx
847
           add ecx, 4095
848
           and ecx, not 4095
849
 
850
.touch:    mov eax, [ebx]
851
           add ebx, 0x1000
852
           cmp ebx, ecx
536 diamond 853
           jb  .touch
164 serge 854
 
855
           popf
856
           xor eax, eax
857
           ret
858
endp
859
 
860
proc sys_ipc_send stdcall, PID:dword, msg_addr:dword, msg_size:dword
861
           locals
862
             dst_slot   dd ?
863
             dst_offset dd ?
864
             buf_size   dd ?
536 diamond 865
             used_buf   dd ?
164 serge 866
           endl
867
 
868
           pushf
869
           cli
870
 
871
           mov  eax, [PID]
872
           call pid_to_slot
873
           test eax,eax
874
           jz   .no_pid
875
 
876
           mov [dst_slot], eax
877
           shl  eax,8
380 serge 878
           mov  edi,[eax+SLOT_BASE+0xa0]  ;is ipc area defined?
164 serge 879
           test edi,edi
880
           jz   .no_ipc_area
881
 
882
           mov ebx, edi
883
           and ebx, 0xFFF
884
           mov [dst_offset], ebx
885
 
380 serge 886
           mov esi, [eax+SLOT_BASE+0xa4]
164 serge 887
           mov [buf_size], esi
888
 
536 diamond 889
           mov ecx, [ipc_tmp]
890
           cmp esi, 0x40000-0x1000 ; size of [ipc_tmp] minus one page
891
           jbe @f
892
           push eax esi edi
893
           add esi,0x1000
894
           stdcall alloc_kernel_space,esi
895
           mov ecx, eax
896
           pop edi esi eax
897
@@:
898
           mov [used_buf], ecx
899
           stdcall map_mem, ecx, [SLOT_BASE+eax+0xB8],\
164 serge 900
                             edi, esi
901
 
902
           mov edi, [dst_offset]
536 diamond 903
           add edi, [used_buf]
164 serge 904
           cmp dword [edi], 0
905
           jnz  .ipc_blocked          ;if dword [buffer]<>0 - ipc blocked now
227 serge 906
 
566 serge 907
           mov edx, dword [edi+4]
908
           lea ebx, [edx+8]
164 serge 909
           add ebx, [msg_size]
910
           cmp ebx, [buf_size]
911
           ja .buffer_overflow         ;esi<0 - not enough memory in buffer
227 serge 912
 
164 serge 913
           mov dword [edi+4], ebx
914
           mov eax,[TASK_BASE]
915
           mov eax, [eax+0x04]         ;eax - our PID
916
           add edi, edx
917
           mov [edi], eax
918
           mov ecx, [msg_size]
919
 
920
           mov [edi+4], ecx
921
           add edi, 8
922
           mov esi, [msg_addr]
465 serge 923
       ;    add esi, new_app_base
164 serge 924
           cld
925
           rep movsb
926
 
927
           mov ebx, [ipc_tmp]
928
           mov edx, ebx
929
           shr ebx, 12
930
           xor eax, eax
365 serge 931
           mov [page_tabs+ebx*4], eax
164 serge 932
           invlpg [edx]
933
 
934
           mov ebx, [ipc_pdir]
935
           mov edx, ebx
936
           shr ebx, 12
937
           xor eax, eax
365 serge 938
           mov [page_tabs+ebx*4], eax
164 serge 939
           invlpg [edx]
940
 
941
           mov ebx, [ipc_ptab]
942
           mov edx, ebx
943
           shr ebx, 12
944
           xor eax, eax
365 serge 945
           mov [page_tabs+ebx*4], eax
164 serge 946
           invlpg [edx]
947
 
948
           mov  eax, [dst_slot]
949
           shl eax, 8
380 serge 950
           or   [eax+SLOT_BASE+0xA8],dword 0x40
164 serge 951
           cmp  dword [check_idle_semaphore],20
952
           jge  .ipc_no_cis
953
 
954
           mov  dword [check_idle_semaphore],5
955
.ipc_no_cis:
536 diamond 956
           push 0
957
           jmp .ret
164 serge 958
.no_pid:
959
           popf
536 diamond 960
           mov eax, 4
164 serge 961
           ret
962
.no_ipc_area:
963
           popf
964
           xor eax, eax
965
           inc eax
966
           ret
967
.ipc_blocked:
536 diamond 968
           push 2
969
           jmp .ret
164 serge 970
.buffer_overflow:
536 diamond 971
           push 3
972
.ret:
973
           mov eax, [used_buf]
974
           cmp eax, [ipc_tmp]
975
           jz @f
976
           stdcall free_kernel_space,eax
977
@@:
978
           pop eax
164 serge 979
           popf
980
           ret
981
endp
982
 
983
align 4
170 serge 984
sysfn_meminfo:
164 serge 985
 
465 serge 986
        ;   add ebx, new_app_base
987
           cmp ebx, OS_BASE
988
           jae .fail
172 serge 989
 
164 serge 990
           mov eax, [pg_data.pages_count]
170 serge 991
           mov [ebx], eax
172 serge 992
           shl eax, 12
993
           mov [esp+36], eax
170 serge 994
           mov ecx, [pg_data.pages_free]
995
           mov [ebx+4], ecx
996
           mov edx, [pg_data.pages_faults]
997
           mov [ebx+8], edx
998
           mov esi, [heap_size]
999
           mov [ebx+12], esi
1000
           mov edi, [heap_free]
1001
           mov [ebx+16], edi
1002
           mov eax, [heap_blocks]
1003
           mov [ebx+20], eax
1004
           mov ecx, [free_blocks]
1005
           mov [ebx+24], ecx
164 serge 1006
           ret
172 serge 1007
.fail:
1008
           mov dword [esp+36], -1
1009
           ret
164 serge 1010
 
1011
align 4
1012
new_services:
1013
 
1014
           cmp  eax,4
1015
           jle  sys_sheduler
1016
 
170 serge 1017
           cmp eax, 11
164 serge 1018
           jb .fail
1019
           ja @f
1020
 
188 serge 1021
           call init_heap
164 serge 1022
           mov [esp+36], eax
1023
           ret
1024
@@:
1025
           cmp eax, 12
1026
           ja @f
1027
 
1028
           stdcall user_alloc, ebx
1029
           mov [esp+36], eax
1030
           ret
1031
@@:
1032
           cmp eax, 13
1033
           ja @f
1034
           stdcall user_free, ebx
1035
           mov [esp+36], eax
1036
           ret
1037
@@:
1038
           cmp eax, 14
1039
           ja @f
465 serge 1040
           cmp ebx, OS_BASE
1041
           jae .fail
227 serge 1042
           stdcall get_event_ex, ebx, ecx
1043
           mov [esp+36], eax
164 serge 1044
           ret
1045
@@:
1046
           cmp eax, 15
1047
           ja @f
465 serge 1048
           mov ecx, [current_slot]
1049
           mov eax, [ecx+APPDATA.fpu_handler]
1050
           mov [ecx+APPDATA.fpu_handler], ebx
164 serge 1051
           mov [esp+36], eax
1052
           ret
1053
@@:
1054
           cmp eax, 16
1055
           ja @f
1056
 
188 serge 1057
           test ebx, ebx
1058
           jz .fail
465 serge 1059
           cmp ebx, OS_BASE
1060
           jae .fail
164 serge 1061
           stdcall get_service, ebx
1062
           mov [esp+36], eax
1063
           ret
1064
@@:
1065
           cmp eax, 17
1066
           ja @f
378 serge 1067
           call srv_handlerEx   ;ebx
164 serge 1068
           mov [esp+36], eax
1069
           ret
168 serge 1070
@@:
1071
           cmp eax, 18
1072
           ja @f
465 serge 1073
           mov ecx, [current_slot]
1074
           mov eax, [ecx+APPDATA.sse_handler]
1075
           mov [ecx+APPDATA.sse_handler], ebx
168 serge 1076
           mov [esp+36], eax
1077
           ret
164 serge 1078
@@:
198 serge 1079
           cmp eax, 19
448 diamond 1080
           ja @f
465 serge 1081
           cmp ebx, OS_BASE
1082
           jae .fail
198 serge 1083
           stdcall load_library, ebx
1084
           mov [esp+36], eax
1085
           ret
448 diamond 1086
@@:
490 serge 1087
           cmp     eax, 20
740 serge 1088
           ja      @F
490 serge 1089
           mov     eax, ecx
1090
           call    user_realloc
1091
           mov     [esp+36], eax
1092
           ret
740 serge 1093
@@:
747 serge 1094
           cmp eax, 21                     ;for test purposes only
1095
           ja @f                           ;will be removed soon
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
1115
 
1116
 
164 serge 1117
.fail:
1118
           xor eax, eax
1119
           mov [esp+36], eax
1120
           ret
1121
 
1122
align 4
819 serge 1123
proc load_pe_driver stdcall, file:dword
1124
 
1125
           stdcall load_PE, [file]
1126
           test eax, eax
1127
           jz .fail
1128
 
1129
           mov esi, eax
1130
           stdcall eax, DRV_ENTRY
1131
           test eax, eax
1132
           jz .fail
1133
 
1134
           mov [eax+SRV.entry], esi
1135
           ret
1136
 
1137
.fail:
1138
           xor eax, eax
1139
           ret
1140
endp
1141
 
1142
 
1143
align 4
164 serge 1144
proc init_mtrr
1145
 
412 serge 1146
           cmp [BOOT_VAR+0x901c],byte 2
164 serge 1147
           je  .exit
1148
 
211 serge 1149
           bt [cpu_caps], CAPS_MTRR
1150
           jnc .exit
1151
 
164 serge 1152
           mov eax, cr0
1153
           or eax, 0x60000000   ;disable caching
1154
           mov cr0, eax
1155
           wbinvd               ;invalidate cache
1156
 
1157
           mov ecx, 0x2FF
1158
           rdmsr                ;
1159
           push eax
1160
 
1161
           xor edx, edx
1162
           xor eax, eax
1163
           mov ecx, 0x2FF
1164
           wrmsr                ;disable all MTRR
1165
 
821 diamond 1166
           mov eax, [MEM_AMOUNT]
1167
; round eax up to next power of 2
1168
           dec eax
1169
           bsr ecx, eax
1170
           mov eax, 2
1171
           shl eax, cl
1172
           stdcall set_mtrr, edx,edx,eax,MEM_WB
1173
           stdcall set_mtrr, 1,[LFBAddress],[LFBSize],MEM_WC
164 serge 1174
           xor edx, edx
1175
           xor eax, eax
1176
           mov ecx, 0x204
1177
           mov ebx, 6
1178
@@:
1179
           wrmsr                ;disable unused MTRR
1180
           inc ecx
1181
           wrmsr
1182
           inc ecx
1183
           dec ebx
1184
           jnz @b
1185
 
1186
           wbinvd               ;again invalidate
1187
 
1188
           pop eax
1189
           or eax, 0x800        ;set default memtype to UC
1190
           and al, 0xF0
1191
           mov ecx, 0x2FF
1192
           wrmsr                ;and enable MTRR
1193
 
1194
           mov eax, cr0
1195
           and eax, not 0x60000000
1196
           mov cr0, eax         ; enable caching
1197
.exit:
1198
           ret
1199
endp
1200
 
1201
align 4
1202
proc set_mtrr stdcall, reg:dword,base:dword,size:dword,mem_type:dword
1203
 
1204
           xor edx, edx
1205
           mov eax, [base]
1206
           or eax, [mem_type]
1207
           mov ecx, [reg]
1208
           lea ecx, [0x200+ecx*2]
1209
           wrmsr
1210
 
1211
           mov ebx, [size]
1212
           dec ebx
1213
           mov eax, 0xFFFFFFFF
1214
           mov edx, 0x0000000F
1215
           sub eax, ebx
1216
           sbb edx, 0
1217
           or eax, 0x800
1218
           inc ecx
1219
           wrmsr
1220
           ret
1221
endp
1222
 
465 serge 1223
align 4
172 serge 1224
proc stall stdcall, delay:dword
1225
           push ecx
1226
           push edx
1227
           push ebx
1228
           push eax
1229
 
1230
           mov eax, [delay]
1231
           mul [stall_mcs]
1232
           mov ebx, eax       ;low
1233
           mov ecx, edx       ;high
1234
           rdtsc
1235
           add ebx, eax
1236
           adc ecx,edx
1237
@@:
1238
           rdtsc
1239
           sub eax, ebx
1240
           sbb edx, ecx
1241
           jb @B
1242
 
1243
           pop eax
1244
           pop ebx
1245
           pop edx
1246
           pop ecx
1247
           ret
1248
endp
1249
 
520 serge 1250
align 4
1251
proc create_ring_buffer stdcall, size:dword, flags:dword
1252
           locals
1253
             buf_ptr  dd ?
1254
           endl
237 serge 1255
 
520 serge 1256
           mov eax, [size]
1257
           test eax, eax
1258
           jz .fail
1259
 
1260
           add eax, eax
1261
           stdcall alloc_kernel_space, eax
1262
           test eax, eax
1263
           jz .fail
1264
 
662 serge 1265
           push ebx
1266
 
520 serge 1267
           mov [buf_ptr], eax
1268
 
1269
           mov ebx, [size]
1270
           shr ebx, 12
1271
           push ebx
1272
 
1273
           stdcall alloc_pages, ebx
1274
           pop ecx
1275
 
1276
           test eax, eax
1277
           jz .mm_fail
1278
 
662 serge 1279
           push edi
1280
 
520 serge 1281
           or eax, [flags]
1282
           mov edi, [buf_ptr]
1283
           mov ebx, [buf_ptr]
1284
           mov edx, ecx
566 serge 1285
           shl edx, 2
520 serge 1286
           shr edi, 10
1287
@@:
1288
           mov [page_tabs+edi], eax
1289
           mov [page_tabs+edi+edx], eax
1290
           add eax, 0x1000
1291
           add ebx, 0x1000
566 serge 1292
           add edi, 4
520 serge 1293
           dec ecx
1294
           jnz @B
1295
 
1296
           mov eax, [buf_ptr]
662 serge 1297
           pop edi
1298
           pop ebx
520 serge 1299
           ret
1300
.mm_fail:
1301
           stdcall free_kernel_space, [buf_ptr]
1302
           xor eax, eax
662 serge 1303
           pop ebx
520 serge 1304
.fail:
1305
           ret
1306
endp
1307