Subversion Repositories Kolibri OS

Rev

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

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