Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
750 victor 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
2465 Serge 3
;; Copyright (C) KolibriOS team 2004-2012. All rights reserved. ;;
750 victor 4
;; Distributed under terms of the GNU General Public License    ;;
5
;;                                                              ;;
6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
593 mikedld 7
 
465 serge 8
$Revision: 3908 $
9
 
593 mikedld 10
 
465 serge 11
MEM_WB     equ 6               ;write-back memory
12
MEM_WC     equ 1               ;write combined memory
13
MEM_UC     equ 0               ;uncached memory
14
 
15
align 4
16
proc mem_test
1103 diamond 17
; if we have BIOS with fn E820, skip the test
3908 Serge 18
        cmp     dword [BOOT_VARS-OS_BASE + 0x9100], 0
2434 Serge 19
        jnz     .ret
465 serge 20
 
2434 Serge 21
        mov     eax, cr0
22
        and     eax, not (CR0_CD+CR0_NW)
23
        or      eax, CR0_CD       ;disable caching
24
        mov     cr0, eax
25
        wbinvd                    ;invalidate cache
465 serge 26
 
2434 Serge 27
        xor     edi, edi
28
        mov     ebx, 'TEST'
465 serge 29
@@:
2434 Serge 30
        add     edi, 0x100000
31
        xchg    ebx, dword [edi]
32
        cmp     dword [edi], 'TEST'
33
        xchg    ebx, dword [edi]
34
        je      @b
465 serge 35
 
2434 Serge 36
        and     eax, not (CR0_CD+CR0_NW) ;enable caching
37
        mov     cr0, eax
3908 Serge 38
        inc     dword [BOOT_VARS-OS_BASE + 0x9100]
2434 Serge 39
        xor     eax, eax
3908 Serge 40
        mov     [BOOT_VARS-OS_BASE + 0x9104], eax
41
        mov     [BOOT_VARS-OS_BASE + 0x9108], eax
42
        mov     [BOOT_VARS-OS_BASE + 0x910C], edi
43
        mov     [BOOT_VARS-OS_BASE + 0x9110], eax
1103 diamond 44
.ret:
2434 Serge 45
        ret
465 serge 46
endp
47
 
48
align 4
49
proc init_mem
1103 diamond 50
; calculate maximum allocatable address and number of allocatable pages
3908 Serge 51
        mov     edi, BOOT_VARS-OS_BASE + 0x9104
2434 Serge 52
        mov     ecx, [edi-4]
53
        xor     esi, esi; esi will hold total amount of memory
54
        xor     edx, edx; edx will hold maximum allocatable address
1103 diamond 55
.calcmax:
56
; round all to pages
2434 Serge 57
        mov     eax, [edi]
2442 Serge 58
        cmp     [edi+16], byte 1
3908 Serge 59
        jne     .unusable
2442 Serge 60
 
2434 Serge 61
        test    eax, 0xFFF
62
        jz      @f
63
        neg     eax
64
        and     eax, 0xFFF
65
        add     [edi], eax
66
        adc     dword [edi+4], 0
67
        sub     [edi+8], eax
68
        sbb     dword [edi+12], 0
69
        jc      .unusable
1103 diamond 70
@@:
2434 Serge 71
        and     dword [edi+8], not 0xFFF
72
        jz      .unusable
1103 diamond 73
; ignore memory after 4 Gb
2434 Serge 74
        cmp     dword [edi+4], 0
75
        jnz     .unusable
76
        mov     eax, [edi]
77
        cmp     dword [edi+12], 0
78
        jnz     .overflow
79
        add     eax, [edi+8]
80
        jnc     @f
1103 diamond 81
.overflow:
2434 Serge 82
        mov     eax, 0xFFFFF000
1103 diamond 83
@@:
2434 Serge 84
        cmp     edx, eax
85
        jae     @f
86
        mov     edx, eax
1103 diamond 87
@@:
2434 Serge 88
        sub     eax, [edi]
89
        mov     [edi+8], eax
90
        add     esi, eax
91
        jmp     .usable
1103 diamond 92
.unusable:
2465 Serge 93
;        and     dword [edi+8], 0
1103 diamond 94
.usable:
2434 Serge 95
        add     edi, 20
