Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
431 serge 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
2465 Serge 3
;; Copyright (C) KolibriOS team 2004-2012. All rights reserved. ;;
431 serge 4
;; Distributed under terms of the GNU General Public License    ;;
5
;;                                                              ;;
6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
164 serge 7
 
593 mikedld 8
$Revision: 4423 $
9
 
10
 
164 serge 11
align 4
12
proc alloc_page
13
 
2434 Serge 14
        pushfd
15
        cli
16
        push    ebx
1461 diamond 17
;//-
2434 Serge 18
        cmp     [pg_data.pages_free], 1
19
        jle     .out_of_memory
1461 diamond 20
;//-
21
 
2434 Serge 22
        mov     ebx, [page_start]
23
        mov     ecx, [page_end]
164 serge 24
.l1:
2434 Serge 25
        bsf     eax, [ebx];
26
        jnz     .found
27
        add     ebx, 4
28
        cmp     ebx, ecx
29
        jb      .l1
30
        pop     ebx
31
        popfd
32
        xor     eax, eax
33
        ret
164 serge 34
.found:
1629 serge 35
;//-
2434 Serge 36
        dec     [pg_data.pages_free]
37
        jz      .out_of_memory
1461 diamond 38
;//-
2434 Serge 39
        btr     [ebx], eax
40
        mov     [page_start], ebx
41
        sub     ebx, sys_pgmap
42
        lea     eax, [eax+ebx*8]
43
        shl     eax, 12
1461 diamond 44
;//-       dec [pg_data.pages_free]
2434 Serge 45
        pop     ebx
46
        popfd
47
        ret
1461 diamond 48
;//-
49
.out_of_memory:
2434 Serge 50
        mov     [pg_data.pages_free], 1
51
        xor     eax, eax
52
        pop     ebx
53
        popfd
54
        ret
1461 diamond 55
;//-
164 serge 56
endp
57
 
58
align 4
59
proc alloc_pages stdcall, count:dword
2434 Serge 60
        pushfd
61
        push    ebx
62
        push    edi
63
        cli
64
        mov     eax, [count]
65
        add     eax, 7
66
        shr     eax, 3
67
        mov     [count], eax
1461 diamond 68
;//-
2434 Serge 69
        mov     ebx, [pg_data.pages_free]
70
        sub     ebx, 9
71
        js      .out_of_memory
72
        shr     ebx, 3
73
        cmp     eax, ebx
74
        jg      .out_of_memory
1461 diamond 75
;//-
2434 Serge 76
        mov     ecx, [page_start]
77
        mov     ebx, [page_end]
164 serge 78
.find:
2434 Serge 79
        mov     edx, [count]
80
        mov     edi, ecx
164 serge 81
.match:
2434 Serge 82
        cmp     byte [ecx], 0xFF
83
        jne     .next
84
        dec     edx
85
        jz      .ok
86
        inc     ecx
87
        cmp     ecx, ebx
88
        jb      .match
1461 diamond 89
.out_of_memory:
660 serge 90
.fail:
2434 Serge 91
        xor     eax, eax
92
        pop     edi
93
        pop     ebx
94
        popfd
95
        ret
164 serge 96
.next:
2434 Serge 97
        inc     ecx
98
        cmp     ecx, ebx
99
        jb      .find
100
        pop     edi
101
        pop     ebx
102
        popfd
103
        xor     eax, eax
104
        ret
164 serge 105
.ok:
2434 Serge 106
        sub     ecx, edi
107
        inc     ecx
108
        push    esi
109
        mov     esi, edi
110
        xor     eax, eax
111
        rep stosb
112
        sub     esi, sys_pgmap
113
        shl     esi, 3+12
114
        mov     eax, esi
115
        mov     ebx, [count]
116
        shl     ebx, 3
117
        sub     [pg_data.pages_free], ebx
118
        pop     esi
119
        pop     edi
120
        pop     ebx
121
        popfd
122
        ret
164 serge 123
endp
124
 
125
align 4
126
proc map_page stdcall,lin_addr:dword,phis_addr:dword,flags:dword
2434 Serge 127
        push    ebx
128
        mov     eax, [phis_addr]
129
        and     eax, not 0xFFF
130
        or      eax, [flags]
131
        mov     ebx, [lin_addr]
132
        shr     ebx, 12
133
        mov     [page_tabs+ebx*4], eax
134
        mov     eax, [lin_addr]
135
        invlpg  [eax]
136
        pop     ebx
137
        ret
164 serge 138
endp
139
 
140
align 4
281 serge 141
map_space:    ;not implemented
142
 
143
 
2434 Serge 144
        ret
281 serge 145
 
146
 
147
align 4
164 serge 148
proc free_page
149
;arg:  eax  page address
2434 Serge 150
        pushfd
151
        cli
152
        shr     eax, 12                       ;page index
153
        bts     dword [sys_pgmap], eax        ;that's all!
154
        cmc
155
        adc     [pg_data.pages_free], 0
156
        shr     eax, 3
157
        and     eax, not 3                    ;dword offset from page_map
158
        add     eax, sys_pgmap
159
        cmp     [page_start], eax
160
        ja      @f
161
        popfd
162
        ret
164 serge 163
@@:
2434 Serge 164
        mov     [page_start], eax
165
        popfd
166
        ret
164 serge 167
endp
168
 
2434 Serge 169
align 4
741 serge 170
proc map_io_mem stdcall, base:dword, size:dword, flags:dword
171
 
2434 Serge 172
        push    ebx
173
        push    edi
174
        mov     eax, [size]
175
        add     eax, [base]
176
        add     eax, 4095
177
        and     eax, -4096
178
        mov     ecx, [base]
179
        and     ecx, -4096
180
        sub     eax, ecx
181
        mov     [size], eax
2217 Serge 182
 
2434 Serge 183
        stdcall alloc_kernel_space, eax
184
        test    eax, eax
185
        jz      .fail
186
        push    eax
741 serge 187
 
2434 Serge 188
        mov     edi, 0x1000
189
        mov     ebx, eax
190
        mov     ecx, [size]
191
        mov     edx, [base]
192
        shr     eax, 12
193
        shr     ecx, 12
194
        and     edx, -4096
195
        or      edx, [flags]
741 serge 196
@@:
2434 Serge 197
        mov     [page_tabs+eax*4], edx
198
        invlpg  [ebx]
199
        inc     eax
200
        add     ebx, edi
201
        add     edx, edi
202
        loop    @B
741 serge 203
 
2434 Serge 204
        pop     eax
205
        mov     edx, [base]
206
        and     edx, 4095
207
        add     eax, edx
741 serge 208
.fail:
2434 Serge 209
        pop     edi
210
        pop     ebx
211
        ret
741 serge 212
endp
213
 
279 serge 214
; param
328 serge 215
;  eax= page base + page flags
819 serge 216
;  ebx= linear address
281 serge 217
;  ecx= count
218
 
219
align 4
328 serge 220
commit_pages:
2434 Serge 221
        test    ecx, ecx
222
        jz      .fail
281 serge 223
 
2434 Serge 224
        push    edi
225
        push    eax
226
        push    ecx
227
        mov     ecx, pg_data.mutex
228
        call    mutex_lock
229
        pop     ecx
