Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
431 serge 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
5565 serge 3
;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;;
431 serge 4
;; Distributed under terms of the GNU General Public License    ;;
5
;;                                                              ;;
6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
164 serge 7
 
593 mikedld 8
$Revision: 6252 $
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
5201 serge 126
;proc map_page stdcall,lin_addr:dword,phis_addr:dword,flags:dword
127
map_page:
2434 Serge 128
        push    ebx
5596 serge 129
        mov     eax, [esp+12]              ; phis_addr
5201 serge 130
        or      eax, [esp+16]              ; flags
5565 serge 131
        and     eax, [pte_valid_mask]
5201 serge 132
        mov     ebx, [esp+8]               ; lin_addr
2434 Serge 133
        shr     ebx, 12
134
        mov     [page_tabs+ebx*4], eax
5201 serge 135
        mov     eax, [esp+8]               ; lin_addr
136
        pop     ebx
2434 Serge 137
        invlpg  [eax]
5201 serge 138
        ret     12
164 serge 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
        or      edx, [flags]
5565 serge 195
        and     edx, [pte_valid_mask]
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
 
5565 serge 232
        and     eax, [pte_valid_mask ]
2434 Serge 233
        mov     edi, ebx
234
        shr     edi, 12
235
        lea     edi, [page_tabs+edi*4]
2130 serge 236
@@:
2434 Serge 237
        stosd
238
        invlpg  [ebx]
239
        add     eax, 0x1000
240
        add     ebx, 0x1000
241
        loop    @B
328 serge 242
 
2434 Serge 243
        pop     edi
2130 serge 244
 
2434 Serge 245
        mov     ecx, pg_data.mutex
246
        call    mutex_unlock
328 serge 247
.fail:
2434 Serge 248
        ret
281 serge 249
 
328 serge 250
 
281 serge 251
; param
279 serge 252
;  eax= base
281 serge 253
;  ecx= count
279 serge 254
 
164 serge 255
align 4
279 serge 256
release_pages:
321 diamond 257
 
2434 Serge 258
        push    ebp
259
        push    esi
260
        push    edi
261
        push    ebx
279 serge 262
 
2434 Serge 263
        mov     esi, eax
264
        mov     edi, eax
279 serge 265
 
2434 Serge 266
        shr     esi, 12
267
        lea     esi, [page_tabs+esi*4]
328 serge 268
 
2434 Serge 269
        push    ecx
270
        mov     ecx, pg_data.mutex
271
        call    mutex_lock
272
        pop     ecx
2130 serge 273
 
2434 Serge 274
        mov     ebp, [pg_data.pages_free]
275
        mov     ebx, [page_start]
276
        mov     edx, sys_pgmap
279 serge 277
@@:
2434 Serge 278
        xor     eax, eax
279
        xchg    eax, [esi]
280
        invlpg  [edi]
279 serge 281
 
2434 Serge 282
        test    eax, 1
283
        jz      .next
279 serge 284
 
2434 Serge 285
        shr     eax, 12
286
        bts     [edx], eax
287
        cmc
288
        adc     ebp, 0
289
        shr     eax, 3
290
        and     eax, -4
291
        add     eax, edx
292
        cmp     eax, ebx
293
        jae     .next
279 serge 294
 
2434 Serge 295
        mov     ebx, eax
279 serge 296
.next:
2434 Serge 297
        add     edi, 0x1000
298
        add     esi, 4
299
        loop    @B
2130 serge 300
 
2434 Serge 301
        mov     [pg_data.pages_free], ebp
302
        mov     ecx, pg_data.mutex
303
        call    mutex_unlock
2130 serge 304
 
2434 Serge 305
        pop     ebx
306
        pop     edi
307
        pop     esi
308
        pop     ebp
309
        ret
279 serge 310
 
819 serge 311
; param
312
;  eax= base
313
;  ecx= count
314
 
279 serge 315
align 4
819 serge 316
unmap_pages:
317
 
2434 Serge 318
        push    edi
819 serge 319
 
2434 Serge 320
        mov     edi, eax
321
        mov     edx, eax
819 serge 322
 
2434 Serge 323
        shr     edi, 10
324
        add     edi, page_tabs
819 serge 325
 
2434 Serge 326
        xor     eax, eax
819 serge 327
@@:
2434 Serge 328
        stosd
329
        invlpg  [edx]
330
        add     edx, 0x1000
331
        loop    @b
819 serge 332
 
2434 Serge 333
        pop     edi
334
        ret
819 serge 335
 
336
 
337
align 4
188 serge 338
proc map_page_table stdcall, lin_addr:dword, phis_addr:dword
2434 Serge 339
        push    ebx
340
        mov     ebx, [lin_addr]
341
        shr     ebx, 22
342
        mov     eax, [phis_addr]
343
        and     eax, not 0xFFF
5565 serge 344
        or      eax, PG_UWR
2434 Serge 345
        mov     dword [master_tab+ebx*4], eax
346
        mov     eax, [lin_addr]
347
        shr     eax, 10
348
        add     eax, page_tabs
349
        invlpg  [eax]
350
        pop     ebx
351
        ret
164 serge 352
endp
353
 
5201 serge 354
uglobal
355
sb16_buffer_allocated db 0
356
endg
357
 
358
; Allocates [.size] bytes so that the target memory block
359
; is inside one 64K page for 24-bit DMA controller,
360
; that is, somewhere between 00xx0000h and 00xxFFFFh.
361
proc alloc_dma24
362
; Implementation note.
363
; The only user of that function is SB16 driver,
364
; so just return a statically allocated buffer.
365
virtual at esp
366
                dd      ? ; return address
367
.size           dd      ?
368
end virtual
369
        cmp     [sb16_buffer_allocated], 0