96
        loop    .calcmax
1103 diamond 97
.calculated:
2434 Serge 98
        mov     [MEM_AMOUNT-OS_BASE], esi
99
        mov     [pg_data.mem_amount-OS_BASE], esi
100
        shr     esi, 12
101
        mov     [pg_data.pages_count-OS_BASE], esi
465 serge 102
 
2434 Serge 103
        shr     edx, 12
104
        add     edx, 31
105
        and     edx, not 31
106
        shr     edx, 3
107
        mov     [pg_data.pagemap_size-OS_BASE], edx
465 serge 108
 
2434 Serge 109
        add     edx, (sys_pgmap-OS_BASE)+4095
110
        and     edx, not 4095
111
        mov     [tmp_page_tabs], edx
513 serge 112
 
2434 Serge 113
        mov     edx, esi
114
        and     edx, -1024
115
        cmp     edx, (OS_BASE/4096)
116
        jbe     @F
117
        mov     edx, (OS_BASE/4096)
118
        jmp     .set
1130 diamond 119
@@:
2434 Serge 120
        cmp     edx, (HEAP_BASE-OS_BASE+HEAP_MIN_SIZE)/4096
121
        jae     .set
122
        mov     edx, (HEAP_BASE-OS_BASE+HEAP_MIN_SIZE)/4096
1130 diamond 123
.set:
2434 Serge 124
        mov     [pg_data.kernel_pages-OS_BASE], edx
125
        shr     edx, 10
126
        mov     [pg_data.kernel_tables-OS_BASE], edx
465 serge 127
 
2434 Serge 128
        xor     eax, eax
129
        mov     edi, sys_pgdir-OS_BASE
130
        mov     ecx, 4096/4
131
        cld
132
        rep stosd
465 serge 133
 
2434 Serge 134
        mov     edx, (sys_pgdir-OS_BASE)+ 0x800; (OS_BASE shr 20)
135
        bt      [cpu_caps-OS_BASE], CAPS_PSE
136
        jnc     .no_PSE
465 serge 137
 
2434 Serge 138
        mov     ebx, cr4
139
        or      ebx, CR4_PSE
140
        mov     eax, PG_LARGE+PG_SW
141
        mov     cr4, ebx
142
        dec     [pg_data.kernel_tables-OS_BASE]
465 serge 143
 
2434 Serge 144
        mov     [edx], eax
145
        add     edx, 4
465 serge 146
 
2434 Serge 147
        mov     edi, [tmp_page_tabs]
148
        jmp     .map_kernel_heap        ; new kernel fits to the first 4Mb - nothing to do with ".map_low"
1455 art_zh 149
.no_PSE:
2434 Serge 150
        mov     eax, PG_SW
151
        mov     ecx, [tmp_page_tabs]
152
        shr     ecx, 12
1455 art_zh 153
.map_low:
2434 Serge 154
        mov     edi, [tmp_page_tabs]
1455 art_zh 155
@@:                                   ;
2434 Serge 156
        stosd
157
        add     eax, 0x1000
158
        dec     ecx
159
        jnz     @B
1455 art_zh 160
 
161
.map_kernel_heap:
2434 Serge 162
        mov     ecx, [pg_data.kernel_tables-OS_BASE]
163
        shl     ecx, 10
164
        xor     eax, eax
165
        rep stosd
465 serge 166
 
2434 Serge 167
        mov     ecx, [pg_data.kernel_tables-OS_BASE]
168
        mov     eax, [tmp_page_tabs]
169
        or      eax, PG_SW
170
        mov     edi, edx
2212 Serge 171
 
465 serge 172
.map_kernel_tabs:
2434 Serge 173
        stosd
174
        add     eax, 0x1000
175
        dec     ecx
176
        jnz     .map_kernel_tabs
465 serge 177
 
2434 Serge 178
        mov     dword [sys_pgdir-OS_BASE+(page_tabs shr 20)], sys_pgdir+PG_SW-OS_BASE
465 serge 179
 
2434 Serge 180
        mov     edi, (sys_pgdir-OS_BASE)
181
        lea     esi, [edi+(OS_BASE shr 20)]
182
        movsd
183
        movsd
184
        ret