230
        pop     eax
2130 serge 231
 
2434 Serge 232
        mov     edi, ebx
233
        shr     edi, 12
234
        lea     edi, [page_tabs+edi*4]
2130 serge 235
@@:
2434 Serge 236
        stosd
237
        invlpg  [ebx]
238
        add     eax, 0x1000
239
        add     ebx, 0x1000
240
        loop    @B
328 serge 241
 
2434 Serge 242
        pop     edi
2130 serge 243
 
2434 Serge 244
        mov     ecx, pg_data.mutex
245
        call    mutex_unlock
328 serge 246
.fail:
2434 Serge 247
        ret
281 serge 248
 
328 serge 249
 
281 serge 250
; param
279 serge 251
;  eax= base
281 serge 252
;  ecx= count
279 serge 253
 
164 serge 254
align 4
279 serge 255
release_pages:
321 diamond 256
 
2434 Serge 257
        push    ebp
258
        push    esi
259
        push    edi
260
        push    ebx
279 serge 261
 
2434 Serge 262
        mov     esi, eax
263
        mov     edi, eax
279 serge 264
 
2434 Serge 265
        shr     esi, 12
266
        lea     esi, [page_tabs+esi*4]
328 serge 267
 
2434 Serge 268
        push    ecx
269
        mov     ecx, pg_data.mutex
270
        call    mutex_lock
271
        pop     ecx
2130 serge 272
 
2434 Serge 273
        mov     ebp, [pg_data.pages_free]
274
        mov     ebx, [page_start]
275
        mov     edx, sys_pgmap
279 serge 276
@@:
2434 Serge 277
        xor     eax, eax
278
        xchg    eax, [esi]
279
        invlpg  [edi]
279 serge 280
 
2434 Serge 281
        test    eax, 1
282
        jz      .next
279 serge 283
 
2434 Serge 284
        shr     eax, 12
285
        bts     [edx], eax
286
        cmc
287
        adc     ebp, 0
288
        shr     eax, 3
289
        and     eax, -4
290
        add     eax, edx
291
        cmp     eax, ebx
292
        jae     .next
279 serge 293
 
2434 Serge 294
        mov     ebx, eax
279 serge 295
.next:
2434 Serge 296
        add     edi, 0x1000
297
        add     esi, 4
298
        loop    @B
2130 serge 299
 
2434 Serge 300
        mov     [pg_data.pages_free], ebp
301
        mov     ecx, pg_data.mutex
302
        call    mutex_unlock
2130 serge 303
 
2434 Serge 304
        pop     ebx
305
        pop     edi
306
        pop     esi
307
        pop     ebp
308
        ret
279 serge 309
 
819 serge 310
; param
311
;  eax= base
312
;  ecx= count
313
 
279 serge 314
align 4
819 serge 315
unmap_pages:
316
 
2434 Serge 317
        push    edi
819 serge 318
 
2434 Serge 319
        mov     edi, eax
320
        mov     edx, eax
819 serge 321
 
2434 Serge 322
        shr     edi, 10
323
        add     edi, page_tabs
819 serge 324
 
2434 Serge 325
        xor     eax, eax
819 serge 326
@@:
2434 Serge 327
        stosd
328
        invlpg  [edx]
329
        add     edx, 0x1000
330
        loop    @b
819 serge 331
 
2434 Serge 332
        pop     edi
333
        ret
819 serge 334
 
335
 
336
align 4
188 serge 337
proc map_page_table stdcall, lin_addr:dword, phis_addr:dword
2434 Serge 338
        push    ebx
339
        mov     ebx, [lin_addr]
340
        shr     ebx, 22
341
        mov     eax, [phis_addr]
342
        and     eax, not 0xFFF
343
        or      eax, PG_UW        ;+PG_NOCACHE
344
        mov     dword [master_tab+ebx*4], eax
345
        mov     eax, [lin_addr]
346
        shr     eax, 10
347
        add     eax, page_tabs
348
        invlpg  [eax]
349
        pop     ebx
350
        ret
164 serge 351
endp
352
 
353
align 4
4269 Serge 354
init_LFB:
355
        xchg bx, bx
378 serge 356
 
2434 Serge 357
        cmp     dword [LFBAddress], -1
358
        jne     @f
3908 Serge 359
        mov     [BOOT_VARS+BOOT_MTRR], byte 2
2434 Serge 360
; max VGA=640*480*4=1228800 bytes
361
; + 32*640*4=81920 bytes for mouse pointer
362
        stdcall alloc_pages, ((1228800+81920)/4096)
1300 serge 363
 
2434 Serge 364
        push    eax
365
        call    alloc_page
366
        stdcall map_page_table, LFB_BASE, eax
367
        pop     eax
368
        or      eax, PG_UW
369
        mov     ebx, LFB_BASE
370
; max VGA=640*480*4=1228800 bytes
371
; + 32*640*4=81920 bytes for mouse pointer
372
        mov     ecx, (1228800+81920)/4096
373
        call    commit_pages
374
        mov     [LFBAddress], dword LFB_BASE
375
        ret
164 serge 376
@@:
2434 Serge 377
        test    [SCR_MODE], word 0100000000000000b
378
        jnz     @f
3908 Serge 379
        mov     [BOOT_VARS+BOOT_MTRR], byte 2
2434 Serge 380
        ret
211 serge 381
@@:
2434 Serge 382
        call    init_mtrr
490 serge 383
 
4269 Serge 384
        xor     edx, edx
385
        mov     eax, [LFBAddress]
2434 Serge 386
        bt      [cpu_caps], CAPS_PGE
4269 Serge 387
        setc    dh                            ;eliminate branch and
388
        mov     ecx, LFB_SIZE/4096
389
        mov     edi, lfb_pd_0
390
        lea     eax, [eax+edx+PG_UW]          ;set PG_GLOBAL if supported
164 serge 391
 
4269 Serge 392
.map_pte:
393
        stosd
394
        add     eax, 0x1000
395
        loop    .map_pte
164 serge 396
 
4269 Serge 397
        mov     ecx, (LFB_SIZE/4096)/1024
398
        mov     edi, sys_pgdir+(LFB_BASE shr 20)
399
        lea     eax, [(lfb_pd_0-OS_BASE)+PG_UW]
164 serge 400
 
4269 Serge 401
.map_pde:
2434 Serge 402
        stosd
403
        add     eax, 0x1000
4269 Serge 404
        loop    .map_pde
164 serge 405
 
4269 Serge 406
        mov     dword [exp_lfb+4], LFB_BASE
2434 Serge 407
        mov     dword [LFBAddress], LFB_BASE
4269 Serge 408
        mov     eax, cr3                      ;flush TLB
2434 Serge 409
        mov     cr3, eax
410
        ret
164 serge 411
 
412
align 4
413
proc new_mem_resize stdcall, new_size:dword
414
 
2987 Serge 415
        push    ebx
416
        push    esi
417
        push    edi
164 serge 418
 
2987 Serge 419
        mov     edx, [current_slot]
420
        cmp     [edx+APPDATA.heap_base], 0
421
        jne     .exit
422
 
2434 Serge 423
        mov     edi, [new_size]
424
        add     edi, 4095
425
        and     edi, not 4095
426
        mov     [new_size], edi
