Subversion Repositories Kolibri OS

Rev

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