465 serge 185
endp
186
 
187
align 4
188
proc init_page_map
1103 diamond 189
; mark all memory as unavailable
2434 Serge 190
        mov     edi, sys_pgmap-OS_BASE
191
        mov     ecx, [pg_data.pagemap_size-OS_BASE]
192
        shr     ecx, 2
193
        xor     eax, eax
194
        cld
195
        rep stosd
465 serge 196
 
1103 diamond 197
; scan through memory map and mark free areas as available
3908 Serge 198
        mov     ebx, BOOT_VARS-OS_BASE + 0x9104
2434 Serge 199
        mov     edx, [ebx-4]
1103 diamond 200
.scanmap:
2465 Serge 201
        cmp     [ebx+16], byte 1
202
        jne     .next
203
 
2434 Serge 204
        mov     ecx, [ebx+8]
205
        shr     ecx, 12; ecx = number of pages
206
        jz      .next
207
        mov     edi, [ebx]
208
        shr     edi, 12; edi = first page
209
        mov     eax, edi
210
        shr     edi, 5
211
        shl     edi, 2
212
        add     edi, sys_pgmap-OS_BASE
213
        and     eax, 31
214
        jz      .startok
215
        add     ecx, eax
216
        sub     ecx, 32
217
        jbe     .onedword
218
        push    ecx
219
        mov     ecx, eax
220
        or      eax, -1
221
        shl     eax, cl
222
        or      [edi], eax
223
        add     edi, 4
224
        pop     ecx
1103 diamond 225
.startok:
2434 Serge 226
        push    ecx
227
        shr     ecx, 5
228
        or      eax, -1
229
        rep stosd
230
        pop     ecx
231
        and     ecx, 31
232
        neg     eax
233
        shl     eax, cl
234
        dec     eax
235
        or      [edi], eax
236
        jmp     .next
1103 diamond 237
.onedword:
2434 Serge 238
        add     ecx, 32
239
        sub     ecx, eax
1103 diamond 240
@@:
2434 Serge 241
        bts     [edi], eax
242
        inc     eax
243
        loop    @b
1103 diamond 244
.next:
2434 Serge 245
        add     ebx, 20
246
        dec     edx
247
        jnz     .scanmap
1103 diamond 248
 
249
; mark kernel memory as allocated (unavailable)
2434 Serge 250
        mov     ecx, [tmp_page_tabs]
251
        mov     edx, [pg_data.pages_count-OS_BASE]
252
        shr     ecx, 12
253
        add     ecx, [pg_data.kernel_tables-OS_BASE]
254
        sub     edx, ecx
255
        mov     [pg_data.pages_free-OS_BASE], edx
465 serge 256
 
2434 Serge 257
        mov     edi, sys_pgmap-OS_BASE
258
        mov     ebx, ecx
259
        shr     ecx, 5
260
        xor     eax, eax
261
        rep stosd
465 serge 262
 
2434 Serge 263
        not     eax
264
        mov     ecx, ebx
265
        and     ecx, 31
266
        shl     eax, cl
267
        and     [edi], eax
268
        add     edi, OS_BASE
269
        mov     [page_start-OS_BASE], edi;
465 serge 270
 
2434 Serge 271
        mov     ebx, sys_pgmap
272
        add     ebx, [pg_data.pagemap_size-OS_BASE]
273
        mov     [page_end-OS_BASE], ebx
465 serge 274
 
2434 Serge 275
        ret
465 serge 276
endp
277
 
278
align 4
586 serge 279
 
280
init_BIOS32:
2434 Serge 281
        mov     edi, 0xE0000
586 serge 282
.pcibios_nxt:
2434 Serge 283
        cmp     dword[edi], '_32_'; "magic" word
284
        je      .BIOS32_found
586 serge 285
.pcibios_nxt2:
2434 Serge 286
        add     edi, 0x10
287
        cmp     edi, 0xFFFF0
288
        je      .BIOS32_not_found
289
        jmp     .pcibios_nxt
290
.BIOS32_found:                  ; magic word found, check control summ
586 serge 291
 
2434 Serge 292
        movzx   ecx, byte[edi + 9]
293
        shl     ecx, 4
294
        mov     esi, edi
295
        xor     eax, eax