164 serge 427
 
2434 Serge 428
        mov     esi, [edx+APPDATA.mem_size]
429
        add     esi, 4095
430
        and     esi, not 4095
164 serge 431
 
2434 Serge 432
        cmp     edi, esi
2987 Serge 433
        ja      .expand
434
        je      .exit
164 serge 435
 
2987 Serge 436
        mov     ebx, edi
2434 Serge 437
        shr     edi, 12
438
        shr     esi, 12
2987 Serge 439
 
440
        mov     ecx, pg_data.mutex
441
        call    mutex_lock
164 serge 442
@@:
2434 Serge 443
        mov     eax, [app_page_tabs+edi*4]
444
        test    eax, 1
445
        jz      .next
2987 Serge 446
 
447
        mov     dword [app_page_tabs+edi*4], 0
2434 Serge 448
        invlpg  [ebx]
449
        call    free_page
164 serge 450
 
2434 Serge 451
.next:
2987 Serge 452
        inc     edi
453
        add     ebx, 0x1000
2434 Serge 454
        cmp     edi, esi
455
        jb      @B
164 serge 456
 
2987 Serge 457
        mov     ecx, pg_data.mutex
458
        call    mutex_unlock
459
 
164 serge 460
.update_size:
2987 Serge 461
        mov     edx, [current_slot]
2434 Serge 462
        mov     ebx, [new_size]
463
        call    update_mem_size
2987 Serge 464
.exit:
465
        pop     edi
466
        pop     esi
467
        pop     ebx
2434 Serge 468
        xor     eax, eax
469
        ret
2987 Serge 470
 
164 serge 471
.expand:
472
 
2987 Serge 473
        mov     ecx, pg_data.mutex
474
        call    mutex_lock
164 serge 475
 
2987 Serge 476
        xchg    esi, edi
477
 
478
        push    esi                   ;new size
479
        push    edi                   ;old size
480
 
2434 Serge 481
        add     edi, 0x3FFFFF
482
        and     edi, not(0x3FFFFF)
483
        add     esi, 0x3FFFFF
484
        and     esi, not(0x3FFFFF)
164 serge 485
 
2987 Serge 486
        cmp     edi, esi
2434 Serge 487
        jae     .grow
2987 Serge 488
 @@:
2434 Serge 489
        call    alloc_page
490
        test    eax, eax
2987 Serge 491
        jz      .exit_fail
164 serge 492
 
2434 Serge 493
        stdcall map_page_table, edi, eax
164 serge 494
 
2434 Serge 495
        push    edi
496
        shr     edi, 10
497
        add     edi, page_tabs
498
        mov     ecx, 1024
499
        xor     eax, eax
500
        cld
501
        rep stosd
502
        pop     edi
164 serge 503
 
2434 Serge 504
        add     edi, 0x00400000
505
        cmp     edi, esi
506
        jb      @B
164 serge 507
.grow:
2987 Serge 508
        pop     edi                   ;old size
509
        pop     ecx                   ;new size
164 serge 510
 
2987 Serge 511
        shr     edi, 10
512
        shr     ecx, 10
513
        sub     ecx, edi
514
        shr     ecx, 2                ;pages count
515
        mov     eax, 2
516
 
517
        add     edi, app_page_tabs
2434 Serge 518
        rep stosd
164 serge 519
 
2987 Serge 520
        mov     ecx, pg_data.mutex
521
        call    mutex_unlock
164 serge 522
 
2434 Serge 523
        jmp     .update_size
2987 Serge 524
 
525
.exit_fail:
2434 Serge 526
        mov     ecx, pg_data.mutex
527
        call    mutex_unlock
2130 serge 528
 
2987 Serge 529
        add     esp, 8
530
        pop     edi
531
        pop     esi
532
        pop     ebx
2434 Serge 533
        xor     eax, eax
534
        inc     eax
535
        ret
164 serge 536
endp
537
 
2987 Serge 538
 
539
align 4
294 diamond 540
update_mem_size:
465 serge 541
; in: edx = slot base
294 diamond 542
;     ebx = new memory size
543
; destroys eax,ecx,edx
544
 
2434 Serge 545
        mov     [APPDATA.mem_size+edx], ebx
294 diamond 546
;search threads and update
547
;application memory size infomation
2434 Serge 548
        mov     ecx, [APPDATA.dir_table+edx]
549
        mov     eax, 2
294 diamond 550
 
551
.search_threads:
552
;eax = current slot
553
;ebx = new memory size
554
;ecx = page directory
2434 Serge 555
        cmp     eax, [TASK_COUNT]
556
        jg      .search_threads_end
557
        mov     edx, eax
558
        shl     edx, 5
559
        cmp     word [CURRENT_TASK+edx+TASKDATA.state], 9  ;if slot empty?
560
        jz      .search_threads_next
561
        shl     edx, 3
562
        cmp     [SLOT_BASE+edx+APPDATA.dir_table], ecx      ;if it is our thread?
563
        jnz     .search_threads_next
564
        mov     [SLOT_BASE+edx+APPDATA.mem_size], ebx      ;update memory size
294 diamond 565
.search_threads_next:
2434 Serge 566
        inc     eax
567
        jmp     .search_threads
294 diamond 568
.search_threads_end:
2434 Serge 569
        ret
294 diamond 570
 
285 serge 571
; param
572
;  eax= linear address
573
;
574
; retval
575
;  eax= phisical page address
576
 
164 serge 577
align 4
285 serge 578
get_pg_addr:
3232 Serge 579
        sub     eax, OS_BASE
580
        cmp     eax, 0x400000
581
        jb      @f
2434 Serge 582
        shr     eax, 12
3232 Serge 583
        mov     eax, [page_tabs+(eax+(OS_BASE shr 12))*4]
584
@@:
2434 Serge 585
        and     eax, 0xFFFFF000
586
        ret
164 serge 587
 
465 serge 588
 
188 serge 589
align 4
1105 Galkov 590
; Now it is called from core/sys32::exc_c (see stack frame there)
164 serge 591
proc page_fault_handler
465 serge 592
 
1056 Galkov 593
    .err_addr   equ ebp-4
709 diamond 594
 