370
        jnz     .fail
371
        inc     [sb16_buffer_allocated]
372
        mov     eax, SB16Buffer
373
        ret     4
374
.fail:
375
        xor     eax, eax
376
        ret     4
377
endp
378
 
379
; Allocates a physical page for master page table
380
; that duplicates first Mb of OS_BASE at address 0;
381
; used for starting APs and for shutting down,
382
; where it is important to execute code in trivial-mapped pages.
383
; Returns eax = allocated physical page.
384
proc create_trampoline_pgmap
385
; The only non-trivial moment:
386
; we need a linear address to fill information,
387
; but we don't need it outside of this function,
388
; so we're returning physical address.
389
; Therefore, allocate memory with kernel_alloc,
390
; this will allocate physical page and a linear address somewhere,
391
; and deallocate only linear address with free_kernel_space.
392
        stdcall kernel_alloc, 0x1000
393
        mov     edi, eax
394
        mov     esi, master_tab
395
        mov     ecx, 1024
396
        rep movsd
397
        mov     ecx, [master_tab+(OS_BASE shr 20)]
398
        mov     [eax], ecx
399
        mov     edi, eax
400
        call    get_pg_addr
401
        push    eax
402
        stdcall free_kernel_space, edi
403
        pop     eax
404
        ret
405
endp
406
 
164 serge 407
align 4
408
proc new_mem_resize stdcall, new_size:dword
409
 
2987 Serge 410
        push    ebx
411
        push    esi
412
        push    edi
164 serge 413
 
2987 Serge 414
        mov     edx, [current_slot]
5201 serge 415
        mov     ebx, [edx+APPDATA.process]
416
 
417
        cmp     [ebx+PROC.heap_base], 0
2987 Serge 418
        jne     .exit
419
 
2434 Serge 420
        mov     edi, [new_size]
421
        add     edi, 4095
422
        and     edi, not 4095
423
        mov     [new_size], edi
164 serge 424
 
5201 serge 425
        mov     esi, [ebx+PROC.mem_used]
2434 Serge 426
        add     esi, 4095
427
        and     esi, not 4095
164 serge 428
 
2434 Serge 429
        cmp     edi, esi
2987 Serge 430
        ja      .expand
431
        je      .exit
164 serge 432
 
2987 Serge 433
        mov     ebx, edi
2434 Serge 434
        shr     edi, 12
435
        shr     esi, 12
2987 Serge 436
 
437
        mov     ecx, pg_data.mutex
438
        call    mutex_lock
164 serge 439
@@:
2434 Serge 440
        mov     eax, [app_page_tabs+edi*4]
441
        test    eax, 1
442
        jz      .next
2987 Serge 443
 
444
        mov     dword [app_page_tabs+edi*4], 0
2434 Serge 445
        invlpg  [ebx]
446
        call    free_page
164 serge 447
 
2434 Serge 448
.next:
2987 Serge 449
        inc     edi
450
        add     ebx, 0x1000
2434 Serge 451
        cmp     edi, esi
452
        jb      @B
164 serge 453
 
2987 Serge 454
        mov     ecx, pg_data.mutex
455
        call    mutex_unlock
456
 
164 serge 457
.update_size:
2987 Serge 458
        mov     edx, [current_slot]
2434 Serge 459
        mov     ebx, [new_size]
5201 serge 460
        mov     edx, [edx+APPDATA.process]
461
        mov     [edx+PROC.mem_used], ebx
2987 Serge 462
.exit:
463
        pop     edi
464
        pop     esi
465
        pop     ebx
2434 Serge 466
        xor     eax, eax
467
        ret
2987 Serge 468
 
164 serge 469
.expand:
470
 
2987 Serge 471
        mov     ecx, pg_data.mutex
472
        call    mutex_lock
164 serge 473
 
2987 Serge 474
        xchg    esi, edi
475
 
476
        push    esi                   ;new size
477
        push    edi                   ;old size
478
 
2434 Serge 479
        add     edi, 0x3FFFFF
480
        and     edi, not(0x3FFFFF)
481
        add     esi, 0x3FFFFF
482
        and     esi, not(0x3FFFFF)
164 serge 483
 
2987 Serge 484
        cmp     edi, esi
2434 Serge 485
        jae     .grow
2987 Serge 486
 @@:
2434 Serge 487
        call    alloc_page
488
        test    eax, eax
2987 Serge 489
        jz      .exit_fail
164 serge 490
 
2434 Serge 491
        stdcall map_page_table, edi, eax
164 serge 492
 
2434 Serge 493
        push    edi
494
        shr     edi, 10
495
        add     edi, page_tabs
496
        mov     ecx, 1024
497
        xor     eax, eax
498
        cld
499
        rep stosd
500
        pop     edi
164 serge 501
 
2434 Serge 502
        add     edi, 0x00400000
503
        cmp     edi, esi
504
        jb      @B
164 serge 505
.grow:
2987 Serge 506
        pop     edi                   ;old size
507
        pop     ecx                   ;new size
164 serge 508
 
2987 Serge 509
        shr     edi, 10
510
        shr     ecx, 10
511
        sub     ecx, edi
512
        shr     ecx, 2                ;pages count
513
        mov     eax, 2
514
 
515
        add     edi, app_page_tabs
2434 Serge 516
        rep stosd
164 serge 517
 
2987 Serge 518
        mov     ecx, pg_data.mutex
519
        call    mutex_unlock
164 serge 520
 
2434 Serge 521
        jmp     .update_size
2987 Serge 522
 
523
.exit_fail:
2434 Serge 524
        mov     ecx, pg_data.mutex
525
        call    mutex_unlock