296
        cld      ; paranoia
297
@@:
298
        lodsb
299
        add     ah, al
300
        loop    @b
301
        jnz     .pcibios_nxt2; control summ must be zero
586 serge 302
    ; BIOS32 service found !
2434 Serge 303
        mov     ebp, [edi + 4]
304
        mov     [bios32_entry], ebp
586 serge 305
    ; check PCI BIOS present
2434 Serge 306
        mov     eax, '$PCI'
307
        xor     ebx, ebx
308
        push    cs  ; special for 'ret far' from  BIOS
309
        call    ebp
310
        test    al, al
311
        jnz     .PCI_BIOS32_not_found
586 serge 312
 
3555 Serge 313
 ; здесь создаются дискрипторы для PCI BIOS
586 serge 314
 
2434 Serge 315
        add     ebx, OS_BASE
316
        dec     ecx
317
        mov     [(pci_code_32-OS_BASE)], cx   ;limit 0-15
318
        mov     [(pci_data_32-OS_BASE)], cx   ;limit 0-15
586 serge 319
 
2434 Serge 320
        mov     [(pci_code_32-OS_BASE)+2], bx ;base  0-15
321
        mov     [(pci_data_32-OS_BASE)+2], bx ;base  0-15
586 serge 322
 
2434 Serge 323
        shr     ebx, 16
324
        mov     [(pci_code_32-OS_BASE)+4], bl ;base  16-23
325
        mov     [(pci_data_32-OS_BASE)+4], bl ;base  16-23
586 serge 326
 
2434 Serge 327
        shr     ecx, 16
328
        and     cl, 0x0F
329
        mov     ch, bh
330
        add     cx, D32
331
        mov     [(pci_code_32-OS_BASE)+6], cx ;lim   16-19 &
332
        mov     [(pci_data_32-OS_BASE)+6], cx ;base  24-31
586 serge 333
 
2434 Serge 334
        mov     [(pci_bios_entry-OS_BASE)], edx
586 serge 335
         ; jmp .end
336
.PCI_BIOS32_not_found:
3555 Serge 337
        ; здесь должна заполнятся pci_emu_dat
586 serge 338
.BIOS32_not_found:
339
.end:
2434 Serge 340
        ret
586 serge 341
 
342
align 4
465 serge 343
proc test_cpu
344
           locals
345
              cpu_type   dd ?
346
              cpu_id     dd ?
347
              cpu_Intel  dd ?
348
              cpu_AMD    dd ?
349
           endl
350
 
2434 Serge 351
        xor     eax, eax
352
        mov     [cpu_type], eax
353
        mov     [cpu_caps-OS_BASE], eax
354
        mov     [cpu_caps+4-OS_BASE], eax
465 serge 355
 
2434 Serge 356
        pushfd
357
        pop     eax
358
        mov     ecx, eax
359
        xor     eax, 0x40000
360
        push    eax
361
        popfd
362
        pushfd
363
        pop     eax
364
        xor     eax, ecx
365
        mov     [cpu_type], CPU_386
366
        jz      .end_cpuid
367
        push    ecx
368
        popfd
465 serge 369
 
2434 Serge 370
        mov     [cpu_type], CPU_486
371
        mov     eax, ecx
372
        xor     eax, 0x200000
373
        push    eax
374
        popfd
375
        pushfd
376
        pop     eax
377
        xor     eax, ecx
378
        je      .end_cpuid
379
        mov     [cpu_id], 1
465 serge 380
 
2434 Serge 381
        xor     eax, eax
382
        cpuid
465 serge 383
 
2434 Serge 384
        mov     [cpu_vendor-OS_BASE], ebx
385
        mov     [cpu_vendor+4-OS_BASE], edx
386
        mov     [cpu_vendor+8-OS_BASE], ecx
387
        cmp     ebx, dword [intel_str-OS_BASE]
388
        jne     .check_AMD
389
        cmp     edx, dword [intel_str+4-OS_BASE]
390
        jne     .check_AMD
391
        cmp     ecx, dword [intel_str+8-OS_BASE]
392
        jne     .check_AMD
393
        mov     [cpu_Intel], 1
394
        cmp     eax, 1
395
        jl      .end_cpuid