1105 Galkov 595
        push    ebx               ;save exception number (#PF)
1056 Galkov 596
        mov     ebp, esp
597
        mov     ebx, cr2
1105 Galkov 598
        push    ebx               ;that is locals: .err_addr = cr2
1056 Galkov 599
        inc     [pg_data.pages_faults]
465 serge 600
 
1056 Galkov 601
        mov     eax, [pf_err_code]
164 serge 602
 
1056 Galkov 603
        cmp     ebx, OS_BASE      ;ebx == .err_addr
3555 Serge 604
        jb      .user_space       ;страница в памяти приложения ;
188 serge 605
 
1056 Galkov 606
        cmp     ebx, page_tabs
3555 Serge 607
        jb      .kernel_space     ;страница в памяти ядра
164 serge 608
 
1056 Galkov 609
        cmp     ebx, kernel_tabs
3555 Serge 610
        jb      .alloc;.app_tabs  ;таблицы страниц приложения ;
611
                                  ;просто создадим одну
612
if 0 ;пока это просто лишнее
1056 Galkov 613
        cmp     ebx, LFB_BASE
3555 Serge 614
        jb      .core_tabs        ;таблицы страниц ядра
615
                                  ;Ошибка
1056 Galkov 616
  .lfb:
3555 Serge 617
                                  ;область LFB
618
                                  ;Ошибка
1056 Galkov 619
        jmp     .fail
620
end if
621
.core_tabs:
622
.fail:  ;simply return to caller
623
        mov     esp, ebp
1105 Galkov 624
        pop     ebx               ;restore exception number (#PF)
1056 Galkov 625
        ret
378 serge 626
 
1300 serge 627
;        xchg bx, bx
628
;        add     esp,12 ;clear in stack: locals(.err_addr) + #PF + ret_to_caller
629
;        restore_ring3_context
630
;        iretd
631
 
164 serge 632
.user_space:
1056 Galkov 633
        test    eax, PG_MAP
3555 Serge 634
        jnz     .err_access       ;Страница присутствует
635
                                  ;Ошибка доступа ?
465 serge 636
 
1056 Galkov 637
        shr     ebx, 12
638
        mov     ecx, ebx
639
        shr     ecx, 10
640
        mov     edx, [master_tab+ecx*4]
641
        test    edx, PG_MAP
3555 Serge 642
        jz      .fail             ;таблица страниц не создана
643
                                  ;неверный адрес в программе
172 serge 644
 
1056 Galkov 645
        mov     eax, [page_tabs+ebx*4]
646
        test    eax, 2
3555 Serge 647
        jz      .fail             ;адрес не зарезервирован для ;
648
                                  ;использования. Ошибка
188 serge 649
.alloc:
1056 Galkov 650
        call    alloc_page
651
        test    eax, eax
652
        jz      .fail
164 serge 653
 
2434 Serge 654
        stdcall map_page, [.err_addr], eax, PG_UW
164 serge 655
 
1056 Galkov 656
        mov     edi, [.err_addr]
657
        and     edi, 0xFFFFF000
658
        mov     ecx, 1024
659
        xor     eax, eax
660
       ;cld     ;caller is duty for this
2434 Serge 661
        rep stosd
1056 Galkov 662
.exit:  ;iret with repeat fault instruction
2434 Serge 663
        add     esp, 12;clear in stack: locals(.err_addr) + #PF + ret_to_caller
1056 Galkov 664
        restore_ring3_context
665
        iretd
465 serge 666
 
1289 diamond 667
.err_access:
668
; access denied? this may be a result of copy-on-write protection for DLL
669
; check list of HDLLs
670
        and     ebx, not 0xFFF
671
        mov     eax, [CURRENT_TASK]
672
        shl     eax, 8
1311 diamond 673
        mov     eax, [SLOT_BASE+eax+APPDATA.dlls_list_ptr]
674
        test    eax, eax
675
        jz      .fail
676
        mov     esi, [eax+HDLL.fd]
1289 diamond 677
.scan_hdll:
678
        cmp     esi, eax
679
        jz      .fail
680
        mov     edx, ebx
681
        sub     edx, [esi+HDLL.base]
682
        cmp     edx, [esi+HDLL.size]
683
        jb      .fault_in_hdll
684
.scan_hdll.next:
1311 diamond 685
        mov     esi, [esi+HDLL.fd]
1289 diamond 686
        jmp     .scan_hdll
687
.fault_in_hdll:
688
; allocate new page, map it as rw and copy data
689
        call    alloc_page
690
        test    eax, eax
691
        jz      .fail
2434 Serge 692
        stdcall map_page, ebx, eax, PG_UW
1289 diamond 693
        mov     edi, ebx
694
        mov     ecx, 1024
695
        sub     ebx, [esi+HDLL.base]
696
        mov     esi, [esi+HDLL.parent]
697
        mov     esi, [esi+DLLDESCR.data]
698
        add     esi, ebx
2434 Serge 699
        rep movsd
1289 diamond 700
        jmp     .exit
465 serge 701
 
702
.kernel_space:
1056 Galkov 703
        test    eax, PG_MAP
3555 Serge 704
        jz      .fail   ;страница не присутствует
465 serge 705
 
2434 Serge 706
        test    eax, 12 ;U/S (+below)
3555 Serge 707
        jnz     .fail   ;приложение обратилось к памяти
708
                        ;ядра
1056 Galkov 709
       ;test    eax, 8
3555 Serge 710
       ;jnz     .fail   ;установлен зарезервированный бит
711
                        ;в таблицах страниц. добавлено в P4/Xeon
465 serge 712
 
3555 Serge 713
;попытка записи в защищённую страницу ядра
465 serge 714
 
1056 Galkov 715
        cmp     ebx, tss._io_map_0
716
        jb      .fail
465 serge 717
 
1056 Galkov 718
        cmp     ebx, tss._io_map_0+8192
719
        jae     .fail
465 serge 720
 
721
; io permission map
722
; copy-on-write protection
723
 
1056 Galkov 724
        call    alloc_page
725
        test    eax, eax
726
        jz      .fail
465 serge 727
 
1056 Galkov 728
        push    eax
2434 Serge 729
        stdcall map_page, [.err_addr], eax, dword PG_SW
1056 Galkov 730
        pop     eax
731
        mov     edi, [.err_addr]
732
        and     edi, -4096
733
        lea     esi, [edi+(not tss._io_map_0)+1]; -tss._io_map_0
465 serge 734
 
1056 Galkov 735
        mov     ebx, esi
736
        shr     ebx, 12
737
        mov     edx, [current_slot]
738
        or      eax, PG_SW
739
        mov     [edx+APPDATA.io_map+ebx*4], eax
465 serge 740
 
1056 Galkov 741
        add     esi, [default_io_map]
742
        mov     ecx, 4096/4
743
       ;cld     ;caller is duty for this
2434 Serge 744
        rep movsd
1056 Galkov 745
        jmp     .exit
164 serge 746
endp
747
 
1314 diamond 748
; returns number of mapped bytes
749
proc map_mem stdcall, lin_addr:dword,slot:dword,\
750
                      ofs:dword,buf_size:dword,req_access:dword
2434 Serge 751
        push    0 ; initialize number of mapped bytes
1314 diamond 752
 
2434 Serge 753
        cmp     [buf_size], 0
754
        jz      .exit
164 serge 755
 
2434 Serge 756
        mov     eax, [slot]
757
        shl     eax, 8
758
        mov     eax, [SLOT_BASE+eax+APPDATA.dir_table]
759
        and     eax, 0xFFFFF000
164 serge 760
 
2434 Serge 761
        stdcall map_page, [ipc_pdir], eax, PG_UW
762
        mov     ebx, [ofs]
763
        shr     ebx, 22
764
        mov     esi, [ipc_pdir]
765
        mov     edi, [ipc_ptab]
766
        mov     eax, [esi+ebx*4]
767
        and     eax, 0xFFFFF000
768
        jz      .exit
769
        stdcall map_page, edi, eax, PG_UW
164 serge 770
;           inc ebx
771
;           add edi, 0x1000
772
;           mov eax, [esi+ebx*4]
773
;           test eax, eax
774
;           jz @f
775
;          and eax, 0xFFFFF000
776
;           stdcall map_page, edi, eax
777
 
2434 Serge 778
@@:
779
        mov     edi, [lin_addr]
780
        and     edi, 0xFFFFF000
781
        mov     ecx, [buf_size]
782
        add     ecx, 4095
783
        shr     ecx, 12
784
        inc     ecx
164 serge 785
 
2434 Serge 786
        mov     edx, [ofs]
787
        shr     edx, 12
788
        and     edx, 0x3FF
789
        mov     esi, [ipc_ptab]
164 serge 790
 
1314 diamond 791
.map:
2434 Serge 792
        stdcall safe_map_page, [slot], [req_access], [ofs]
793
        jnc     .exit
794
        add     dword [ebp-4], 4096
795
        add     [ofs], 4096
796
        dec     ecx
797
        jz      .exit
798
        add     edi, 0x1000
799
        inc     edx
800
        cmp     edx, 0x400
801
        jnz     .map
802
        inc     ebx
803
        mov     eax, [ipc_pdir]
804
        mov     eax, [eax+ebx*4]
805
        and     eax, 0xFFFFF000
806
        jz      .exit
807
        stdcall map_page, esi, eax, PG_UW
808
        xor     edx, edx
809
        jmp     .map
164 serge 810
 
811
.exit:
2434 Serge 812
        pop     eax
813
        ret
164 serge 814
endp
815
 
1314 diamond 816
proc map_memEx stdcall, lin_addr:dword,slot:dword,\
817
                        ofs:dword,buf_size:dword,req_access:dword
2434 Serge 818
        push    0 ; initialize number of mapped bytes
1314 diamond 819
 
2434 Serge 820
        cmp     [buf_size], 0
821
        jz      .exit
164 serge 822
 
2434 Serge 823
        mov     eax, [slot]
824
        shl     eax, 8
825
        mov     eax, [SLOT_BASE+eax+APPDATA.dir_table]
826
        and     eax, 0xFFFFF000
164 serge 827
 
2434 Serge 828
        stdcall map_page, [proc_mem_pdir], eax, PG_UW
829
        mov     ebx, [ofs]
830
        shr     ebx, 22
831
        mov     esi, [proc_mem_pdir]
832
        mov     edi, [proc_mem_tab]
833
        mov     eax, [esi+ebx*4]
834
        and     eax, 0xFFFFF000
835
        test    eax, eax
836
        jz      .exit
837
        stdcall map_page, edi, eax, PG_UW
164 serge 838
 
2434 Serge 839
@@:
840
        mov     edi, [lin_addr]
841
        and     edi, 0xFFFFF000
842
        mov     ecx, [buf_size]
843
        add     ecx, 4095
844
        shr     ecx, 12
845
        inc     ecx
164 serge 846
 
2434 Serge 847
        mov     edx, [ofs]
848
        shr     edx, 12
849
        and     edx, 0x3FF
850
        mov     esi, [proc_mem_tab]
164 serge 851
 
1314 diamond 852
.map:
2434 Serge 853
        stdcall safe_map_page, [slot], [req_access], [ofs]
854
        jnc     .exit
855
        add     dword [ebp-4], 0x1000
856
        add     edi, 0x1000
857
        add     [ofs], 0x1000
858
        inc     edx
859
        dec     ecx
860
        jnz     .map
164 serge 861
.exit:
2434 Serge 862
        pop     eax
863
        ret
164 serge 864
endp
865
 
1314 diamond 866
; in: esi+edx*4 = pointer to page table entry
867
; in: [slot], [req_access], [ofs] on the stack
868
; in: edi = linear address to map
869
; out: CF cleared <=> failed
870
; destroys: only eax
871
proc safe_map_page stdcall, slot:dword, req_access:dword, ofs:dword
2434 Serge 872
        mov     eax, [esi+edx*4]
873
        test    al, PG_MAP
874
        jz      .not_present
875
        test    al, PG_WRITE
876
        jz      .resolve_readonly
1314 diamond 877
; normal case: writable page, just map with requested access
878
.map:
2434 Serge 879
        stdcall map_page, edi, eax, [req_access]
880
        stc
1314 diamond 881
.fail:
2434 Serge 882
        ret
1314 diamond 883
.not_present:
884
; check for alloc-on-demand page
2434 Serge 885
        test    al, 2
886
        jz      .fail
1314 diamond 887
; allocate new page, save it to source page table
2434 Serge 888
        push    ecx
889
        call    alloc_page
890
        pop     ecx
891
        test    eax, eax
892
        jz      .fail
893
        or      al, PG_UW
894
        mov     [esi+edx*4], eax
895
        jmp     .map
1314 diamond 896
.resolve_readonly:
897
; readonly page, probably copy-on-write
898
; check: readonly request of readonly page is ok
2434 Serge 899
        test    [req_access], PG_WRITE
900
        jz      .map
1314 diamond 901
; find control structure for this page
2434 Serge 902
        pushf
903
        cli
904
        cld
905
        push    ebx ecx
906
        mov     eax, [slot]
907
        shl     eax, 8
908
        mov     eax, [SLOT_BASE+eax+APPDATA.dlls_list_ptr]
909
        test    eax, eax
910
        jz      .no_hdll
911
        mov     ecx, [eax+HDLL.fd]
1314 diamond 912
.scan_hdll:
2434 Serge 913
        cmp     ecx, eax
914
        jz      .no_hdll
915
        mov     ebx, [ofs]
916
        and     ebx, not 0xFFF
917
        sub     ebx, [ecx+HDLL.base]
918
        cmp     ebx, [ecx+HDLL.size]
919
        jb      .hdll_found
920
        mov     ecx, [ecx+HDLL.fd]
921
        jmp     .scan_hdll
1314 diamond 922
.no_hdll:
2434 Serge 923
        pop     ecx ebx
924
        popf
925
        clc
926
        ret
1314 diamond 927
.hdll_found:
928
; allocate page, save it in page table, map it, copy contents from base
2434 Serge 929
        mov     eax, [ecx+HDLL.parent]
930
        add     ebx, [eax+DLLDESCR.data]
931
        call    alloc_page
932
        test    eax, eax
933
        jz      .no_hdll
934
        or      al, PG_UW
935
        mov     [esi+edx*4], eax
936
        stdcall map_page, edi, eax, [req_access]
937
        push    esi edi
938
        mov     esi, ebx
939
        mov     ecx, 4096/4
940
        rep movsd
941
        pop     edi esi
942
        pop     ecx ebx
943
        popf
944
        stc
945
        ret
1314 diamond 946
endp
164 serge 947
 
948
sys_IPC:
949
;input:
1496 Lrz 950
;  ebx=1 - set ipc buffer area
951
;    ecx=address of buffer
952
;    edx=size of buffer
164 serge 953
;  eax=2 - send message
954
;    ebx=PID
955
;    ecx=address of message
956
;    edx=size of message
957
 
2434 Serge 958
        dec     ebx
959
        jnz     @f
164 serge 960
 
2434 Serge 961
        mov     eax, [current_slot]
1496 Lrz 962
        pushf
963
        cli
2434 Serge 964
        mov     [eax+APPDATA.ipc_start], ecx    ;set fields in extended information area
965
        mov     [eax+APPDATA.ipc_size], edx
164 serge 966
 
2434 Serge 967
        add     edx, ecx
968
        add     edx, 4095
969
        and     edx, not 4095
164 serge 970
 
2434 Serge 971
.touch:
972
        mov     eax, [ecx]
973
        add     ecx, 0x1000
974
        cmp     ecx, edx
975
        jb      .touch
164 serge 976
 
1496 Lrz 977
        popf
2434 Serge 978
        mov     [esp+32], ebx   ;ebx=0
1496 Lrz 979
        ret
164 serge 980
 
1496 Lrz 981
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
982
;2
983
@@:
2434 Serge 984
        dec     ebx
985
        jnz     @f
164 serge 986
 
1496 Lrz 987
        stdcall sys_ipc_send, ecx, edx, esi
2434 Serge 988
        mov     [esp+32], eax
1496 Lrz 989
        ret
990
@@:
2434 Serge 991
        or      eax, -1
992
        mov     [esp+32], eax
1496 Lrz 993
        ret
994
 
995
;align 4
996
;proc set_ipc_buff
997
 
998
;           mov  eax,[current_slot]
999
;           pushf
1000
;           cli
1001
;           mov  [eax+APPDATA.ipc_start],ebx     ;set fields in extended information area
1002
;           mov  [eax+APPDATA.ipc_size],ecx
1003
;
1004
;           add ecx, ebx
1005
;           add ecx, 4095
1006
;           and ecx, not 4095
1007
;
1008
;.touch:    mov eax, [ebx]
1009
;           add ebx, 0x1000
1010
;           cmp ebx, ecx
1011
;           jb  .touch
1012
;
1013
;           popf
1014
;           xor eax, eax
1015
;           ret
1016
;endp
1017
 
164 serge 1018
proc sys_ipc_send stdcall, PID:dword, msg_addr:dword, msg_size:dword
1019
           locals
1020
             dst_slot   dd ?
1021
             dst_offset dd ?
1022
             buf_size   dd ?
536 diamond 1023
             used_buf   dd ?
164 serge 1024
           endl
1025
 
2434 Serge 1026
        pushf
1027
        cli
164 serge 1028
 
2434 Serge 1029
        mov     eax, [PID]
1030
        call    pid_to_slot
1031
        test    eax, eax
1032
        jz      .no_pid
164 serge 1033
 
2434 Serge 1034
        mov     [dst_slot], eax
1035
        shl     eax, 8
1036
        mov     edi, [eax+SLOT_BASE+0xa0] ;is ipc area defined?
1037
        test    edi, edi
1038
        jz      .no_ipc_area
164 serge 1039
 
2434 Serge 1040
        mov     ebx, edi
1041
        and     ebx, 0xFFF
1042
        mov     [dst_offset], ebx
164 serge 1043
 
2434 Serge 1044
        mov     esi, [eax+SLOT_BASE+0xa4]
1045
        mov     [buf_size], esi
164 serge 1046
 
2434 Serge 1047
        mov     ecx, [ipc_tmp]
1048
        cmp     esi, 0x40000-0x1000; size of [ipc_tmp] minus one page
1049
        jbe     @f
1050
        push    esi edi
1051
        add     esi, 0x1000
1052
        stdcall alloc_kernel_space, esi
1053
        mov     ecx, eax
1054
        pop     edi esi
536 diamond 1055
@@:
2434 Serge 1056
        mov     [used_buf], ecx
1057
        stdcall map_mem, ecx, [dst_slot], \
1058
                edi, esi, PG_SW
164 serge 1059
 
2434 Serge 1060
        mov     edi, [dst_offset]
1061
        add     edi, [used_buf]
1062
        cmp     dword [edi], 0
1063
        jnz     .ipc_blocked          ;if dword [buffer]<>0 - ipc blocked now
227 serge 1064
 
2434 Serge 1065
        mov     edx, dword [edi+4]
1066
        lea     ebx, [edx+8]
1067
        add     ebx, [msg_size]
1068
        cmp     ebx, [buf_size]
1069
        ja      .buffer_overflow       ;esi<0 - not enough memory in buffer
227 serge 1070
 
2434 Serge 1071
        mov     dword [edi+4], ebx
1072
        mov     eax, [TASK_BASE]
1073
        mov     eax, [eax+0x04]        ;eax - our PID
1074
        add     edi, edx
1075
        mov     [edi], eax
1076
        mov     ecx, [msg_size]
164 serge 1077
 
2434 Serge 1078
        mov     [edi+4], ecx
1079
        add     edi, 8
1080
        mov     esi, [msg_addr]
465 serge 1081
       ;    add esi, new_app_base
2434 Serge 1082
        cld
1083
        rep movsb
164 serge 1084
 
2434 Serge 1085
        mov     ebx, [ipc_tmp]
1086
        mov     edx, ebx
1087
        shr     ebx, 12
1088
        xor     eax, eax
1089
        mov     [page_tabs+ebx*4], eax
1090
        invlpg  [edx]
164 serge 1091
 
2434 Serge 1092
        mov     ebx, [ipc_pdir]
1093
        mov     edx, ebx
1094
        shr     ebx, 12
1095
        xor     eax, eax
1096
        mov     [page_tabs+ebx*4], eax
1097
        invlpg  [edx]
164 serge 1098
 
2434 Serge 1099
        mov     ebx, [ipc_ptab]
1100
        mov     edx, ebx
1101
        shr     ebx, 12
1102
        xor     eax, eax
1103
        mov     [page_tabs+ebx*4], eax
1104
        invlpg  [edx]
164 serge 1105
 
2434 Serge 1106
        mov     eax, [dst_slot]
1107
        shl     eax, 8
1108
        or      [eax+SLOT_BASE+0xA8], dword 0x40
1109
        push    0
1110
        jmp     .ret
164 serge 1111
.no_pid:
2434 Serge 1112
        popf
1113
        mov     eax, 4
1114
        ret
164 serge 1115
.no_ipc_area:
2434 Serge 1116
        popf
1117
        xor     eax, eax
1118
        inc     eax
1119
        ret
164 serge 1120
.ipc_blocked:
2434 Serge 1121
        push    2
1122
        jmp     .ret
164 serge 1123
.buffer_overflow:
2434 Serge 1124
        push    3
536 diamond 1125
.ret:
2434 Serge 1126
        mov     eax, [used_buf]
1127
        cmp     eax, [ipc_tmp]
1128
        jz      @f
1129
        stdcall free_kernel_space, eax
536 diamond 1130
@@:
2434 Serge 1131
        pop     eax
1132
        popf
1133
        ret
164 serge 1134
endp
1135
 
1136
align 4
170 serge 1137
sysfn_meminfo:
164 serge 1138
 
1072 diamond 1139
        ;   add ecx, new_app_base
2434 Serge 1140
        cmp     ecx, OS_BASE
1141
        jae     .fail
172 serge 1142
 
2434 Serge 1143
        mov     eax, [pg_data.pages_count]
1144
        mov     [ecx], eax
1145
        shl     eax, 12
1146
        mov     [esp+32], eax
1147
        mov     eax, [pg_data.pages_free]
1148
        mov     [ecx+4], eax
1149
        mov     eax, [pg_data.pages_faults]
1150
        mov     [ecx+8], eax
1151
        mov     eax, [heap_size]
1152
        mov     [ecx+12], eax
1153
        mov     eax, [heap_free]
1154
        mov     [ecx+16], eax
1155
        mov     eax, [heap_blocks]
1156
        mov     [ecx+20], eax
1157
        mov     eax, [free_blocks]
1158
        mov     [ecx+24], eax
1159
        ret
172 serge 1160
.fail:
2434 Serge 1161
        or      dword [esp+32], -1
1162
        ret
1629 serge 1163
 
164 serge 1164
align 4
940 serge 1165
f68:
2434 Serge 1166
        cmp     ebx, 4
1167
        jbe     sys_sheduler
164 serge 1168
 
2434 Serge 1169
        cmp     ebx, 11
1170
        jb      .fail
164 serge 1171
 
3908 Serge 1172
        cmp     ebx, 27
2434 Serge 1173
        ja      .fail
940 serge 1174
 
2434 Serge 1175
        jmp     dword [f68call+ebx*4-11*4]
940 serge 1176
.11:
2434 Serge 1177
        call    init_heap
1178
        mov     [esp+32], eax
1179
        ret
940 serge 1180
.12:
2434 Serge 1181
        stdcall user_alloc, ecx
1182
        mov     [esp+32], eax
1183
        ret
940 serge 1184
.13:
2434 Serge 1185
        stdcall user_free, ecx
1186
        mov     [esp+32], eax
1187
        ret
940 serge 1188
.14:
2434 Serge 1189
        cmp     ecx, OS_BASE
1190
        jae     .fail
1191
        mov     edi, ecx
1192
        call    get_event_ex
1193
        mov     [esp+32], eax
1194
        ret
940 serge 1195
.16:
2434 Serge 1196
        test    ecx, ecx
1197
        jz      .fail
1198
        cmp     ecx, OS_BASE
1199
        jae     .fail
1200
        stdcall get_service, ecx
1201
        mov     [esp+32], eax
1202
        ret
940 serge 1203
.17:
2434 Serge 1204
        call    srv_handlerEx   ;ecx
1205
        mov     [esp+32], eax
1206
        ret
940 serge 1207
.19:
2434 Serge 1208
        cmp     ecx, OS_BASE
1209
        jae     .fail
1210
        stdcall load_library, ecx
1211
        mov     [esp+32], eax
1212
        ret
940 serge 1213
.20:
2434 Serge 1214
        mov     eax, edx
1215
        mov     ebx, ecx
1216
        call    user_realloc            ;in: eax = pointer, ebx = new size
1217
        mov     [esp+32], eax
1218
        ret
940 serge 1219
.21:
2434 Serge 1220
        cmp     ecx, OS_BASE
1221
        jae     .fail
740 serge 1222
 
2987 Serge 1223
        cmp     edx, OS_BASE
2434 Serge 1224
        jae     .fail
1316 serge 1225
 
4423 Serge 1226
        stdcall load_pe_driver, ecx, edx
2434 Serge 1227
        mov     [esp+32], eax
1228
        ret
940 serge 1229
.22:
2434 Serge 1230
        cmp     ecx, OS_BASE
1231
        jae     .fail
740 serge 1232
 
2434 Serge 1233
        stdcall shmem_open, ecx, edx, esi
1234
        mov     [esp+24], edx
1235
        mov     [esp+32], eax
1236
        ret
740 serge 1237
 
943 serge 1238
.23:
2434 Serge 1239
        cmp     ecx, OS_BASE
1240
        jae     .fail
943 serge 1241
 
2434 Serge 1242
        stdcall shmem_close, ecx
1243
        mov     [esp+32], eax
1244
        ret
1275 serge 1245
.24:
2434 Serge 1246
        mov     eax, [current_slot]
1247
        xchg    ecx, [eax+APPDATA.exc_handler]
1248
        xchg    edx, [eax+APPDATA.except_mask]
1249
        mov     [esp+32], ecx ; reg_eax+8
1250
        mov     [esp+20], edx ; reg_ebx+8
1251
        ret
1275 serge 1252
.25:
2434 Serge 1253
        cmp     ecx, 32
1254
        jae     .fail
1255
        mov     eax, [current_slot]
1256
        btr     [eax+APPDATA.except_mask], ecx
1257
        setc    byte[esp+32]
1258
        jecxz   @f
1259
        bts     [eax+APPDATA.except_mask], ecx
1275 serge 1260
@@:
2434 Serge 1261
        ret
943 serge 1262
 
2434 Serge 1263
.26:
1264
        stdcall user_unmap, ecx, edx, esi
1265
        mov     [esp+32], eax
1266
        ret
1267
 
3908 Serge 1268
.27:
1269
        cmp     ecx, OS_BASE
1270
        jae     .fail
1271
 
1272
        stdcall load_file_umode, ecx
1273
        mov     [esp+24], edx
1274
        mov     [esp+32], eax
1275
        ret
1276
 
164 serge 1277
.fail:
2434 Serge 1278
        xor     eax, eax
1279
        mov     [esp+32], eax
1280
        ret
164 serge 1281
 
1629 serge 1282
 
164 serge 1283
align 4
1629 serge 1284
f68call:   ; keep this table closer to main code
1285
 
1286
           dd f68.11   ; init_heap
1287
           dd f68.12   ; user_alloc
1288
           dd f68.13   ; user_free
1289
           dd f68.14   ; get_event_ex
1290
           dd f68.fail ; moved to f68.24
1291
           dd f68.16   ; get_service
1292
           dd f68.17   ; call_service
1293
           dd f68.fail ; moved to f68.25
1294
           dd f68.19   ; load_dll
1295
           dd f68.20   ; user_realloc
1296
           dd f68.21   ; load_driver
1297
           dd f68.22   ; shmem_open
1298
           dd f68.23   ; shmem_close
2434 Serge 1299
           dd f68.24   ; set exception handler
1300
           dd f68.25   ; unmask exception
1301
           dd f68.26   ; user_unmap
3908 Serge 1302
           dd f68.27   ; load_file_umode
1629 serge 1303
 
1304
 
1305
align 4
4423 Serge 1306
proc load_pe_driver stdcall, file:dword, cmdline:dword
1307
        push    esi
819 serge 1308
 
2434 Serge 1309
        stdcall load_PE, [file]
1310
        test    eax, eax
1311
        jz      .fail
819 serge 1312
 
2434 Serge 1313
        mov     esi, eax
4423 Serge 1314
        push    [cmdline]
1315
        push    DRV_ENTRY
1316
        call    eax
1317
        pop     ecx
1318
        pop     ecx
2434 Serge 1319
        test    eax, eax
1320
        jz      .fail
819 serge 1321
 
2434 Serge 1322
        mov     [eax+SRV.entry], esi
4423 Serge 1323
        pop     esi
2434 Serge 1324
        ret
819 serge 1325
 
1326
.fail:
2434 Serge 1327
        xor     eax, eax
4423 Serge 1328
        pop     esi
2434 Serge 1329
        ret
819 serge 1330
endp
1331
 
1332
align 4
164 serge 1333
proc init_mtrr
1334
 
3908 Serge 1335
        cmp     [BOOT_VARS+BOOT_MTRR], byte 2
2434 Serge 1336
        je      .exit
164 serge 1337
 
2434 Serge 1338
        bt      [cpu_caps], CAPS_MTRR
1339
        jnc     .exit
211 serge 1340
 
2434 Serge 1341
        mov     eax, cr0
1342
        or      eax, 0x60000000 ;disable caching
1343
        mov     cr0, eax
1344
        wbinvd                  ;invalidate cache
164 serge 1345
 
2434 Serge 1346
        mov     ecx, 0x2FF
1347
        rdmsr                   ;
1030 diamond 1348
; has BIOS already initialized MTRRs?
2434 Serge 1349
        test    ah, 8
1350
        jnz     .skip_init
1030 diamond 1351
; rarely needed, so mainly placeholder
1352
; main memory - cached
2434 Serge 1353
        push    eax
164 serge 1354
 
2434 Serge 1355
        mov     eax, [MEM_AMOUNT]
821 diamond 1356
; round eax up to next power of 2
2434 Serge 1357
        dec     eax
1358
        bsr     ecx, eax
1359
        mov     ebx, 2
1360
        shl     ebx, cl
1361
        dec     ebx
1030 diamond 1362
; base of memory range = 0, type of memory range = MEM_WB
2434 Serge 1363
        xor     edx, edx
1364
        mov     eax, MEM_WB
1365
        mov     ecx, 0x200
1366
        wrmsr
1030 diamond 1367
; mask of memory range = 0xFFFFFFFFF - (size - 1), ebx = size - 1
2434 Serge 1368
        mov     eax, 0xFFFFFFFF
1369
        mov     edx, 0x0000000F
1370
        sub     eax, ebx
1371
        sbb     edx, 0
1372
        or      eax, 0x800
1373
        inc     ecx
1374
        wrmsr
1030 diamond 1375
; clear unused MTRRs
2434 Serge 1376
        xor     eax, eax
1377
        xor     edx, edx
164 serge 1378
@@:
4423 Serge 1379
        inc     ecx
2434 Serge 1380
        wrmsr
4423 Serge 1381
        cmp     ecx, 0x20F
2434 Serge 1382
        jb      @b
1030 diamond 1383
; enable MTRRs
2434 Serge 1384
        pop     eax
1385
        or      ah, 8
1386
        and     al, 0xF0; default memtype = UC
1387
        mov     ecx, 0x2FF
1388
        wrmsr
1030 diamond 1389
.skip_init:
2434 Serge 1390
        stdcall set_mtrr, [LFBAddress], [LFBSize], MEM_WC
164 serge 1391
 
2434 Serge 1392
        wbinvd                  ;again invalidate
164 serge 1393
 
2434 Serge 1394
        mov     eax, cr0
1395
        and     eax, not 0x60000000
1396
        mov     cr0, eax        ; enable caching
164 serge 1397
.exit:
2434 Serge 1398
        ret
164 serge 1399
endp
1400
 
1401
align 4
1030 diamond 1402
proc set_mtrr stdcall, base:dword,size:dword,mem_type:dword
1403
; find unused register
2434 Serge 1404
        mov     ecx, 0x201
1030 diamond 1405
@@:
2434 Serge 1406
        rdmsr
1407
        dec     ecx
1408
        test    ah, 8
1409
        jz      .found
1410
        rdmsr
1411
        mov     al, 0; clear memory type field
1412
        cmp     eax, [base]
1413
        jz      .ret
1414
        add     ecx, 3
1415
        cmp     ecx, 0x210
1416
        jb      @b
1030 diamond 1417
; no free registers, ignore the call
1418
.ret:
2434 Serge 1419
        ret
1030 diamond 1420
.found:
1421
; found, write values
2434 Serge 1422
        xor     edx, edx
1423
        mov     eax, [base]
1424
        or      eax, [mem_type]
1425
        wrmsr
164 serge 1426
 
2434 Serge 1427
        mov     ebx, [size]
1428
        dec     ebx
1429
        mov     eax, 0xFFFFFFFF
3908 Serge 1430
        mov     edx, 0x00000000
2434 Serge 1431
        sub     eax, ebx
1432
        sbb     edx, 0
1433
        or      eax, 0x800
1434
        inc     ecx
1435
        wrmsr
1436
        ret
164 serge 1437
endp
1438
 
465 serge 1439
align 4
520 serge 1440
proc create_ring_buffer stdcall, size:dword, flags:dword
1441
           locals
1442
             buf_ptr  dd ?
1443
           endl
237 serge 1444
 
2434 Serge 1445
        mov     eax, [size]
1446
        test    eax, eax
1447
        jz      .fail
520 serge 1448
 
2434 Serge 1449
        add     eax, eax
1450
        stdcall alloc_kernel_space, eax
1451
        test    eax, eax
1452
        jz      .fail
520 serge 1453
 
2434 Serge 1454
        push    ebx
662 serge 1455
 
2434 Serge 1456
        mov     [buf_ptr], eax
520 serge 1457
 
2434 Serge 1458
        mov     ebx, [size]
1459
        shr     ebx, 12
1460
        push    ebx
520 serge 1461
 
2434 Serge 1462
        stdcall alloc_pages, ebx
1463
        pop     ecx
520 serge 1464
 
2434 Serge 1465
        test    eax, eax
1466
        jz      .mm_fail
520 serge 1467
 
2434 Serge 1468
        push    edi
662 serge 1469
 
2434 Serge 1470
        or      eax, [flags]
1471
        mov     edi, [buf_ptr]
1472
        mov     ebx, [buf_ptr]
1473
        mov     edx, ecx
1474
        shl     edx, 2
1475
        shr     edi, 10
520 serge 1476
@@:
2434 Serge 1477
        mov     [page_tabs+edi], eax
1478
        mov     [page_tabs+edi+edx], eax
1479
        invlpg  [ebx]
1480
        invlpg  [ebx+0x10000]
1481
        add     eax, 0x1000
1482
        add     ebx, 0x1000
1483
        add     edi, 4
1484
        dec     ecx
1485
        jnz     @B
520 serge 1486
 
2434 Serge 1487
        mov     eax, [buf_ptr]
1488
        pop     edi
1489
        pop     ebx
1490
        ret
520 serge 1491
.mm_fail:
2434 Serge 1492
        stdcall free_kernel_space, [buf_ptr]
1493
        xor     eax, eax
1494
        pop     ebx
520 serge 1495
.fail:
2434 Serge 1496
        ret
520 serge 1497
endp
2442 Serge 1498
 
1499
 
1500
align 4
2467 Serge 1501
proc print_mem
2442 Serge 1502
        mov     edi, BOOT_VAR + 0x9104
1503
        mov     ecx, [edi-4]
1504
        test    ecx, ecx
3908 Serge 1505
        jz      .done
2442 Serge 1506
 
1507
@@:
3908 Serge 1508
        mov     eax, [edi]
1509
        mov     edx, [edi+4]
1510
        add     eax, [edi+8]
1511
        adc     edx, [edi+12]
2442 Serge 1512
 
1513
        DEBUGF  1, "K : E820 %x%x - %x%x type %d\n", \
1514
                    [edi+4], [edi],\
1515
                    edx, eax, [edi+16]
1516
        add     edi, 20
1517
        dec     ecx
1518
        jnz     @b
1519
.done:
1520
        ret
2467 Serge 1521
endp