2130 serge 526
 
2987 Serge 527
        add     esp, 8
528
        pop     edi
529
        pop     esi
530
        pop     ebx
2434 Serge 531
        xor     eax, eax
532
        inc     eax
533
        ret
164 serge 534
endp
535
 
2987 Serge 536
 
285 serge 537
; param
538
;  eax= linear address
539
;
540
; retval
541
;  eax= phisical page address
542
 
164 serge 543
align 4
285 serge 544
get_pg_addr:
3232 Serge 545
        sub     eax, OS_BASE
546
        cmp     eax, 0x400000
547
        jb      @f
2434 Serge 548
        shr     eax, 12
3232 Serge 549
        mov     eax, [page_tabs+(eax+(OS_BASE shr 12))*4]
550
@@:
2434 Serge 551
        and     eax, 0xFFFFF000
552
        ret
164 serge 553
 
465 serge 554
 
188 serge 555
align 4
1105 Galkov 556
; Now it is called from core/sys32::exc_c (see stack frame there)
164 serge 557
proc page_fault_handler
465 serge 558
 
1056 Galkov 559
    .err_addr   equ ebp-4
709 diamond 560
 
1105 Galkov 561
        push    ebx               ;save exception number (#PF)
1056 Galkov 562
        mov     ebp, esp
563
        mov     ebx, cr2
1105 Galkov 564
        push    ebx               ;that is locals: .err_addr = cr2
1056 Galkov 565
        inc     [pg_data.pages_faults]
465 serge 566
 
1056 Galkov 567
        mov     eax, [pf_err_code]
164 serge 568
 
1056 Galkov 569
        cmp     ebx, OS_BASE      ;ebx == .err_addr
3555 Serge 570
        jb      .user_space       ;страница в памяти приложения ;
188 serge 571
 
1056 Galkov 572
        cmp     ebx, page_tabs
3555 Serge 573
        jb      .kernel_space     ;страница в памяти ядра
164 serge 574
 
1056 Galkov 575
        cmp     ebx, kernel_tabs
3555 Serge 576
        jb      .alloc;.app_tabs  ;таблицы страниц приложения ;
577
                                  ;просто создадим одну
578
if 0 ;пока это просто лишнее
1056 Galkov 579
        cmp     ebx, LFB_BASE
3555 Serge 580
        jb      .core_tabs        ;таблицы страниц ядра
581
                                  ;Ошибка
1056 Galkov 582
  .lfb:
3555 Serge 583
                                  ;область LFB
584
                                  ;Ошибка
1056 Galkov 585
        jmp     .fail
586
end if
587
.core_tabs:
588
.fail:  ;simply return to caller
589
        mov     esp, ebp
1105 Galkov 590
        pop     ebx               ;restore exception number (#PF)
1056 Galkov 591
        ret
378 serge 592
 
164 serge 593
.user_space:
5565 serge 594
        test    eax, PG_READ
3555 Serge 595
        jnz     .err_access       ;Страница присутствует
596
                                  ;Ошибка доступа ?
465 serge 597
 
1056 Galkov 598
        shr     ebx, 12
599
        mov     ecx, ebx
600
        shr     ecx, 10
601
        mov     edx, [master_tab+ecx*4]
5565 serge 602
        test    edx, PG_READ
3555 Serge 603
        jz      .fail             ;таблица страниц не создана
604
                                  ;неверный адрес в программе
172 serge 605
 
1056 Galkov 606
        mov     eax, [page_tabs+ebx*4]
607
        test    eax, 2
3555 Serge 608
        jz      .fail             ;адрес не зарезервирован для ;
609
                                  ;использования. Ошибка
188 serge 610
.alloc:
1056 Galkov 611
        call    alloc_page
612
        test    eax, eax
613
        jz      .fail
164 serge 614
 
5565 serge 615
        stdcall map_page, [.err_addr], eax, PG_UWR
164 serge 616
 
1056 Galkov 617
        mov     edi, [.err_addr]
618
        and     edi, 0xFFFFF000
619
        mov     ecx, 1024
620
        xor     eax, eax
621
       ;cld     ;caller is duty for this
2434 Serge 622
        rep stosd
1056 Galkov 623
.exit:  ;iret with repeat fault instruction
2434 Serge 624
        add     esp, 12;clear in stack: locals(.err_addr) + #PF + ret_to_caller
1056 Galkov 625
        restore_ring3_context
626
        iretd
465 serge 627
 
1289 diamond 628
.err_access:
629
; access denied? this may be a result of copy-on-write protection for DLL
630
; check list of HDLLs
631
        and     ebx, not 0xFFF
5201 serge 632
        mov     eax, [current_process]
633
        mov     eax, [eax+PROC.dlls_list_ptr]
1311 diamond 634
        test    eax, eax
635
        jz      .fail
636
        mov     esi, [eax+HDLL.fd]
1289 diamond 637
.scan_hdll:
638
        cmp     esi, eax
639
        jz      .fail
640
        mov     edx, ebx
641
        sub     edx, [esi+HDLL.base]
642
        cmp     edx, [esi+HDLL.size]
643
        jb      .fault_in_hdll
644
.scan_hdll.next:
1311 diamond 645
        mov     esi, [esi+HDLL.fd]
1289 diamond 646
        jmp     .scan_hdll
647
.fault_in_hdll:
648
; allocate new page, map it as rw and copy data
649
        call    alloc_page
650
        test    eax, eax
651
        jz      .fail
5565 serge 652
        stdcall map_page, ebx, eax, PG_UWR
1289 diamond 653
        mov     edi, ebx
654
        mov     ecx, 1024
655
        sub     ebx, [esi+HDLL.base]
656
        mov     esi, [esi+HDLL.parent]
657
        mov     esi, [esi+DLLDESCR.data]
658
        add     esi, ebx
2434 Serge 659
        rep movsd
1289 diamond 660
        jmp     .exit
465 serge 661
 
662
.kernel_space:
5565 serge 663
        test    eax, PG_READ
3555 Serge 664
        jz      .fail   ;страница не присутствует
465 serge 665
 
2434 Serge 666
        test    eax, 12 ;U/S (+below)
3555 Serge 667
        jnz     .fail   ;приложение обратилось к памяти
668
                        ;ядра
1056 Galkov 669
       ;test    eax, 8
3555 Serge 670
       ;jnz     .fail   ;установлен зарезервированный бит
671
                        ;в таблицах страниц. добавлено в P4/Xeon
465 serge 672
 
3555 Serge 673
;попытка записи в защищённую страницу ядра
465 serge 674
 
1056 Galkov 675
        cmp     ebx, tss._io_map_0
676
        jb      .fail
465 serge 677
 
1056 Galkov 678
        cmp     ebx, tss._io_map_0+8192
679
        jae     .fail
465 serge 680
 
681
; io permission map
682
; copy-on-write protection
683
 
1056 Galkov 684
        call    alloc_page
685
        test    eax, eax
686
        jz      .fail
465 serge 687
 
1056 Galkov 688
        push    eax
5565 serge 689
        stdcall map_page, [.err_addr], eax, dword PG_SWR
1056 Galkov 690
        pop     eax
691
        mov     edi, [.err_addr]
692
        and     edi, -4096
693
        lea     esi, [edi+(not tss._io_map_0)+1]; -tss._io_map_0
465 serge 694
 
1056 Galkov 695
        mov     ebx, esi
696
        shr     ebx, 12
697
        mov     edx, [current_slot]
5565 serge 698
        or      eax, PG_SWR
1056 Galkov 699
        mov     [edx+APPDATA.io_map+ebx*4], eax
465 serge 700
 
1056 Galkov 701
        add     esi, [default_io_map]
702
        mov     ecx, 4096/4
703
       ;cld     ;caller is duty for this
2434 Serge 704
        rep movsd
1056 Galkov 705
        jmp     .exit
164 serge 706
endp
707
 
1314 diamond 708
; returns number of mapped bytes
5201 serge 709
proc map_mem_ipc stdcall, lin_addr:dword,slot:dword,\
1314 diamond 710
                      ofs:dword,buf_size:dword,req_access:dword
5201 serge 711
        locals
712
             count   dd ?
713
             process dd ?
714
        endl
1314 diamond 715
 
5201 serge 716
        mov     [count], 0
2434 Serge 717
        cmp     [buf_size], 0
718
        jz      .exit
164 serge 719
 
2434 Serge 720
        mov     eax, [slot]
721
        shl     eax, 8
5201 serge 722
        mov     eax, [SLOT_BASE+eax+APPDATA.process]
723
        test    eax, eax
724
        jz      .exit
164 serge 725
 
5201 serge 726
        mov     [process], eax
2434 Serge 727
        mov     ebx, [ofs]
728
        shr     ebx, 22
5201 serge 729
        mov     eax, [eax+PROC.pdt_0+ebx*4]                 ;get page table
730
        mov     esi, [ipc_ptab]
2434 Serge 731
        and     eax, 0xFFFFF000
732
        jz      .exit
5565 serge 733
        stdcall map_page, esi, eax, PG_SWR
2434 Serge 734
@@:
735
        mov     edi, [lin_addr]
736
        and     edi, 0xFFFFF000
737
        mov     ecx, [buf_size]
738
        add     ecx, 4095
739
        shr     ecx, 12
5201 serge 740
        inc     ecx                  ; ???????????
164 serge 741
 
2434 Serge 742
        mov     edx, [ofs]
743
        shr     edx, 12
744
        and     edx, 0x3FF
1314 diamond 745
.map:
2434 Serge 746
        stdcall safe_map_page, [slot], [req_access], [ofs]
747
        jnc     .exit
5201 serge 748
        add     [count], PAGE_SIZE
749
        add     [ofs], PAGE_SIZE
2434 Serge 750
        dec     ecx
751
        jz      .exit
5201 serge 752
 
753
        add     edi, PAGE_SIZE
2434 Serge 754
        inc     edx
5201 serge 755
        cmp     edx, 1024
2434 Serge 756
        jnz     .map
5201 serge 757
 
2434 Serge 758
        inc     ebx
5201 serge 759
        mov     eax, [process]
760
        mov     eax, [eax+PROC.pdt_0+ebx*4]
2434 Serge 761
        and     eax, 0xFFFFF000
762
        jz      .exit
5201 serge 763
 
5565 serge 764
        stdcall map_page, esi, eax, PG_SWR
2434 Serge 765
        xor     edx, edx
766
        jmp     .map
164 serge 767
.exit:
5201 serge 768
        mov     eax, [count]
2434 Serge 769
        ret
164 serge 770
endp
771
 
1314 diamond 772
proc map_memEx stdcall, lin_addr:dword,slot:dword,\
773
                        ofs:dword,buf_size:dword,req_access:dword
5201 serge 774
        locals
775
             count   dd ?
776
             process dd ?
777
        endl
1314 diamond 778
 
5201 serge 779
        mov     [count], 0
2434 Serge 780
        cmp     [buf_size], 0
781
        jz      .exit
164 serge 782
 
2434 Serge 783
        mov     eax, [slot]
784
        shl     eax, 8
5201 serge 785
        mov     eax, [SLOT_BASE+eax+APPDATA.process]
786
        test    eax, eax
787
        jz      .exit
164 serge 788
 
5201 serge 789
        mov     [process], eax
2434 Serge 790
        mov     ebx, [ofs]
791
        shr     ebx, 22
5201 serge 792
        mov     eax, [eax+PROC.pdt_0+ebx*4]                 ;get page table
793
        mov     esi, [proc_mem_tab]
2434 Serge 794
        and     eax, 0xFFFFF000
795
        jz      .exit
5565 serge 796
        stdcall map_page, esi, eax, PG_SWR
2434 Serge 797
@@:
798
        mov     edi, [lin_addr]
799
        and     edi, 0xFFFFF000
800
        mov     ecx, [buf_size]
801
        add     ecx, 4095
802
        shr     ecx, 12
5201 serge 803
        inc     ecx                  ; ???????????
164 serge 804
 
2434 Serge 805
        mov     edx, [ofs]
806
        shr     edx, 12
807
        and     edx, 0x3FF
1314 diamond 808
.map:
2434 Serge 809
        stdcall safe_map_page, [slot], [req_access], [ofs]
810
        jnc     .exit
5201 serge 811
        add     [count], PAGE_SIZE
812
        add     [ofs], PAGE_SIZE
813
        dec     ecx
814
        jz      .exit
815
 
816
        add     edi, PAGE_SIZE
2434 Serge 817
        inc     edx
5201 serge 818
        cmp     edx, 1024
2434 Serge 819
        jnz     .map
5201 serge 820
 
821
        inc     ebx
822
        mov     eax, [process]
823
        mov     eax, [eax+PROC.pdt_0+ebx*4]
824
        and     eax, 0xFFFFF000
825
        jz      .exit
826
 
5565 serge 827
        stdcall map_page, esi, eax, PG_SWR
5201 serge 828
        xor     edx, edx
829
        jmp     .map
164 serge 830
.exit:
5201 serge 831
        mov     eax, [count]
2434 Serge 832
        ret
164 serge 833
endp
834
 
1314 diamond 835
; in: esi+edx*4 = pointer to page table entry
836
; in: [slot], [req_access], [ofs] on the stack
837
; in: edi = linear address to map
838
; out: CF cleared <=> failed
839
; destroys: only eax
840
proc safe_map_page stdcall, slot:dword, req_access:dword, ofs:dword
2434 Serge 841
        mov     eax, [esi+edx*4]
5565 serge 842
        test    al, PG_READ
2434 Serge 843
        jz      .not_present
844
        test    al, PG_WRITE
845
        jz      .resolve_readonly
1314 diamond 846
; normal case: writable page, just map with requested access
847
.map:
2434 Serge 848
        stdcall map_page, edi, eax, [req_access]
849
        stc
1314 diamond 850
.fail:
2434 Serge 851
        ret
1314 diamond 852
.not_present:
853
; check for alloc-on-demand page
2434 Serge 854
        test    al, 2
855
        jz      .fail
1314 diamond 856
; allocate new page, save it to source page table
2434 Serge 857
        push    ecx
858
        call    alloc_page
859
        pop     ecx
860
        test    eax, eax
861
        jz      .fail
5565 serge 862
        or      al, PG_UWR
2434 Serge 863
        mov     [esi+edx*4], eax
864
        jmp     .map
1314 diamond 865
.resolve_readonly:
866
; readonly page, probably copy-on-write
867
; check: readonly request of readonly page is ok
2434 Serge 868
        test    [req_access], PG_WRITE
869
        jz      .map
1314 diamond 870
; find control structure for this page
2434 Serge 871
        pushf
872
        cli
873
        cld
874
        push    ebx ecx
875
        mov     eax, [slot]
876
        shl     eax, 8
5201 serge 877
        mov     eax, [SLOT_BASE+eax+APPDATA.process]
878
        mov     eax, [eax+PROC.dlls_list_ptr]
2434 Serge 879
        test    eax, eax
880
        jz      .no_hdll
881
        mov     ecx, [eax+HDLL.fd]
1314 diamond 882
.scan_hdll:
2434 Serge 883
        cmp     ecx, eax
884
        jz      .no_hdll
885
        mov     ebx, [ofs]
886
        and     ebx, not 0xFFF
887
        sub     ebx, [ecx+HDLL.base]
888
        cmp     ebx, [ecx+HDLL.size]
889
        jb      .hdll_found
890
        mov     ecx, [ecx+HDLL.fd]
891
        jmp     .scan_hdll
1314 diamond 892
.no_hdll:
2434 Serge 893
        pop     ecx ebx
894
        popf
895
        clc
896
        ret
1314 diamond 897
.hdll_found:
898
; allocate page, save it in page table, map it, copy contents from base
2434 Serge 899
        mov     eax, [ecx+HDLL.parent]
900
        add     ebx, [eax+DLLDESCR.data]
901
        call    alloc_page
902
        test    eax, eax
903
        jz      .no_hdll
5565 serge 904
        or      al, PG_UWR
2434 Serge 905
        mov     [esi+edx*4], eax
906
        stdcall map_page, edi, eax, [req_access]
907
        push    esi edi
908
        mov     esi, ebx
909
        mov     ecx, 4096/4
910
        rep movsd
911
        pop     edi esi
912
        pop     ecx ebx
913
        popf
914
        stc
915
        ret
1314 diamond 916
endp
164 serge 917
 
918
sys_IPC:
919
;input:
1496 Lrz 920
;  ebx=1 - set ipc buffer area
921
;    ecx=address of buffer
922
;    edx=size of buffer
164 serge 923
;  eax=2 - send message
924
;    ebx=PID
925
;    ecx=address of message
926
;    edx=size of message
927
 
2434 Serge 928
        dec     ebx
929
        jnz     @f
164 serge 930
 
2434 Serge 931
        mov     eax, [current_slot]
1496 Lrz 932
        pushf
933
        cli
2434 Serge 934
        mov     [eax+APPDATA.ipc_start], ecx    ;set fields in extended information area
935
        mov     [eax+APPDATA.ipc_size], edx
164 serge 936
 
2434 Serge 937
        add     edx, ecx
938
        add     edx, 4095
939
        and     edx, not 4095
164 serge 940
 
2434 Serge 941
.touch:
942
        mov     eax, [ecx]
943
        add     ecx, 0x1000
944
        cmp     ecx, edx
945
        jb      .touch
164 serge 946
 
1496 Lrz 947
        popf
2434 Serge 948
        mov     [esp+32], ebx   ;ebx=0
1496 Lrz 949
        ret
164 serge 950
 
1496 Lrz 951
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
952
;2
953
@@:
2434 Serge 954
        dec     ebx
955
        jnz     @f
164 serge 956
 
1496 Lrz 957
        stdcall sys_ipc_send, ecx, edx, esi
2434 Serge 958
        mov     [esp+32], eax
1496 Lrz 959
        ret
960
@@:
2434 Serge 961
        or      eax, -1
962
        mov     [esp+32], eax
1496 Lrz 963
        ret
964
 
164 serge 965
proc sys_ipc_send stdcall, PID:dword, msg_addr:dword, msg_size:dword
966
           locals
967
             dst_slot   dd ?
968
             dst_offset dd ?
969
             buf_size   dd ?
536 diamond 970
             used_buf   dd ?
164 serge 971
           endl
972
 
2434 Serge 973
        pushf
974
        cli
164 serge 975
 
2434 Serge 976
        mov     eax, [PID]
977
        call    pid_to_slot
978
        test    eax, eax
979
        jz      .no_pid
164 serge 980
 
2434 Serge 981
        mov     [dst_slot], eax
982
        shl     eax, 8
5201 serge 983
        mov     edi, [eax+SLOT_BASE+APPDATA.ipc_start] ;is ipc area defined?
2434 Serge 984
        test    edi, edi
985
        jz      .no_ipc_area
164 serge 986
 
2434 Serge 987
        mov     ebx, edi
988
        and     ebx, 0xFFF
989
        mov     [dst_offset], ebx
164 serge 990
 
5201 serge 991
        mov     esi, [eax+SLOT_BASE+APPDATA.ipc_size]
2434 Serge 992
        mov     [buf_size], esi
164 serge 993
 
2434 Serge 994
        mov     ecx, [ipc_tmp]
995
        cmp     esi, 0x40000-0x1000; size of [ipc_tmp] minus one page
996
        jbe     @f
997
        push    esi edi
998
        add     esi, 0x1000
999
        stdcall alloc_kernel_space, esi
1000
        mov     ecx, eax
1001
        pop     edi esi
536 diamond 1002
@@:
2434 Serge 1003
        mov     [used_buf], ecx
5201 serge 1004
        stdcall map_mem_ipc, ecx, [dst_slot], \
5565 serge 1005
                edi, esi, PG_SWR
164 serge 1006
 
2434 Serge 1007
        mov     edi, [dst_offset]
1008
        add     edi, [used_buf]
1009
        cmp     dword [edi], 0
1010
        jnz     .ipc_blocked          ;if dword [buffer]<>0 - ipc blocked now
227 serge 1011
 
2434 Serge 1012
        mov     edx, dword [edi+4]
1013
        lea     ebx, [edx+8]
1014
        add     ebx, [msg_size]
1015
        cmp     ebx, [buf_size]
1016
        ja      .buffer_overflow       ;esi<0 - not enough memory in buffer
227 serge 1017
 
2434 Serge 1018
        mov     dword [edi+4], ebx
1019
        mov     eax, [TASK_BASE]
1020
        mov     eax, [eax+0x04]        ;eax - our PID
1021
        add     edi, edx
1022
        mov     [edi], eax
1023
        mov     ecx, [msg_size]
164 serge 1024
 
2434 Serge 1025
        mov     [edi+4], ecx
1026
        add     edi, 8
1027
        mov     esi, [msg_addr]
465 serge 1028
       ;    add esi, new_app_base
2434 Serge 1029
        cld
1030
        rep movsb
164 serge 1031
 
2434 Serge 1032
        mov     ebx, [ipc_tmp]
1033
        mov     edx, ebx
1034
        shr     ebx, 12
1035
        xor     eax, eax
1036
        mov     [page_tabs+ebx*4], eax
1037
        invlpg  [edx]
164 serge 1038
 
2434 Serge 1039
        mov     ebx, [ipc_pdir]
1040
        mov     edx, ebx
1041
        shr     ebx, 12
1042
        xor     eax, eax
1043
        mov     [page_tabs+ebx*4], eax
1044
        invlpg  [edx]
164 serge 1045
 
2434 Serge 1046
        mov     ebx, [ipc_ptab]
1047
        mov     edx, ebx
1048
        shr     ebx, 12
1049
        xor     eax, eax
1050
        mov     [page_tabs+ebx*4], eax
1051
        invlpg  [edx]
164 serge 1052
 
2434 Serge 1053
        mov     eax, [dst_slot]
1054
        shl     eax, 8
1055
        or      [eax+SLOT_BASE+0xA8], dword 0x40
1056
        push    0
1057
        jmp     .ret
164 serge 1058
.no_pid:
2434 Serge 1059
        popf
1060
        mov     eax, 4
1061
        ret
164 serge 1062
.no_ipc_area:
2434 Serge 1063
        popf
1064
        xor     eax, eax
1065
        inc     eax
1066
        ret
164 serge 1067
.ipc_blocked:
2434 Serge 1068
        push    2
1069
        jmp     .ret
164 serge 1070
.buffer_overflow:
2434 Serge 1071
        push    3
536 diamond 1072
.ret:
2434 Serge 1073
        mov     eax, [used_buf]
1074
        cmp     eax, [ipc_tmp]
5201 serge 1075
        je      @f
2434 Serge 1076
        stdcall free_kernel_space, eax
536 diamond 1077
@@:
2434 Serge 1078
        pop     eax
1079
        popf
1080
        ret
164 serge 1081
endp
1082
 
1083
align 4
170 serge 1084
sysfn_meminfo:
2434 Serge 1085
        cmp     ecx, OS_BASE
1086
        jae     .fail
172 serge 1087
 
2434 Serge 1088
        mov     eax, [pg_data.pages_count]
1089
        mov     [ecx], eax
1090
        shl     eax, 12
1091
        mov     [esp+32], eax
1092
        mov     eax, [pg_data.pages_free]
1093
        mov     [ecx+4], eax
1094
        mov     eax, [pg_data.pages_faults]
1095
        mov     [ecx+8], eax
1096
        mov     eax, [heap_size]
1097
        mov     [ecx+12], eax
1098
        mov     eax, [heap_free]
1099
        mov     [ecx+16], eax
1100
        mov     eax, [heap_blocks]
1101
        mov     [ecx+20], eax
1102
        mov     eax, [free_blocks]
1103
        mov     [ecx+24], eax
1104
        ret
172 serge 1105
.fail:
2434 Serge 1106
        or      dword [esp+32], -1
1107
        ret
1629 serge 1108
 
164 serge 1109
align 4
940 serge 1110
f68:
2434 Serge 1111
        cmp     ebx, 4
1112
        jbe     sys_sheduler
164 serge 1113
 
2434 Serge 1114
        cmp     ebx, 11
1115
        jb      .fail
164 serge 1116
 
3908 Serge 1117
        cmp     ebx, 27
2434 Serge 1118
        ja      .fail
940 serge 1119
 
2434 Serge 1120
        jmp     dword [f68call+ebx*4-11*4]
940 serge 1121
.11:
2434 Serge 1122
        call    init_heap
1123
        mov     [esp+32], eax
1124
        ret
940 serge 1125
.12:
2434 Serge 1126
        stdcall user_alloc, ecx
1127
        mov     [esp+32], eax
1128
        ret
940 serge 1129
.13:
2434 Serge 1130
        stdcall user_free, ecx
1131
        mov     [esp+32], eax
1132
        ret
940 serge 1133
.14:
2434 Serge 1134
        cmp     ecx, OS_BASE
1135
        jae     .fail
1136
        mov     edi, ecx
1137
        call    get_event_ex
1138
        mov     [esp+32], eax
1139
        ret
940 serge 1140
.16:
2434 Serge 1141
        test    ecx, ecx
1142
        jz      .fail
1143
        cmp     ecx, OS_BASE
1144
        jae     .fail
1145
        stdcall get_service, ecx
1146
        mov     [esp+32], eax
1147
        ret
940 serge 1148
.17:
2434 Serge 1149
        call    srv_handlerEx   ;ecx
1150
        mov     [esp+32], eax
1151
        ret
940 serge 1152
.19:
2434 Serge 1153
        cmp     ecx, OS_BASE
1154
        jae     .fail
1155
        stdcall load_library, ecx
1156
        mov     [esp+32], eax
1157
        ret
940 serge 1158
.20:
2434 Serge 1159
        mov     eax, edx
1160
        mov     ebx, ecx
1161
        call    user_realloc            ;in: eax = pointer, ebx = new size
1162
        mov     [esp+32], eax
1163
        ret
940 serge 1164
.21:
2434 Serge 1165
        cmp     ecx, OS_BASE
1166
        jae     .fail
740 serge 1167
 
2987 Serge 1168
        cmp     edx, OS_BASE
2434 Serge 1169
        jae     .fail
1316 serge 1170
 
4423 Serge 1171
        stdcall load_pe_driver, ecx, edx
2434 Serge 1172
        mov     [esp+32], eax
1173
        ret
940 serge 1174
.22:
2434 Serge 1175
        cmp     ecx, OS_BASE
1176
        jae     .fail
740 serge 1177
 
2434 Serge 1178
        stdcall shmem_open, ecx, edx, esi
1179
        mov     [esp+24], edx
1180
        mov     [esp+32], eax
1181
        ret
740 serge 1182
 
943 serge 1183
.23:
2434 Serge 1184
        cmp     ecx, OS_BASE
1185
        jae     .fail
943 serge 1186
 
2434 Serge 1187
        stdcall shmem_close, ecx
1188
        mov     [esp+32], eax
1189
        ret
1275 serge 1190
.24:
2434 Serge 1191
        mov     eax, [current_slot]
1192
        xchg    ecx, [eax+APPDATA.exc_handler]
1193
        xchg    edx, [eax+APPDATA.except_mask]
1194
        mov     [esp+32], ecx ; reg_eax+8
1195
        mov     [esp+20], edx ; reg_ebx+8
1196
        ret
1275 serge 1197
.25:
2434 Serge 1198
        cmp     ecx, 32
1199
        jae     .fail
1200
        mov     eax, [current_slot]
1201
        btr     [eax+APPDATA.except_mask], ecx
1202
        setc    byte[esp+32]
1203
        jecxz   @f
1204
        bts     [eax+APPDATA.except_mask], ecx
1275 serge 1205
@@:
2434 Serge 1206
        ret
943 serge 1207
 
2434 Serge 1208
.26:
1209
        stdcall user_unmap, ecx, edx, esi
1210
        mov     [esp+32], eax
1211
        ret
1212
 
3908 Serge 1213
.27:
1214
        cmp     ecx, OS_BASE
1215
        jae     .fail
1216
 
1217
        stdcall load_file_umode, ecx
1218
        mov     [esp+24], edx
1219
        mov     [esp+32], eax
1220
        ret
1221
 
164 serge 1222
.fail:
2434 Serge 1223
        xor     eax, eax
1224
        mov     [esp+32], eax
1225
        ret
164 serge 1226
 
5596 serge 1227
 
164 serge 1228
align 4
5596 serge 1229
f68call:   ; keep this table closer to main code
1230
 
1629 serge 1231
           dd f68.11   ; init_heap
1232
           dd f68.12   ; user_alloc
1233
           dd f68.13   ; user_free
1234
           dd f68.14   ; get_event_ex
1235
           dd f68.fail ; moved to f68.24
1236
           dd f68.16   ; get_service
1237
           dd f68.17   ; call_service
1238
           dd f68.fail ; moved to f68.25
1239
           dd f68.19   ; load_dll
1240
           dd f68.20   ; user_realloc
1241
           dd f68.21   ; load_driver
1242
           dd f68.22   ; shmem_open
1243
           dd f68.23   ; shmem_close
2434 Serge 1244
           dd f68.24   ; set exception handler
1245
           dd f68.25   ; unmask exception
1246
           dd f68.26   ; user_unmap
3908 Serge 1247
           dd f68.27   ; load_file_umode
1629 serge 1248
 
5596 serge 1249
 
1629 serge 1250
align 4
4423 Serge 1251
proc load_pe_driver stdcall, file:dword, cmdline:dword
1252
        push    esi
819 serge 1253
 
2434 Serge 1254
        stdcall load_PE, [file]
1255
        test    eax, eax
1256
        jz      .fail
819 serge 1257
 
2434 Serge 1258
        mov     esi, eax
4423 Serge 1259
        push    [cmdline]
1260
        push    DRV_ENTRY
1261
        call    eax
1262
        pop     ecx
1263
        pop     ecx
2434 Serge 1264
        test    eax, eax
1265
        jz      .fail
819 serge 1266
 
2434 Serge 1267
        mov     [eax+SRV.entry], esi
4423 Serge 1268
        pop     esi
2434 Serge 1269
        ret
819 serge 1270
 
1271
.fail:
2434 Serge 1272
        xor     eax, eax
4423 Serge 1273
        pop     esi
2434 Serge 1274
        ret
819 serge 1275
endp
1276
 
1277
align 4
520 serge 1278
proc create_ring_buffer stdcall, size:dword, flags:dword
1279
           locals
1280
             buf_ptr  dd ?
1281
           endl
237 serge 1282
 
2434 Serge 1283
        mov     eax, [size]
1284
        test    eax, eax
1285
        jz      .fail
520 serge 1286
 
2434 Serge 1287
        add     eax, eax
1288
        stdcall alloc_kernel_space, eax
1289
        test    eax, eax
1290
        jz      .fail
520 serge 1291
 
2434 Serge 1292
        push    ebx
662 serge 1293
 
2434 Serge 1294
        mov     [buf_ptr], eax
520 serge 1295
 
2434 Serge 1296
        mov     ebx, [size]
1297
        shr     ebx, 12
1298
        push    ebx
520 serge 1299
 
2434 Serge 1300
        stdcall alloc_pages, ebx
1301
        pop     ecx
520 serge 1302
 
2434 Serge 1303
        test    eax, eax
1304
        jz      .mm_fail
520 serge 1305
 
2434 Serge 1306
        push    edi
662 serge 1307
 
2434 Serge 1308
        or      eax, [flags]
1309
        mov     edi, [buf_ptr]
1310
        mov     ebx, [buf_ptr]
1311
        mov     edx, ecx
1312
        shl     edx, 2
1313
        shr     edi, 10
520 serge 1314
@@:
2434 Serge 1315
        mov     [page_tabs+edi], eax
1316
        mov     [page_tabs+edi+edx], eax
1317
        invlpg  [ebx]
1318
        invlpg  [ebx+0x10000]
1319
        add     eax, 0x1000
1320
        add     ebx, 0x1000
1321
        add     edi, 4
1322
        dec     ecx
1323
        jnz     @B
520 serge 1324
 
2434 Serge 1325
        mov     eax, [buf_ptr]
1326
        pop     edi
1327
        pop     ebx
1328
        ret
520 serge 1329
.mm_fail:
2434 Serge 1330
        stdcall free_kernel_space, [buf_ptr]
1331
        xor     eax, eax
1332
        pop     ebx
520 serge 1333
.fail:
2434 Serge 1334
        ret
520 serge 1335
endp
2442 Serge 1336
 
1337
 
1338
align 4
2467 Serge 1339
proc print_mem
2442 Serge 1340
        mov     edi, BOOT_VAR + 0x9104
1341
        mov     ecx, [edi-4]
1342
        test    ecx, ecx
3908 Serge 1343
        jz      .done
2442 Serge 1344
 
1345
@@:
3908 Serge 1346
        mov     eax, [edi]
1347
        mov     edx, [edi+4]
1348
        add     eax, [edi+8]
1349
        adc     edx, [edi+12]
2442 Serge 1350
 
1351
        DEBUGF  1, "K : E820 %x%x - %x%x type %d\n", \
1352
                    [edi+4], [edi],\
1353
                    edx, eax, [edi+16]
1354
        add     edi, 20
1355
        dec     ecx
1356
        jnz     @b
1357
.done:
1358
        ret
2467 Serge 1359
endp