396
        mov     eax, 1
397
        cpuid
398
        mov     [cpu_sign-OS_BASE], eax
399
        mov     [cpu_info-OS_BASE], ebx
400
        mov     [cpu_caps-OS_BASE], edx
401
        mov     [cpu_caps+4-OS_BASE], ecx
465 serge 402
 
2434 Serge 403
        shr     eax, 8
404
        and     eax, 0x0f
405
        ret
465 serge 406
.end_cpuid:
2434 Serge 407
        mov     eax, [cpu_type]
408
        ret
465 serge 409
 
410
.check_AMD:
2434 Serge 411
        cmp     ebx, dword [AMD_str-OS_BASE]
412
        jne     .unknown
413
        cmp     edx, dword [AMD_str+4-OS_BASE]
414
        jne     .unknown
415
        cmp     ecx, dword [AMD_str+8-OS_BASE]
416
        jne     .unknown
417
        mov     [cpu_AMD], 1
418
        cmp     eax, 1
419
        jl      .unknown
420
        mov     eax, 1
421
        cpuid
422
        mov     [cpu_sign-OS_BASE], eax
423
        mov     [cpu_info-OS_BASE], ebx
424
        mov     [cpu_caps-OS_BASE], edx
425
        mov     [cpu_caps+4-OS_BASE], ecx
426
        shr     eax, 8
427
        and     eax, 0x0f
428
        ret
465 serge 429
.unknown:
2434 Serge 430
        mov     eax, 1
431
        cpuid
432
        mov     [cpu_sign-OS_BASE], eax
433
        mov     [cpu_info-OS_BASE], ebx
434
        mov     [cpu_caps-OS_BASE], edx
435
        mov     [cpu_caps+4-OS_BASE], ecx
436
        shr     eax, 8
437
        and     eax, 0x0f
438
        ret
465 serge 439
endp
440
 
2439 Serge 441
iglobal
442
align 4
443
acpi_lapic_base   dd 0xfee00000   ; default local apic base
444
endg
445
 
2212 Serge 446
uglobal
447
align 4
448
acpi_rsdp         rd 1
449
acpi_rsdt         rd 1
450
acpi_madt         rd 1
1455 art_zh 451
 
2219 Serge 452
acpi_dev_data     rd 1
453
acpi_dev_size     rd 1
454
 
2212 Serge 455
acpi_rsdt_base    rd 1
3725 Serge 456
acpi_fadt_base    rd 1
457
acpi_dsdt_base    rd 1
458
acpi_dsdt_size    rd 1
2212 Serge 459
acpi_madt_base    rd 1
460
acpi_ioapic_base  rd 1
2439 Serge 461
 
462
cpu_count         rd 1
463
smpt              rd 16
2212 Serge 464
endg
465
 
466
ACPI_HI_RSDP_WINDOW_START  equ 0x000E0000
467
ACPI_HI_RSDP_WINDOW_END    equ 0x00100000
468
ACPI_RSDP_CHECKSUM_LENGTH  equ 20
469
ACPI_MADT_SIGN             equ 0x43495041
3725 Serge 470
ACPI_FADT_SIGN             equ 0x50434146
2212 Serge 471
 
472
 
473
acpi_locate:
2434 Serge 474
        push    ebx
475
        mov     ebx, ACPI_HI_RSDP_WINDOW_START
2212 Serge 476
.check:
2434 Serge 477
        cmp     [ebx], dword 0x20445352
478
        jne     .next
479
        cmp     [ebx+4], dword 0x20525450
480
        jne     .next
2212 Serge 481
 
2434 Serge 482
        mov     edx, ebx
483
        mov     ecx, ACPI_RSDP_CHECKSUM_LENGTH
484
        xor     eax, eax
2212 Serge 485
.sum:
2434 Serge 486
        add     al, [edx]
487
        inc     edx
488
        loop    .sum
2212 Serge 489
 
2434 Serge 490
        test    al, al
491
        jnz     .next
2212 Serge 492
 
2434 Serge 493
        mov     eax, ebx
494
        pop     ebx
2212 Serge 495
        ret
496
.next:
2434 Serge 497
        add     ebx, 16
498
        cmp     ebx, ACPI_HI_RSDP_WINDOW_END
499
        jb      .check
2212 Serge 500
 
2434 Serge 501
        pop     ebx
502
        xor     eax, eax
2212 Serge 503
        ret
504
 
505
align 4
506
rsdt_find:           ;ecx= rsdt edx= SIG
2434 Serge 507
        push    ebx
508
        push    esi
2212 Serge 509
 
2434 Serge 510
        lea     ebx, [ecx+36]
511
        mov     esi, [ecx+4]
512
        add     esi, ecx
2439 Serge 513
align 4
2212 Serge 514
.next:
2434 Serge 515
        mov     eax, [ebx]
516
        cmp     [eax], edx
517
        je      .done
2212 Serge 518
 
2434 Serge 519
        add     ebx, 4
520
        cmp     ebx, esi
521
        jb      .next
2212 Serge 522
 
2434 Serge 523
        xor     eax, eax
524
        pop     esi
525
        pop     ebx
2212 Serge 526
        ret
527
 
528
.done:
2434 Serge 529
        mov     eax, [ebx]
530
        pop     esi
531
        pop     ebx
2212 Serge 532
        ret
533
 
2439 Serge 534
align 4
2212 Serge 535
check_acpi:
536
 
2434 Serge 537
        call    acpi_locate
538
        test    eax, eax
539
        jz      .done
2212 Serge 540
 
2434 Serge 541
        mov     ecx, [eax+16]
3725 Serge 542
        mov     edx, 0x50434146
2434 Serge 543
        mov     [acpi_rsdt_base-OS_BASE], ecx
544
        call    rsdt_find
3725 Serge 545
        mov     [acpi_fadt_base-OS_BASE], eax
2434 Serge 546
        test    eax, eax
3725 Serge 547
        jz      @f
548
 
549
        mov     eax, [eax+40]
550
        mov     [acpi_dsdt_base-OS_BASE], eax
551
        mov     eax, [eax+4]
552
        mov     [acpi_dsdt_size-OS_BASE], eax
553
 
554
@@:
555
        mov     edx, ACPI_MADT_SIGN
556
        mov     ecx, [acpi_rsdt_base-OS_BASE]
557
        call    rsdt_find
558
        test    eax, eax
2434 Serge 559
        jz      .done
2212 Serge 560
 
2434 Serge 561
        mov     [acpi_madt_base-OS_BASE], eax
562
        mov     ecx, [eax+36]
563
        mov     [acpi_lapic_base-OS_BASE], ecx
2212 Serge 564
 
2439 Serge 565
        mov     edi, smpt-OS_BASE
566
        mov     ebx, [ecx+0x20]
567
        shr     ebx, 24              ; read APIC ID
568
 
569
        mov     [edi], ebx           ; bootstrap always first
2441 Serge 570
        inc     [cpu_count-OS_BASE]
2439 Serge 571
        add     edi, 4
572
 
2434 Serge 573
        lea     edx, [eax+44]
574
        mov     ecx, [eax+4]
575
        add     ecx, eax
2212 Serge 576
.check:
2434 Serge 577
        mov     eax, [edx]
2439 Serge 578
        cmp     al, 0
579
        jne     .io_apic
2212 Serge 580
 
2439 Serge 581
        shr     eax, 24              ; get APIC ID
582
        cmp     eax, ebx             ; skip self
583
        je      .next
584
 
585
        test    [edx+4], byte 1      ; is enabled ?
586
        jz      .next
587
 
588
        cmp     [cpu_count-OS_BASE], 16
589
        jae     .next
590
 
591
        stosd                        ; store APIC ID
592
        inc     [cpu_count-OS_BASE]
2212 Serge 593
.next:
2439 Serge 594
        mov     eax, [edx]
2434 Serge 595
        movzx   eax, ah
596
        add     edx, eax
597
        cmp     edx, ecx
598
        jb      .check
2212 Serge 599
.done:
600
        ret
2439 Serge 601
 
602
.io_apic:
603
        cmp     al, 1
604
        jne     .next
605
 
2434 Serge 606
        mov     eax, [edx+4]
607
        mov     [acpi_ioapic_base-OS_BASE], eax
2439 Serge 608
        jmp     .next